Skip to content

Commit

Permalink
fix: diagnose to use new guards
Browse files Browse the repository at this point in the history
  • Loading branch information
phanshiyu committed Apr 26, 2024
1 parent d8c4694 commit c5a5c96
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 114 deletions.
22 changes: 22 additions & 0 deletions src/4.0/diagnose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Diagnose } from "src/shared/utils/@types/diagnose";
import { V4WrappedDocument, V4SignedWrappedDocument } from "./types";

export const v4Diagnose: Diagnose = ({ document, kind, debug }) => {
const Validator = kind === "signed" ? V4SignedWrappedDocument : V4WrappedDocument;

const results = Validator.safeParse(document);

if (results.success) {
return [];
}

return results.error.errors.map(({ code, message, path }) => {
const errorMessage = `${code}: ${message} at ${path.join(".")}`;
if (debug) {
console.debug(errorMessage);
}
return {
message: errorMessage,
};
});
};
3 changes: 3 additions & 0 deletions src/shared/utils/@types/diagnose.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export type Kind = "raw" | "wrapped" | "signed";
export type Mode = "strict" | "non-strict";
export type Diagnose = (props: { kind: Exclude<Kind, "raw">; document: any; debug: boolean; mode: Mode }) => {
message: string;
}[];
130 changes: 16 additions & 114 deletions src/shared/utils/diagnose.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { logger } from "ethers";
import { ContextUrl, SchemaId } from "../@types/document";
import { SchemaId } from "../@types/document";
import { validateSchema as validate } from "../validate";
import {
VerifiableCredentialWrappedProof as WrappedProofV3,
Expand All @@ -10,7 +10,7 @@ import { ArrayProof, Signature, SignatureStrict } from "../../2.0/types";
import { clone, cloneDeepWith } from "lodash";
import { buildAjv, getSchema } from "../ajv";
import { Kind, Mode } from "./@types/diagnose";
import { isStringArray } from "./utils";
import { v4Diagnose } from "src/4.0/diagnose";

type Version = "2.0" | "3.0" | "4.0";

Expand Down Expand Up @@ -85,25 +85,24 @@ export const diagnose = ({
return handleError(debug, "The document must be an object");
}

const versionToSchemaId: Record<Version, SchemaId> = {
const versionToSchemaId: Record<Version, SchemaId | undefined> = {
"2.0": SchemaId.v2,
"3.0": SchemaId.v3,
"4.0": "" as SchemaId,
"4.0": undefined,
};

const errors = validate(
document,
getSchema(versionToSchemaId[version], mode === "non-strict" ? ajv : undefined),
kind
);
const schemaId = versionToSchemaId[version];
if (schemaId) {
const errors = validate(document, getSchema(schemaId, mode === "non-strict" ? ajv : undefined), kind);

if (errors.length > 0) {
// TODO this can be improved later
return handleError(
debug,
`The document does not match OpenAttestation schema ${version}`,
...errors.map((error) => `${error.instancePath || "document"} - ${error.message}`)
);
if (errors.length > 0) {
// TODO this can be improved later
return handleError(
debug,
`The document does not match OpenAttestation schema ${version}`,
...errors.map((error) => `${error.instancePath || "document"} - ${error.message}`)
);
}
}

if (kind === "raw") {
Expand All @@ -112,7 +111,7 @@ export const diagnose = ({

switch (version) {
case "4.0":
return diagnoseV4({ mode, debug, document, kind });
return v4Diagnose({ mode, debug, document, kind });
case "3.0":
return diagnoseV3({ mode, debug, document, kind });
case "2.0":
Expand Down Expand Up @@ -185,100 +184,3 @@ const diagnoseV3 = ({ kind, document, debug, mode }: { kind: Kind; document: any
}
return [];
};

const diagnoseV4 = ({
kind,
document,
debug,
mode,
}: {
kind: Exclude<Kind, "raw">;
document: any;
debug: boolean;
mode: Mode;
}) => {
/* Wrapped document checks */
try {
// 1. Since OA v4 has deprecated a few properties from v2/v3, check that they are not used
const deprecatedProperties = ["version", "openAttestationMetadata"];
const documentProperties = Object.keys(document);
const deprecatedDocumentProperties = documentProperties.filter((p) => deprecatedProperties.includes(p));

if (deprecatedDocumentProperties.length > 0) {
return handleError(
debug,
`The document has outdated properties previously used in v2/v3. The following properties are no longer in use in a v4 document: ${deprecatedDocumentProperties}`
);
}

// 2. Ensure that required @contexts are present
// @context: [Base, OA, ...]
const contexts = [ContextUrl.v2_vc, ContextUrl.v4_alpha];
if (isStringArray(document["@context"])) {
for (let i = 0; i < contexts.length; i++) {
if (document["@context"][i] !== contexts[i]) {
return handleError(
debug,
`The document @context contains an unexpected value or in the wrong order. Expected "${contexts}" but received "${document["@context"]}"`
);
}
}
} else {
return handleError(
debug,
`The document @context should be an array of string values. Expected "${contexts}" but received "${document["@context"]}"`
);
}

// 3. Ensure that required types are present
// type: ["VerifiableCredential", "OpenAttestationCredential", ...]
const types = ["VerifiableCredential", "OpenAttestationCredential"];
if (isStringArray(document["type"])) {
for (let i = 0; i < types.length; i++) {
if (document["type"][i] !== types[i]) {
return handleError(
debug,
`The document type contains an unexpected value or in the wrong order. Expected "${types}" but received "${document["type"]}"`
);
}
}
} else {
return handleError(
debug,
`The document type should be an array of string values. Expected "${types}" but received "${document["type"]}"`
);
}

// 4. Check proof object
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
if (mode === "strict") {
// WrappedProofStrictV4.check(document.proof);
} else {
// WrappedProofV4.check(document.proof);
}
} catch (e) {
if (e instanceof Error) {
return handleError(debug, e.message);
} else {
console.error(e);
}
}

/* Signed & wrapped document checks */
if (kind === "signed") {
if (!document.proof) {
return handleError(debug, `The document does not have a proof`);
}
try {
// SignedWrappedProofV4.check(document.proof);
} catch (e) {
if (e instanceof Error) {
return handleError(debug, e.message);
} else {
console.error(e);
}
}
}

return [];
};

0 comments on commit c5a5c96

Please sign in to comment.