diff --git a/package-lock.json b/package-lock.json index 0009216e..e9df7ba5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,8 @@ "semantic-release": "^22.0.8", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", - "typescript": "^5.1.6" + "typescript": "^5.1.6", + "zod-to-json-schema": "^3.23.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -17375,12 +17376,21 @@ } }, "node_modules/zod": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", - "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "version": "3.23.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.6.tgz", + "integrity": "sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA==", "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zod-to-json-schema": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz", + "integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==", + "dev": true, + "peerDependencies": { + "zod": "^3.23.3" + } } } } diff --git a/package.json b/package.json index 4f5d47c2..1a2aee50 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "lint": "eslint . --ext .ts,.json --max-warnings 0", "lint:fix": "npm run lint -- --fix", "generate-v4-fixtures": "npx ts-node scripts/generateV4JsonFixtures.ts", + "generate-v4-json-schemas": "npx ts-node scripts/generateV4JsonSchemas.ts", "publish:schema": "./scripts/publishSchema.sh", "postinstall": "node scripts/postInstall; npm run generate-v4-fixtures", "prebuild": "node scripts/preBuild" @@ -90,7 +91,8 @@ "semantic-release": "^22.0.8", "ts-jest": "^29.1.2", "ts-node": "^10.9.2", - "typescript": "^5.1.6" + "typescript": "^5.1.6", + "zod-to-json-schema": "^3.23.0" }, "dependencies": { "@govtechsg/jsonld": "^0.1.0", diff --git a/scripts/generateV4JsonSchemas.ts b/scripts/generateV4JsonSchemas.ts new file mode 100644 index 00000000..bae336fb --- /dev/null +++ b/scripts/generateV4JsonSchemas.ts @@ -0,0 +1,36 @@ +import fs from "fs"; +import path from "path"; +import { zodToJsonSchema } from "zod-to-json-schema"; +import { V4Document, V4WrappedDocument, V4SignedWrappedDocument } from "../src/4.0/types"; + +const OUTPUT_DIR = path.resolve("./src/4.0/jsonSchemas/__generated__"); + +// make sure the output directory exists +if (fs.existsSync(OUTPUT_DIR)) { + fs.rmSync(OUTPUT_DIR, { recursive: true }); +} +fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + +const ZOD_SCHEMAS = [ + { + filename: "v4-document.schema.json", + schemaName: "v4Document", + zodSchema: V4Document, + }, + { + filename: "v4-wrapped-document.schema.json", + schemaName: "v4WrappedDocument", + zodSchema: V4WrappedDocument, + }, + { + filename: "v4-signed-wrapped-document.schema.json", + schemaName: "v4SignedWrappedDocument", + zodSchema: V4SignedWrappedDocument, + }, +]; + +for (const { filename, zodSchema, schemaName } of ZOD_SCHEMAS) { + const jsonSchema = zodToJsonSchema(zodSchema, schemaName); + + fs.writeFileSync(path.join(OUTPUT_DIR, filename), JSON.stringify(jsonSchema, null, 2)); +} diff --git a/src/4.0/jsonSchemas/__generated__/v4-document.schema.json b/src/4.0/jsonSchemas/__generated__/v4-document.schema.json new file mode 100644 index 00000000..3f9aea71 --- /dev/null +++ b/src/4.0/jsonSchemas/__generated__/v4-document.schema.json @@ -0,0 +1,386 @@ +{ + "$ref": "#/definitions/v4Document", + "definitions": { + "v4Document": { + "type": "object", + "properties": { + "@context": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "https://www.w3.org/ns/credentials/v2" + }, + { + "type": "string", + "const": "https://schemata.openattestation.com/com/openattestation/4.0/alpha-context.json" + } + ], + "additionalItems": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": {} + } + ] + } + }, + "name": { + "type": "string" + }, + "id": { + "type": "string", + "pattern": "^(?=.)(?!https?:\\/(?:$|[^/]))(?!https?:\\/\\/\\/)(?!https?:[^/])(?:[a-zA-Z][a-zA-Z\\d+-\\.]*:(?:(?:\\/\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:]*@)?(?:\\[(?:(?:(?:[\\dA-Fa-f]{1,4}:){6}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|::(?:[\\dA-Fa-f]{1,4}:){5}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){4}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,1}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){3}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,2}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){2}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,3}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}:(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,4}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,5}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}|(?:(?:[\\dA-Fa-f]{1,4}:){0,6}[\\dA-Fa-f]{1,4})?::)|v[\\dA-Fa-f]+\\.[\\w-\\.~!\\$&'\\(\\)\\*\\+,;=:]+)\\]|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=]{1,255})(?::\\d*)?(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)|\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)?|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*|(?:\\/\\/\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)))(?:\\?[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*(?=#|$))?(?:#[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*)?$" + }, + "type": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "VerifiableCredential" + }, + { + "type": "string", + "const": "OpenAttestationCredential" + } + ], + "additionalItems": { + "type": "string" + } + }, + "credentialSchema": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + } + } + ] + }, + "issuer": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string", + "const": "OpenAttestationIssuer" + }, + "name": { + "type": "string" + }, + "identityProof": { + "type": "object", + "properties": { + "identityProofType": { + "type": "string", + "enum": [ + "DNS-TXT", + "DNS-DID", + "DID" + ] + }, + "identifier": { + "type": "string" + } + }, + "required": [ + "identityProofType", + "identifier" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "type", + "name", + "identityProof" + ], + "additionalProperties": false + }, + "validFrom": { + "type": "string", + "format": "date-time" + }, + "validUntil": { + "type": "string", + "format": "date-time" + }, + "credentialSubject": { + "anyOf": [ + { + "type": "object", + "additionalProperties": {} + }, + { + "type": "array", + "items": { + "type": "object", + "additionalProperties": {} + } + } + ] + }, + "credentialStatus": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri" + }, + "type": { + "type": "string", + "const": "OpenAttestationOcspResponder" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + }, + "termsOfUse": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "evidence": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4Document/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "proof": { + "anyOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "renderMethod": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri", + "description": "URL of a decentralised renderer to render this document" + }, + "type": { + "type": "string", + "const": "OpenAttestationEmbeddedRenderer" + }, + "templateName": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "templateName" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "uri" + } + ], + "description": "A URL that dereferences to an SVG image [SVG] with an associated image/svg+xml media type. Or an embedded SVG image [SVG]" + }, + "type": { + "type": "string", + "const": "SvgRenderingTemplate2023" + }, + "name": { + "type": "string" + }, + "digestMultibase": { + "type": "string", + "description": "An optional multibase-encoded multihash of the SVG image. The multibase value MUST be z and the multihash value MUST be SHA-2 with 256-bits of output (0x12)." + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + } + ] + } + }, + "attachments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Base64 encoding of this attachment" + }, + "fileName": { + "type": "string", + "minLength": 1, + "description": "Name of this attachment, with appropriate extensions" + }, + "mimeType": { + "type": "string", + "minLength": 1, + "description": "Media type (or MIME type) of this attachment" + } + }, + "required": [ + "data", + "fileName", + "mimeType" + ], + "additionalProperties": false + } + } + }, + "required": [ + "@context", + "type", + "issuer", + "credentialSubject" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/src/4.0/jsonSchemas/__generated__/v4-signed-wrapped-document.schema.json b/src/4.0/jsonSchemas/__generated__/v4-signed-wrapped-document.schema.json new file mode 100644 index 00000000..7a8f696e --- /dev/null +++ b/src/4.0/jsonSchemas/__generated__/v4-signed-wrapped-document.schema.json @@ -0,0 +1,417 @@ +{ + "$ref": "#/definitions/v4SignedWrappedDocument", + "definitions": { + "v4SignedWrappedDocument": { + "type": "object", + "properties": { + "@context": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "https://www.w3.org/ns/credentials/v2" + }, + { + "type": "string", + "const": "https://schemata.openattestation.com/com/openattestation/4.0/alpha-context.json" + } + ], + "additionalItems": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": {} + } + ] + } + }, + "name": { + "type": "string" + }, + "id": { + "type": "string", + "pattern": "^(?=.)(?!https?:\\/(?:$|[^/]))(?!https?:\\/\\/\\/)(?!https?:[^/])(?:[a-zA-Z][a-zA-Z\\d+-\\.]*:(?:(?:\\/\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:]*@)?(?:\\[(?:(?:(?:[\\dA-Fa-f]{1,4}:){6}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|::(?:[\\dA-Fa-f]{1,4}:){5}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){4}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,1}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){3}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,2}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){2}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,3}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}:(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,4}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,5}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}|(?:(?:[\\dA-Fa-f]{1,4}:){0,6}[\\dA-Fa-f]{1,4})?::)|v[\\dA-Fa-f]+\\.[\\w-\\.~!\\$&'\\(\\)\\*\\+,;=:]+)\\]|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=]{1,255})(?::\\d*)?(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)|\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)?|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*|(?:\\/\\/\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)))(?:\\?[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*(?=#|$))?(?:#[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*)?$" + }, + "type": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "VerifiableCredential" + }, + { + "type": "string", + "const": "OpenAttestationCredential" + } + ], + "additionalItems": { + "type": "string" + } + }, + "credentialSchema": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + } + } + ] + }, + "issuer": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string", + "const": "OpenAttestationIssuer" + }, + "name": { + "type": "string" + }, + "identityProof": { + "type": "object", + "properties": { + "identityProofType": { + "type": "string", + "enum": [ + "DNS-TXT", + "DNS-DID", + "DID" + ] + }, + "identifier": { + "type": "string" + } + }, + "required": [ + "identityProofType", + "identifier" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "type", + "name", + "identityProof" + ], + "additionalProperties": false + }, + "validFrom": { + "type": "string", + "format": "date-time" + }, + "validUntil": { + "type": "string", + "format": "date-time" + }, + "credentialSubject": { + "anyOf": [ + { + "type": "object", + "additionalProperties": {} + }, + { + "type": "array", + "items": { + "type": "object", + "additionalProperties": {} + } + } + ] + }, + "credentialStatus": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri" + }, + "type": { + "type": "string", + "const": "OpenAttestationOcspResponder" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + }, + "termsOfUse": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "evidence": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4SignedWrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "proof": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "OpenAttestationMerkleProofSignature2018" + }, + "proofPurpose": { + "type": "string", + "const": "assertionMethod" + }, + "targetHash": { + "type": "string" + }, + "proofs": { + "type": "array", + "items": { + "type": "string" + } + }, + "merkleRoot": { + "type": "string" + }, + "salts": { + "type": "string" + }, + "privacy": { + "type": "object", + "properties": { + "obfuscated": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "obfuscated" + ], + "additionalProperties": false + }, + "key": { + "type": "string" + }, + "signature": { + "type": "string" + } + }, + "required": [ + "type", + "proofPurpose", + "targetHash", + "proofs", + "merkleRoot", + "salts", + "privacy", + "key", + "signature" + ], + "additionalProperties": false + }, + "renderMethod": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri", + "description": "URL of a decentralised renderer to render this document" + }, + "type": { + "type": "string", + "const": "OpenAttestationEmbeddedRenderer" + }, + "templateName": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "templateName" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "uri" + } + ], + "description": "A URL that dereferences to an SVG image [SVG] with an associated image/svg+xml media type. Or an embedded SVG image [SVG]" + }, + "type": { + "type": "string", + "const": "SvgRenderingTemplate2023" + }, + "name": { + "type": "string" + }, + "digestMultibase": { + "type": "string", + "description": "An optional multibase-encoded multihash of the SVG image. The multibase value MUST be z and the multihash value MUST be SHA-2 with 256-bits of output (0x12)." + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + } + ] + } + }, + "attachments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Base64 encoding of this attachment" + }, + "fileName": { + "type": "string", + "minLength": 1, + "description": "Name of this attachment, with appropriate extensions" + }, + "mimeType": { + "type": "string", + "minLength": 1, + "description": "Media type (or MIME type) of this attachment" + } + }, + "required": [ + "data", + "fileName", + "mimeType" + ], + "additionalProperties": false + } + } + }, + "required": [ + "@context", + "type", + "issuer", + "credentialSubject", + "proof" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/src/4.0/jsonSchemas/__generated__/v4-wrapped-document.schema.json b/src/4.0/jsonSchemas/__generated__/v4-wrapped-document.schema.json new file mode 100644 index 00000000..0ccb72f0 --- /dev/null +++ b/src/4.0/jsonSchemas/__generated__/v4-wrapped-document.schema.json @@ -0,0 +1,409 @@ +{ + "$ref": "#/definitions/v4WrappedDocument", + "definitions": { + "v4WrappedDocument": { + "type": "object", + "properties": { + "@context": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "https://www.w3.org/ns/credentials/v2" + }, + { + "type": "string", + "const": "https://schemata.openattestation.com/com/openattestation/4.0/alpha-context.json" + } + ], + "additionalItems": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": {} + } + ] + } + }, + "name": { + "type": "string" + }, + "id": { + "type": "string", + "pattern": "^(?=.)(?!https?:\\/(?:$|[^/]))(?!https?:\\/\\/\\/)(?!https?:[^/])(?:[a-zA-Z][a-zA-Z\\d+-\\.]*:(?:(?:\\/\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:]*@)?(?:\\[(?:(?:(?:[\\dA-Fa-f]{1,4}:){6}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|::(?:[\\dA-Fa-f]{1,4}:){5}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){4}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,1}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){3}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,2}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:){2}(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,3}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}:(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,4}[\\dA-Fa-f]{1,4})?::(?:[\\dA-Fa-f]{1,4}:[\\dA-Fa-f]{1,4}|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(?:(?:[\\dA-Fa-f]{1,4}:){0,5}[\\dA-Fa-f]{1,4})?::[\\dA-Fa-f]{1,4}|(?:(?:[\\dA-Fa-f]{1,4}:){0,6}[\\dA-Fa-f]{1,4})?::)|v[\\dA-Fa-f]+\\.[\\w-\\.~!\\$&'\\(\\)\\*\\+,;=:]+)\\]|(?:(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:0{0,2}\\d|0?[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=]{1,255})(?::\\d*)?(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)|\\/(?:[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)?|[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]+(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*|(?:\\/\\/\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*(?:\\/[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@]*)*)))(?:\\?[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*(?=#|$))?(?:#[\\w-\\.~%\\dA-Fa-f!\\$&'\\(\\)\\*\\+,;=:@\\/\\?]*)?$" + }, + "type": { + "type": "array", + "minItems": 2, + "items": [ + { + "type": "string", + "const": "VerifiableCredential" + }, + { + "type": "string", + "const": "OpenAttestationCredential" + } + ], + "additionalItems": { + "type": "string" + } + }, + "credentialSchema": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": true + } + } + ] + }, + "issuer": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string", + "const": "OpenAttestationIssuer" + }, + "name": { + "type": "string" + }, + "identityProof": { + "type": "object", + "properties": { + "identityProofType": { + "type": "string", + "enum": [ + "DNS-TXT", + "DNS-DID", + "DID" + ] + }, + "identifier": { + "type": "string" + } + }, + "required": [ + "identityProofType", + "identifier" + ], + "additionalProperties": false + } + }, + "required": [ + "id", + "type", + "name", + "identityProof" + ], + "additionalProperties": false + }, + "validFrom": { + "type": "string", + "format": "date-time" + }, + "validUntil": { + "type": "string", + "format": "date-time" + }, + "credentialSubject": { + "anyOf": [ + { + "type": "object", + "additionalProperties": {} + }, + { + "type": "array", + "items": { + "type": "object", + "additionalProperties": {} + } + } + ] + }, + "credentialStatus": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri" + }, + "type": { + "type": "string", + "const": "OpenAttestationOcspResponder" + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + }, + "termsOfUse": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "evidence": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + }, + { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "$ref": "#/definitions/v4WrappedDocument/properties/id" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "additionalProperties": true + } + } + ] + }, + "proof": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "OpenAttestationMerkleProofSignature2018" + }, + "proofPurpose": { + "type": "string", + "const": "assertionMethod" + }, + "targetHash": { + "type": "string" + }, + "proofs": { + "type": "array", + "items": { + "type": "string" + } + }, + "merkleRoot": { + "type": "string" + }, + "salts": { + "type": "string" + }, + "privacy": { + "type": "object", + "properties": { + "obfuscated": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "obfuscated" + ], + "additionalProperties": false + } + }, + "required": [ + "type", + "proofPurpose", + "targetHash", + "proofs", + "merkleRoot", + "salts", + "privacy" + ], + "additionalProperties": true + }, + "renderMethod": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uri", + "description": "URL of a decentralised renderer to render this document" + }, + "type": { + "type": "string", + "const": "OpenAttestationEmbeddedRenderer" + }, + "templateName": { + "type": "string" + } + }, + "required": [ + "id", + "type", + "templateName" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "uri" + } + ], + "description": "A URL that dereferences to an SVG image [SVG] with an associated image/svg+xml media type. Or an embedded SVG image [SVG]" + }, + "type": { + "type": "string", + "const": "SvgRenderingTemplate2023" + }, + "name": { + "type": "string" + }, + "digestMultibase": { + "type": "string", + "description": "An optional multibase-encoded multihash of the SVG image. The multibase value MUST be z and the multihash value MUST be SHA-2 with 256-bits of output (0x12)." + } + }, + "required": [ + "id", + "type" + ], + "additionalProperties": false + } + ] + } + }, + "attachments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "data": { + "type": "string", + "description": "Base64 encoding of this attachment" + }, + "fileName": { + "type": "string", + "minLength": 1, + "description": "Name of this attachment, with appropriate extensions" + }, + "mimeType": { + "type": "string", + "minLength": 1, + "description": "Media type (or MIME type) of this attachment" + } + }, + "required": [ + "data", + "fileName", + "mimeType" + ], + "additionalProperties": false + } + } + }, + "required": [ + "@context", + "type", + "issuer", + "credentialSubject", + "proof" + ], + "additionalProperties": false + } + }, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 28b13138..4230b4af 100644 --- a/src/index.ts +++ b/src/index.ts @@ -128,8 +128,7 @@ export async function signDocument; - // Unreachable code atm until utils.isWrappedV2Document & utils.isWrappedV3Document becomes more strict - throw new Error("Unsupported document type: Only OpenAttestation v2 or v3documents can be signed"); + throw new Error("Unsupported document type: Only OpenAttestation v2 or v3 documents can be signed"); } export { digestDocument } from "./2.0/digest";