diff --git a/package-lock.json b/package-lock.json index 8ead929d..07f73376 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1958,9 +1958,9 @@ } }, "@govtechsg/open-attestation": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@govtechsg/open-attestation/-/open-attestation-6.2.0.tgz", - "integrity": "sha512-LSssNwtEXHvkJFKlP/rOCdx1S8S1B2k5MwgDvtUVbhLiBKDlmSbUZl3FS5uCF7bTHzaJJmgDrxZs5QJ969gE3Q==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@govtechsg/open-attestation/-/open-attestation-6.4.1.tgz", + "integrity": "sha512-/fM8zpUJ847SHZEGhuR8MIcFZVx5Gi/UnR+imm0cZYXkTqy/pA8shj0M01RiHEyEM5Z/64atk5zh3lsfN/7qDw==", "requires": { "@govtechsg/jsonld": "^0.1.0", "ajv": "^8.6.2", @@ -5239,9 +5239,9 @@ "dev": true }, "canonicalize": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.5.tgz", - "integrity": "sha512-mAjKJPIyP0xqqv6IAkvso07StOmz6cmGtNDg3pXCSzXVZOqka7StIkAhJl/zHOi4M2CgpYfD6aeRWbnrmtvBEA==" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", + "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==" }, "capture-exit": { "version": "2.0.0", diff --git a/package.json b/package.json index ad43d425..475c83d0 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "@govtechsg/document-store": "^2.2.2", "@govtechsg/oa-encryption": "^1.3.3", "@govtechsg/oa-verify": "^7.5.2", - "@govtechsg/open-attestation": "^6.2.0", + "@govtechsg/open-attestation": "^6.4.1", "@govtechsg/token-registry": "^2.5.3", "ajv": "^8.4.0", "ajv-formats": "^2.1.0", diff --git a/src/implementations/config/create.ts b/src/implementations/config/create.ts index 4ea933f3..9665c365 100644 --- a/src/implementations/config/create.ts +++ b/src/implementations/config/create.ts @@ -13,6 +13,7 @@ import { getTokenRegistryAddress, getDocumentStoreAddress, } from "./helpers"; +import { utils, v2, v3 } from "@govtechsg/open-attestation"; const SANDBOX_ENDPOINT_URL = "https://sandbox.fyntech.io"; @@ -35,9 +36,21 @@ export const create = async ({ const hasTransferableRecord = forms.some((form) => form.type === "TRANSFERABLE_RECORD"); const hasDocumentStore = forms.some((form) => form.type === "VERIFIABLE_DOCUMENT"); - const hasDid = forms.some( - (form) => form.defaults.issuers.some((issuer) => issuer.identityProof?.type.includes("DID")) // TODO: v3 does not have `issuers` but `issuer` instead - ); + const hasDid = forms.some((form) => { + //check form for v2/v3 + const didCheckList = ["DID", "DNS-DID"]; + if (utils.isRawV3Document(form.defaults)) { + const v3Defaults = form.defaults as v3.OpenAttestationDocument; + return didCheckList.includes(v3Defaults.openAttestationMetadata.proof.method); + } else { + const v2Defaults = form.defaults as v2.OpenAttestationDocument; + return v2Defaults.issuers.some((issuer) => { + const identityProof = issuer.identityProof; + if (!identityProof) return false; + return didCheckList.includes(identityProof.type); + }); + } + }); let tokenRegistryAddress = ""; let documentStoreAddress = ""; diff --git a/src/implementations/config/helpers.ts b/src/implementations/config/helpers.ts index bee8af20..76a6eb7a 100644 --- a/src/implementations/config/helpers.ts +++ b/src/implementations/config/helpers.ts @@ -1,4 +1,4 @@ -import { v2 } from "@govtechsg/open-attestation"; +import { utils, v2, v3 } from "@govtechsg/open-attestation"; import fetch from "node-fetch"; import { info, success } from "signale"; import { highlight } from "../../utils"; @@ -37,37 +37,28 @@ export const getConfigWithUpdatedForms = ({ dnsTransferableRecord, }: UpdatedForms): ConfigFile => { const { wallet, forms } = configFile; - const { encryptedJson } = wallet; - const { address } = JSON.parse(encryptedJson); const updatedForms = forms.map((form: Form) => { - if (form.type === "VERIFIABLE_DOCUMENT") { - const updatedIssuers = form.defaults.issuers.map((issuer) => { - if (issuer.identityProof) { - if (issuer.identityProof.type === "DNS-TXT") { - issuer.documentStore = documentStoreAddress; - issuer.identityProof.location = dnsVerifiable; - } else if (issuer.identityProof.type === "DID" || issuer.identityProof.type === "DNS-DID") { - issuer.id = `did:ethr:0x${address}`; - issuer.identityProof.location = dnsDid; - issuer.identityProof.key = `did:ethr:0x${address}#controller`; - if (issuer.revocation) { - issuer.revocation.type = "NONE" as v2.RevocationType; - } - } - } - return issuer; + if (utils.isRawV3Document(form.defaults)) { + utils.updateFormV3({ + wallet, + form, + documentStoreAddress, + tokenRegistryAddress, + dnsVerifiable: dnsVerifiable || "", + dnsDid: dnsDid || "", + dnsTransferableRecord: dnsTransferableRecord || "", }); - form.defaults.issuers = updatedIssuers; - } - - if (form.type === "TRANSFERABLE_RECORD") { - const updatedIssuers = form.defaults.issuers.map((issuer) => { - issuer.tokenRegistry = tokenRegistryAddress; - if (issuer.identityProof?.location) issuer.identityProof.location = dnsTransferableRecord; - return issuer; + } else { + utils.updateFormV2({ + wallet, + form, + documentStoreAddress, + tokenRegistryAddress, + dnsVerifiable: dnsVerifiable || "", + dnsDid: dnsDid || "", + dnsTransferableRecord: dnsTransferableRecord || "", }); - form.defaults.issuers = updatedIssuers; } return form; @@ -124,14 +115,30 @@ export const getDocumentStoreAddress = async (encryptedWalletPath: string): Prom }; export const validate = (forms: Form[]): boolean => { - const isValidForm = forms.some((form: Form) => { - const isValidFormType = form.type === "TRANSFERABLE_RECORD" && "VERIFIABLE_DOCUMENT"; - const isValidIdentityProofType = form.defaults.issuers.some( - (issuer) => issuer.identityProof?.type === "DNS-TXT" && "DNS-DID" && "DID" - ); - + const isValidForm = forms.map((form: Form) => { + const formTypeCheckList = ["TRANSFERABLE_RECORD", "VERIFIABLE_DOCUMENT"]; + const isValidFormType = formTypeCheckList.includes(form.type); + let isValidIdentityProofType: boolean; + + const identityProofTypeCheckList = ["DNS-TXT", "DNS-DID", "DID"]; + // test for v2/v3 form defaults + if (utils.isRawV3Document(form.defaults)) { + const v3Defaults = form.defaults as v3.OpenAttestationDocument; + isValidIdentityProofType = identityProofTypeCheckList.includes( + v3Defaults.openAttestationMetadata.identityProof.type + ); + } else { + const v2Defaults = form.defaults as v2.OpenAttestationDocument; + isValidIdentityProofType = v2Defaults.issuers.some((issuer) => { + const identityProofType = issuer.identityProof?.type; + if (identityProofType) { + return identityProofTypeCheckList.includes(identityProofType); + } + return false; + }); + } return isValidFormType && isValidIdentityProofType; }); - - return isValidForm; + const anyInvalidForm = !isValidForm.some((validForm: boolean) => validForm === false); + return anyInvalidForm; }; diff --git a/src/implementations/config/types.ts b/src/implementations/config/types.ts index 8e450c88..cdefe31e 100644 --- a/src/implementations/config/types.ts +++ b/src/implementations/config/types.ts @@ -1,4 +1,4 @@ -import { v2 } from "@govtechsg/open-attestation"; +import { OpenAttestationDocument } from "@govtechsg/open-attestation"; type WalletEncryptedJson = { type: "ENCRYPTED_JSON"; @@ -10,7 +10,7 @@ export type Dns = string | undefined; export type Form = { name: string; type: "VERIFIABLE_DOCUMENT" | "TRANSFERABLE_RECORD"; - defaults: v2.OpenAttestationDocument; + defaults: OpenAttestationDocument; schema: any; uiSchema?: any; attachments?: {