diff --git a/packages/app/package.json b/packages/app/package.json index ddc8f13..03aafb8 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -27,6 +27,7 @@ "@zk-email/circuits": "6.1.1", "@zk-email/helpers": "6.1.1", "@zk-email/zk-email-sdk": "^1.0.5", + "@zk-email/relayer-utils": "^0.4.2", "archiver": "^7.0.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", diff --git a/packages/app/src/app/submit/email/action.ts b/packages/app/src/app/submit/email/action.ts index 7253659..4d7cdf4 100644 --- a/packages/app/src/app/submit/email/action.ts +++ b/packages/app/src/app/submit/email/action.ts @@ -3,6 +3,7 @@ import { z } from 'zod'; import { formSchema } from '../form'; import { generateCodeLibrary } from '@/lib/code-gen/gen'; import { verifyDKIMSignature } from "@zk-email/helpers/dist/dkim"; +import { extractMatches, extractMatchesWasm, Values } from '@/lib/regex'; export interface ProcessEmailResult { error: boolean, @@ -73,7 +74,7 @@ export async function processEmail(values: z.infer, email: st } // Apply regex - const matches = extractMatches(headerString, bodyString, values.parameters.values as Values[]); + const matches = await extractMatchesWasm(headerString, bodyString, values.parameters.values as Values[]); const parameters = { ...values.parameters, @@ -94,62 +95,4 @@ export async function processEmail(values: z.infer, email: st parameters: res, matches, } -} - -interface Values { - name: string, - location: "header" | "body", - parts: { - regex_def: string, - is_public: boolean, - }[], -} - -function extractMatches(headerString: string, bodyString: string | undefined, values: Values[]) { - const regexes = values.map((v: any) => { - let publicGroups: number[] = []; - let index = 1; - const regex = v.parts.reduce((acc: any, part: any) => { - if (part.regex_def.match(/\([^\)]+/)) index++; - if (part.is_public) { - publicGroups.push(index); - index++; - return acc + "(" + part.regex_def + ")" - } - return acc + part.regex_def - }, ""); - return { - regex, - publicGroups, - name: v.name, - location: v.location, - } - }) - - let matches = [] - - for (const regex of regexes) { - if (regex.location == "body" && bodyString) { - const match = bodyString.match(regex.regex) - if (match) { - for (const group of regex.publicGroups) { - matches.push({ - name: regex.name, - match: match[group], - }) - } - } - } else { - const match = headerString.match(regex.regex) - if (match) { - for (const group of regex.publicGroups) { - matches.push({ - name: regex.name, - match: match[group], - }) - } - } - } - } - return matches; } \ No newline at end of file diff --git a/packages/app/src/lib/regex.ts b/packages/app/src/lib/regex.ts new file mode 100644 index 0000000..20fa78c --- /dev/null +++ b/packages/app/src/lib/regex.ts @@ -0,0 +1,103 @@ +import initWasm, { extractSubstr, extractSubstrIdxes } from "@zk-email/relayer-utils"; +import fs from "fs"; + +let wasmLoaded: Promise; +const code = fs.readFileSync("node_modules/@zk-email/relayer-utils/relayer_utils_bg.wasm"); +wasmLoaded = initWasm({ module_or_path: code }).then(() => { + return true; +}) + +export interface Values { + name: string, + location: "header" | "body", + parts: { + regex_def: string, + is_public: boolean, + }[], +} + +export function extractMatches(headerString: string, bodyString: string | undefined, values: Values[]) { + const regexes = values.map((v: any) => { + let publicGroups: number[] = []; + let index = 1; + const regex = v.parts.reduce((acc: any, part: any) => { + const regexWithoutGroup = part.regex_def.replace("(", "(?:") + if (part.is_public) { + publicGroups.push(index); + index++; + return acc + "(" + regexWithoutGroup + ")" + } + return acc + regexWithoutGroup + }, ""); + return { + regex, + publicGroups, + name: v.name, + location: v.location, + } + }) + + let matches = [] + + for (const regex of regexes) { + if (regex.location == "body" && bodyString) { + const match = bodyString.match(regex.regex) + if (match) { + for (const group of regex.publicGroups) { + matches.push({ + name: regex.name, + match: match[group], + }) + } + } + } else { + const match = headerString.match(regex.regex) + if (match) { + for (const group of regex.publicGroups) { + matches.push({ + name: regex.name, + match: match[group], + }) + } + } + } + } + return matches; +} + +export async function extractMatchesWasm(headerString: string, bodyString: string | undefined, values: Values[]) { + let ready = await wasmLoaded; + let matches: {name: string, match: string}[] = []; + for (const value of values) { + if (value.location == "body" && bodyString) { + try { + let match = extractSubstr(bodyString, value, false) + if (match.length > 0) { + matches = matches.concat(match.map( (m:string) => { + return { + name: value.name, + match: m, + } + })); + } + } catch (e) { + console.error(e); + } + } else { + try { + let match = extractSubstr(headerString, value, false) + if (match.length > 0) { + matches = matches.concat(match.map( (m:string) => { + return { + name: value.name, + match: m, + } + })); + } + } catch (e) { + console.error(e); + } + } + } + return matches; +} diff --git a/packages/app/src/scripts/regex.ts b/packages/app/src/scripts/regex.ts new file mode 100644 index 0000000..fc9e1fb --- /dev/null +++ b/packages/app/src/scripts/regex.ts @@ -0,0 +1,53 @@ +// import initWasm, { extractSubstr, extractSubstrIdxes } from "@zk-email/relayer-utils"; +// import fs from "fs"; + +import { extractMatches, extractMatchesWasm } from "@/lib/regex" + +// (async () => { +// const code = fs.readFileSync("node_modules/@zk-email/relayer-utils/relayer_utils_bg.wasm"); +// await initWasm({module_or_path: code}); +// const email = "subject:Congratulations mr x\r\n"; +// const matches = extractSubstr(email, { +// parts: [ +// { +// "is_public": false, +// "regex_def": "(\r\n|^)subject:" +// }, +// { +// "is_public": true, +// "regex_def": "Congratulations" +// }, +// { +// "is_public": false, +// "regex_def": "[^\r]+\r\n" +// } +// ] +// }, false) +// console.log(matches) +// })() + +const matches = extractMatchesWasm("\r\nsubject:Congratulations mr x\r\n", "body", [{ + name: "subject", + location: "header", + parts: [ + { + "is_public": false, + "regex_def": "(\r\n|^)subject:" + }, + { + "is_public": true, + "regex_def": "Congratulations" + }, + { + "is_public": false, + "regex_def": "[^\r]+\r\n" + } + ], +}, {name: "body", location: "body", parts: [ + { + "is_public": true, + "regex_def": "body" + } +]}]).then((matches) => { + console.log(matches) +}) \ No newline at end of file diff --git a/packages/app/yarn.lock b/packages/app/yarn.lock index d4cecb6..e59df71 100644 --- a/packages/app/yarn.lock +++ b/packages/app/yarn.lock @@ -2531,6 +2531,11 @@ psl "^1.9.0" snarkjs "https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e" +"@zk-email/relayer-utils@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@zk-email/relayer-utils/-/relayer-utils-0.4.2.tgz#8e13277c1c14ac7c17a0df60803eb8ab5a3d0091" + integrity sha512-IqJOQ75xou1H6LpTEekYMkSFtBKW2KNtCkbGVKg/vps3w3xso/qSzT8myHYKw7nm69bPRRMPVkhtFyyd33DDhQ== + "@zk-email/zk-email-sdk@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@zk-email/zk-email-sdk/-/zk-email-sdk-1.0.5.tgz#2ae9724653c652b87d0d9b62fcf12dc0a15ac545"