diff --git a/package-lock.json b/package-lock.json index e6b0981..2a342c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33008,13 +33008,13 @@ }, "packages/w3c": { "name": "@trustvc/w3c", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "dependencies": { - "@trustvc/w3c-context": "^2.0.0", - "@trustvc/w3c-credential-status": "^2.0.0", - "@trustvc/w3c-issuer": "^2.0.0", - "@trustvc/w3c-vc": "^2.0.0" + "@trustvc/w3c-context": "^2.0.1", + "@trustvc/w3c-credential-status": "^2.0.1", + "@trustvc/w3c-issuer": "^2.0.1", + "@trustvc/w3c-vc": "^2.0.1" }, "engines": { "node": ">=18.x" @@ -33022,7 +33022,7 @@ }, "packages/w3c-context": { "name": "@trustvc/w3c-context", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "dependencies": { "did-resolver": "^4.1.0", @@ -33114,11 +33114,11 @@ }, "packages/w3c-credential-status": { "name": "@trustvc/w3c-credential-status", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "dependencies": { - "@trustvc/w3c-context": "^2.0.0", - "@trustvc/w3c-issuer": "^2.0.0", + "@trustvc/w3c-context": "^2.0.1", + "@trustvc/w3c-issuer": "^2.0.1", "base64url-universal": "^2.0.0", "pako": "^2.1.0" }, @@ -33128,7 +33128,7 @@ }, "packages/w3c-issuer": { "name": "@trustvc/w3c-issuer", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "dependencies": { "@digitalbazaar/bls12-381-multikey": "^2.1.0", @@ -33145,7 +33145,7 @@ }, "packages/w3c-vc": { "name": "@trustvc/w3c-vc", - "version": "2.0.0", + "version": "2.0.1", "license": "Apache-2.0", "dependencies": { "@digitalbazaar/bbs-2023-cryptosuite": "^2.0.1", @@ -33154,8 +33154,8 @@ "@digitalbazaar/ecdsa-multikey": "^1.8.0", "@digitalbazaar/ecdsa-sd-2023-cryptosuite": "^3.4.1", "@mattrglobal/jsonld-signatures-bbs": "^1.2.0", - "@trustvc/w3c-credential-status": "^2.0.0", - "@trustvc/w3c-issuer": "^2.0.0", + "@trustvc/w3c-credential-status": "^2.0.1", + "@trustvc/w3c-issuer": "^2.0.1", "base64url-universal": "^2.0.0", "cbor": "^9.0.2", "did-resolver": "^4.1.0", @@ -33264,105 +33264,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "packages/w3c/node_modules/jsonld-signatures": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-11.5.0.tgz", - "integrity": "sha512-Kdto+e8uvY/5u3HYkmAbpy52bplWX9uqS8fmqdCv6oxnCFwCTM0hMt6r4rWqlhw5/aHoCHJIRxwYb4QKGC69Jw==", - "license": "BSD-3-Clause", - "dependencies": { - "@digitalbazaar/security-context": "^1.0.0", - "jsonld": "^8.0.0", - "rdf-canonize": "^4.0.1", - "serialize-error": "^8.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "packages/w3c/node_modules/jsonld-signatures/node_modules/jsonld": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.3.3.tgz", - "integrity": "sha512-9YcilrF+dLfg9NTEof/mJLMtbdX1RJ8dbWtJgE00cMOIohb1lIyJl710vFiTaiHTl6ZYODJuBd32xFvUhmv3kg==", - "license": "BSD-3-Clause", - "dependencies": { - "@digitalbazaar/http-client": "^3.4.1", - "canonicalize": "^1.0.1", - "lru-cache": "^6.0.0", - "rdf-canonize": "^3.4.0" - }, - "engines": { - "node": ">=14" - } - }, - "packages/w3c/node_modules/jsonld-signatures/node_modules/jsonld/node_modules/rdf-canonize": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz", - "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==", - "license": "BSD-3-Clause", - "dependencies": { - "setimmediate": "^1.0.5" - }, - "engines": { - "node": ">=12" - } - }, - "packages/w3c/node_modules/jsonld-signatures/node_modules/rdf-canonize": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-4.0.1.tgz", - "integrity": "sha512-B5ynHt4sasbUafzrvYI2GFARgeFcD8Sx9yXPbg7gEyT2EH76rlCv84kyO6tnxzVbxUN/uJDbK1S/MXh+DsnuTA==", - "license": "BSD-3-Clause", - "dependencies": { - "setimmediate": "^1.0.5" - }, - "engines": { - "node": ">=18" - } - }, - "packages/w3c/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "packages/w3c/node_modules/serialize-error": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", - "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/w3c/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/w3c/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" } } } diff --git a/packages/w3c-issuer/src/did-web/wellKnown/generate.ts b/packages/w3c-issuer/src/did-web/wellKnown/generate.ts index 723c06c..b98bc8b 100644 --- a/packages/w3c-issuer/src/did-web/wellKnown/generate.ts +++ b/packages/w3c-issuer/src/did-web/wellKnown/generate.ts @@ -134,17 +134,20 @@ export const nextKeyId = (wellKnown: DidWellKnownDocument): number => { // Filter for all key id const keyIds = wellKnown?.verificationMethod?.map((s) => s?.id) ?? []; - // strip the key id to get the number - const keyIdNumbers = keyIds.map((s) => { - const parts = s?.split('#'); - if (!parts) return 0; - return parts?.[parts.length - 1]?.split('keys-')?.[1]; - }); + // strip the key id to get the number (only for keys that follow 'keys-{number}' pattern) + const keyIdNumbers = keyIds + .map((s) => { + const parts = s?.split('#'); + if (!parts || parts.length < 2) return null; + const fragment = parts[parts.length - 1]; + // Only process if it follows the 'keys-' pattern + if (!fragment?.includes('keys-')) return null; + return fragment.split('keys-')[1]; + }) + .filter((s) => s !== null && s !== undefined); // Remove null/undefined values - // filter out the non-numeric values using Number and convert to number - const keyIdNumbersFiltered = keyIdNumbers - .filter((s) => !Number.isInteger(s)) - .map((s) => Number(s)); + // filter out the non-numeric values and convert to number + const keyIdNumbersFiltered = keyIdNumbers.filter((s) => !isNaN(Number(s))).map((s) => Number(s)); // get the max number if (keyIdNumbersFiltered.length === 0) return 1; diff --git a/packages/w3c-issuer/src/did-web/wellKnown/index.ts b/packages/w3c-issuer/src/did-web/wellKnown/index.ts index 2f1dedb..a80c304 100644 --- a/packages/w3c-issuer/src/did-web/wellKnown/index.ts +++ b/packages/w3c-issuer/src/did-web/wellKnown/index.ts @@ -30,7 +30,18 @@ export const issueDID = async (didInput: IssuedDIDOption): Promise => const keyId = nextKeyId(wellKnownDid); - const generatedKeyPair = await generateKeyPair(didInput); + // Check if user provided public key data + const hasModernPublicKey = didInput.publicKeyMultibase; + const hasLegacyPublicKey = didInput.publicKeyBase58; + const userProvidedKeys = hasModernPublicKey || hasLegacyPublicKey; + + // Validate that type is provided when keys are provided + if (userProvidedKeys && !didInput.type) { + throw new Error('Key pair type must be provided when supplying existing keys'); + } + + // Only generate if user didn't provide complete key pair + const generatedKeyPair = userProvidedKeys ? { ...didInput } : await generateKeyPair(didInput); let keyPairs: PrivateKeyPair;