diff --git a/src/models/proof.ts b/src/models/proof.ts index 679d0e8..b00012f 100644 --- a/src/models/proof.ts +++ b/src/models/proof.ts @@ -83,11 +83,6 @@ type FlagMatchInfo = { re: string; }; -type FlagMatch = { - re: RegExp; - value: string; -}; - const ruleScreenshot = (): FlagMatchRule[] => { return [ { @@ -146,85 +141,19 @@ const aiHintFlags = (): FlagMatchRule[] => { }; const matchFlag = (rules: FlagMatchRule[], file: any) => { - const matchParts = (parts: string[], o: any, re: RegExp[]): FlagMatch[] | undefined => { - if (parts.length == 0 || o == undefined) return undefined; - let part = parts[0]; - const lastBracket = part.lastIndexOf("["); - if (part.endsWith("]") && lastBracket > 0) { - const optionalConstraint = part.substring(lastBracket + 1, part.length - 1); - part = part.substring(0, lastBracket); - if (o[part] != undefined) { - let opart: any[] = o[part]; - if (!Array.isArray(opart)) { - opart = Object.values(opart) ?? []; - } - - // Any constraints controlling what array object(s) to consider? - if (optionalConstraint) { - const [prop, val] = optionalConstraint.split("="); - opart = opart.filter((item) => item[prop] === val); - } - - if (parts.length == 1) { - let strings = opart as string[]; - if (!strings) return undefined; - return strings.reduce((res: FlagMatch[] | undefined, s: any) => { - return re.reduce((res: FlagMatch[] | undefined, r: any) => { - if (r.test(s)) { - const r2 = res || []; - r2.push({ re: r, value: s as string }); - return r2; - } - return res; - }, res); - }, undefined); - } else { - return opart.reduce((res: FlagMatch[] | undefined, o: any) => { - let matches = matchParts(parts.slice(1), o, re); - if (matches) { - const r2 = res || []; - r2.push(...matches); - return r2; - } - return res; - }, undefined); - } - } else { - return undefined; - } - } else { - if (o[part] != undefined) { - if (parts.length == 1) { - return re.reduce((res: FlagMatch[] | undefined, r: any) => { - if (r.test(o[part])) { - const r2 = res || []; - r2.push({ re: r, value: o[part] as string }); - return r2; - } - return res; - }, undefined); - } else { - return matchParts(parts.slice(1), o[part], re); - } - } else { - return undefined; - } - } - }; - let result = false; let resultInfo: FlagMatchInfo[] = []; for (let rule of rules) { try { const re: RegExp[] = (!Array.isArray(rule.match) ? [rule.match] : rule.match).map((m) => new RegExp(m, "gi")); - let parts = rule.field.split("/"); - let matches = matchParts(parts, file, re); - if (matches) { - matches.forEach((m) => { - resultInfo.push({ field: rule.description, value: m.value, re: m.re.source }); + const values = extractFlagValues(rule.field, file); + values.forEach((v) => { + re.forEach((r) => { + if (r.test(v.value)) { + resultInfo.push({ field: v.path, value: v.value, re: r.source }) + } }); - result = true; - } + }) } catch (e) { console.error("Invalid RE", e); } @@ -300,11 +229,6 @@ const extractFlagValues = (flagPath: string, file: any): FlagMatchRuleValue[] => export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined => { if (!proof) return undefined; - let foundCreated = false; - - let screenshot = false; - let camera = false; - let aiGenerated = false; let aiEdited = false; let valid = false; @@ -313,55 +237,16 @@ export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined if (results) { valid = results.failure.length == 0 && results.success.length > 0; } - - const manifests = Object.values(proof.integrity?.c2pa?.manifest_info.manifests ?? {}); - for (const manifest of manifests) { - for (const assertion of manifest.assertions) { - if (assertion.label === "c2pa.actions") { - const actions = (assertion.data as C2PAActionsAssertion)?.actions ?? []; - const a = actions.find((a) => a.action === "c2pa.created"); - if (a) { - // creator.value = a.softwareAgent; - // dateCreated.value = dayjs(Date.parse(manifest.signature_info.time)); - if (a.digitalSourceType === C2PASourceTypeScreenCapture) { - screenshot = true; - } - if ( - a.digitalSourceType === C2PASourceTypeDigitalCapture || - a.digitalSourceType === C2PASourceTypeComputationalCapture || - a.digitalSourceType === C2PASourceTypeCompositeCapture - ) { - camera = true; - } - if ( - a.digitalSourceType === C2PASourceTypeTrainedAlgorithmicMedia || - a.digitalSourceType === C2PASourceTypeCompositeWithTrainedAlgorithmicMedia - ) { - aiGenerated = true; - } - foundCreated = true; - break; - } - } - if (foundCreated) { - break; - } - } - if (foundCreated) { - break; - } - } if (valid) { - const dateCreated = extractFlagValues("integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/../../../../signature_info/issuer", proof); - console.error("DATE CREATED", dateCreated); + const dateCreated = extractFlagValues("integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/../../../../signature_info/time", proof); + console.log("DATE CREATED", dateCreated); - screenshot = matchFlag(ruleScreenshot(), proof).result; const flags: ProofHintFlags = { - aiGenerated, + aiGenerated: matchFlag(ruleAiGenerated(), proof).result, aiEdited, - screenshot, - camera, + screenshot: matchFlag(ruleScreenshot(), proof).result, + camera: matchFlag(ruleCamera(), proof).result, }; return flags; }