diff --git a/source/main/services/browser/api.ts b/source/main/services/browser/api.ts index b0d2a13f..b5f2b102 100644 --- a/source/main/services/browser/api.ts +++ b/source/main/services/browser/api.ts @@ -2,7 +2,7 @@ import express, { Request, Response, NextFunction } from "express"; import createRouter from "express-promise-router"; import { VERSION } from "../../library/build"; import { handleAuthPing, processAuthRequest, processAuthResponse } from "./controllers/auth"; -import { searchEntries } from "./controllers/entries"; +import { searchEntries, searchSpecificEntries } from "./controllers/entries"; import { getAllOTPs } from "./controllers/otp"; import { getVaults, getVaultsTree, promptVaultLock, promptVaultUnlock } from "./controllers/vaults"; import { handleError } from "./error"; @@ -29,6 +29,7 @@ function createRoutes(app: express.Application): void { router.post("/auth/response", processAuthResponse); router.post("/auth/test", requireClient, requireKeyAuth, handleAuthPing); router.get("/entries", requireClient, searchEntries); + router.post("/entries/specific", requireClient, requireKeyAuth, searchSpecificEntries); router.get("/otps", requireClient, getAllOTPs); router.get("/vaults", requireClient, getVaults); router.get("/vaults-tree", requireClient, getVaultsTree); diff --git a/source/main/services/browser/controllers/entries.ts b/source/main/services/browser/controllers/entries.ts index d729ab75..abcd0120 100644 --- a/source/main/services/browser/controllers/entries.ts +++ b/source/main/services/browser/controllers/entries.ts @@ -1,11 +1,12 @@ import { Request, Response } from "express"; -import { SearchResult } from "buttercup"; -import { EntriesSearchPayloadSchema, EntriesSearchType } from "../models"; +import { PropertyKeyValueObject, SearchResult, getEntryURLs } from "buttercup"; +import { EntriesSearchBodySchema, EntriesSearchQuerySchema, EntriesSearchType } from "../models"; import { searchAllVaultsByTerm, searchAllVaultsByURL } from "../../search"; import { respondJSON } from "../response"; +import { getEntries } from "../../buttercup"; export async function searchEntries(req: Request, res: Response) { - const config = EntriesSearchPayloadSchema.parse(req.query); + const config = EntriesSearchQuerySchema.parse(req.query); let results: Array = []; if (config.type === EntriesSearchType.Term) { results = await searchAllVaultsByTerm(config.term); @@ -16,3 +17,21 @@ export async function searchEntries(req: Request, res: Response) { results }); } + +export async function searchSpecificEntries(req: Request, res: Response) { + const { entries } = EntriesSearchBodySchema.parse(req.body); + const resultItems = await getEntries(entries as Array<{ entryID: string; sourceID: string }>); + const results: Array = resultItems.map((item) => ({ + entryType: item.entry.getType(), + groupID: item.entry.getGroup().id, + id: item.entry.id, + properties: item.entry.getProperty() as PropertyKeyValueObject, + tags: item.entry.getTags(), + sourceID: item.sourceID, + urls: getEntryURLs(item.entry.getProperty() as PropertyKeyValueObject), + vaultID: item.entry.vault.id + })); + await respondJSON(res, { + results + }); +} diff --git a/source/main/services/browser/models.ts b/source/main/services/browser/models.ts index af7afa65..16a513a9 100644 --- a/source/main/services/browser/models.ts +++ b/source/main/services/browser/models.ts @@ -21,7 +21,16 @@ export enum EntriesSearchType { URL = "url" } -export const EntriesSearchPayloadSchema = z.discriminatedUnion("type", [ +export const EntriesSearchBodySchema = z.object({ + entries: z.array( + z.object({ + entryID: z.string().min(1), + sourceID: z.string().min(1) + }) + ) +}); + +export const EntriesSearchQuerySchema = z.discriminatedUnion("type", [ z.object({ term: z.string(), type: z.literal(EntriesSearchType.Term) diff --git a/source/main/services/buttercup.ts b/source/main/services/buttercup.ts index 38a684de..7cde1b39 100644 --- a/source/main/services/buttercup.ts +++ b/source/main/services/buttercup.ts @@ -164,6 +164,23 @@ export async function getAttachmentDetails( return source.attachmentManager.getAttachmentDetails(entry, attachmentID); } +export async function getEntries( + entries: Array<{ entryID: EntryID; sourceID: VaultSourceID }> +): Promise> { + const vaultManager = getVaultManager(); + return entries.reduce((output, item) => { + const source = vaultManager.getSourceForID(item.sourceID); + if (!source || source.status !== VaultSourceStatus.Unlocked) return output; + return [ + ...output, + { + entry: source.vault.findEntryByID(item.entryID), + sourceID: item.sourceID + } + ]; + }, []); +} + export function getSourceDescription(sourceID: VaultSourceID): VaultSourceDescription { const vaultManager = getVaultManager(); const source = vaultManager.getSourceForID(sourceID);