From a02324284de8882447a1eb7c2c246d1f6e3a40b9 Mon Sep 17 00:00:00 2001 From: abdulla-ashurov <99400260+abdulla-ashurov@users.noreply.github.com> Date: Tue, 6 Jun 2023 18:23:16 +0500 Subject: [PATCH 1/4] feat: Implement USE_EXTERNAL_DB toggle [DEV 2630] (#233) * Rename ISSUER_SECRET_KEY to DB_ENCRYPTION_KEY * Rename env variable name from ISSUER_DATABASE_URL to DB_CONNECTION_URL. * Add implementation of USE_EXTERNAL_DB toggle. * Refactor code: Use Strategy pattern. * Add beforeInsert, beforeUpdate, and afterInsert methods for correctly storing arrays in SQLite database. * Refactor code. * Refactor code. * Rename env variable from "USE_EXTERNAL_DB" to "ENABLE_EXTERNAL_DB". * Update package-lock.json. * Update .env.example. * Add SQLite package to package-lock.json. * Fix linter mistake. * Update .env.example. * feat: Add FEE_PAYER env * feat: Update Identity service * feat: Fix minor issues * feat: Add access control middleware * feat: Refactor code * feat: Update .env example --------- Co-authored-by: Andrew Nikitin Co-authored-by: DaevMithran Co-authored-by: DaevMithran <61043607+DaevMithran@users.noreply.github.com> --- .env.example | 13 +- .gitignore | 5 +- package-lock.json | 1384 ++++++++++++----- package.json | 1 + src/app.ts | 1 + src/controllers/credentials.ts | 5 - src/controllers/customer.ts | 5 +- src/controllers/issuer.ts | 27 +- src/database/connection/connection.ts | 41 +- src/database/entities/customer.entity.ts | 106 +- .../migrations/CreateCustomersTable.ts | 8 +- src/database/types/types.ts | 54 + src/middleware/authentication.ts | 43 +- src/services/credentials.ts | 32 +- src/services/customer.ts | 33 +- src/services/identity.ts | 235 --- src/services/identity/IIdentity.ts | 34 + src/services/identity/index.ts | 6 + src/services/identity/local.ts | 195 +++ src/services/identity/postgres.ts | 262 ++++ src/types/environment.d.ts | 19 +- src/types/types.ts | 101 +- 22 files changed, 1705 insertions(+), 905 deletions(-) create mode 100644 src/database/types/types.ts delete mode 100644 src/services/identity.ts create mode 100644 src/services/identity/IIdentity.ts create mode 100644 src/services/identity/index.ts create mode 100644 src/services/identity/local.ts create mode 100644 src/services/identity/postgres.ts diff --git a/.env.example b/.env.example index dcf74355..6f5292e8 100644 --- a/.env.example +++ b/.env.example @@ -4,9 +4,10 @@ RESOLVER_URL="https://resolver.cheqd.net/1.0/identifiers/" ALLOWED_ORIGINS="http://localhost:8787" # Database -DB_CONNECTION_URL=postgres://logto:password@localhost:5432/logto -DB_ENCRYPTION_KEY="" -# DB_CERTIFICATE="certs/issuer.crt" +ENABLE_EXTERNAL_DB="false" +EXTERNAL_DB_CONNECTION_URL=postgres://logto:password@localhost:5432/logto +EXTERNAL_DB_ENCRYPTION_KEY="" +# EXTERNAL_DB_CERT="certs/issuer.crt" # OpenId OIDC_JWKS_ENDPOINT='http://localhost:3001/oidc/jwks' @@ -22,3 +23,9 @@ ENABLE_VERIDA_CONNECTOR="string,default:false" VERIDA_PRIVATE_KEY="akjvncanv....avoa" POLYGON_PRIVATE_KEY="alnvca...dvncioa" VERIDA_NETWORK="testnet" + +# Without Database +ISSUER_ID_PRIVATE_KEY_HEX="akjvncanv....avoa" +ISSUER_ID_PUBLIC_KEY_HEX="alnvca...dvncioa" +ISSUER_DID="did:cheqd:testnet:afcnoa...adv" +FEE_PAYER_MNEMONIC="sketch mountain ....." \ No newline at end of file diff --git a/.gitignore b/.gitignore index 19c989f7..774b9fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -453,4 +453,7 @@ cred.json _wrangler.toml # verida -v[0-9,a-z]* \ No newline at end of file +v[0-9,a-z]* + +# sqlite +*.sqlite \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bebb0f0e..e7d06df6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "pg": "^8.11.0", "pg-connection-string": "^2.6.0", "secp256k1": "^5.0.0", + "sqlite3": "^5.1.6", "swagger-ui-express": "^4.6.3", "typeorm": "^0.3.16", "uint8arrays": "^4.0.3" @@ -2885,7 +2886,68 @@ "node": ">=16" } }, + "node_modules/@digitalbazaar/bitstring/node_modules/base64url-universal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-2.0.0.tgz", + "integrity": "sha512-6Hpg7EBf3t148C3+fMzjf+CHnADVDafWzlJUXAqqqbm4MKNXbsoPdOkWeRTjNlkYG7TpyjIpRO1Gk0SnsFD1rw==", + "dependencies": { + "base64url": "^3.0.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@digitalbazaar/http-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-1.2.0.tgz", + "integrity": "sha512-W9KQQ5pUJcaR0I4c2HPJC0a7kRbZApIorZgPnEDwMBgj16iQzutGLrCXYaZOmxqVLVNqqlQ4aUJh+HBQZy4W6Q==", + "dependencies": { + "esm": "^3.2.22", + "ky": "^0.25.1", + "ky-universal": "^0.8.2" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@digitalbazaar/security-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/security-context/-/security-context-1.0.0.tgz", + "integrity": "sha512-mlj+UmodxTAdMCHGxnGVTRLHcSLyiEOVRiz3J6yiRliJWyrgeXs34wlWjBorDIEMDIjK2JwZrDuFEKO9bS5nKQ==" + }, + "node_modules/@digitalbazaar/vc": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/vc/-/vc-5.0.0.tgz", + "integrity": "sha512-XmLM7Ag5W+XidGnFuxFIyUFSMnHnWEMJlHei602GG94+WzFJ6Ik8txzPQL8T18egSoiTsd1VekymbIlSimhuaQ==", + "dependencies": { + "credentials-context": "^2.0.0", + "jsonld": "^8.0.0", + "jsonld-signatures": "^11.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/vc-status-list": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/vc-status-list/-/vc-status-list-7.0.0.tgz", + "integrity": "sha512-fFSZx5S/LG9PRxHkoVgH+jMib18zAVjWLbcsrdK2qE8jalX8Kg/IILFr37ifmL4CYXIwelM0cff0P/SIaz96zw==", + "dependencies": { + "@digitalbazaar/bitstring": "^3.0.0", + "@digitalbazaar/vc": "^5.0.0", + "@digitalbazaar/vc-status-list-context": "^3.0.1", + "credentials-context": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@digitalbazaar/vc-status-list-context": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@digitalbazaar/vc-status-list-context/-/vc-status-list-context-3.0.1.tgz", + "integrity": "sha512-vQsqQXpmSXKNy/C0xxFUOBzz60dHh6oupQam1xRC8IspVC11hYJiX9SAhmbI0ulHvX1R2JfqZaJHZjmAyMZ/aA==" + }, + "node_modules/@digitalbazaar/vc/node_modules/@digitalbazaar/http-client": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.1.tgz", "integrity": "sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==", @@ -2898,7 +2960,51 @@ "node": ">=14.0" } }, - "node_modules/@digitalbazaar/http-client/node_modules/ky": { + "node_modules/@digitalbazaar/vc/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@digitalbazaar/vc/node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/@digitalbazaar/vc/node_modules/jsonld": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.2.0.tgz", + "integrity": "sha512-qHUa9pn3/cdAZw26HY1Jmy9+sHOxaLrveTRWUcrSDx5apTa20bBTe+X4nzI7dlqc+M5GkwQW6RgRdqO6LF5nkw==", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", + "canonicalize": "^1.0.1", + "lru-cache": "^6.0.0", + "rdf-canonize": "^3.4.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/vc/node_modules/ky": { "version": "0.33.3", "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", @@ -2909,7 +3015,7 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, - "node_modules/@digitalbazaar/http-client/node_modules/ky-universal": { + "node_modules/@digitalbazaar/vc/node_modules/ky-universal": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", @@ -2933,7 +3039,7 @@ } } }, - "node_modules/@digitalbazaar/http-client/node_modules/node-fetch": { + "node_modules/@digitalbazaar/vc/node_modules/node-fetch": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", @@ -2950,43 +3056,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/@digitalbazaar/security-context": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/security-context/-/security-context-1.0.0.tgz", - "integrity": "sha512-mlj+UmodxTAdMCHGxnGVTRLHcSLyiEOVRiz3J6yiRliJWyrgeXs34wlWjBorDIEMDIjK2JwZrDuFEKO9bS5nKQ==" - }, - "node_modules/@digitalbazaar/vc": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/vc/-/vc-5.0.0.tgz", - "integrity": "sha512-XmLM7Ag5W+XidGnFuxFIyUFSMnHnWEMJlHei602GG94+WzFJ6Ik8txzPQL8T18egSoiTsd1VekymbIlSimhuaQ==", - "dependencies": { - "credentials-context": "^2.0.0", - "jsonld": "^8.0.0", - "jsonld-signatures": "^11.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@digitalbazaar/vc-status-list": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/vc-status-list/-/vc-status-list-7.0.0.tgz", - "integrity": "sha512-fFSZx5S/LG9PRxHkoVgH+jMib18zAVjWLbcsrdK2qE8jalX8Kg/IILFr37ifmL4CYXIwelM0cff0P/SIaz96zw==", - "dependencies": { - "@digitalbazaar/bitstring": "^3.0.0", - "@digitalbazaar/vc": "^5.0.0", - "@digitalbazaar/vc-status-list-context": "^3.0.1", - "credentials-context": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@digitalbazaar/vc-status-list-context": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@digitalbazaar/vc-status-list-context/-/vc-status-list-context-3.0.1.tgz", - "integrity": "sha512-vQsqQXpmSXKNy/C0xxFUOBzz60dHh6oupQam1xRC8IspVC11hYJiX9SAhmbI0ulHvX1R2JfqZaJHZjmAyMZ/aA==" - }, "node_modules/@digitalcredentials/base58-universal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@digitalcredentials/base58-universal/-/base58-universal-1.0.1.tgz", @@ -3024,17 +3093,6 @@ "node": ">=14" } }, - "node_modules/@digitalcredentials/ed25519-signature-2020/node_modules/base64url-universal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz", - "integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==", - "dependencies": { - "base64url": "^3.0.0" - }, - "engines": { - "node": ">=8.3.0" - } - }, "node_modules/@digitalcredentials/ed25519-signature-2020/node_modules/crypto-ld": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/crypto-ld/-/crypto-ld-6.0.0.tgz", @@ -3927,9 +3985,9 @@ } }, "node_modules/@expo/cli": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.7.3.tgz", - "integrity": "sha512-uMGHbAhApqXR2sd1KPhgvpbOhBBnspad8msEqHleT2PHXwKIwTUDzBGO9+jdOAWwCx2MJfw3+asYjzoD3DN9Bg==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-0.7.2.tgz", + "integrity": "sha512-QOooDZ1qy31GsXj2Z5JxpofhZO51loF7NK8QPj5/dHJmG88dQdM4TBA5BWutDN/CA3Dseg+oTCaFiehu3Rn1ew==", "optional": true, "peer": true, "dependencies": { @@ -4976,7 +5034,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "devOptional": true + "optional": true }, "node_modules/@graphql-typed-document-node/core": { "version": "3.2.0", @@ -5786,6 +5844,14 @@ "node": ">=8" } }, + "node_modules/@lit-protocol/auth-browser/node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@lit-protocol/auth-browser/node_modules/proxy-compare": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-2.5.0.tgz", @@ -6128,13 +6194,55 @@ } }, "node_modules/@lit/reactive-element": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.1.tgz", - "integrity": "sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz", + "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.0.0" } }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", + "integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@motionone/animation": { "version": "10.15.1", "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.15.1.tgz", @@ -6304,7 +6412,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "devOptional": true, + "optional": true, "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" @@ -6315,7 +6423,7 @@ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", "deprecated": "This functionality has been moved to @npmcli/fs", - "devOptional": true, + "optional": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -6851,43 +6959,6 @@ "wcwidth": "^1.0.1" } }, - "node_modules/@react-native-community/cli-doctor/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, - "peer": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/@react-native-community/cli-doctor/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/@react-native-community/cli-doctor/node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7060,21 +7131,6 @@ "node": ">=4" } }, - "node_modules/@react-native-community/cli-doctor/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "optional": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@react-native-community/cli-doctor/node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -7336,43 +7392,6 @@ "ora": "^5.4.1" } }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, - "peer": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/@react-native-community/cli-platform-ios/node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7522,21 +7541,6 @@ "node": ">=4" } }, - "node_modules/@react-native-community/cli-platform-ios/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "optional": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@react-native-community/cli-platform-ios/node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -7781,43 +7785,6 @@ "shell-quote": "^1.7.3" } }, - "node_modules/@react-native-community/cli-tools/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "optional": true, - "peer": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/@react-native-community/cli-tools/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "optional": true, - "peer": true, - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -7921,21 +7888,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@react-native-community/cli-tools/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "optional": true, - "peer": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@react-native-community/cli-tools/node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -9049,33 +9001,6 @@ "node": ">=16" } }, - "node_modules/@transmute/jsonld/node_modules/@digitalbazaar/http-client": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-1.2.0.tgz", - "integrity": "sha512-W9KQQ5pUJcaR0I4c2HPJC0a7kRbZApIorZgPnEDwMBgj16iQzutGLrCXYaZOmxqVLVNqqlQ4aUJh+HBQZy4W6Q==", - "dependencies": { - "esm": "^3.2.22", - "ky": "^0.25.1", - "ky-universal": "^0.8.2" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@transmute/jsonld/node_modules/jsonld": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-5.2.0.tgz", - "integrity": "sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw==", - "dependencies": { - "@digitalbazaar/http-client": "^1.1.0", - "canonicalize": "^1.0.1", - "lru-cache": "^6.0.0", - "rdf-canonize": "^3.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@transmute/ld-key-pair": { "version": "0.7.0-unstable.80", "resolved": "https://registry.npmjs.org/@transmute/ld-key-pair/-/ld-key-pair-0.7.0-unstable.80.tgz", @@ -9432,9 +9357,9 @@ } }, "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, "node_modules/@types/qs": { @@ -11985,6 +11910,11 @@ "dev": true, "peer": true }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -12041,11 +11971,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/abstract-leveldown/node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -12115,6 +12040,20 @@ "node": ">= 14" } }, + "node_modules/agentkeepalive": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", + "optional": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^2.0.0", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -12306,6 +12245,36 @@ "optional": true, "peer": true }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", @@ -12874,14 +12843,14 @@ } }, "node_modules/base64url-universal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-2.0.0.tgz", - "integrity": "sha512-6Hpg7EBf3t148C3+fMzjf+CHnADVDafWzlJUXAqqqbm4MKNXbsoPdOkWeRTjNlkYG7TpyjIpRO1Gk0SnsFD1rw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz", + "integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==", "dependencies": { - "base64url": "^3.0.1" + "base64url": "^3.0.0" }, "engines": { - "node": ">=14" + "node": ">=8.3.0" } }, "node_modules/bech32": { @@ -12917,19 +12886,48 @@ } }, "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "optional": true, + "peer": true, "dependencies": { - "buffer": "^6.0.3", + "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -12971,6 +12969,11 @@ "npm": ">=7.0.0" } }, + "node_modules/blockstore-core/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/blueimp-md5": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", @@ -13218,7 +13221,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "devOptional": true + "optional": true, + "peer": true }, "node_modules/busboy": { "version": "1.6.0", @@ -13243,7 +13247,7 @@ "version": "15.3.0", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "devOptional": true, + "optional": true, "dependencies": { "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", @@ -13460,7 +13464,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "devOptional": true, "engines": { "node": ">=10" } @@ -13777,6 +13780,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", @@ -14004,6 +14015,11 @@ "node": ">= 0.6" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -14513,11 +14529,11 @@ "peer": true }, "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", "engines": { - "node": ">= 12" + "node": ">= 6" } }, "node_modules/date-fns": { @@ -14893,6 +14909,11 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, "node_modules/denodeify": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", @@ -14940,6 +14961,14 @@ "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==" }, + "node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -15061,9 +15090,9 @@ } }, "node_modules/dotenv": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.3.tgz", - "integrity": "sha512-FYssxsmCTtKL72fGBSvb1K9dRz0/VZeWqFme/vSb7r7323x4CRaHu4LvQ5JG3+s6yt2YPbBrkpiEODktfyjI9A==", + "version": "16.1.4", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz", + "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==", "engines": { "node": ">=12" }, @@ -15152,9 +15181,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.417", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.417.tgz", - "integrity": "sha512-8rY8HdCxuSVY8wku3i/eDac4g1b4cSbruzocenrqBlzqruAZYHjQCHIjC66dLR9DXhEHTojsC4EjhZ8KmzwXqA==", + "version": "1.4.414", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.414.tgz", + "integrity": "sha512-RRuCvP6ekngVh2SAJaOKT/hxqc9JAsK+Pe0hP5tGQIfonU2Zy9gMGdJ+mBdyl/vNucMG6gkXYtuM4H/1giws5w==", "devOptional": true }, "node_modules/elliptic": { @@ -15413,6 +15442,15 @@ "node": ">=8" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -15434,9 +15472,10 @@ "peer": true }, "node_modules/err-code": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", - "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "optional": true }, "node_modules/errno": { "version": "0.1.8", @@ -16052,14 +16091,14 @@ } }, "node_modules/expo": { - "version": "48.0.19", - "resolved": "https://registry.npmjs.org/expo/-/expo-48.0.19.tgz", - "integrity": "sha512-Pmz2HEwcDdjWPq5fM3vF++je0hjZIBX9aTZEkm6sBv09Vfhe4+CuiuKDq3iE+N6G9l2+eFYoRCApDwLqcRMiPA==", + "version": "48.0.18", + "resolved": "https://registry.npmjs.org/expo/-/expo-48.0.18.tgz", + "integrity": "sha512-mRsOQC3e+VhUKEaYJlvIDiqwaQtFEJv9JZZ8yRkofsj1y+9WoQFq5WN+w2sKg+aMvTE3ReNzhhwBM7QMVy5FrA==", "optional": true, "peer": true, "dependencies": { "@babel/runtime": "^7.20.0", - "@expo/cli": "0.7.3", + "@expo/cli": "0.7.2", "@expo/config": "8.0.2", "@expo/config-plugins": "6.0.2", "@expo/vector-icons": "^13.0.0", @@ -16635,9 +16674,9 @@ } }, "node_modules/fbjs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", - "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.4.tgz", + "integrity": "sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==", "optional": true, "peer": true, "dependencies": { @@ -16647,7 +16686,7 @@ "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", - "ua-parser-js": "^1.0.35" + "ua-parser-js": "^0.7.30" } }, "node_modules/fbjs-css-vars": { @@ -16658,25 +16697,16 @@ "peer": true }, "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", + "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", "engines": { - "node": "^12.20 || >= 14.13" + "node": "^10.17.0 || >=12.3.0" + }, + "peerDependenciesMeta": { + "domexception": { + "optional": true + } } }, "node_modules/fetch-cookie": { @@ -17110,6 +17140,28 @@ "node": ">=12.20.0" } }, + "node_modules/formdata-polyfill/node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -17177,7 +17229,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "devOptional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -17221,6 +17272,25 @@ "node": ">=12" } }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/generate-password": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.0.tgz", @@ -17605,6 +17675,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -17809,6 +17884,12 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "optional": true + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -17859,6 +17940,15 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "optional": true, + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -17912,9 +18002,9 @@ } }, "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -17985,7 +18075,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "devOptional": true + "optional": true }, "node_modules/inflight": { "version": "1.0.6", @@ -18167,6 +18257,11 @@ "uint8arrays": "^3.0.0" } }, + "node_modules/ipfs-core-utils/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/ipfs-core-utils/node_modules/it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -18215,6 +18310,11 @@ "npm": ">=3.0.0" } }, + "node_modules/ipfs-http-client/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/ipfs-http-client/node_modules/multiformats": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", @@ -18279,6 +18379,11 @@ "npm": ">=7.0.0" } }, + "node_modules/ipfs-unixfs-importer/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/ipfs-unixfs-importer/node_modules/ipfs-unixfs": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-9.0.1.tgz", @@ -18301,6 +18406,11 @@ "npm": ">=7.0.0" } }, + "node_modules/ipfs-unixfs/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/ipfs-unixfs/node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -18358,6 +18468,11 @@ "npm": ">=7.0.0" } }, + "node_modules/ipfs-utils/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/ipfs-utils/node_modules/it-all": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz", @@ -18631,6 +18746,12 @@ "node": ">=8" } }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "optional": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -18669,11 +18790,12 @@ } }, "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-plain-object": { @@ -20385,17 +20507,17 @@ } }, "node_modules/jsonld": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.2.0.tgz", - "integrity": "sha512-qHUa9pn3/cdAZw26HY1Jmy9+sHOxaLrveTRWUcrSDx5apTa20bBTe+X4nzI7dlqc+M5GkwQW6RgRdqO6LF5nkw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-5.2.0.tgz", + "integrity": "sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw==", "dependencies": { - "@digitalbazaar/http-client": "^3.4.1", + "@digitalbazaar/http-client": "^1.1.0", "canonicalize": "^1.0.1", "lru-cache": "^6.0.0", - "rdf-canonize": "^3.4.0" + "rdf-canonize": "^3.0.0" }, "engines": { - "node": ">=14" + "node": ">=12" } }, "node_modules/jsonld-checker": { @@ -20410,44 +20532,126 @@ "node": ">=10" } }, - "node_modules/jsonld-checker/node_modules/@digitalbazaar/http-client": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-1.2.0.tgz", - "integrity": "sha512-W9KQQ5pUJcaR0I4c2HPJC0a7kRbZApIorZgPnEDwMBgj16iQzutGLrCXYaZOmxqVLVNqqlQ4aUJh+HBQZy4W6Q==", + "node_modules/jsonld-signatures": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-11.2.1.tgz", + "integrity": "sha512-RNaHTEeRrX0jWeidPCwxMq/E/Ze94zFyEZz/v267ObbCHQlXhPO7GtkY6N5PSHQfQhZPXa8NlMBg5LiDF4dNbA==", "dependencies": { - "esm": "^3.2.22", - "ky": "^0.25.1", - "ky-universal": "^0.8.2" + "@digitalbazaar/security-context": "^1.0.0", + "jsonld": "^8.0.0", + "serialize-error": "^8.1.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=14" } }, - "node_modules/jsonld-checker/node_modules/jsonld": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-5.2.0.tgz", - "integrity": "sha512-JymgT6Xzk5CHEmHuEyvoTNviEPxv6ihLWSPu1gFdtjSAyM6cFqNrv02yS/SIur3BBIkCf0HjizRc24d8/FfQKw==", + "node_modules/jsonld-signatures/node_modules/@digitalbazaar/http-client": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.1.tgz", + "integrity": "sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==", "dependencies": { - "@digitalbazaar/http-client": "^1.1.0", + "ky": "^0.33.3", + "ky-universal": "^0.11.0", + "undici": "^5.21.2" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/jsonld-signatures/node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/jsonld-signatures/node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/jsonld-signatures/node_modules/jsonld": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.2.0.tgz", + "integrity": "sha512-qHUa9pn3/cdAZw26HY1Jmy9+sHOxaLrveTRWUcrSDx5apTa20bBTe+X4nzI7dlqc+M5GkwQW6RgRdqO6LF5nkw==", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", "canonicalize": "^1.0.1", "lru-cache": "^6.0.0", - "rdf-canonize": "^3.0.0" + "rdf-canonize": "^3.4.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, - "node_modules/jsonld-signatures": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-11.2.1.tgz", - "integrity": "sha512-RNaHTEeRrX0jWeidPCwxMq/E/Ze94zFyEZz/v267ObbCHQlXhPO7GtkY6N5PSHQfQhZPXa8NlMBg5LiDF4dNbA==", + "node_modules/jsonld-signatures/node_modules/ky": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", + "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/jsonld-signatures/node_modules/ky-universal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", + "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", "dependencies": { - "@digitalbazaar/security-context": "^1.0.0", - "jsonld": "^8.0.0", - "serialize-error": "^8.1.0" + "abort-controller": "^3.0.0", + "node-fetch": "^3.2.10" }, "engines": { - "node": ">=14" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" + }, + "peerDependencies": { + "ky": ">=0.31.4", + "web-streams-polyfill": ">=3.2.1" + }, + "peerDependenciesMeta": { + "web-streams-polyfill": { + "optional": true + } + } + }, + "node_modules/jsonld-signatures/node_modules/node-fetch": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" } }, "node_modules/jsonparse": { @@ -20582,27 +20786,6 @@ } } }, - "node_modules/ky-universal/node_modules/data-uri-to-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", - "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/ky-universal/node_modules/fetch-blob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", - "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", - "engines": { - "node": "^10.17.0 || >=12.3.0" - }, - "peerDependenciesMeta": { - "domexception": { - "optional": true - } - } - }, "node_modules/ky-universal/node_modules/node-fetch": { "version": "3.0.0-beta.9", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0-beta.9.tgz", @@ -20852,6 +21035,11 @@ "immediate": "~3.0.5" } }, + "node_modules/lie/node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -21324,7 +21512,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, "dependencies": { "semver": "^6.0.0" }, @@ -21339,7 +21526,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, "bin": { "semver": "bin/semver.js" } @@ -21350,6 +21536,81 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "devOptional": true }, + "node_modules/make-fetch-happen": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", + "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", + "optional": true, + "dependencies": { + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/make-fetch-happen/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -21714,6 +21975,14 @@ "node": ">=10" } }, + "node_modules/merge-options/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "engines": { + "node": ">=8" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -22583,20 +22852,10 @@ "node": ">= 6" } }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/minipass": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "devOptional": true, "dependencies": { "yallist": "^4.0.0" }, @@ -22608,7 +22867,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "devOptional": true, + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -22616,11 +22875,28 @@ "node": ">= 8" } }, + "node_modules/minipass-fetch": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", + "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", + "optional": true, + "dependencies": { + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "encoding": "^0.1.12" + } + }, "node_modules/minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "devOptional": true, + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -22632,7 +22908,19 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "devOptional": true, + "optional": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -22644,7 +22932,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "devOptional": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -22733,6 +23020,11 @@ "multiaddr": "^10.0.0" } }, + "node_modules/multiaddr/node_modules/err-code": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-3.0.1.tgz", + "integrity": "sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==" + }, "node_modules/multiaddr/node_modules/multiformats": { "version": "9.9.0", "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz", @@ -23071,6 +23363,30 @@ "node": ">= 6.13.0" } }, + "node_modules/node-gyp": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", + "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", + "optional": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^9.1.0", + "nopt": "^5.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, "node_modules/node-gyp-build": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", @@ -23081,6 +23397,67 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "optional": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/node-gyp/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -23137,6 +23514,20 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -23326,7 +23717,8 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz", "integrity": "sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "hosted-git-info": "^3.0.2", "osenv": "^0.1.5", @@ -23338,7 +23730,8 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -23350,7 +23743,8 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "devOptional": true, + "optional": true, + "peer": true, "bin": { "semver": "bin/semver" } @@ -26520,6 +26914,17 @@ "inBundle": true, "license": "ISC" }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", @@ -26883,7 +27288,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -26892,7 +27298,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "devOptional": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -26901,7 +27308,8 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -27010,7 +27418,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "devOptional": true, + "optional": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -27096,16 +27504,6 @@ "node": ">=10" } }, - "node_modules/parse-png/node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "optional": true, - "peer": true, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -27733,11 +28131,13 @@ } }, "node_modules/pngjs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", - "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "optional": true, + "peer": true, "engines": { - "node": ">=10.13.0" + "node": ">=4.0.0" } }, "node_modules/posix-character-classes": { @@ -27940,11 +28340,6 @@ "uuid": "8.3.2" } }, - "node_modules/pouchdb-utils/node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, "node_modules/pouchdb-utils/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -27958,11 +28353,6 @@ "resolved": "https://registry.npmjs.org/pouchdb-wrappers/-/pouchdb-wrappers-5.0.0.tgz", "integrity": "sha512-fXqsVn+rmlPtxaAIGaQP5TkiaT39OMwvMk+ScLLtHrmfXD2KBO6fe/qBl38N/rpTn0h/A058dPN4fLAHt550zA==" }, - "node_modules/pouchdb/node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" - }, "node_modules/pouchdb/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -28155,7 +28545,29 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "devOptional": true + "optional": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "optional": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise-retry/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true, + "engines": { + "node": ">= 4" + } }, "node_modules/prompts": { "version": "2.4.2", @@ -28332,7 +28744,8 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.11.0.tgz", "integrity": "sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==", - "devOptional": true, + "optional": true, + "peer": true, "bin": { "qrcode-terminal": "bin/qrcode-terminal.js" } @@ -28395,6 +28808,14 @@ "node": ">=8" } }, + "node_modules/qrcode/node_modules/pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/qrcode/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -28541,6 +28962,16 @@ "rabin-wasm": "cli/bin.js" } }, + "node_modules/rabin-wasm/node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/rabin-wasm/node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -29479,7 +29910,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "devOptional": true, "dependencies": { "glob": "^7.1.3" }, @@ -30263,8 +30693,7 @@ "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "devOptional": true + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/signale": { "version": "1.4.0", @@ -30490,6 +30919,16 @@ "node": ">=8.0.0" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -30704,6 +31143,52 @@ "node": ">=0.10.0" } }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "optional": true, + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/socks/node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "optional": true + }, "node_modules/sonic-boom": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", @@ -30862,11 +31347,38 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "devOptional": true }, + "node_modules/sqlite3": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz", + "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==", + "hasInstallScript": true, + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.0", + "node-addon-api": "^4.2.0", + "tar": "^6.1.11" + }, + "optionalDependencies": { + "node-gyp": "8.x" + }, + "peerDependencies": { + "node-gyp": "8.x" + }, + "peerDependenciesMeta": { + "node-gyp": { + "optional": true + } + } + }, + "node_modules/sqlite3/node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "devOptional": true, + "optional": true, "dependencies": { "minipass": "^3.1.1" }, @@ -31368,7 +31880,6 @@ "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "devOptional": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -31385,7 +31896,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "devOptional": true, "engines": { "node": ">=8" } @@ -31483,14 +31993,14 @@ } }, "node_modules/terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "version": "5.17.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.6.tgz", + "integrity": "sha512-V8QHcs8YuyLkLHsJO5ucyff1ykrLVsR4dNnS//L5Y3NiSXpbK1J+WMVUs67eI0KTxs9JtHhgEQpXQVHlHI92DQ==", "devOptional": true, "peer": true, "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -32241,9 +32751,9 @@ } }, "node_modules/ua-parser-js": { - "version": "1.0.35", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", - "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", + "version": "0.7.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", + "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", "funding": [ { "type": "opencollective", @@ -32407,7 +32917,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "devOptional": true, + "optional": true, "dependencies": { "unique-slug": "^2.0.0" } @@ -32416,7 +32926,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "devOptional": true, + "optional": true, "dependencies": { "imurmurhash": "^0.1.4" } @@ -32684,7 +33194,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "builtins": "^1.0.3" } @@ -32811,9 +33322,9 @@ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/webpack": { - "version": "5.85.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz", - "integrity": "sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg==", + "version": "5.84.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.84.1.tgz", + "integrity": "sha512-ZP4qaZ7vVn/K8WN/p990SGATmrL1qg4heP/MrVneczYtpDGJWlrgZv55vxaV2ul885Kz+25MP2kSXkPe3LZfmg==", "dev": true, "peer": true, "dependencies": { @@ -32888,7 +33399,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, + "devOptional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -32923,6 +33434,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, "node_modules/wonka": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/wonka/-/wonka-4.0.15.tgz", @@ -32970,7 +33489,8 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "devOptional": true, + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", diff --git a/package.json b/package.json index 0f8fe3d0..8f71e8f1 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "pg": "^8.11.0", "pg-connection-string": "^2.6.0", "secp256k1": "^5.0.0", + "sqlite3": "^5.1.6", "swagger-ui-express": "^4.6.3", "typeorm": "^0.3.16", "uint8arrays": "^4.0.3" diff --git a/src/app.ts b/src/app.ts index b4935c87..6598dba3 100644 --- a/src/app.ts +++ b/src/app.ts @@ -49,6 +49,7 @@ class App { ) this.express.use(Authentication.guard) this.express.use(Authentication.handleError) + this.express.use(Authentication.accessControl) } private routes() { diff --git a/src/controllers/credentials.ts b/src/controllers/credentials.ts index 5b7c35e7..360b92e3 100644 --- a/src/controllers/credentials.ts +++ b/src/controllers/credentials.ts @@ -32,11 +32,6 @@ export class CredentialController { return response.status(400).json({ error: result.array()[0].msg }) } try { - if (!await CustomerService.instance.find(response.locals.customerId, {did: request.body.issuerDid})) { - return response.status(400).json({ - error: `Issuer DID ${request.body.issuerDid} not found` - }) - } const credential: VerifiableCredential = await Credentials.instance.issue_credential(request.body, response.locals.customerId) response.status(200).json(credential) } catch (error) { diff --git a/src/controllers/customer.ts b/src/controllers/customer.ts index c1dc425c..648a66f5 100644 --- a/src/controllers/customer.ts +++ b/src/controllers/customer.ts @@ -1,14 +1,12 @@ import type { Request, Response } from 'express' import { CustomerService } from '../services/customer.js' -import { Identity } from '../services/identity.js' export class CustomerController { public async create(request: Request, response: Response) { try { - const kid = (await Identity.instance.createKey('Secp256k1')).kid - const customer = await CustomerService.instance.create(response.locals.customerId, kid) + const customer = await CustomerService.instance.create(response.locals.customerId) if(!customer) { return response.status(400).json({ error: `Error creating customer. Please try again` @@ -16,7 +14,6 @@ export class CustomerController { } return response.status(200).json({ customerId: customer.customerId, - address: customer.address }) } catch (error) { return response.status(500).json({ diff --git a/src/controllers/issuer.ts b/src/controllers/issuer.ts index a91588ba..5932578e 100644 --- a/src/controllers/issuer.ts +++ b/src/controllers/issuer.ts @@ -5,10 +5,8 @@ import { v4 } from 'uuid' import { MethodSpecificIdAlgo, VerificationMethods, CheqdNetwork } from '@cheqd/sdk' import { MsgCreateResourcePayload } from '@cheqd/ts-proto/cheqd/resource/v2/index.js' -import { Identity } from '../services/identity.js' -import { CustomerService } from '../services/customer.js' +import { Identity } from '../services/identity/index.js' import { generateDidDoc, validateSpecCompliantPayload } from '../helpers/helpers.js' -import { CustomerEntity } from '../database/entities/customer.entity.js' import { check, param, validationResult } from 'express-validator' import { fromString } from 'uint8arrays' @@ -48,8 +46,7 @@ export class IssuerController { public async createKey(request: Request, response: Response) { try { - const key = await Identity.instance.createKey() - await CustomerService.instance.update(response.locals.customerId, { kids: [key.kid] }) + const key = await Identity.createKey('Ed25519', response.locals.customerId) return response.status(200).json(key) } catch (error) { return response.status(500).json({ @@ -60,11 +57,7 @@ export class IssuerController { public async getKey(request: Request, response: Response) { try { - const isOwner = await CustomerService.instance.find(response.locals.customerId, {kid: request.params.kid}) - if(!isOwner) { - return response.status(401).json(`Not found`) - } - const key = await Identity.instance.getKey(request.params.kid) + const key = await Identity.getKey(request.params.kid, response.locals.customerId) return response.status(200).json(key) } catch (error) { return response.status(500).json({ @@ -90,7 +83,7 @@ export class IssuerController { if (options.didDocument) { didDocument = options.didDocument } else if (verificationMethod) { - const key = await Identity.instance.createKey() + const key = await Identity.createKey('Ed25519', response.locals.customerId) kids.push(key.kid) didDocument = generateDidDoc({ verificationMethod: verificationMethod.type, @@ -106,8 +99,7 @@ export class IssuerController { }) } - const did = await Identity.instance.createDid(network, didDocument, response.locals.customerId) - await CustomerService.instance.update(response.locals.customerId, { kids, dids: [did.did] }) + const did = await Identity.createDid(network, didDocument, response.locals.customerId) return response.status(200).json(did) } catch (error) { return response.status(500).json({ @@ -130,7 +122,7 @@ export class IssuerController { let resourcePayload: Partial = {} try { // check if did is registered on the ledger - let resolvedDocument = await Identity.instance.resolveDid(did) + let resolvedDocument = await Identity.resolveDid(did) if(!resolvedDocument?.didDocument || resolvedDocument.didDocumentMetadata.deactivated) { return response.status(400).send({ error: `${did} is a Deactivated DID` @@ -149,7 +141,7 @@ export class IssuerController { alsoKnownAs } network = network || (did.split(':'))[2] - const result = await Identity.instance.createResource( network, resourcePayload, response.locals.customerId) + const result = await Identity.createResource( network, resourcePayload, response.locals.customerId) if ( result ) { return response.status(201).json({ resource: resourcePayload @@ -170,10 +162,9 @@ export class IssuerController { try { let did: any if(request.params.did) { - did = await Identity.instance.resolveDid(request.params.did) + did = await Identity.resolveDid(request.params.did) } else { - const customer = await CustomerService.instance.get(response.locals.customerId) as CustomerEntity - did = customer.dids + did = await Identity.listDids(response.locals.customerId) } return response.status(200).json(did) diff --git a/src/database/connection/connection.ts b/src/database/connection/connection.ts index edb8da32..d325ca88 100644 --- a/src/database/connection/connection.ts +++ b/src/database/connection/connection.ts @@ -1,43 +1,24 @@ -import pkg from 'pg-connection-string' import { DataSource } from 'typeorm' -import { migrations, Entities } from '@veramo/data-store' - -import { CustomerEntity } from '../entities/customer.entity.js' -import { CreateCustomersTable1683723285946 } from '../migrations/CreateCustomersTable.js' +import { AbstractDatabase, Memory, Postgres } from '../types/types.js' import * as dotenv from 'dotenv' dotenv.config() -const { DB_CONNECTION_URL, DB_CERTIFICATE } = process.env +const { ENABLE_EXTERNAL_DB } = process.env export class Connection { - public dbConnection : DataSource + private db: AbstractDatabase + public dbConnection: DataSource public static instance = new Connection() - constructor () { - const { parse } = pkg - if(!DB_CONNECTION_URL) { - throw new Error(`Error: Invalid Database url`) - } - const config = parse(DB_CONNECTION_URL) - if(!(config.host && config.port && config.database)) { - throw new Error(`Error: Invalid Database url`) + constructor() { + if (ENABLE_EXTERNAL_DB == "true") { + this.db = new Postgres() + } else { + this.db = new Memory() } - this.dbConnection = new DataSource({ - type: 'postgres', - host: config.host, - port: Number(config.port), - username: config.user, - password: config.password, - database: config.database, - ssl: config.ssl ? { - ca: DB_CERTIFICATE - } : false, - migrations: [...migrations, CreateCustomersTable1683723285946], - entities: [...Entities, CustomerEntity], - logging: ['error', 'info', 'warn'] - }) + this.dbConnection = this.db.setup() } public async connect() { @@ -48,5 +29,3 @@ export class Connection { } } } - - diff --git a/src/database/entities/customer.entity.ts b/src/database/entities/customer.entity.ts index cc52611b..076e7861 100644 --- a/src/database/entities/customer.entity.ts +++ b/src/database/entities/customer.entity.ts @@ -1,36 +1,76 @@ -import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm' +import { Column, Entity, PrimaryGeneratedColumn, ValueTransformer } from 'typeorm' + +import * as dotenv from 'dotenv' +dotenv.config() + +const { ENABLE_EXTERNAL_DB } = process.env; + +const arrayToJsonTransformer = (shouldTransform: string): ValueTransformer => { + return { + to: (array: any[]) => { + if (shouldTransform == "false") { + // Convert the array to a JSON string + return JSON.stringify(array); + } + return array; + }, + from: (jsonString: string) => { + if (shouldTransform == "false") { + // Parse the JSON string and return the array + return JSON.parse(jsonString); + } + return jsonString; + }, + }; +}; @Entity('customers') export class CustomerEntity { - @PrimaryGeneratedColumn('uuid') - customerId!: string - - @Column('text') - account!: string - - @Column('text') - address!: string - - @Column('text', {array: true, default: []}) - kids!: string[] - - @Column('text', {array: true, default: []}) - dids!: string[] - - @Column('text', {array: true, default: []}) - claimIds!: string[] - - @Column('text', {array: true, default: []}) - presentationIds!: string[] - - - constructor(customerId: string, account: string, address: string) { - this.customerId= customerId - this.account = account - this.address = address - this.kids= [] - this.dids= [] - this.claimIds= [] - this.presentationIds= [] - } -} \ No newline at end of file + @PrimaryGeneratedColumn('uuid') + customerId!: string + + @Column('text') + account!: string + + @Column('text') + address!: string + + @Column({ + type: 'text', + transformer: arrayToJsonTransformer(ENABLE_EXTERNAL_DB), + array: true, + nullable: true, + }) + kids!: string[] + + @Column({ + type: 'text', + transformer: arrayToJsonTransformer(ENABLE_EXTERNAL_DB), + array: true, + nullable: true, + }) + dids!: string[] + + @Column({ + type: 'text', + transformer: arrayToJsonTransformer(ENABLE_EXTERNAL_DB), + array: true, + nullable: true, + }) + claimIds!: string[] + + @Column({ + type: 'text', + transformer: arrayToJsonTransformer(ENABLE_EXTERNAL_DB), + array: true, + nullable: true, + }) + presentationIds!: string[] + + + constructor(customerId: string, account: string, address: string) { + this.customerId = customerId + this.account = account + this.address = address + } +} diff --git a/src/database/migrations/CreateCustomersTable.ts b/src/database/migrations/CreateCustomersTable.ts index 4c721605..92b0759b 100644 --- a/src/database/migrations/CreateCustomersTable.ts +++ b/src/database/migrations/CreateCustomersTable.ts @@ -8,10 +8,10 @@ export class CreateCustomersTable1683723285946 implements MigrationInterface { { name: 'customerId', type: 'varchar', isPrimary: true, generationStrategy: 'uuid' }, { name: 'account', type: 'text' }, { name: 'address', type: 'text' }, - { name: 'kids', type: 'text', isArray: true, default: "'{}'" }, - { name: 'dids', type: 'text', isArray: true, default: "'{}'" }, - { name: 'claimIds', type: 'text', isArray: true, default: "'{}'" }, - { name: 'presentationIds', type: 'text', isArray: true, default: "'{}'" }, + { name: 'kids', type: 'text', isArray: true, isNullable: true }, + { name: 'dids', type: 'text', isArray: true, isNullable: true }, + { name: 'claimIds', type: 'text', isArray: true, isNullable: true }, + { name: 'presentationIds', type: 'text', isArray: true, isNullable: true }, ] }), true) } diff --git a/src/database/types/types.ts b/src/database/types/types.ts new file mode 100644 index 00000000..2f3d273b --- /dev/null +++ b/src/database/types/types.ts @@ -0,0 +1,54 @@ +import pkg from 'pg-connection-string' +import { DataSource } from 'typeorm' +import { migrations, Entities } from '@veramo/data-store' + +import { CustomerEntity } from '../entities/customer.entity.js' +import { CreateCustomersTable1683723285946 } from '../migrations/CreateCustomersTable.js' + +import * as dotenv from 'dotenv' +dotenv.config() + +const { EXTERNAL_DB_CONNECTION_URL, EXTERNAL_DB_CERT } = process.env; + +export interface AbstractDatabase { + setup(): DataSource; +} + +export class Memory implements AbstractDatabase { + setup(): DataSource { + return new DataSource({ + type: 'sqlite', + database: ':memory:', + entities: [...Entities], + synchronize: false, + migrations: [...migrations], + migrationsRun: true, + logging: ['error', 'info', 'warn'] + }); + } +} + +export class Postgres implements AbstractDatabase { + setup(): DataSource { + const { parse } = pkg; + const config = parse(EXTERNAL_DB_CONNECTION_URL) + if (!(config.host && config.port && config.database)) { + throw new Error(`Error: Invalid Database URL`) + } + + return new DataSource({ + type: 'postgres', + host: config.host, + port: Number(config.port), + username: config.user, + password: config.password, + database: config.database, + ssl: config.ssl ? { + ca: EXTERNAL_DB_CERT + } : false, + migrations: [...migrations, CreateCustomersTable1683723285946], + entities: [...Entities, CustomerEntity], + logging: ['error', 'info', 'warn'] + }); + } +} diff --git a/src/middleware/authentication.ts b/src/middleware/authentication.ts index 45ea8ffb..8b5c9ec6 100644 --- a/src/middleware/authentication.ts +++ b/src/middleware/authentication.ts @@ -8,7 +8,13 @@ import { IncomingHttpHeaders } from 'http'; import * as dotenv from 'dotenv' dotenv.config() -const { LOGTO_ENDPOINT, LOGTO_RESOURCE_URL, ENABLE_AUTHENTICATION, DEFAULT_CUSTOMER_ID } = process.env +const { + LOGTO_ENDPOINT, + LOGTO_RESOURCE_URL, + ENABLE_AUTHENTICATION, + DEFAULT_CUSTOMER_ID, + ENABLE_EXTERNAL_DB +} = process.env const OIDC_ISSUER = LOGTO_ENDPOINT + '/oidc' const OIDC_JWKS_ENDPOINT = LOGTO_ENDPOINT + '/oidc/jwks' @@ -26,11 +32,6 @@ export const extractBearerTokenFromHeaders = ({ authorization }: IncomingHttpHea }; export class Authentication { - static expressJWT = expressjwt({ - secret: "random-secret", - algorithms: ["ES384"], - credentialsRequired: false - }) static handleError(error: Error, jwtRequest: JWTRequest, response: Response, next: NextFunction) { if (error) { @@ -41,18 +42,26 @@ export class Authentication { next() } - static async authenticate(jwtRequest: JWTRequest, response: Response, next: NextFunction) { - if(jwtRequest.path == '/') return next() - - if (!jwtRequest.auth?.sub) return response.status(401).json({ - error: 'Invalid auth token' - }) - - if(jwtRequest.path != '/account' && !await CustomerService.instance.find(jwtRequest.auth.sub, {})) return response.status(401).json({ - error: 'Customer not found' - }) + static async accessControl(request: Request, response: Response, next: NextFunction) { + let message = undefined + switch(ENABLE_EXTERNAL_DB) { + case 'false': + if (['/account', '/did/create', '/key/create'].includes(request.path)) { + message = 'Api not supported' + } + break + default: + if (request.path != '/account' && !await CustomerService.instance.find(response.locals.customerId, {})) { + message = 'Customer not found' + } + break + } - response.locals.customerId = jwtRequest.auth.sub + if(message) { + return response.status(400).json({ + error: message + }) + } next() } diff --git a/src/services/credentials.ts b/src/services/credentials.ts index a59d86cd..66452e19 100644 --- a/src/services/credentials.ts +++ b/src/services/credentials.ts @@ -2,12 +2,10 @@ import { CredentialPayload, IVerifyResult, VerifiableCredential, W3CVerifiableCr import { VC_CONTEXT, - VC_PROOF_FORMAT, - VC_REMOVE_ORIGINAL_FIELDS, VC_TYPE } from '../types/constants.js' import { CredentialRequest } from '../types/types.js' -import { Identity } from './identity.js' +import { Identity } from './identity/index.js' import { VeridaService } from '../services/connectors/verida.js' import { v4 } from 'uuid' import * as dotenv from 'dotenv' @@ -34,22 +32,7 @@ export class Credentials { credential.expirationDate = request.expirationDate } - const agent = await Identity.instance.create_agent(agentId) - let verifiable_credential: VerifiableCredential - verifiable_credential = await agent.createVerifiableCredential( - { - save: false, - credential, - proofFormat: request.format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, - removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS - } - ) - - // if (verifiable_credential?.vc) delete verifiable_credential.vc - // if (verifiable_credential?.sub) delete verifiable_credential.sub - // if (verifiable_credential?.iss) delete verifiable_credential.iss - // if (verifiable_credential?.nbf) delete verifiable_credential.nbf - // if (verifiable_credential?.exp) delete verifiable_credential.exp + let verifiable_credential = await Identity.createCredential(credential, request.format, agentId) if (ENABLE_VERIDA_CONNECTOR === 'true' && request.subjectDid.startsWith('did:vda')) { await VeridaService.instance.sendCredential( @@ -64,20 +47,13 @@ export class Credentials { } async verify_credentials(credential: W3CVerifiableCredential | string, agentId: string): Promise { - const agent = await Identity.instance.create_agent(agentId) - const result = await agent.verifyCredential({ credential, fetchRemoteContexts: true }) + const result = await Identity.verifyCredential(credential, agentId) delete(result.payload) return result } async verify_presentation(presentation: W3CVerifiablePresentation, agentId: string): Promise { - const agent = await Identity.instance.create_agent(agentId) - const result = await agent.execute( - 'verifyPresentation', - { - presentation - } - ) + const result = await Identity.verifyPresentation(presentation, agentId) return result } } diff --git a/src/services/customer.ts b/src/services/customer.ts index b6caffbd..e0a78b72 100644 --- a/src/services/customer.ts +++ b/src/services/customer.ts @@ -1,11 +1,17 @@ -import { ArrayContains, Like, Repository } from 'typeorm' +import { ArrayContains, Repository } from 'typeorm' import { Connection } from '../database/connection/connection.js' import { CustomerEntity } from '../database/entities/customer.entity.js' import { getCosmosAccount } from '../helpers/helpers.js' +import { Identity } from './identity/index.js' + +import * as dotenv from 'dotenv' +dotenv.config() + +const { ENABLE_EXTERNAL_DB } = process.env; export class CustomerService { - public customerRepository : Repository + public customerRepository: Repository public static instance = new CustomerService() @@ -13,9 +19,13 @@ export class CustomerService { this.customerRepository = Connection.instance.dbConnection.getRepository(CustomerEntity) } - public async create(customerId: string, kid: string) { + public async create(customerId: string) { + if(await this.find(customerId, {})) { + throw new Error('Customer exists') + } + const kid = (await Identity.createKey('Secp256k1', customerId)).kid const customer = new CustomerEntity(customerId, kid, getCosmosAccount(kid)) - return (await this.customerRepository.insert(customer)).generatedMaps[0] + return (await this.customerRepository.insert(customer)).identifiers[0] } public async update(customerId: string, { kids=[], dids=[], claimIds=[], presentationIds=[]} : { kids?: string[], dids?: string[], claimIds?: string[], presentationIds?: string[] }) { @@ -24,10 +34,11 @@ export class CustomerService { throw new Error(`CustomerId not found`) } - existingCustomer.kids= existingCustomer.kids.concat(kids) - existingCustomer.dids= existingCustomer.dids.concat(dids) - existingCustomer.claimIds= existingCustomer.claimIds.concat(claimIds) - existingCustomer.presentationIds= existingCustomer.presentationIds.concat(presentationIds) + existingCustomer.kids = this.concatenate(existingCustomer.kids, kids) + existingCustomer.dids = this.concatenate(existingCustomer.dids, dids) + existingCustomer.claimIds = this.concatenate(existingCustomer.claimIds, claimIds) + existingCustomer.presentationIds = this.concatenate(existingCustomer.presentationIds, presentationIds) + return await this.customerRepository.save(existingCustomer) } @@ -35,7 +46,7 @@ export class CustomerService { return customerId ? await this.customerRepository.findOneBy({ customerId }) : await this.customerRepository.find() } - public async find(customerId: string, { kid, did, claimId, presentationId }: {kid?: string, did?: string, claimId?: string, presentationId?: string}) { + public async find(customerId: string, { kid, did, claimId, presentationId }: { kid?: string, did?: string, claimId?: string, presentationId?: string }) { const where: any = { customerId } @@ -62,4 +73,8 @@ export class CustomerService { return false } } + + private concatenate(array: any[], items: any[]): any { + return array ? array.concat(items) : items + } } \ No newline at end of file diff --git a/src/services/identity.ts b/src/services/identity.ts deleted file mode 100644 index 9ee5f2f8..00000000 --- a/src/services/identity.ts +++ /dev/null @@ -1,235 +0,0 @@ -import { - DIDDocument, - IIdentifier, - ManagedKeyInfo, - MinimalImportableIdentifier, - MinimalImportableKey, - TAgent, - createAgent, - IDataStore, - IDIDManager, - IKeyManager, - IResolver, - ICredentialIssuer, - ICredentialVerifier, -} from '@veramo/core' -import { CredentialPlugin } from '@veramo/credential-w3c' -import { DIDManager } from '@veramo/did-manager' -import { DIDResolverPlugin } from '@veramo/did-resolver' -import { KeyManager } from '@veramo/key-manager' -import { KeyManagementSystem, SecretBox } from '@veramo/kms-local' -import { KeyStore, DIDStore, PrivateKeyStore } from '@veramo/data-store' -import { CredentialIssuerLD, ICredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' -import { CheqdDIDProvider, getResolver as CheqdDidResolver, ResourcePayload, Cheqd } from '@cheqd/did-provider-cheqd' -import { ICheqd } from '@cheqd/did-provider-cheqd/build/types/agent/ICheqd.js' -import { CheqdNetwork } from '@cheqd/sdk' -import { Resolver, ResolverRegistry } from 'did-resolver' -import { v4 } from 'uuid' - -import { cheqdDidRegex, DefaultRPCUrl } from '../types/types.js' -import { Connection } from '../database/connection/connection.js' -import { CustomerEntity } from '../database/entities/customer.entity.js' -import { CustomerService } from './customer.js' - -import * as dotenv from 'dotenv' -dotenv.config() - -const { - DB_ENCRYPTION_KEY, - MAINNET_RPC_URL, - TESTNET_RPC_URL, - RESOLVER_URL, -} = process.env - -export class Identity { - agent: TAgent - privateStore?: PrivateKeyStore - public static instance = new Identity() - - constructor() { - this.agent = this.init_agent() - } - - init_agent(): TAgent { - const dbConnection = Connection.instance.dbConnection - this.privateStore = new PrivateKeyStore(dbConnection, new SecretBox(DB_ENCRYPTION_KEY)) - return createAgent({ - plugins: [ - new KeyManager({ - store: new KeyStore(dbConnection), - kms: { - local: new KeyManagementSystem( - this.privateStore - ) - } - }), - new DIDManager({ - store: new DIDStore(dbConnection), - defaultProvider: 'did:cheqd:testnet', - providers: { - } - }), - new DIDResolverPlugin({ - resolver: new Resolver({ - ...CheqdDidResolver({url: RESOLVER_URL}) as ResolverRegistry - }) - }), - ] - }) - } - - async create_agent(agentId: string) { - const customer = await CustomerService.instance.get(agentId) as CustomerEntity - const dbConnection = Connection.instance.dbConnection - const privateKey = (await this.getPrivateKey(customer.account)).privateKeyHex - if (!privateKey || !this.privateStore) { - throw new Error(`No keys is initialized`) - } - const mainnetProvider = new CheqdDIDProvider( - { - defaultKms: 'local', - cosmosPayerSeed: privateKey, - networkType: CheqdNetwork.Mainnet as any, - rpcUrl: MAINNET_RPC_URL || DefaultRPCUrl.Mainnet, - } - ) - const testnetProvider = new CheqdDIDProvider( - { - defaultKms: 'local', - cosmosPayerSeed: privateKey, - networkType: CheqdNetwork.Testnet as any, - rpcUrl: TESTNET_RPC_URL || DefaultRPCUrl.Testnet, - } - ) - - return createAgent< - IDIDManager & - IKeyManager & - IDataStore & - IResolver & - ICredentialIssuer & - ICredentialVerifier & - ICheqd & - ICredentialIssuerLD - >({ - plugins: [ - new KeyManager({ - store: new KeyStore(dbConnection), - kms: { - local: new KeyManagementSystem( - this.privateStore - ) - } - }), - new DIDManager({ - store: new DIDStore(dbConnection), - defaultProvider: 'did:cheqd:testnet', - providers: { - 'did:cheqd:mainnet': mainnetProvider, - 'did:cheqd:testnet': testnetProvider - } - }), - new DIDResolverPlugin({ - resolver: new Resolver({ - ...CheqdDidResolver({url: RESOLVER_URL}) as ResolverRegistry - }) - }), - new CredentialPlugin(), - new CredentialIssuerLD({ - contextMaps: [LdDefaultContexts], - suites: [new VeramoEd25519Signature2018()] - }), - new Cheqd({ - providers: [mainnetProvider, testnetProvider] - }) - ] - }) - } - - async createKey(type?: 'Ed25519' | 'Secp256k1') : Promise { - if (!this.agent) throw new Error('No initialised agent found.') - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - const key = await this.agent.keyManagerCreate({ - type: type || 'Ed25519', - kms, - }) - return key - } - - async getKey(kid: string) { - return await this.agent.keyManagerGet({ kid }) - } - - private async getPrivateKey(kid: string) { - return await this.privateStore!.getKey({ alias: kid }) - } - - async createDid(network: string, didDocument: DIDDocument, agentId?: string): Promise { - try { - const agentService = agentId ? await this.create_agent(agentId) : this.agent - if (!agentService) throw new Error('No initialised agent found.') - - const [kms] = await agentService.keyManagerGetKeyManagementSystems() - - const identifier: IIdentifier = await agentService.didManagerCreate({ - provider: `did:cheqd:${network}`, - kms, - options: { - document: didDocument - } - }) - return identifier - } catch (error) { - throw new Error(`${error}`) - } - } - - async listDids() { - return await this.agent.didManagerFind() - } - - async resolveDid(did: string) { - return await this.agent.resolveDid({didUrl: did}) - } - - async getDid(did: string) { - return await this.agent.didManagerGet({did}) - } - - async importDid(did: string, privateKeyHex: string, publicKeyHex: string): Promise { - if (!this.agent) throw new Error('No initialised agent found.') - - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - - if(!did.match(cheqdDidRegex)){ - throw new Error('Invalid DID') - } - - const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', kid: v4(), privateKeyHex, publicKeyHex } - - const identifier: IIdentifier = await this.agent.didManagerImport({ keys: [key], did, controllerKeyId: key.kid } as MinimalImportableIdentifier) - - return identifier - } - - async createResource(network: string, payload: ResourcePayload, agentId?: string) { - try { - const agentService = agentId ? await this.create_agent(agentId) : this.agent - if (!agentService) throw new Error('No initialised agent found.') - - const [kms] = await agentService.keyManagerGetKeyManagementSystems() - - const result: boolean = await agentService.execute( - 'cheqdCreateLinkedResource', - { - kms, - payload, - network - } - ) - return result - } catch (error) { - throw new Error(`${error}`) - } - } -} diff --git a/src/services/identity/IIdentity.ts b/src/services/identity/IIdentity.ts new file mode 100644 index 00000000..34101c1e --- /dev/null +++ b/src/services/identity/IIdentity.ts @@ -0,0 +1,34 @@ +import { + CredentialPayload, + DIDDocument, + DIDResolutionResult, + IIdentifier, + IVerifyResult, + ManagedKeyInfo, + TAgent, + VerifiableCredential, + VerifiablePresentation, +} from '@veramo/core' +import { AbstractPrivateKeyStore } from '@veramo/key-manager' +import { ResourcePayload } from '@cheqd/did-provider-cheqd' +import * as dotenv from 'dotenv' +import { CredentialRequest, VeramoAgent } from '../../types/types' +dotenv.config() + +export interface IIdentity { + agent: TAgent + privateStore?: AbstractPrivateKeyStore + initAgent(): TAgent + createAgent?(agentId: string): Promise + createKey(type: 'Ed25519' | 'Secp256k1', agentId?: string): Promise + getKey(kid: string, agentId?: string): Promise + createDid(network: string, didDocument: DIDDocument, agentId?: string): Promise + listDids(agentId?: string): Promise + resolveDid(did: string): Promise + getDid(did: string, agentId?: string): Promise + importDid(did: string, privateKeyHex: string, publicKeyHex: string, agentId?: string): Promise + createResource(network: string, payload: ResourcePayload, agentId?: string): Promise + createCredential(credential: CredentialPayload, format: CredentialRequest['format'], agentId?: string): Promise + verifyCredential(credential: VerifiableCredential | string, agentId?: string): Promise + verifyPresentation(presentation: VerifiablePresentation | string, agentId?: string): Promise +} diff --git a/src/services/identity/index.ts b/src/services/identity/index.ts new file mode 100644 index 00000000..c60f516a --- /dev/null +++ b/src/services/identity/index.ts @@ -0,0 +1,6 @@ +import { LocalIdentity } from './local.js' +import { PostgresIdentity } from './postgres.js' + +export { IIdentity } from './IIdentity.js' + +export const Identity = process.env.ENABLE_EXTERNAL_DB === 'true' ? new PostgresIdentity() : new LocalIdentity() \ No newline at end of file diff --git a/src/services/identity/local.ts b/src/services/identity/local.ts new file mode 100644 index 00000000..0e1a273a --- /dev/null +++ b/src/services/identity/local.ts @@ -0,0 +1,195 @@ +import { + DIDDocument, + IIdentifier, + ManagedKeyInfo, + MinimalImportableIdentifier, + MinimalImportableKey, + TAgent, + createAgent, + CredentialPayload, + VerifiableCredential, + IVerifyResult, + VerifiablePresentation, +} from '@veramo/core' +import { DIDManager } from '@veramo/did-manager' +import { DIDResolverPlugin } from '@veramo/did-resolver' +import { AbstractPrivateKeyStore, KeyManager, MemoryPrivateKeyStore } from '@veramo/key-manager' +import { KeyManagementSystem } from '@veramo/kms-local' +import { KeyStore, DIDStore } from '@veramo/data-store' +import { Cheqd, CheqdDIDProvider, getResolver as CheqdDidResolver, ResourcePayload } from '@cheqd/did-provider-cheqd' +import { CheqdNetwork } from '@cheqd/sdk' +import { Resolver, ResolverRegistry } from 'did-resolver' + +import { cheqdDidRegex, CredentialRequest, DefaultRPCUrl, VeramoAgent } from '../../types/types.js' +import * as dotenv from 'dotenv' +import { Connection } from '../../database/connection/connection.js' +import { IIdentity } from './IIdentity.js' +import { VC_PROOF_FORMAT, VC_REMOVE_ORIGINAL_FIELDS } from '../../types/constants.js' +import { CredentialPlugin } from '@veramo/credential-w3c' +import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' +dotenv.config() + +const { + MAINNET_RPC_URL, + TESTNET_RPC_URL, + RESOLVER_URL, + FEE_PAYER_MNEMONIC, + ISSUER_ID_PUBLIC_KEY_HEX, + ISSUER_ID_PRIVATE_KEY_HEX, + ISSUER_DID +} = process.env + +export class LocalIdentity implements IIdentity { + agent: VeramoAgent + privateStore?: AbstractPrivateKeyStore + public static instance = new LocalIdentity() + + constructor() { + this.agent = this.initAgent() + if (!FEE_PAYER_MNEMONIC) { + throw new Error(`No fee payer found`) + } + } + + initAgent() { + const dbConnection = Connection.instance.dbConnection + this.privateStore = new MemoryPrivateKeyStore() + + const mainnetProvider = new CheqdDIDProvider( + { + defaultKms: 'local', + cosmosPayerSeed: FEE_PAYER_MNEMONIC, + networkType: CheqdNetwork.Mainnet as any, + rpcUrl: MAINNET_RPC_URL || DefaultRPCUrl.Mainnet, + } + ) + const testnetProvider = new CheqdDIDProvider( + { + defaultKms: 'local', + cosmosPayerSeed: FEE_PAYER_MNEMONIC, + networkType: CheqdNetwork.Testnet as any, + rpcUrl: TESTNET_RPC_URL || DefaultRPCUrl.Testnet, + } + ) + return createAgent>({ + plugins: [ + new KeyManager({ + store: new KeyStore(dbConnection), + kms: { + local: new KeyManagementSystem( + this.privateStore + ) + } + }), + new DIDManager({ + store: new DIDStore(dbConnection), + defaultProvider: 'did:cheqd:testnet', + providers: { + 'did:cheqd:mainnet': mainnetProvider, + 'did:cheqd:testnet': testnetProvider + } + }), + new DIDResolverPlugin({ + resolver: new Resolver({ + ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry + }) + }), + new CredentialPlugin(), + new CredentialIssuerLD({ + contextMaps: [LdDefaultContexts], + suites: [new VeramoEd25519Signature2018()] + }), + new Cheqd({ + providers: [mainnetProvider, testnetProvider] + }) + ] + }) + } + + async createKey(): Promise { + throw new Error('Not supported') + } + + async getKey(kid: string) { + return await this.agent.keyManagerGet({ kid }) + } + + async createDid(): Promise { + throw new Error('Not supported') + } + + async listDids() { + return [(await this.importDid()).did] + } + + async resolveDid(did: string) { + return await this.agent.resolveDid({ didUrl: did }) + } + + async getDid(did: string) { + return await this.agent.didManagerGet({ did }) + } + + async importDid(): Promise { + if (!this.agent) throw new Error('No initialised agent found.') + if (!(ISSUER_DID && ISSUER_ID_PUBLIC_KEY_HEX && ISSUER_ID_PRIVATE_KEY_HEX)) throw new Error('No DIDs and Keys found') + + const [kms] = await this.agent.keyManagerGetKeyManagementSystems() + + if (!ISSUER_DID.match(cheqdDidRegex)) { + throw new Error('Invalid DID') + } + + const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', kid: ISSUER_ID_PUBLIC_KEY_HEX, privateKeyHex: ISSUER_ID_PRIVATE_KEY_HEX, publicKeyHex: ISSUER_ID_PUBLIC_KEY_HEX } + + const identifier: IIdentifier = await this.agent.didManagerImport({ keys: [key], did: ISSUER_DID, controllerKeyId: key.kid } as MinimalImportableIdentifier) + + return identifier + } + + async createResource(network: string, payload: ResourcePayload) { + try { + // import DID + await this.importDid() + if (!this.agent) throw new Error('No initialised agent found.') + + const [kms] = await this.agent.keyManagerGetKeyManagementSystems() + + const result: boolean = await this.agent.cheqdCreateLinkedResource({ + kms, + payload, + network: network as CheqdNetwork + } + ) + return result + } catch (error) { + throw new Error(`${error}`) + } + } + + async createCredential(credential: CredentialPayload, format: CredentialRequest['format']): Promise { + try { + // import DID + await this.importDid() + const verifiable_credential = await this.agent.createVerifiableCredential( + { + save: false, + credential, + proofFormat: format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, + removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS + } + ) + return verifiable_credential + } catch (error) { + throw new Error(`${error}`) + } + } + + async verifyCredential(credential: VerifiableCredential | string): Promise { + return await this.agent.verifyCredential({ credential, fetchRemoteContexts: true }) + } + + async verifyPresentation(presentation: VerifiablePresentation | string): Promise { + return await this.agent.verifyPresentation({ presentation, fetchRemoteContexts: true }) + } +} diff --git a/src/services/identity/postgres.ts b/src/services/identity/postgres.ts new file mode 100644 index 00000000..8c9ed6e9 --- /dev/null +++ b/src/services/identity/postgres.ts @@ -0,0 +1,262 @@ +import { + CredentialPayload, + DIDDocument, + IIdentifier, + IVerifyResult, + ManagedKeyInfo, + MinimalImportableIdentifier, + MinimalImportableKey, + TAgent, + VerifiableCredential, + VerifiablePresentation, + createAgent, +} from '@veramo/core' +import { CredentialPlugin } from '@veramo/credential-w3c' +import { DIDManager } from '@veramo/did-manager' +import { DIDResolverPlugin } from '@veramo/did-resolver' +import { AbstractPrivateKeyStore, KeyManager } from '@veramo/key-manager' +import { KeyManagementSystem, SecretBox } from '@veramo/kms-local' +import { KeyStore, DIDStore, PrivateKeyStore } from '@veramo/data-store' +import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' +import { CheqdDIDProvider, getResolver as CheqdDidResolver, ResourcePayload, Cheqd } from '@cheqd/did-provider-cheqd' +import { CheqdNetwork } from '@cheqd/sdk' +import { Resolver, ResolverRegistry } from 'did-resolver' +import { v4 } from 'uuid' + +import { cheqdDidRegex, CredentialRequest, DefaultRPCUrl, VeramoAgent } from '../../types/types.js' +import { Connection } from '../../database/connection/connection.js' +import { CustomerEntity } from '../../database/entities/customer.entity.js' +import { CustomerService } from '../customer.js' + +import * as dotenv from 'dotenv' +import { IIdentity } from './IIdentity.js' +import { VC_PROOF_FORMAT, VC_REMOVE_ORIGINAL_FIELDS } from '../../types/constants.js' +dotenv.config() + +const { + MAINNET_RPC_URL, + TESTNET_RPC_URL, + RESOLVER_URL, + EXTERNAL_DB_ENCRYPTION_KEY, +} = process.env + +export class PostgresIdentity implements IIdentity { + agent: TAgent + privateStore?: AbstractPrivateKeyStore + public static instance = new PostgresIdentity() + + constructor() { + this.agent = this.initAgent() + } + + initAgent(): TAgent { + const dbConnection = Connection.instance.dbConnection + this.privateStore = new PrivateKeyStore(dbConnection, new SecretBox(EXTERNAL_DB_ENCRYPTION_KEY)) + + return createAgent({ + plugins: [ + new KeyManager({ + store: new KeyStore(dbConnection), + kms: { + postgres: new KeyManagementSystem( + this.privateStore + ) + } + }), + new DIDManager({ + store: new DIDStore(dbConnection), + defaultProvider: 'did:cheqd:testnet', + providers: {} + }), + new DIDResolverPlugin({ + resolver: new Resolver({ + ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry + }) + }), + ] + }) + } + + async createAgent(agentId: string) : Promise { + const customer = await CustomerService.instance.get(agentId) as CustomerEntity + const dbConnection = Connection.instance.dbConnection + + const privateKey = (await this.getPrivateKey(customer.account)).privateKeyHex + if (!privateKey || !this.privateStore) { + throw new Error(`No keys is initialized`) + } + + const mainnetProvider = new CheqdDIDProvider( + { + defaultKms: 'postgres', + cosmosPayerSeed: privateKey, + networkType: CheqdNetwork.Mainnet as any, + rpcUrl: MAINNET_RPC_URL || DefaultRPCUrl.Mainnet, + } + ) + const testnetProvider = new CheqdDIDProvider( + { + defaultKms: 'postgres', + cosmosPayerSeed: privateKey, + networkType: CheqdNetwork.Testnet as any, + rpcUrl: TESTNET_RPC_URL || DefaultRPCUrl.Testnet, + } + ) + + return createAgent({ + plugins: [ + new KeyManager({ + store: new KeyStore(dbConnection), + kms: { + postgres: new KeyManagementSystem( + this.privateStore + ) + } + }), + new DIDManager({ + store: new DIDStore(dbConnection), + defaultProvider: 'did:cheqd:testnet', + providers: { + 'did:cheqd:mainnet': mainnetProvider, + 'did:cheqd:testnet': testnetProvider + } + }), + new DIDResolverPlugin({ + resolver: new Resolver({ + ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry + }) + }), + new CredentialPlugin(), + new CredentialIssuerLD({ + contextMaps: [LdDefaultContexts], + suites: [new VeramoEd25519Signature2018()] + }), + new Cheqd({ + providers: [mainnetProvider, testnetProvider] + }) + ] + }) + } + + async createKey(type: 'Ed25519' | 'Secp256k1'='Ed25519', agentId: string): Promise { + if (!this.agent) throw new Error('No initialised agent found.') + const [kms] = await this.agent.keyManagerGetKeyManagementSystems() + const key = await this.agent.keyManagerCreate({ + type: type || 'Ed25519', + kms, + }) + await CustomerService.instance.update(agentId, { kids: [key.kid] }) + return key + } + + async getKey(kid: string, agentId: string) { + const isOwner = await CustomerService.instance.find(agentId, {kid}) + if(!isOwner) { + throw new Error(`Customer not found`) + } + return await this.agent.keyManagerGet({ kid }) + } + + private async getPrivateKey(kid: string) { + return await this.privateStore!.getKey({ alias: kid }) + } + + async createDid(network: string, didDocument: DIDDocument, agentId: string): Promise { + try { + const agent = await this.createAgent(agentId) + if (!agent) throw new Error('No initialised agent found.') + + const [kms] = await agent.keyManagerGetKeyManagementSystems() + + const identifier: IIdentifier = await agent.didManagerCreate({ + provider: `did:cheqd:${network}`, + kms, + options: { + document: didDocument + } + }) + await CustomerService.instance.update(agentId, { dids: [identifier.did] }) + return identifier + } catch (error) { + throw new Error(`${error}`) + } + } + + async listDids(agentId: string) { + const customer = await CustomerService.instance.get(agentId) as CustomerEntity + return customer?.dids || [] + } + + async resolveDid(did: string) { + return await this.agent.resolveDid({ didUrl: did }) + } + + async getDid(did: string) { + return await this.agent.didManagerGet({ did }) + } + + async importDid(did: string, privateKeyHex: string, publicKeyHex: string): Promise { + if (!this.agent) throw new Error('No initialised agent found.') + + const [kms] = await this.agent.keyManagerGetKeyManagementSystems() + + if (!did.match(cheqdDidRegex)) { + throw new Error('Invalid DID') + } + + const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', kid: v4(), privateKeyHex, publicKeyHex } + + const identifier: IIdentifier = await this.agent.didManagerImport({ keys: [key], did, controllerKeyId: key.kid } as MinimalImportableIdentifier) + + return identifier + } + + async createResource(network: string, payload: ResourcePayload, agentId: string) { + try { + const agent = await this.createAgent(agentId) + if (!agent) throw new Error('No initialised agent found.') + + const [kms] = await agent.keyManagerGetKeyManagementSystems() + + const result: boolean = await agent.cheqdCreateLinkedResource({ + kms, + payload, + network: network as CheqdNetwork + }) + return result + } catch (error) { + throw new Error(`${error}`) + } + } + + async createCredential(credential: CredentialPayload, format: CredentialRequest['format'], agentId: string): Promise { + try { + const did = typeof(credential.issuer) == 'string' ? credential.issuer : credential.issuer.id + if (!await CustomerService.instance.find(agentId, {did})) { + throw new Error('Customer not found') + } + const agent = await this.createAgent(agentId) + const verifiable_credential = await agent.createVerifiableCredential( + { + save: false, + credential, + proofFormat: format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, + removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS + } + ) + return verifiable_credential + } catch (error) { + throw new Error(`${error}`) + } + } + + async verifyCredential(credential: string | VerifiableCredential, agentId: string): Promise { + const agent = await this.createAgent(agentId) + return await agent.verifyCredential({ credential, fetchRemoteContexts: true }) + } + + async verifyPresentation(presentation: VerifiablePresentation | string, agentId: string): Promise { + const agent = await this.createAgent(agentId) + return await agent.verifyPresentation({ presentation, fetchRemoteContexts: true }) + } +} diff --git a/src/types/environment.d.ts b/src/types/environment.d.ts index da451827..ea4650bf 100644 --- a/src/types/environment.d.ts +++ b/src/types/environment.d.ts @@ -11,12 +11,13 @@ declare global { // Network API endpoints MAINNET_RPC_URL: string TESTNET_RPC_URL: string - RESOLVER_URL: string - - // Veramo Database configuration - DB_CONNECTION_URL: string - DB_ENCRYPTION_KEY: string - DB_CERTIFICATE: string | undefined + RESOLVER_URL: string + ALLOWED_ORIGINS: string | undefined + ENABLE_EXTERNAL_DB: string + EXTERNAL_DB_CONNECTION_URL: string + EXTERNAL_DB_ENCRYPTION_KEY: string + EXTERNAL_DB_CERT: string | undefined + ISSUER_DATABASE_CERT: string | undefined // LogTo ENABLE_AUTHENTICATION: string @@ -33,6 +34,12 @@ declare global { POLYGON_RPC_URL: string VERIDA_PRIVATE_KEY: string POLYGON_PRIVATE_KEY: string + + // Without external db + ISSUER_ID_PRIVATE_KEY_HEX: string + ISSUER_ID_PUBLIC_KEY_HEX: string + FEE_PAYER_MNEMONIC: string + ISSUER_DID: string } } } diff --git a/src/types/types.ts b/src/types/types.ts index 440d0fff..98bdd7ed 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,5 +1,16 @@ import { ContextType } from '@veramo/core-types' -import { W3CVerifiableCredential } from '@veramo/core' +import { + IDIDManager, + IKeyManager, + IDataStore, + IResolver, + ICredentialIssuer, + ICredentialVerifier, + W3CVerifiableCredential, + TAgent +} from '@veramo/core' +import { ICheqd } from '@cheqd/did-provider-cheqd/build/types/agent/ICheqd' +import { ICredentialIssuerLD } from '@veramo/credential-ld' export type ErrorResponse = { name: string @@ -10,73 +21,8 @@ export type ErrorResponse = { export type CompactJWT = string -export type IssuerType = { id: string;[x: string]: any } | string - -export type CredentialSubject = { - id?: string - [x: string]: any -} - -export type CredentialStatus = { - id?: string - type?: string - [x: string]: any -} - - -export interface ProofType { - type?: string - - [x: string]: any -} - -export interface UnsignedCredential { - issuer: IssuerType - credentialSubject: CredentialSubject - type?: string[] | string - '@context': string[] | string - issuanceDate: string - expirationDate?: string - credentialStatus?: CredentialStatus - id?: string - - [x: string]: any -} - -export type VerifiableCredential = UnsignedCredential & { proof: ProofType } - -export interface UnsignedPresentation { - holder: string - verifiableCredential?: W3CVerifiableCredential[] - type?: string[] | string - '@context': string[] | string - verifier?: string[] - issuanceDate?: string - expirationDate?: string - id?: string - - [x: string]: any -} - -export type VerifiablePresentation = UnsignedPresentation & { proof: ProofType } - -export type W3CVerifiablePresentation = VerifiablePresentation | CompactJWT - export type DateType = string | Date -export interface CredentialPayload { - issuer?: IssuerType - credentialSubject?: CredentialSubject - type?: string[] - '@context'?: ContextType - issuanceDate?: DateType - expirationDate?: DateType - credentialStatus?: CredentialStatus - id?: string - - [x: string]: any -} - export interface PresentationPayload { holder: string verifiableCredential?: W3CVerifiableCredential[] @@ -97,16 +43,6 @@ export type GenericAuthResponse = { error?: any } -export type WebPage = { - '@type': string, - description?: string, - name?: string - identifier?: string - URL?: string - lastReviewed?: Date - thumbnailUrl?: string -} - export interface CredentialRequest { subjectDid: string attributes: Record @@ -121,8 +57,6 @@ export interface CredentialRequest { export type GenericAuthUser = Record | null | undefined -export type Credential = VerifiableCredential // Omit - const UUID = '([a-z,0-9,-]{36,36})' const ID_CHAR = `(?:[a-zA-Z0-9]{21,22}|${UUID})` const NETWORK = '(testnet|mainnet)' @@ -146,4 +80,13 @@ export enum DefaultResolverUrl { export type SpecValidationResult = { valid: boolean error?: string -} \ No newline at end of file +} + +export type VeramoAgent = TAgent \ No newline at end of file From 15228644abf1fe083bc55db26d013d9dca974969 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 6 Jun 2023 13:38:18 +0000 Subject: [PATCH 2/4] chore(release): 2.1.0-develop.16 [skip ci] ## [2.1.0-develop.16](https://github.com/cheqd/credential-service/compare/2.1.0-develop.15...2.1.0-develop.16) (2023-06-06) ### Features * Implement USE_EXTERNAL_DB toggle [DEV 2630] ([#233](https://github.com/cheqd/credential-service/issues/233)) ([a023242](https://github.com/cheqd/credential-service/commit/a02324284de8882447a1eb7c2c246d1f6e3a40b9)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7fbb7b9..a9c04252 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.1.0-develop.16](https://github.com/cheqd/credential-service/compare/2.1.0-develop.15...2.1.0-develop.16) (2023-06-06) + + +### Features + +* Implement USE_EXTERNAL_DB toggle [DEV 2630] ([#233](https://github.com/cheqd/credential-service/issues/233)) ([a023242](https://github.com/cheqd/credential-service/commit/a02324284de8882447a1eb7c2c246d1f6e3a40b9)) + ## [2.1.0-develop.15](https://github.com/cheqd/credential-service/compare/2.1.0-develop.14...2.1.0-develop.15) (2023-06-05) diff --git a/package.json b/package.json index 8f71e8f1..643b1e64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cheqd/credential-service", - "version": "2.1.0-develop.15", + "version": "2.1.0-develop.16", "description": "cheqd Credential Service Backend", "source": "src/index.ts", "main": "dist/index.js", From a33cd25b7aa17972afd83c64937ed571f4bf1e2b Mon Sep 17 00:00:00 2001 From: DaevMithran <61043607+DaevMithran@users.noreply.github.com> Date: Wed, 7 Jun 2023 19:15:44 +0530 Subject: [PATCH 3/4] fix: External db toggle panic (#248) * fix: External db toggle panic * fix: Null agent condition * fix: Fix init_agent initialization * feat: Refactor code --- package-lock.json | 4 +- src/app.ts | 3 +- src/controllers/credentials.ts | 4 +- src/controllers/issuer.ts | 16 +-- src/database/entities/customer.entity.ts | 14 +- src/database/types/types.ts | 10 +- src/middleware/authentication.ts | 14 +- src/services/credentials.ts | 6 +- src/services/customer.ts | 4 +- src/services/identity/IIdentity.ts | 2 +- src/services/identity/agent.ts | 174 +++++++++++++++++++++++ src/services/identity/index.ts | 19 ++- src/services/identity/local.ts | 130 ++++++----------- src/services/identity/postgres.ts | 160 +++++++-------------- src/services/store.ts | 2 +- src/types/types.ts | 16 ++- swagger.json | 2 +- 17 files changed, 336 insertions(+), 244 deletions(-) create mode 100644 src/services/identity/agent.ts diff --git a/package-lock.json b/package-lock.json index e7d06df6..bd6ccc0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cheqd/credential-service", - "version": "2.1.0-develop.13", + "version": "2.1.0-develop.16", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cheqd/credential-service", - "version": "2.1.0-develop.13", + "version": "2.1.0-develop.16", "license": "Apache-2.0", "dependencies": { "@cheqd/did-provider-cheqd": "^3.3.0", diff --git a/src/app.ts b/src/app.ts index 6598dba3..227ab8cd 100644 --- a/src/app.ts +++ b/src/app.ts @@ -14,6 +14,7 @@ import { CORS_ERROR_MSG } from './types/constants.js' import swaggerJSONDoc from '../swagger.json' assert { type: "json" } import * as dotenv from 'dotenv' +import { Identity } from './services/identity/index.js' dotenv.config() class App { @@ -28,7 +29,7 @@ class App { private middleware() { this.express.use(express.json({ limit: '50mb' })) - this.express.use(express.urlencoded({ extended: false })) + this.express.use(express.urlencoded({ extended: false })) this.express.use(Helmet()) this.express.use(cors({ origin: function(origin, callback){ diff --git a/src/controllers/credentials.ts b/src/controllers/credentials.ts index 360b92e3..79be76a4 100644 --- a/src/controllers/credentials.ts +++ b/src/controllers/credentials.ts @@ -27,7 +27,7 @@ export class CredentialController { ] public async issue(request: Request, response: Response) { - const result = validationResult(request); + const result = validationResult(request) if (!result.isEmpty()) { return response.status(400).json({ error: result.array()[0].msg }) } @@ -46,7 +46,7 @@ export class CredentialController { return response.status(405).json({ error: 'Unsupported media type.' }) } - const result = validationResult(request); + const result = validationResult(request) if (!result.isEmpty()) { return response.status(400).json({ error: result.array()[0].msg }) } diff --git a/src/controllers/issuer.ts b/src/controllers/issuer.ts index 5932578e..188fb3ed 100644 --- a/src/controllers/issuer.ts +++ b/src/controllers/issuer.ts @@ -46,7 +46,7 @@ export class IssuerController { public async createKey(request: Request, response: Response) { try { - const key = await Identity.createKey('Ed25519', response.locals.customerId) + const key = await Identity.instance.createKey('Ed25519', response.locals.customerId) return response.status(200).json(key) } catch (error) { return response.status(500).json({ @@ -57,7 +57,7 @@ export class IssuerController { public async getKey(request: Request, response: Response) { try { - const key = await Identity.getKey(request.params.kid, response.locals.customerId) + const key = await Identity.instance.getKey(request.params.kid, response.locals.customerId) return response.status(200).json(key) } catch (error) { return response.status(500).json({ @@ -83,7 +83,7 @@ export class IssuerController { if (options.didDocument) { didDocument = options.didDocument } else if (verificationMethod) { - const key = await Identity.createKey('Ed25519', response.locals.customerId) + const key = await Identity.instance.createKey('Ed25519', response.locals.customerId) kids.push(key.kid) didDocument = generateDidDoc({ verificationMethod: verificationMethod.type, @@ -99,7 +99,7 @@ export class IssuerController { }) } - const did = await Identity.createDid(network, didDocument, response.locals.customerId) + const did = await Identity.instance.createDid(network, didDocument, response.locals.customerId) return response.status(200).json(did) } catch (error) { return response.status(500).json({ @@ -122,7 +122,7 @@ export class IssuerController { let resourcePayload: Partial = {} try { // check if did is registered on the ledger - let resolvedDocument = await Identity.resolveDid(did) + let resolvedDocument: any = await Identity.instance.resolveDid(did) if(!resolvedDocument?.didDocument || resolvedDocument.didDocumentMetadata.deactivated) { return response.status(400).send({ error: `${did} is a Deactivated DID` @@ -141,7 +141,7 @@ export class IssuerController { alsoKnownAs } network = network || (did.split(':'))[2] - const result = await Identity.createResource( network, resourcePayload, response.locals.customerId) + const result = await Identity.instance.createResource( network, resourcePayload, response.locals.customerId) if ( result ) { return response.status(201).json({ resource: resourcePayload @@ -162,9 +162,9 @@ export class IssuerController { try { let did: any if(request.params.did) { - did = await Identity.resolveDid(request.params.did) + did = await Identity.instance.resolveDid(request.params.did) } else { - did = await Identity.listDids(response.locals.customerId) + did = await Identity.instance.listDids(response.locals.customerId) } return response.status(200).json(did) diff --git a/src/database/entities/customer.entity.ts b/src/database/entities/customer.entity.ts index 076e7861..14632fd6 100644 --- a/src/database/entities/customer.entity.ts +++ b/src/database/entities/customer.entity.ts @@ -3,26 +3,26 @@ import { Column, Entity, PrimaryGeneratedColumn, ValueTransformer } from 'typeor import * as dotenv from 'dotenv' dotenv.config() -const { ENABLE_EXTERNAL_DB } = process.env; +const { ENABLE_EXTERNAL_DB } = process.env const arrayToJsonTransformer = (shouldTransform: string): ValueTransformer => { return { to: (array: any[]) => { if (shouldTransform == "false") { // Convert the array to a JSON string - return JSON.stringify(array); + return JSON.stringify(array) } - return array; + return array }, from: (jsonString: string) => { if (shouldTransform == "false") { // Parse the JSON string and return the array - return JSON.parse(jsonString); + return JSON.parse(jsonString) } - return jsonString; + return jsonString }, - }; -}; + } +} @Entity('customers') export class CustomerEntity { diff --git a/src/database/types/types.ts b/src/database/types/types.ts index 2f3d273b..3ace438b 100644 --- a/src/database/types/types.ts +++ b/src/database/types/types.ts @@ -8,10 +8,10 @@ import { CreateCustomersTable1683723285946 } from '../migrations/CreateCustomers import * as dotenv from 'dotenv' dotenv.config() -const { EXTERNAL_DB_CONNECTION_URL, EXTERNAL_DB_CERT } = process.env; +const { EXTERNAL_DB_CONNECTION_URL, EXTERNAL_DB_CERT } = process.env export interface AbstractDatabase { - setup(): DataSource; + setup(): DataSource } export class Memory implements AbstractDatabase { @@ -24,13 +24,13 @@ export class Memory implements AbstractDatabase { migrations: [...migrations], migrationsRun: true, logging: ['error', 'info', 'warn'] - }); + }) } } export class Postgres implements AbstractDatabase { setup(): DataSource { - const { parse } = pkg; + const { parse } = pkg const config = parse(EXTERNAL_DB_CONNECTION_URL) if (!(config.host && config.port && config.database)) { throw new Error(`Error: Invalid Database URL`) @@ -49,6 +49,6 @@ export class Postgres implements AbstractDatabase { migrations: [...migrations, CreateCustomersTable1683723285946], entities: [...Entities, CustomerEntity], logging: ['error', 'info', 'warn'] - }); + }) } } diff --git a/src/middleware/authentication.ts b/src/middleware/authentication.ts index 8b5c9ec6..498ccc2f 100644 --- a/src/middleware/authentication.ts +++ b/src/middleware/authentication.ts @@ -1,9 +1,9 @@ import { Request, Response, NextFunction } from 'express' -import { expressjwt, Request as JWTRequest } from 'express-jwt' -import { createRemoteJWKSet, jwtVerify } from 'jose'; +import { Request as JWTRequest } from 'express-jwt' +import { createRemoteJWKSet, jwtVerify } from 'jose' import { CustomerService } from '../services/customer.js' -import { IncomingHttpHeaders } from 'http'; +import { IncomingHttpHeaders } from 'http' import * as dotenv from 'dotenv' dotenv.config() @@ -28,8 +28,8 @@ export const extractBearerTokenFromHeaders = ({ authorization }: IncomingHttpHea throw new Error(`Authorization token type is not supported. Valid type: "${bearerTokenIdentifier}".`) } - return authorization.slice(bearerTokenIdentifier.length + 1); -}; + return authorization.slice(bearerTokenIdentifier.length + 1) +} export class Authentication { @@ -51,7 +51,7 @@ export class Authentication { } break default: - if (request.path != '/account' && !await CustomerService.instance.find(response.locals.customerId, {})) { + if (!['/account', '/', '/store'].includes(request.path) && !await CustomerService.instance.find(response.locals.customerId, {})) { message = 'Customer not found' } break @@ -82,7 +82,7 @@ export class Authentication { // expected audience token, should be the resource indicator of the current API audience: LOGTO_RESOURCE_URL, } - ); + ) // custom payload logic response.locals.customerId = payload.sub diff --git a/src/services/credentials.ts b/src/services/credentials.ts index 66452e19..15007a6d 100644 --- a/src/services/credentials.ts +++ b/src/services/credentials.ts @@ -32,7 +32,7 @@ export class Credentials { credential.expirationDate = request.expirationDate } - let verifiable_credential = await Identity.createCredential(credential, request.format, agentId) + let verifiable_credential = await Identity.instance.createCredential(credential, request.format, agentId) if (ENABLE_VERIDA_CONNECTOR === 'true' && request.subjectDid.startsWith('did:vda')) { await VeridaService.instance.sendCredential( @@ -47,13 +47,13 @@ export class Credentials { } async verify_credentials(credential: W3CVerifiableCredential | string, agentId: string): Promise { - const result = await Identity.verifyCredential(credential, agentId) + const result = await Identity.instance.verifyCredential(credential, agentId) delete(result.payload) return result } async verify_presentation(presentation: W3CVerifiablePresentation, agentId: string): Promise { - const result = await Identity.verifyPresentation(presentation, agentId) + const result = await Identity.instance.verifyPresentation(presentation, agentId) return result } } diff --git a/src/services/customer.ts b/src/services/customer.ts index e0a78b72..c92cc700 100644 --- a/src/services/customer.ts +++ b/src/services/customer.ts @@ -8,8 +8,6 @@ import { Identity } from './identity/index.js' import * as dotenv from 'dotenv' dotenv.config() -const { ENABLE_EXTERNAL_DB } = process.env; - export class CustomerService { public customerRepository: Repository @@ -23,7 +21,7 @@ export class CustomerService { if(await this.find(customerId, {})) { throw new Error('Customer exists') } - const kid = (await Identity.createKey('Secp256k1', customerId)).kid + const kid = (await Identity.instance.createKey('Secp256k1', customerId)).kid const customer = new CustomerEntity(customerId, kid, getCosmosAccount(kid)) return (await this.customerRepository.insert(customer)).identifiers[0] } diff --git a/src/services/identity/IIdentity.ts b/src/services/identity/IIdentity.ts index 34101c1e..e6e4dd0a 100644 --- a/src/services/identity/IIdentity.ts +++ b/src/services/identity/IIdentity.ts @@ -16,7 +16,7 @@ import { CredentialRequest, VeramoAgent } from '../../types/types' dotenv.config() export interface IIdentity { - agent: TAgent + agent?: TAgent privateStore?: AbstractPrivateKeyStore initAgent(): TAgent createAgent?(agentId: string): Promise diff --git a/src/services/identity/agent.ts b/src/services/identity/agent.ts new file mode 100644 index 00000000..42a76e0d --- /dev/null +++ b/src/services/identity/agent.ts @@ -0,0 +1,174 @@ +import { + createAgent, + CredentialPayload, + DIDDocument, + IAgentPlugin, + IDIDManager, + IIdentifier, + IKeyManager, + IResolver, + IVerifyResult, + ManagedKeyInfo, + MinimalImportableIdentifier, + MinimalImportableKey, + TAgent, + VerifiableCredential, + VerifiablePresentation, +} from '@veramo/core' + +import { Cheqd, getResolver as CheqdDidResolver, ResourcePayload } from '@cheqd/did-provider-cheqd' +import { CheqdNetwork } from '@cheqd/sdk' + +import { cheqdDidRegex, CreateAgentRequest, CredentialRequest, VeramoAgent } from '../../types/types.js' +import { VC_PROOF_FORMAT, VC_REMOVE_ORIGINAL_FIELDS } from '../../types/constants.js' +import { KeyManager } from '@veramo/key-manager' +import { DIDStore, KeyStore } from '@veramo/data-store' +import { DIDManager } from '@veramo/did-manager' +import { DIDResolverPlugin } from '@veramo/did-resolver' +import { Resolver, ResolverRegistry } from 'did-resolver' +import { CredentialPlugin } from '@veramo/credential-w3c' +import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' + +export class Veramo { + + static instance = new Veramo() + + public createVeramoAgent({ providers, kms, dbConnection, cheqdProviders, enableResolver, enableCredential }: CreateAgentRequest) : VeramoAgent { + const plugins: IAgentPlugin[] = [] + + if(providers) { + plugins.push(new DIDManager({ + store: new DIDStore(dbConnection), + defaultProvider: 'did:cheqd:testnet', + providers + })) + } + + if(kms) { + plugins.push(new KeyManager({ + store: new KeyStore(dbConnection), + kms + })) + } + + if(cheqdProviders) { + plugins.push(new Cheqd({ + providers: cheqdProviders + })) + } + + if (enableResolver) { + plugins.push( + new DIDResolverPlugin({ + resolver: new Resolver({ + ...CheqdDidResolver({ url: process.env.RESOLVER_URL }) as ResolverRegistry + }) + }) + ) + } + + if (enableCredential) { + plugins.push( + new CredentialPlugin(), + new CredentialIssuerLD({ + contextMaps: [LdDefaultContexts], + suites: [new VeramoEd25519Signature2018()] + }) + ) + } + return createAgent({ plugins }) + } + + async createKey(agent: TAgent, type: 'Ed25519' | 'Secp256k1'='Ed25519'): Promise { + const [kms] = await agent.keyManagerGetKeyManagementSystems() + const key = await agent.keyManagerCreate({ + type: type || 'Ed25519', + kms, + }) + return key + } + + async getKey(agent: TAgent, kid: string) { + return await agent.keyManagerGet({ kid }) + } + + async createDid(agent: TAgent, network: string, didDocument: DIDDocument): Promise { + try { + const [kms] = await agent.keyManagerGetKeyManagementSystems() + + const identifier: IIdentifier = await agent.didManagerCreate({ + provider: `did:cheqd:${network}`, + kms, + options: { + document: didDocument + } + }) + return identifier + } catch (error) { + throw new Error(`${error}`) + } + } + + async listDids(agent: TAgent) { + return (await agent.didManagerFind()).map((res)=>res.did) + } + + async resolveDid(agent: TAgent, did: string) { + return await agent.resolveDid({ didUrl: did }) + } + + async getDid(agent: TAgent, did: string) { + return await agent.didManagerGet({ did }) + } + + async importDid(agent: TAgent, did: string, privateKeyHex: string, publicKeyHex: string): Promise { + const [kms] = await agent.keyManagerGetKeyManagementSystems() + + if (!did.match(cheqdDidRegex)) { + throw new Error('Invalid DID') + } + + const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', privateKeyHex, publicKeyHex } + const identifier: IIdentifier = await agent.didManagerImport({ keys: [key], did, controllerKeyId: key.kid } as MinimalImportableIdentifier) + return identifier + } + + async createResource(agent: VeramoAgent, network: string, payload: ResourcePayload) { + try { + const [kms] = await agent.keyManagerGetKeyManagementSystems() + + const result: boolean = await agent.cheqdCreateLinkedResource({ + kms, + payload, + network: network as CheqdNetwork + }) + return result + } catch (error) { + throw new Error(`${error}`) + } + } + + async createCredential(agent: VeramoAgent, credential: CredentialPayload, format: CredentialRequest['format']): Promise { + try { + const verifiable_credential = await agent.createVerifiableCredential( + { + save: false, + credential, + proofFormat: format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, + removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS + } + ) + return verifiable_credential + } catch (error) { + throw new Error(`${error}`) + } + } + + async verifyCredential(agent: VeramoAgent, credential: string | VerifiableCredential): Promise { + return await agent.verifyCredential({ credential, fetchRemoteContexts: true }) + } + + async verifyPresentation(agent: VeramoAgent, presentation: VerifiablePresentation | string): Promise { + return await agent.verifyPresentation({ presentation, fetchRemoteContexts: true }) + } +} diff --git a/src/services/identity/index.ts b/src/services/identity/index.ts index c60f516a..b4bf3962 100644 --- a/src/services/identity/index.ts +++ b/src/services/identity/index.ts @@ -1,6 +1,21 @@ import { LocalIdentity } from './local.js' import { PostgresIdentity } from './postgres.js' - export { IIdentity } from './IIdentity.js' -export const Identity = process.env.ENABLE_EXTERNAL_DB === 'true' ? new PostgresIdentity() : new LocalIdentity() \ No newline at end of file +import * as dotenv from 'dotenv' +dotenv.config() + +export class Identity { + private agent: LocalIdentity | PostgresIdentity + + static instance = new Identity().agent + + constructor() { + if (process.env.ENABLE_EXTERNAL_DB == 'true') { + this.agent = PostgresIdentity.instance + } else { + this.agent = LocalIdentity.instance + } + this.agent.initAgent() + } +} \ No newline at end of file diff --git a/src/services/identity/local.ts b/src/services/identity/local.ts index 0e1a273a..3af319af 100644 --- a/src/services/identity/local.ts +++ b/src/services/identity/local.ts @@ -1,9 +1,6 @@ import { - DIDDocument, IIdentifier, ManagedKeyInfo, - MinimalImportableIdentifier, - MinimalImportableKey, TAgent, createAgent, CredentialPayload, @@ -19,14 +16,16 @@ import { KeyStore, DIDStore } from '@veramo/data-store' import { Cheqd, CheqdDIDProvider, getResolver as CheqdDidResolver, ResourcePayload } from '@cheqd/did-provider-cheqd' import { CheqdNetwork } from '@cheqd/sdk' import { Resolver, ResolverRegistry } from 'did-resolver' +import { CredentialPlugin } from '@veramo/credential-w3c' +import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' -import { cheqdDidRegex, CredentialRequest, DefaultRPCUrl, VeramoAgent } from '../../types/types.js' -import * as dotenv from 'dotenv' +import { CredentialRequest, DefaultRPCUrl, VeramoAgent } from '../../types/types.js' import { Connection } from '../../database/connection/connection.js' import { IIdentity } from './IIdentity.js' -import { VC_PROOF_FORMAT, VC_REMOVE_ORIGINAL_FIELDS } from '../../types/constants.js' -import { CredentialPlugin } from '@veramo/credential-w3c' -import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } from '@veramo/credential-ld' +import { Veramo } from './agent.js' + +import * as dotenv from 'dotenv' + dotenv.config() const { @@ -40,18 +39,17 @@ const { } = process.env export class LocalIdentity implements IIdentity { - agent: VeramoAgent + agent?: VeramoAgent privateStore?: AbstractPrivateKeyStore public static instance = new LocalIdentity() - constructor() { - this.agent = this.initAgent() + initAgent() { if (!FEE_PAYER_MNEMONIC) { throw new Error(`No fee payer found`) } - } - - initAgent() { + if(this.agent) { + return this.agent + } const dbConnection = Connection.instance.dbConnection this.privateStore = new MemoryPrivateKeyStore() @@ -59,7 +57,7 @@ export class LocalIdentity implements IIdentity { { defaultKms: 'local', cosmosPayerSeed: FEE_PAYER_MNEMONIC, - networkType: CheqdNetwork.Mainnet as any, + networkType: CheqdNetwork.Mainnet, rpcUrl: MAINNET_RPC_URL || DefaultRPCUrl.Mainnet, } ) @@ -67,51 +65,34 @@ export class LocalIdentity implements IIdentity { { defaultKms: 'local', cosmosPayerSeed: FEE_PAYER_MNEMONIC, - networkType: CheqdNetwork.Testnet as any, + networkType: CheqdNetwork.Testnet, rpcUrl: TESTNET_RPC_URL || DefaultRPCUrl.Testnet, } ) - return createAgent>({ - plugins: [ - new KeyManager({ - store: new KeyStore(dbConnection), - kms: { - local: new KeyManagementSystem( - this.privateStore - ) - } - }), - new DIDManager({ - store: new DIDStore(dbConnection), - defaultProvider: 'did:cheqd:testnet', - providers: { - 'did:cheqd:mainnet': mainnetProvider, - 'did:cheqd:testnet': testnetProvider - } - }), - new DIDResolverPlugin({ - resolver: new Resolver({ - ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry - }) - }), - new CredentialPlugin(), - new CredentialIssuerLD({ - contextMaps: [LdDefaultContexts], - suites: [new VeramoEd25519Signature2018()] - }), - new Cheqd({ - providers: [mainnetProvider, testnetProvider] - }) - ] + this.agent = Veramo.instance.createVeramoAgent({ + dbConnection, + kms: { + local: new KeyManagementSystem( + this.privateStore + ) + }, + providers: { + 'did:cheqd:mainnet': mainnetProvider, + 'did:cheqd:testnet': testnetProvider + }, + cheqdProviders: [mainnetProvider, testnetProvider], + enableCredential: true, + enableResolver: true }) + return this.agent } async createKey(): Promise { - throw new Error('Not supported') + throw new Error(`Not supported`) } async getKey(kid: string) { - return await this.agent.keyManagerGet({ kid }) + return Veramo.instance.getKey(this.initAgent(), kid) } async createDid(): Promise { @@ -123,45 +104,27 @@ export class LocalIdentity implements IIdentity { } async resolveDid(did: string) { - return await this.agent.resolveDid({ didUrl: did }) + return Veramo.instance.resolveDid(this.initAgent(), did) } async getDid(did: string) { - return await this.agent.didManagerGet({ did }) + return Veramo.instance.getDid(this.initAgent(), did) } async importDid(): Promise { - if (!this.agent) throw new Error('No initialised agent found.') if (!(ISSUER_DID && ISSUER_ID_PUBLIC_KEY_HEX && ISSUER_ID_PRIVATE_KEY_HEX)) throw new Error('No DIDs and Keys found') - - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - - if (!ISSUER_DID.match(cheqdDidRegex)) { - throw new Error('Invalid DID') + try { + return await this.getDid(ISSUER_DID) + } catch { + const identifier: IIdentifier = await Veramo.instance.importDid(this.initAgent(), ISSUER_DID, ISSUER_ID_PRIVATE_KEY_HEX, ISSUER_ID_PUBLIC_KEY_HEX) + return identifier } - - const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', kid: ISSUER_ID_PUBLIC_KEY_HEX, privateKeyHex: ISSUER_ID_PRIVATE_KEY_HEX, publicKeyHex: ISSUER_ID_PUBLIC_KEY_HEX } - - const identifier: IIdentifier = await this.agent.didManagerImport({ keys: [key], did: ISSUER_DID, controllerKeyId: key.kid } as MinimalImportableIdentifier) - - return identifier } async createResource(network: string, payload: ResourcePayload) { try { - // import DID await this.importDid() - if (!this.agent) throw new Error('No initialised agent found.') - - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - - const result: boolean = await this.agent.cheqdCreateLinkedResource({ - kms, - payload, - network: network as CheqdNetwork - } - ) - return result + return await Veramo.instance.createResource(this.initAgent(), network, payload) } catch (error) { throw new Error(`${error}`) } @@ -169,27 +132,18 @@ export class LocalIdentity implements IIdentity { async createCredential(credential: CredentialPayload, format: CredentialRequest['format']): Promise { try { - // import DID await this.importDid() - const verifiable_credential = await this.agent.createVerifiableCredential( - { - save: false, - credential, - proofFormat: format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, - removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS - } - ) - return verifiable_credential + return await Veramo.instance.createCredential(this.initAgent(), credential, format) } catch (error) { throw new Error(`${error}`) } } async verifyCredential(credential: VerifiableCredential | string): Promise { - return await this.agent.verifyCredential({ credential, fetchRemoteContexts: true }) + return await Veramo.instance.verifyCredential(this.initAgent(), credential) } async verifyPresentation(presentation: VerifiablePresentation | string): Promise { - return await this.agent.verifyPresentation({ presentation, fetchRemoteContexts: true }) + return await Veramo.instance.verifyPresentation(this.initAgent(), presentation) } } diff --git a/src/services/identity/postgres.ts b/src/services/identity/postgres.ts index 8c9ed6e9..5555faf5 100644 --- a/src/services/identity/postgres.ts +++ b/src/services/identity/postgres.ts @@ -1,11 +1,12 @@ import { - CredentialPayload, + CredentialPayload, DIDDocument, + IDIDManager, IIdentifier, + IKeyManager, + IResolver, IVerifyResult, ManagedKeyInfo, - MinimalImportableIdentifier, - MinimalImportableKey, TAgent, VerifiableCredential, VerifiablePresentation, @@ -21,16 +22,16 @@ import { CredentialIssuerLD, LdDefaultContexts, VeramoEd25519Signature2018 } fro import { CheqdDIDProvider, getResolver as CheqdDidResolver, ResourcePayload, Cheqd } from '@cheqd/did-provider-cheqd' import { CheqdNetwork } from '@cheqd/sdk' import { Resolver, ResolverRegistry } from 'did-resolver' -import { v4 } from 'uuid' import { cheqdDidRegex, CredentialRequest, DefaultRPCUrl, VeramoAgent } from '../../types/types.js' import { Connection } from '../../database/connection/connection.js' import { CustomerEntity } from '../../database/entities/customer.entity.js' import { CustomerService } from '../customer.js' -import * as dotenv from 'dotenv' import { IIdentity } from './IIdentity.js' -import { VC_PROOF_FORMAT, VC_REMOVE_ORIGINAL_FIELDS } from '../../types/constants.js' + +import * as dotenv from 'dotenv' +import { Veramo } from './agent.js' dotenv.config() const { @@ -41,40 +42,31 @@ const { } = process.env export class PostgresIdentity implements IIdentity { - agent: TAgent + agent: TAgent privateStore?: AbstractPrivateKeyStore public static instance = new PostgresIdentity() - + constructor() { this.agent = this.initAgent() } - initAgent(): TAgent { + initAgent(): TAgent { + if(this.agent) return this.agent const dbConnection = Connection.instance.dbConnection this.privateStore = new PrivateKeyStore(dbConnection, new SecretBox(EXTERNAL_DB_ENCRYPTION_KEY)) - return createAgent({ - plugins: [ - new KeyManager({ - store: new KeyStore(dbConnection), - kms: { - postgres: new KeyManagementSystem( - this.privateStore - ) - } - }), - new DIDManager({ - store: new DIDStore(dbConnection), - defaultProvider: 'did:cheqd:testnet', - providers: {} - }), - new DIDResolverPlugin({ - resolver: new Resolver({ - ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry - }) - }), - ] + this.agent = Veramo.instance.createVeramoAgent({ + dbConnection, + kms: { + local: new KeyManagementSystem( + this.privateStore + ) + }, + providers: {}, + enableCredential: false, + enableResolver: true }) + return this.agent } async createAgent(agentId: string) : Promise { @@ -103,49 +95,26 @@ export class PostgresIdentity implements IIdentity { } ) - return createAgent({ - plugins: [ - new KeyManager({ - store: new KeyStore(dbConnection), - kms: { - postgres: new KeyManagementSystem( - this.privateStore - ) - } - }), - new DIDManager({ - store: new DIDStore(dbConnection), - defaultProvider: 'did:cheqd:testnet', - providers: { - 'did:cheqd:mainnet': mainnetProvider, - 'did:cheqd:testnet': testnetProvider - } - }), - new DIDResolverPlugin({ - resolver: new Resolver({ - ...CheqdDidResolver({ url: RESOLVER_URL }) as ResolverRegistry - }) - }), - new CredentialPlugin(), - new CredentialIssuerLD({ - contextMaps: [LdDefaultContexts], - suites: [new VeramoEd25519Signature2018()] - }), - new Cheqd({ - providers: [mainnetProvider, testnetProvider] - }) - ] + return Veramo.instance.createVeramoAgent({ + dbConnection, + kms: { + local: new KeyManagementSystem( + this.privateStore + ) + }, + providers: { + 'did:cheqd:mainnet': mainnetProvider, + 'did:cheqd:testnet': testnetProvider + }, + cheqdProviders: [mainnetProvider, testnetProvider], + enableCredential: true, + enableResolver: true }) } async createKey(type: 'Ed25519' | 'Secp256k1'='Ed25519', agentId: string): Promise { - if (!this.agent) throw new Error('No initialised agent found.') - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - const key = await this.agent.keyManagerCreate({ - type: type || 'Ed25519', - kms, - }) - await CustomerService.instance.update(agentId, { kids: [key.kid] }) + const key = await Veramo.instance.createKey(this.agent, type) + if(await CustomerService.instance.find(agentId, {})) await CustomerService.instance.update(agentId, { kids: [key.kid] }) return key } @@ -154,7 +123,7 @@ export class PostgresIdentity implements IIdentity { if(!isOwner) { throw new Error(`Customer not found`) } - return await this.agent.keyManagerGet({ kid }) + return await Veramo.instance.getKey(this.agent, kid) } private async getPrivateKey(kid: string) { @@ -166,15 +135,7 @@ export class PostgresIdentity implements IIdentity { const agent = await this.createAgent(agentId) if (!agent) throw new Error('No initialised agent found.') - const [kms] = await agent.keyManagerGetKeyManagementSystems() - - const identifier: IIdentifier = await agent.didManagerCreate({ - provider: `did:cheqd:${network}`, - kms, - options: { - document: didDocument - } - }) + const identifier: IIdentifier = await Veramo.instance.createDid(agent, network, didDocument) await CustomerService.instance.update(agentId, { dids: [identifier.did] }) return identifier } catch (error) { @@ -188,42 +149,27 @@ export class PostgresIdentity implements IIdentity { } async resolveDid(did: string) { - return await this.agent.resolveDid({ didUrl: did }) + return await Veramo.instance.resolveDid(this.agent, did) } async getDid(did: string) { - return await this.agent.didManagerGet({ did }) + return await Veramo.instance.getDid(this.agent, did) } - async importDid(did: string, privateKeyHex: string, publicKeyHex: string): Promise { - if (!this.agent) throw new Error('No initialised agent found.') - - const [kms] = await this.agent.keyManagerGetKeyManagementSystems() - + async importDid(did: string, privateKeyHex: string, publicKeyHex: string, agentId: string): Promise { if (!did.match(cheqdDidRegex)) { throw new Error('Invalid DID') } - const key: MinimalImportableKey = { kms: kms, type: 'Ed25519', kid: v4(), privateKeyHex, publicKeyHex } - - const identifier: IIdentifier = await this.agent.didManagerImport({ keys: [key], did, controllerKeyId: key.kid } as MinimalImportableIdentifier) - + const identifier: IIdentifier = await Veramo.instance.importDid(this.agent, did, privateKeyHex, publicKeyHex) + await CustomerService.instance.update(agentId, { dids: [identifier.did]}) return identifier } async createResource(network: string, payload: ResourcePayload, agentId: string) { try { const agent = await this.createAgent(agentId) - if (!agent) throw new Error('No initialised agent found.') - - const [kms] = await agent.keyManagerGetKeyManagementSystems() - - const result: boolean = await agent.cheqdCreateLinkedResource({ - kms, - payload, - network: network as CheqdNetwork - }) - return result + return await Veramo.instance.createResource(agent, network, payload) } catch (error) { throw new Error(`${error}`) } @@ -236,15 +182,7 @@ export class PostgresIdentity implements IIdentity { throw new Error('Customer not found') } const agent = await this.createAgent(agentId) - const verifiable_credential = await agent.createVerifiableCredential( - { - save: false, - credential, - proofFormat: format == 'jsonld' ? 'lds' : VC_PROOF_FORMAT, - removeOriginalFields: VC_REMOVE_ORIGINAL_FIELDS - } - ) - return verifiable_credential + return await Veramo.instance.createCredential(agent, credential, format) } catch (error) { throw new Error(`${error}`) } @@ -252,11 +190,11 @@ export class PostgresIdentity implements IIdentity { async verifyCredential(credential: string | VerifiableCredential, agentId: string): Promise { const agent = await this.createAgent(agentId) - return await agent.verifyCredential({ credential, fetchRemoteContexts: true }) + return await Veramo.instance.verifyCredential(agent, credential) } async verifyPresentation(presentation: VerifiablePresentation | string, agentId: string): Promise { const agent = await this.createAgent(agentId) - return await agent.verifyPresentation({ presentation, fetchRemoteContexts: true }) + return await Veramo.instance.verifyPresentation(agent, presentation) } } diff --git a/src/services/store.ts b/src/services/store.ts index fb537b92..396404e7 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -6,7 +6,7 @@ export class LocalStore { public static instance = new LocalStore() constructor() { - this.cache = new NodeCache(); + this.cache = new NodeCache() } setItem(data: string) : string { diff --git a/src/types/types.ts b/src/types/types.ts index 98bdd7ed..378028e4 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,4 +1,3 @@ -import { ContextType } from '@veramo/core-types' import { IDIDManager, IKeyManager, @@ -11,6 +10,10 @@ import { } from '@veramo/core' import { ICheqd } from '@cheqd/did-provider-cheqd/build/types/agent/ICheqd' import { ICredentialIssuerLD } from '@veramo/credential-ld' +import { AbstractIdentifierProvider } from '@veramo/did-manager' +import { AbstractKeyManagementSystem } from '@veramo/key-manager' +import { DataSource } from 'typeorm' +import { CheqdDIDProvider } from '@cheqd/did-provider-cheqd' export type ErrorResponse = { name: string @@ -89,4 +92,13 @@ IResolver & ICredentialIssuer & ICredentialVerifier & ICheqd & -ICredentialIssuerLD> \ No newline at end of file +ICredentialIssuerLD> + +export type CreateAgentRequest = { + providers?: Record, + kms?: Record, + dbConnection: DataSource, + cheqdProviders?: CheqdDIDProvider[], + enableResolver?: boolean, + enableCredential?: boolean +} \ No newline at end of file diff --git a/swagger.json b/swagger.json index aa6edf72..1b858229 100644 --- a/swagger.json +++ b/swagger.json @@ -873,7 +873,7 @@ "name": "Bob" }, "@context": [ - "https://schema.org/Person" + "https://schema.org" ], "type": [ "Person" From f3ef100506923ac878862daecc4e618768f5db4c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 7 Jun 2023 14:00:17 +0000 Subject: [PATCH 4/4] chore(release): 2.1.0-develop.17 [skip ci] ## [2.1.0-develop.17](https://github.com/cheqd/credential-service/compare/2.1.0-develop.16...2.1.0-develop.17) (2023-06-07) ### Bug Fixes * External db toggle panic ([#248](https://github.com/cheqd/credential-service/issues/248)) ([a33cd25](https://github.com/cheqd/credential-service/commit/a33cd25b7aa17972afd83c64937ed571f4bf1e2b)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c04252..65f34cf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.1.0-develop.17](https://github.com/cheqd/credential-service/compare/2.1.0-develop.16...2.1.0-develop.17) (2023-06-07) + + +### Bug Fixes + +* External db toggle panic ([#248](https://github.com/cheqd/credential-service/issues/248)) ([a33cd25](https://github.com/cheqd/credential-service/commit/a33cd25b7aa17972afd83c64937ed571f4bf1e2b)) + ## [2.1.0-develop.16](https://github.com/cheqd/credential-service/compare/2.1.0-develop.15...2.1.0-develop.16) (2023-06-06) diff --git a/package.json b/package.json index 643b1e64..3d933a61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cheqd/credential-service", - "version": "2.1.0-develop.16", + "version": "2.1.0-develop.17", "description": "cheqd Credential Service Backend", "source": "src/index.ts", "main": "dist/index.js",