diff --git a/libs/common/src/vault/search/ast.ts b/libs/common/src/vault/search/ast.ts index eb4a5e97151..e0d37afed3d 100644 --- a/libs/common/src/vault/search/ast.ts +++ b/libs/common/src/vault/search/ast.ts @@ -13,6 +13,7 @@ export const AstNodeTypeNames = [ "inFolder", "inCollection", "inOrg", + "inTrash", "isFavorite", ] as const; export type AstNodeType = (typeof AstNodeTypeNames)[number]; @@ -31,6 +32,7 @@ export type AstNode = | InFolder | InCollection | InOrg + | InTrash | IsFavorite; type AstNodeBase = { @@ -165,6 +167,14 @@ export function isInOrg(x: AstNode): x is InOrg { return x.type === "inOrg"; } +export type InTrash = AstNodeBase & { + type: "inTrash"; +}; + +export function isInTrash(x: AstNode): x is InTrash { + return x.type === "inTrash"; +} + export type IsFavorite = AstNodeBase & { type: "isFavorite"; }; diff --git a/libs/common/src/vault/search/bitwarden-query-grammar.ne b/libs/common/src/vault/search/bitwarden-query-grammar.ne index a641406b62a..2690cabb0e3 100644 --- a/libs/common/src/vault/search/bitwarden-query-grammar.ne +++ b/libs/common/src/vault/search/bitwarden-query-grammar.ne @@ -55,6 +55,8 @@ TERM -> | %func_in "collection" %access %string {% function(d) { const start = d[0].offset; const end = d[3].offset + d[3].value.length; return { type: 'inCollection', collection: d[3].value, d: d, start, end, length: end - start + 1 } } %} # only items assigned to a specified organization | %func_in "org" %access %string {% function(d) { const start = d[0].offset; const end = d[3].offset + d[3].value.length; return { type: 'inOrg', org: d[3].value, d: d, start, end, length: end - start + 1 } } %} + # only items in trash + | %func_in "trash" {% function(d) { const start = d[0].offset; const length = 8; return { type: 'inTrash', d: d, start, end: start + length, length } } %} # only items marked as favorites | %func_is "favorite" {% function(d) { const start = d[0].offset; const length = 11; return { type: 'isFavorite', d: d, start, end: d[0].offset + length, length } } %} # Boolean NOT operator diff --git a/libs/common/src/vault/search/bitwarden-query-grammar.ts b/libs/common/src/vault/search/bitwarden-query-grammar.ts index b52c915b87d..96eb107d2c4 100644 --- a/libs/common/src/vault/search/bitwarden-query-grammar.ts +++ b/libs/common/src/vault/search/bitwarden-query-grammar.ts @@ -260,6 +260,15 @@ const grammar: Grammar = { return { type: "inOrg", org: d[3].value, d: d, start, end, length: end - start + 1 }; }, }, + { + name: "TERM", + symbols: [lexer.has("func_in") ? { type: "func_in" } : func_in, { literal: "trash" }], + postprocess: function (d) { + const start = d[0].offset; + const length = 8; + return { type: "inTrash", d: d, start, end: start + length, length }; + }, + }, { name: "TERM", symbols: [lexer.has("func_is") ? { type: "func_is" } : func_is, { literal: "favorite" }], diff --git a/libs/common/src/vault/search/parse.ts b/libs/common/src/vault/search/parse.ts index 70b891d2368..9ea2340e057 100644 --- a/libs/common/src/vault/search/parse.ts +++ b/libs/common/src/vault/search/parse.ts @@ -14,6 +14,7 @@ import { isInCollection, isInFolder, isInOrg, + isInTrash, isIsFavorite, isNot, isOr, @@ -265,6 +266,20 @@ function handleNode(node: AstNode): ProcessInstructions { }, ], }; + } else if (isInTrash(node)) { + return { + filter: (context) => ({ + ...context, + ciphers: context.ciphers.filter((cipher) => cipher.isDeleted), + }), + sections: [ + { + start: node.start, + end: node.end, + type: node.type, + }, + ], + }; } else if (isIsFavorite(node)) { return { filter: (context) => ({