@awiki/anp-typescript-sdk 0.2.0 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.cjs +983 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +147 -1
- package/dist/index.d.ts +147 -1
- package/dist/index.js +950 -2
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/dist/index.cjs
CHANGED
|
@@ -7,6 +7,8 @@ var net = require('net');
|
|
|
7
7
|
var canonicalize = require('canonicalize');
|
|
8
8
|
var promises = require('fs/promises');
|
|
9
9
|
var jose = require('jose');
|
|
10
|
+
var p256 = require('@noble/curves/p256');
|
|
11
|
+
var secp256k1 = require('@noble/curves/secp256k1');
|
|
10
12
|
var path = require('path');
|
|
11
13
|
|
|
12
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -46,6 +48,13 @@ var ProofError = class extends ANPError {
|
|
|
46
48
|
this.name = "ProofError";
|
|
47
49
|
}
|
|
48
50
|
};
|
|
51
|
+
var DeviceManifestError = class extends AuthenticationError {
|
|
52
|
+
constructor(message, cause) {
|
|
53
|
+
super(message, cause);
|
|
54
|
+
this.name = "DeviceManifestError";
|
|
55
|
+
Object.defineProperty(this, "code", { value: "DEVICE_MANIFEST_ERROR" });
|
|
56
|
+
}
|
|
57
|
+
};
|
|
49
58
|
var NetworkError = class extends ANPError {
|
|
50
59
|
constructor(message, statusCode, cause) {
|
|
51
60
|
super(message, "NETWORK_ERROR", cause);
|
|
@@ -2063,6 +2072,750 @@ function selectAnpMessageService(didDocument, serviceId, serviceEndpoint) {
|
|
|
2063
2072
|
);
|
|
2064
2073
|
}
|
|
2065
2074
|
|
|
2075
|
+
// src/authentication/device-manifest.ts
|
|
2076
|
+
var device_manifest_exports = {};
|
|
2077
|
+
__export(device_manifest_exports, {
|
|
2078
|
+
DEVICE_MANIFEST_TYPE: () => DEVICE_MANIFEST_TYPE,
|
|
2079
|
+
DeviceManifest: () => DeviceManifest,
|
|
2080
|
+
DeviceManifestEntry: () => DeviceManifestEntry,
|
|
2081
|
+
PROFILE_CORE_BINDING_V1: () => PROFILE_CORE_BINDING_V1,
|
|
2082
|
+
PROFILE_CORE_BINDING_V2: () => PROFILE_CORE_BINDING_V2,
|
|
2083
|
+
PROFILE_DIRECT_BASE_V1: () => PROFILE_DIRECT_BASE_V1,
|
|
2084
|
+
PROFILE_DIRECT_BASE_V2: () => PROFILE_DIRECT_BASE_V2,
|
|
2085
|
+
PROFILE_DIRECT_E2EE_V2: () => PROFILE_DIRECT_E2EE_V2,
|
|
2086
|
+
PROFILE_GROUP_BASE_V1: () => PROFILE_GROUP_BASE_V1,
|
|
2087
|
+
PROFILE_GROUP_BASE_V2: () => PROFILE_GROUP_BASE_V2,
|
|
2088
|
+
PROFILE_GROUP_E2EE_V2: () => PROFILE_GROUP_E2EE_V2,
|
|
2089
|
+
PROFILE_IDENTITY_DISCOVERY_V1: () => PROFILE_IDENTITY_DISCOVERY_V1,
|
|
2090
|
+
PROFILE_IDENTITY_DISCOVERY_V2: () => PROFILE_IDENTITY_DISCOVERY_V2,
|
|
2091
|
+
addDeviceToDidDocument: () => addDeviceToDidDocument,
|
|
2092
|
+
buildVnextDidDocument: () => buildVnextDidDocument,
|
|
2093
|
+
findEligibleDevice: () => findEligibleDevice,
|
|
2094
|
+
parseDeviceManifest: () => parseDeviceManifest,
|
|
2095
|
+
removeDeviceFromDidDocument: () => removeDeviceFromDidDocument,
|
|
2096
|
+
updateDeviceInDidDocument: () => updateDeviceInDidDocument,
|
|
2097
|
+
validateDeviceManifest: () => validateDeviceManifest
|
|
2098
|
+
});
|
|
2099
|
+
var DEVICE_MANIFEST_TYPE = "ANPDeviceManifest";
|
|
2100
|
+
var PROFILE_CORE_BINDING_V1 = "anp.core.binding.v1";
|
|
2101
|
+
var PROFILE_IDENTITY_DISCOVERY_V1 = "anp.identity.discovery.v1";
|
|
2102
|
+
var PROFILE_DIRECT_BASE_V1 = "anp.direct.base.v1";
|
|
2103
|
+
var PROFILE_GROUP_BASE_V1 = "anp.group.base.v1";
|
|
2104
|
+
var PROFILE_DIRECT_E2EE_V2 = "anp.direct.e2ee.v2";
|
|
2105
|
+
var PROFILE_GROUP_E2EE_V2 = "anp.group.e2ee.v2";
|
|
2106
|
+
var PROFILE_CORE_BINDING_V2 = "anp.core.binding.v2";
|
|
2107
|
+
var PROFILE_IDENTITY_DISCOVERY_V2 = "anp.identity.discovery.v2";
|
|
2108
|
+
var PROFILE_DIRECT_BASE_V2 = "anp.direct.base.v2";
|
|
2109
|
+
var PROFILE_GROUP_BASE_V2 = "anp.group.base.v2";
|
|
2110
|
+
var MANIFEST_FIELDS = /* @__PURE__ */ new Set(["type", "devices"]);
|
|
2111
|
+
var ENTRY_FIELDS = /* @__PURE__ */ new Set(["device_id", "signing_key_id", "e2ee_key_id", "profiles"]);
|
|
2112
|
+
var P5_DEPENDENCIES = /* @__PURE__ */ new Set([
|
|
2113
|
+
PROFILE_CORE_BINDING_V1,
|
|
2114
|
+
PROFILE_IDENTITY_DISCOVERY_V1,
|
|
2115
|
+
PROFILE_DIRECT_BASE_V1,
|
|
2116
|
+
PROFILE_DIRECT_E2EE_V2
|
|
2117
|
+
]);
|
|
2118
|
+
var P6_DEPENDENCIES = /* @__PURE__ */ new Set([
|
|
2119
|
+
PROFILE_CORE_BINDING_V1,
|
|
2120
|
+
PROFILE_IDENTITY_DISCOVERY_V1,
|
|
2121
|
+
PROFILE_GROUP_BASE_V1,
|
|
2122
|
+
PROFILE_GROUP_E2EE_V2
|
|
2123
|
+
]);
|
|
2124
|
+
var P5_LEGACY_DRAFT_DEPENDENCIES = /* @__PURE__ */ new Set([
|
|
2125
|
+
PROFILE_CORE_BINDING_V2,
|
|
2126
|
+
PROFILE_IDENTITY_DISCOVERY_V2,
|
|
2127
|
+
PROFILE_DIRECT_BASE_V2,
|
|
2128
|
+
PROFILE_DIRECT_E2EE_V2
|
|
2129
|
+
]);
|
|
2130
|
+
var P6_LEGACY_DRAFT_DEPENDENCIES = /* @__PURE__ */ new Set([
|
|
2131
|
+
PROFILE_CORE_BINDING_V2,
|
|
2132
|
+
PROFILE_IDENTITY_DISCOVERY_V2,
|
|
2133
|
+
PROFILE_GROUP_BASE_V2,
|
|
2134
|
+
PROFILE_GROUP_E2EE_V2
|
|
2135
|
+
]);
|
|
2136
|
+
var LEGACY_DRAFT_FOUNDATION_PROFILES = /* @__PURE__ */ new Set([
|
|
2137
|
+
PROFILE_CORE_BINDING_V2,
|
|
2138
|
+
PROFILE_IDENTITY_DISCOVERY_V2,
|
|
2139
|
+
PROFILE_DIRECT_BASE_V2,
|
|
2140
|
+
PROFILE_GROUP_BASE_V2
|
|
2141
|
+
]);
|
|
2142
|
+
var BASE64URL_RE = /^[A-Za-z0-9_-]+$/;
|
|
2143
|
+
var SIGNING_ALGORITHMS = /* @__PURE__ */ new Set(["Ed25519", "P-256", "secp256k1"]);
|
|
2144
|
+
var DeviceManifestEntry = class _DeviceManifestEntry {
|
|
2145
|
+
constructor(deviceId, signingKeyId, e2eeKeyId, profiles) {
|
|
2146
|
+
this.deviceId = deviceId;
|
|
2147
|
+
this.signingKeyId = signingKeyId;
|
|
2148
|
+
this.e2eeKeyId = e2eeKeyId;
|
|
2149
|
+
this.profiles = profiles;
|
|
2150
|
+
}
|
|
2151
|
+
static fromWire(value) {
|
|
2152
|
+
return new _DeviceManifestEntry(value.device_id, value.signing_key_id, value.e2ee_key_id, [
|
|
2153
|
+
...value.profiles
|
|
2154
|
+
]);
|
|
2155
|
+
}
|
|
2156
|
+
toDict() {
|
|
2157
|
+
return {
|
|
2158
|
+
device_id: this.deviceId,
|
|
2159
|
+
signing_key_id: this.signingKeyId,
|
|
2160
|
+
e2ee_key_id: this.e2eeKeyId,
|
|
2161
|
+
profiles: [...this.profiles]
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
};
|
|
2165
|
+
var DeviceManifest = class {
|
|
2166
|
+
constructor(type, devices) {
|
|
2167
|
+
this.type = type;
|
|
2168
|
+
this.devices = devices;
|
|
2169
|
+
}
|
|
2170
|
+
toDict() {
|
|
2171
|
+
return {
|
|
2172
|
+
type: this.type,
|
|
2173
|
+
devices: this.devices.map((device) => device.toDict())
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
};
|
|
2177
|
+
function parseDeviceManifest(didDocument) {
|
|
2178
|
+
if (!Object.prototype.hasOwnProperty.call(didDocument, "deviceManifest")) {
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|
|
2181
|
+
const rawManifest = didDocument.deviceManifest;
|
|
2182
|
+
if (!isPlainObject(rawManifest)) {
|
|
2183
|
+
throw new DeviceManifestError("deviceManifest must be an object");
|
|
2184
|
+
}
|
|
2185
|
+
requireExactFields(rawManifest, MANIFEST_FIELDS, "deviceManifest");
|
|
2186
|
+
if (rawManifest.type !== DEVICE_MANIFEST_TYPE) {
|
|
2187
|
+
throw new DeviceManifestError("deviceManifest.type must equal ANPDeviceManifest");
|
|
2188
|
+
}
|
|
2189
|
+
const rawDevices = rawManifest.devices;
|
|
2190
|
+
if (!Array.isArray(rawDevices)) {
|
|
2191
|
+
throw new DeviceManifestError("deviceManifest.devices must be an array");
|
|
2192
|
+
}
|
|
2193
|
+
const devices = [];
|
|
2194
|
+
rawDevices.forEach((rawEntry, index) => {
|
|
2195
|
+
const subject = `deviceManifest.devices[${index}]`;
|
|
2196
|
+
if (!isPlainObject(rawEntry)) {
|
|
2197
|
+
throw new DeviceManifestError(`${subject} must be an object`);
|
|
2198
|
+
}
|
|
2199
|
+
requireExactFields(rawEntry, ENTRY_FIELDS, subject);
|
|
2200
|
+
const deviceId = requireString(rawEntry.device_id, `${subject}.device_id`);
|
|
2201
|
+
const signingKeyId = requireString(rawEntry.signing_key_id, `${subject}.signing_key_id`);
|
|
2202
|
+
const e2eeKeyId = requireString(rawEntry.e2ee_key_id, `${subject}.e2ee_key_id`);
|
|
2203
|
+
const rawProfiles = rawEntry.profiles;
|
|
2204
|
+
if (!Array.isArray(rawProfiles)) {
|
|
2205
|
+
throw new DeviceManifestError(`${subject}.profiles must be a string array`);
|
|
2206
|
+
}
|
|
2207
|
+
const profiles = rawProfiles.map((profile) => requireString(profile, `${subject}.profiles[]`));
|
|
2208
|
+
devices.push(new DeviceManifestEntry(deviceId, signingKeyId, e2eeKeyId, profiles));
|
|
2209
|
+
});
|
|
2210
|
+
return new DeviceManifest(DEVICE_MANIFEST_TYPE, devices);
|
|
2211
|
+
}
|
|
2212
|
+
function validateDeviceManifest(didDocument) {
|
|
2213
|
+
const manifest = parseDeviceManifest(didDocument);
|
|
2214
|
+
if (manifest === null) {
|
|
2215
|
+
return null;
|
|
2216
|
+
}
|
|
2217
|
+
const did = requireNonEmptyString(didDocument.id, "DID document id");
|
|
2218
|
+
const verificationMethods = didDocument.verificationMethod;
|
|
2219
|
+
if (!Array.isArray(verificationMethods)) {
|
|
2220
|
+
throw new DeviceManifestError("DID document verificationMethod must be an array");
|
|
2221
|
+
}
|
|
2222
|
+
const methodsById = /* @__PURE__ */ new Map();
|
|
2223
|
+
for (const method of verificationMethods) {
|
|
2224
|
+
if (!isPlainObject(method)) {
|
|
2225
|
+
continue;
|
|
2226
|
+
}
|
|
2227
|
+
const methodId = method.id;
|
|
2228
|
+
if (typeof methodId === "string") {
|
|
2229
|
+
const existing = methodsById.get(methodId) ?? [];
|
|
2230
|
+
existing.push(method);
|
|
2231
|
+
methodsById.set(methodId, existing);
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
const seenDeviceIds = /* @__PURE__ */ new Set();
|
|
2235
|
+
const seenKeyIds = /* @__PURE__ */ new Set();
|
|
2236
|
+
for (const entry of manifest.devices) {
|
|
2237
|
+
requireNonEmptyString(entry.deviceId, "device_id");
|
|
2238
|
+
requireNonEmptyString(entry.signingKeyId, "signing_key_id");
|
|
2239
|
+
requireNonEmptyString(entry.e2eeKeyId, "e2ee_key_id");
|
|
2240
|
+
if (entry.profiles.length === 0) {
|
|
2241
|
+
throw new DeviceManifestError("profiles must be non-empty");
|
|
2242
|
+
}
|
|
2243
|
+
for (const profile of entry.profiles) {
|
|
2244
|
+
requireNonEmptyString(profile, "profile");
|
|
2245
|
+
}
|
|
2246
|
+
if (seenDeviceIds.has(entry.deviceId)) {
|
|
2247
|
+
throw new DeviceManifestError("device_id must be unique");
|
|
2248
|
+
}
|
|
2249
|
+
seenDeviceIds.add(entry.deviceId);
|
|
2250
|
+
if (entry.signingKeyId === entry.e2eeKeyId) {
|
|
2251
|
+
throw new DeviceManifestError("signing_key_id and e2ee_key_id must be distinct");
|
|
2252
|
+
}
|
|
2253
|
+
for (const keyId of [entry.signingKeyId, entry.e2eeKeyId]) {
|
|
2254
|
+
if (seenKeyIds.has(keyId)) {
|
|
2255
|
+
throw new DeviceManifestError("a verification method can belong to only one device entry");
|
|
2256
|
+
}
|
|
2257
|
+
seenKeyIds.add(keyId);
|
|
2258
|
+
validateSameDocumentMethod(did, keyId, methodsById);
|
|
2259
|
+
}
|
|
2260
|
+
const profileSet = new Set(entry.profiles);
|
|
2261
|
+
if (profileSet.has(PROFILE_DIRECT_E2EE_V2)) {
|
|
2262
|
+
requireDependencies(profileSet, P5_DEPENDENCIES, P5_LEGACY_DRAFT_DEPENDENCIES, "P5");
|
|
2263
|
+
requireRelationship(didDocument, "assertionMethod", entry.signingKeyId, "P5 signing key");
|
|
2264
|
+
}
|
|
2265
|
+
if (profileSet.has(PROFILE_GROUP_E2EE_V2)) {
|
|
2266
|
+
requireDependencies(profileSet, P6_DEPENDENCIES, P6_LEGACY_DRAFT_DEPENDENCIES, "P6");
|
|
2267
|
+
requireRelationship(didDocument, "assertionMethod", entry.signingKeyId, "P6 binding key");
|
|
2268
|
+
requireRelationship(didDocument, "authentication", entry.signingKeyId, "P6 origin-proof key");
|
|
2269
|
+
}
|
|
2270
|
+
requireRelationship(didDocument, "keyAgreement", entry.e2eeKeyId, "device E2EE key");
|
|
2271
|
+
}
|
|
2272
|
+
return manifest;
|
|
2273
|
+
}
|
|
2274
|
+
function findEligibleDevice(didDocument, deviceId, requiredProfile) {
|
|
2275
|
+
const manifest = validateDeviceManifest(didDocument);
|
|
2276
|
+
if (manifest === null) {
|
|
2277
|
+
return null;
|
|
2278
|
+
}
|
|
2279
|
+
if (requiredProfile !== PROFILE_DIRECT_E2EE_V2 && requiredProfile !== PROFILE_GROUP_E2EE_V2) {
|
|
2280
|
+
return null;
|
|
2281
|
+
}
|
|
2282
|
+
return manifest.devices.find(
|
|
2283
|
+
(entry) => entry.deviceId === deviceId && entry.profiles.includes(requiredProfile)
|
|
2284
|
+
) ?? null;
|
|
2285
|
+
}
|
|
2286
|
+
function buildVnextDidDocument(baseDocument, rootKeyId, rootVerificationMethod, device, deviceSigningVerificationMethod, deviceE2eeVerificationMethod) {
|
|
2287
|
+
requireCanonicalWriteProfiles(device);
|
|
2288
|
+
const document = cloneDocument(baseDocument);
|
|
2289
|
+
for (const field of [
|
|
2290
|
+
"verificationMethod",
|
|
2291
|
+
"authentication",
|
|
2292
|
+
"assertionMethod",
|
|
2293
|
+
"keyAgreement",
|
|
2294
|
+
"deviceManifest",
|
|
2295
|
+
"proof"
|
|
2296
|
+
]) {
|
|
2297
|
+
if (field in document) {
|
|
2298
|
+
throw new DeviceManifestError(`base DID document must not contain managed field ${field}`);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
const did = documentDid(document);
|
|
2302
|
+
validateRootMethod(did, rootKeyId, rootVerificationMethod);
|
|
2303
|
+
validateDeviceMethods(
|
|
2304
|
+
did,
|
|
2305
|
+
rootKeyId,
|
|
2306
|
+
device,
|
|
2307
|
+
deviceSigningVerificationMethod,
|
|
2308
|
+
deviceE2eeVerificationMethod
|
|
2309
|
+
);
|
|
2310
|
+
Object.assign(document, {
|
|
2311
|
+
verificationMethod: [
|
|
2312
|
+
structuredClone(rootVerificationMethod),
|
|
2313
|
+
structuredClone(deviceSigningVerificationMethod),
|
|
2314
|
+
structuredClone(deviceE2eeVerificationMethod)
|
|
2315
|
+
],
|
|
2316
|
+
authentication: [device.signingKeyId],
|
|
2317
|
+
assertionMethod: [rootKeyId, device.signingKeyId],
|
|
2318
|
+
keyAgreement: [device.e2eeKeyId],
|
|
2319
|
+
deviceManifest: {
|
|
2320
|
+
type: DEVICE_MANIFEST_TYPE,
|
|
2321
|
+
devices: [device.toDict()]
|
|
2322
|
+
}
|
|
2323
|
+
});
|
|
2324
|
+
validateVnextDocument(document, rootKeyId);
|
|
2325
|
+
return document;
|
|
2326
|
+
}
|
|
2327
|
+
function addDeviceToDidDocument(didDocument, rootKeyId, device, deviceSigningVerificationMethod, deviceE2eeVerificationMethod, retiredDeviceIds) {
|
|
2328
|
+
requireCanonicalWriteProfiles(device);
|
|
2329
|
+
const document = prepareDocumentForMutation(didDocument, rootKeyId);
|
|
2330
|
+
const manifest = validateDeviceManifest(document);
|
|
2331
|
+
if (manifest === null) {
|
|
2332
|
+
throw new DeviceManifestError("deviceManifest is required for device update");
|
|
2333
|
+
}
|
|
2334
|
+
if (manifest.devices.some((entry) => entry.deviceId === device.deviceId)) {
|
|
2335
|
+
throw new DeviceManifestError("device_id already exists");
|
|
2336
|
+
}
|
|
2337
|
+
const retired = validateRetiredDeviceIds(retiredDeviceIds);
|
|
2338
|
+
if (retired.has(device.deviceId)) {
|
|
2339
|
+
throw new DeviceManifestError("retired device_id cannot be reused");
|
|
2340
|
+
}
|
|
2341
|
+
appendDeviceMaterial(
|
|
2342
|
+
document,
|
|
2343
|
+
rootKeyId,
|
|
2344
|
+
device,
|
|
2345
|
+
deviceSigningVerificationMethod,
|
|
2346
|
+
deviceE2eeVerificationMethod
|
|
2347
|
+
);
|
|
2348
|
+
validateVnextDocument(document, rootKeyId);
|
|
2349
|
+
return document;
|
|
2350
|
+
}
|
|
2351
|
+
function updateDeviceInDidDocument(didDocument, rootKeyId, device, deviceSigningVerificationMethod, deviceE2eeVerificationMethod) {
|
|
2352
|
+
requireCanonicalWriteProfiles(device);
|
|
2353
|
+
const document = prepareDocumentForMutation(didDocument, rootKeyId);
|
|
2354
|
+
const manifest = validateDeviceManifest(document);
|
|
2355
|
+
if (manifest === null) {
|
|
2356
|
+
throw new DeviceManifestError("deviceManifest is required for device update");
|
|
2357
|
+
}
|
|
2358
|
+
const oldEntry = manifest.devices.find((entry) => entry.deviceId === device.deviceId);
|
|
2359
|
+
if (oldEntry === void 0) {
|
|
2360
|
+
throw new DeviceManifestError("device_id does not exist");
|
|
2361
|
+
}
|
|
2362
|
+
removeDeviceMaterial(document, oldEntry);
|
|
2363
|
+
appendDeviceMaterial(
|
|
2364
|
+
document,
|
|
2365
|
+
rootKeyId,
|
|
2366
|
+
device,
|
|
2367
|
+
deviceSigningVerificationMethod,
|
|
2368
|
+
deviceE2eeVerificationMethod
|
|
2369
|
+
);
|
|
2370
|
+
validateVnextDocument(document, rootKeyId);
|
|
2371
|
+
return document;
|
|
2372
|
+
}
|
|
2373
|
+
function removeDeviceFromDidDocument(didDocument, rootKeyId, deviceId) {
|
|
2374
|
+
const document = prepareDocumentForMutation(didDocument, rootKeyId);
|
|
2375
|
+
const manifest = validateDeviceManifest(document);
|
|
2376
|
+
if (manifest === null) {
|
|
2377
|
+
throw new DeviceManifestError("deviceManifest is required for device update");
|
|
2378
|
+
}
|
|
2379
|
+
const oldEntry = manifest.devices.find((entry) => entry.deviceId === deviceId);
|
|
2380
|
+
if (oldEntry === void 0) {
|
|
2381
|
+
throw new DeviceManifestError("device_id does not exist");
|
|
2382
|
+
}
|
|
2383
|
+
removeDeviceMaterial(document, oldEntry);
|
|
2384
|
+
validateVnextDocument(document, rootKeyId);
|
|
2385
|
+
return document;
|
|
2386
|
+
}
|
|
2387
|
+
function cloneDocument(didDocument) {
|
|
2388
|
+
if (!isPlainObject(didDocument)) {
|
|
2389
|
+
throw new DeviceManifestError("DID document must be an object");
|
|
2390
|
+
}
|
|
2391
|
+
validateJsonValue(didDocument, "DID document");
|
|
2392
|
+
return structuredClone(didDocument);
|
|
2393
|
+
}
|
|
2394
|
+
function documentDid(didDocument) {
|
|
2395
|
+
return requireNonEmptyString(didDocument.id, "DID document id");
|
|
2396
|
+
}
|
|
2397
|
+
function prepareDocumentForMutation(didDocument, rootKeyId) {
|
|
2398
|
+
const document = cloneDocument(didDocument);
|
|
2399
|
+
validateVnextDocument(document, rootKeyId);
|
|
2400
|
+
const manifest = validateDeviceManifest(document);
|
|
2401
|
+
if (manifest === null) {
|
|
2402
|
+
throw new DeviceManifestError("deviceManifest is required");
|
|
2403
|
+
}
|
|
2404
|
+
for (const entry of manifest.devices) {
|
|
2405
|
+
requireCanonicalWriteProfiles(entry);
|
|
2406
|
+
}
|
|
2407
|
+
delete document.proof;
|
|
2408
|
+
return document;
|
|
2409
|
+
}
|
|
2410
|
+
function requireCanonicalWriteProfiles(device) {
|
|
2411
|
+
if (device.profiles.some((profile) => LEGACY_DRAFT_FOUNDATION_PROFILES.has(profile))) {
|
|
2412
|
+
throw new DeviceManifestError(
|
|
2413
|
+
"legacy draft foundation profiles are read-only and cannot be published"
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
function validateVnextDocument(didDocument, rootKeyId) {
|
|
2418
|
+
validateJsonValue(didDocument, "DID document");
|
|
2419
|
+
rejectPrivateKeyMaterial(didDocument, "DID document");
|
|
2420
|
+
const did = documentDid(didDocument);
|
|
2421
|
+
const methods = didDocument.verificationMethod;
|
|
2422
|
+
if (!Array.isArray(methods)) {
|
|
2423
|
+
throw new DeviceManifestError("DID document verificationMethod must be an array");
|
|
2424
|
+
}
|
|
2425
|
+
const rootMethods = methods.filter((method) => isPlainObject(method) && method.id === rootKeyId);
|
|
2426
|
+
if (rootMethods.length !== 1 || !isPlainObject(rootMethods[0])) {
|
|
2427
|
+
throw new DeviceManifestError("root key must resolve exactly once in verificationMethod");
|
|
2428
|
+
}
|
|
2429
|
+
const rootIdentity = validateRootMethod(did, rootKeyId, rootMethods[0]);
|
|
2430
|
+
requireRelationship(didDocument, "assertionMethod", rootKeyId, "DID root key");
|
|
2431
|
+
const manifest = validateDeviceManifest(didDocument);
|
|
2432
|
+
if (manifest === null) {
|
|
2433
|
+
throw new DeviceManifestError("deviceManifest is required");
|
|
2434
|
+
}
|
|
2435
|
+
const seenMaterial = /* @__PURE__ */ new Set([rootIdentity.rawPublicKey]);
|
|
2436
|
+
for (const entry of manifest.devices) {
|
|
2437
|
+
if (rootKeyId === entry.signingKeyId || rootKeyId === entry.e2eeKeyId) {
|
|
2438
|
+
throw new DeviceManifestError("DID root key cannot be a device key");
|
|
2439
|
+
}
|
|
2440
|
+
const signingMethod = uniqueMethod(didDocument, entry.signingKeyId);
|
|
2441
|
+
const e2eeMethod = uniqueMethod(didDocument, entry.e2eeKeyId);
|
|
2442
|
+
const [signingIdentity, e2eeIdentity] = validateDeviceMethods(
|
|
2443
|
+
did,
|
|
2444
|
+
rootKeyId,
|
|
2445
|
+
entry,
|
|
2446
|
+
signingMethod,
|
|
2447
|
+
e2eeMethod
|
|
2448
|
+
);
|
|
2449
|
+
requireRelationship(didDocument, "authentication", entry.signingKeyId, "device signing key");
|
|
2450
|
+
requireRelationship(didDocument, "assertionMethod", entry.signingKeyId, "device signing key");
|
|
2451
|
+
requireRelationship(didDocument, "keyAgreement", entry.e2eeKeyId, "device E2EE key");
|
|
2452
|
+
if (relationshipContains(didDocument, "keyAgreement", entry.signingKeyId)) {
|
|
2453
|
+
throw new DeviceManifestError("device signing key must not be in keyAgreement");
|
|
2454
|
+
}
|
|
2455
|
+
if (relationshipContains(didDocument, "authentication", entry.e2eeKeyId) || relationshipContains(didDocument, "assertionMethod", entry.e2eeKeyId)) {
|
|
2456
|
+
throw new DeviceManifestError("device E2EE key must not be a signing relationship");
|
|
2457
|
+
}
|
|
2458
|
+
for (const identity of [signingIdentity, e2eeIdentity]) {
|
|
2459
|
+
if (seenMaterial.has(identity.rawPublicKey)) {
|
|
2460
|
+
throw new DeviceManifestError("root and device public key material must be unique");
|
|
2461
|
+
}
|
|
2462
|
+
seenMaterial.add(identity.rawPublicKey);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
function validateRootMethod(did, rootKeyId, verificationMethod) {
|
|
2467
|
+
return validatePublicMethod(
|
|
2468
|
+
did,
|
|
2469
|
+
rootKeyId,
|
|
2470
|
+
verificationMethod,
|
|
2471
|
+
SIGNING_ALGORITHMS,
|
|
2472
|
+
"DID root verification method"
|
|
2473
|
+
);
|
|
2474
|
+
}
|
|
2475
|
+
function validateDeviceMethods(did, rootKeyId, device, signingMethod, e2eeMethod) {
|
|
2476
|
+
if (rootKeyId === device.signingKeyId || rootKeyId === device.e2eeKeyId) {
|
|
2477
|
+
throw new DeviceManifestError("DID root key cannot be a device key");
|
|
2478
|
+
}
|
|
2479
|
+
const standardObjectProof = device.profiles.some(
|
|
2480
|
+
(profile) => profile === PROFILE_DIRECT_E2EE_V2 || profile === PROFILE_GROUP_E2EE_V2
|
|
2481
|
+
);
|
|
2482
|
+
const signingIdentity = validatePublicMethod(
|
|
2483
|
+
did,
|
|
2484
|
+
device.signingKeyId,
|
|
2485
|
+
signingMethod,
|
|
2486
|
+
standardObjectProof ? /* @__PURE__ */ new Set(["Ed25519"]) : SIGNING_ALGORITHMS,
|
|
2487
|
+
"device signing verification method"
|
|
2488
|
+
);
|
|
2489
|
+
const e2eeIdentity = validatePublicMethod(
|
|
2490
|
+
did,
|
|
2491
|
+
device.e2eeKeyId,
|
|
2492
|
+
e2eeMethod,
|
|
2493
|
+
/* @__PURE__ */ new Set(["X25519"]),
|
|
2494
|
+
"device E2EE verification method"
|
|
2495
|
+
);
|
|
2496
|
+
if (signingIdentity.rawPublicKey === e2eeIdentity.rawPublicKey) {
|
|
2497
|
+
throw new DeviceManifestError("device key material must be unique across roles");
|
|
2498
|
+
}
|
|
2499
|
+
return [signingIdentity, e2eeIdentity];
|
|
2500
|
+
}
|
|
2501
|
+
function validatePublicMethod(did, expectedKeyId, method, allowedAlgorithms, subject) {
|
|
2502
|
+
if (!isPlainObject(method)) {
|
|
2503
|
+
throw new DeviceManifestError(`${subject} must be an object`);
|
|
2504
|
+
}
|
|
2505
|
+
validateJsonValue(method, subject);
|
|
2506
|
+
if (method.id !== expectedKeyId) {
|
|
2507
|
+
throw new DeviceManifestError(`${subject} id does not match its role`);
|
|
2508
|
+
}
|
|
2509
|
+
if (method.controller !== did) {
|
|
2510
|
+
throw new DeviceManifestError(`${subject} controller must match the DID`);
|
|
2511
|
+
}
|
|
2512
|
+
validateSameDocumentKeyId(did, expectedKeyId);
|
|
2513
|
+
rejectPrivateKeyMaterial(method, subject);
|
|
2514
|
+
const methodType = requireNonEmptyString(method.type, `${subject}.type`);
|
|
2515
|
+
const materialFields = ["publicKeyJwk", "publicKeyMultibase", "publicKeyBase58"].filter(
|
|
2516
|
+
(field) => Object.prototype.hasOwnProperty.call(method, field)
|
|
2517
|
+
);
|
|
2518
|
+
if (materialFields.length !== 1) {
|
|
2519
|
+
throw new DeviceManifestError(`${subject} must contain exactly one supported public key field`);
|
|
2520
|
+
}
|
|
2521
|
+
const materialField = materialFields[0];
|
|
2522
|
+
let identity;
|
|
2523
|
+
if (materialField === "publicKeyJwk") {
|
|
2524
|
+
identity = decodePublicJwk(methodType, method[materialField], subject);
|
|
2525
|
+
} else if (materialField === "publicKeyMultibase") {
|
|
2526
|
+
identity = decodePublicMultikey(methodType, method[materialField], subject);
|
|
2527
|
+
} else {
|
|
2528
|
+
throw new DeviceManifestError(`${subject} publicKeyBase58 is not supported by vNext helpers`);
|
|
2529
|
+
}
|
|
2530
|
+
if (!allowedAlgorithms.has(identity.algorithm)) {
|
|
2531
|
+
throw new DeviceManifestError(`${subject} uses the wrong key algorithm`);
|
|
2532
|
+
}
|
|
2533
|
+
return identity;
|
|
2534
|
+
}
|
|
2535
|
+
function validateSameDocumentKeyId(did, keyId) {
|
|
2536
|
+
if (!keyId.startsWith(`${did}#`) || keyId === `${did}#`) {
|
|
2537
|
+
throw new DeviceManifestError("key id must be a DID URL in the same document");
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
function decodePublicJwk(methodType, value, subject) {
|
|
2541
|
+
if (methodType !== "JsonWebKey2020" && methodType !== "EcdsaSecp256k1VerificationKey2019" && methodType !== "EcdsaSecp256r1VerificationKey2019") {
|
|
2542
|
+
throw new DeviceManifestError(`${subject} type is incompatible with publicKeyJwk`);
|
|
2543
|
+
}
|
|
2544
|
+
if (!isPlainObject(value)) {
|
|
2545
|
+
throw new DeviceManifestError(`${subject}.publicKeyJwk must be an object`);
|
|
2546
|
+
}
|
|
2547
|
+
const kty = value.kty;
|
|
2548
|
+
const curve = value.crv;
|
|
2549
|
+
if (kty === "OKP" && (curve === "Ed25519" || curve === "X25519")) {
|
|
2550
|
+
if (methodType !== "JsonWebKey2020") {
|
|
2551
|
+
throw new DeviceManifestError(`${subject} type contradicts its JWK`);
|
|
2552
|
+
}
|
|
2553
|
+
const raw = decodeCanonicalBase64url32(value.x, `${subject}.x`);
|
|
2554
|
+
return { algorithm: curve, rawPublicKey: encodeRaw(raw) };
|
|
2555
|
+
}
|
|
2556
|
+
if (kty === "EC" && (curve === "P-256" || curve === "secp256k1")) {
|
|
2557
|
+
const expectedType = curve === "P-256" ? "EcdsaSecp256r1VerificationKey2019" : "EcdsaSecp256k1VerificationKey2019";
|
|
2558
|
+
if (methodType !== "JsonWebKey2020" && methodType !== expectedType) {
|
|
2559
|
+
throw new DeviceManifestError(`${subject} type contradicts its JWK`);
|
|
2560
|
+
}
|
|
2561
|
+
const x = decodeCanonicalBase64url32(value.x, `${subject}.x`);
|
|
2562
|
+
const y = decodeCanonicalBase64url32(value.y, `${subject}.y`);
|
|
2563
|
+
validateEcPoint(curve, x, y, subject);
|
|
2564
|
+
return { algorithm: curve, rawPublicKey: encodeRaw(concatBytes(x, y)) };
|
|
2565
|
+
}
|
|
2566
|
+
throw new DeviceManifestError(`${subject} contains an unsupported public JWK`);
|
|
2567
|
+
}
|
|
2568
|
+
function decodePublicMultikey(methodType, value, subject) {
|
|
2569
|
+
if (methodType !== "Multikey" && methodType !== "X25519KeyAgreementKey2019") {
|
|
2570
|
+
throw new DeviceManifestError(`${subject} type is incompatible with publicKeyMultibase`);
|
|
2571
|
+
}
|
|
2572
|
+
if (typeof value !== "string" || !value.startsWith("z") || value.length === 1) {
|
|
2573
|
+
throw new DeviceManifestError(`${subject}.publicKeyMultibase must be base58btc`);
|
|
2574
|
+
}
|
|
2575
|
+
let decoded;
|
|
2576
|
+
try {
|
|
2577
|
+
decoded = bs58__default.default.decode(value.slice(1));
|
|
2578
|
+
} catch (error) {
|
|
2579
|
+
throw new DeviceManifestError(`${subject}.publicKeyMultibase is invalid`, error);
|
|
2580
|
+
}
|
|
2581
|
+
if (`z${bs58__default.default.encode(decoded)}` !== value) {
|
|
2582
|
+
throw new DeviceManifestError(`${subject}.publicKeyMultibase must be canonical`);
|
|
2583
|
+
}
|
|
2584
|
+
if (decoded.length !== 34) {
|
|
2585
|
+
throw new DeviceManifestError(`${subject}.publicKeyMultibase must contain a 32-byte key`);
|
|
2586
|
+
}
|
|
2587
|
+
const prefix = decoded[0] * 256 + decoded[1];
|
|
2588
|
+
let algorithm;
|
|
2589
|
+
if (prefix === 60673) {
|
|
2590
|
+
algorithm = "Ed25519";
|
|
2591
|
+
} else if (prefix === 60417) {
|
|
2592
|
+
algorithm = "X25519";
|
|
2593
|
+
} else {
|
|
2594
|
+
throw new DeviceManifestError(`${subject}.publicKeyMultibase uses an unsupported codec`);
|
|
2595
|
+
}
|
|
2596
|
+
if (methodType === "X25519KeyAgreementKey2019" && algorithm !== "X25519") {
|
|
2597
|
+
throw new DeviceManifestError(`${subject} type contradicts its Multikey`);
|
|
2598
|
+
}
|
|
2599
|
+
return { algorithm, rawPublicKey: encodeRaw(decoded.slice(2)) };
|
|
2600
|
+
}
|
|
2601
|
+
function decodeCanonicalBase64url32(value, subject) {
|
|
2602
|
+
if (typeof value !== "string" || !BASE64URL_RE.test(value)) {
|
|
2603
|
+
throw new DeviceManifestError(`${subject} must be unpadded base64url`);
|
|
2604
|
+
}
|
|
2605
|
+
let decoded;
|
|
2606
|
+
try {
|
|
2607
|
+
decoded = decodeBase64Url(value);
|
|
2608
|
+
} catch (error) {
|
|
2609
|
+
throw new DeviceManifestError(`${subject} is invalid base64url`, error);
|
|
2610
|
+
}
|
|
2611
|
+
const canonical = encodeBase64Url(decoded);
|
|
2612
|
+
if (decoded.length !== 32 || canonical !== value) {
|
|
2613
|
+
throw new DeviceManifestError(`${subject} must canonically encode 32 bytes`);
|
|
2614
|
+
}
|
|
2615
|
+
return decoded;
|
|
2616
|
+
}
|
|
2617
|
+
function validateEcPoint(curve, x, y, subject) {
|
|
2618
|
+
const uncompressed = new Uint8Array(65);
|
|
2619
|
+
uncompressed[0] = 4;
|
|
2620
|
+
uncompressed.set(x, 1);
|
|
2621
|
+
uncompressed.set(y, 33);
|
|
2622
|
+
try {
|
|
2623
|
+
if (curve === "P-256") {
|
|
2624
|
+
p256.p256.ProjectivePoint.fromHex(uncompressed);
|
|
2625
|
+
} else {
|
|
2626
|
+
secp256k1.secp256k1.ProjectivePoint.fromHex(uncompressed);
|
|
2627
|
+
}
|
|
2628
|
+
} catch (error) {
|
|
2629
|
+
throw new DeviceManifestError(`${subject} contains an invalid EC point`, error);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
function rejectPrivateKeyMaterial(value, subject) {
|
|
2633
|
+
if (isPlainObject(value)) {
|
|
2634
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
2635
|
+
const normalizedKey = key.toLowerCase().replaceAll("_", "").replaceAll("-", "");
|
|
2636
|
+
if (normalizedKey.includes("privatekey") || key === "d" && "kty" in value) {
|
|
2637
|
+
throw new DeviceManifestError(`${subject} must not contain private key material`);
|
|
2638
|
+
}
|
|
2639
|
+
rejectPrivateKeyMaterial(nested, subject);
|
|
2640
|
+
}
|
|
2641
|
+
return;
|
|
2642
|
+
}
|
|
2643
|
+
if (Array.isArray(value)) {
|
|
2644
|
+
for (const nested of value) {
|
|
2645
|
+
rejectPrivateKeyMaterial(nested, subject);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
function validateJsonValue(value, subject) {
|
|
2650
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") {
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
if (typeof value === "number") {
|
|
2654
|
+
if (!Number.isFinite(value)) {
|
|
2655
|
+
throw new DeviceManifestError(`${subject} contains a non-finite number`);
|
|
2656
|
+
}
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
if (Array.isArray(value)) {
|
|
2660
|
+
for (const nested of value) {
|
|
2661
|
+
validateJsonValue(nested, subject);
|
|
2662
|
+
}
|
|
2663
|
+
return;
|
|
2664
|
+
}
|
|
2665
|
+
if (isPlainObject(value)) {
|
|
2666
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
2667
|
+
if (typeof key !== "string") {
|
|
2668
|
+
throw new DeviceManifestError(`${subject} contains a non-string object key`);
|
|
2669
|
+
}
|
|
2670
|
+
validateJsonValue(nested, subject);
|
|
2671
|
+
}
|
|
2672
|
+
return;
|
|
2673
|
+
}
|
|
2674
|
+
throw new DeviceManifestError(`${subject} contains a non-JSON value`);
|
|
2675
|
+
}
|
|
2676
|
+
function validateRetiredDeviceIds(retiredDeviceIds) {
|
|
2677
|
+
if (typeof retiredDeviceIds === "string") {
|
|
2678
|
+
throw new DeviceManifestError("retired_device_ids must be a string collection");
|
|
2679
|
+
}
|
|
2680
|
+
const values = [];
|
|
2681
|
+
try {
|
|
2682
|
+
for (const deviceId of retiredDeviceIds) {
|
|
2683
|
+
values.push(deviceId);
|
|
2684
|
+
}
|
|
2685
|
+
} catch (error) {
|
|
2686
|
+
throw new DeviceManifestError("retired_device_ids must be a string collection", error);
|
|
2687
|
+
}
|
|
2688
|
+
for (const deviceId of values) {
|
|
2689
|
+
requireNonEmptyString(deviceId, "retired device_id");
|
|
2690
|
+
}
|
|
2691
|
+
return new Set(values);
|
|
2692
|
+
}
|
|
2693
|
+
function uniqueMethod(didDocument, keyId) {
|
|
2694
|
+
const methods = didDocument.verificationMethod;
|
|
2695
|
+
if (!Array.isArray(methods)) {
|
|
2696
|
+
throw new DeviceManifestError("DID document verificationMethod must be an array");
|
|
2697
|
+
}
|
|
2698
|
+
const matches = methods.filter((method) => isPlainObject(method) && method.id === keyId);
|
|
2699
|
+
if (matches.length !== 1 || !isPlainObject(matches[0])) {
|
|
2700
|
+
throw new DeviceManifestError("key id must resolve exactly once in verificationMethod");
|
|
2701
|
+
}
|
|
2702
|
+
return matches[0];
|
|
2703
|
+
}
|
|
2704
|
+
function appendDeviceMaterial(document, rootKeyId, device, signingMethod, e2eeMethod) {
|
|
2705
|
+
const did = documentDid(document);
|
|
2706
|
+
validateDeviceMethods(did, rootKeyId, device, signingMethod, e2eeMethod);
|
|
2707
|
+
const methods = document.verificationMethod;
|
|
2708
|
+
const authentication2 = document.authentication;
|
|
2709
|
+
const assertionMethod = document.assertionMethod;
|
|
2710
|
+
const keyAgreement = document.keyAgreement;
|
|
2711
|
+
const manifest = document.deviceManifest;
|
|
2712
|
+
if (!Array.isArray(methods) || !Array.isArray(authentication2) || !Array.isArray(assertionMethod) || !Array.isArray(keyAgreement) || !isPlainObject(manifest) || !Array.isArray(manifest.devices)) {
|
|
2713
|
+
throw new DeviceManifestError("DID document relationships are invalid");
|
|
2714
|
+
}
|
|
2715
|
+
methods.push(structuredClone(signingMethod), structuredClone(e2eeMethod));
|
|
2716
|
+
authentication2.push(device.signingKeyId);
|
|
2717
|
+
assertionMethod.push(device.signingKeyId);
|
|
2718
|
+
keyAgreement.push(device.e2eeKeyId);
|
|
2719
|
+
manifest.devices.push(device.toDict());
|
|
2720
|
+
}
|
|
2721
|
+
function removeDeviceMaterial(document, device) {
|
|
2722
|
+
const keyIds = /* @__PURE__ */ new Set([device.signingKeyId, device.e2eeKeyId]);
|
|
2723
|
+
const methods = document.verificationMethod;
|
|
2724
|
+
if (!Array.isArray(methods)) {
|
|
2725
|
+
throw new DeviceManifestError("DID document verificationMethod must be an array");
|
|
2726
|
+
}
|
|
2727
|
+
document.verificationMethod = methods.filter(
|
|
2728
|
+
(method) => !(isPlainObject(method) && typeof method.id === "string" && keyIds.has(method.id))
|
|
2729
|
+
);
|
|
2730
|
+
for (const relationship of ["authentication", "assertionMethod", "keyAgreement"]) {
|
|
2731
|
+
const entries = document[relationship];
|
|
2732
|
+
if (!Array.isArray(entries)) {
|
|
2733
|
+
throw new DeviceManifestError(`${relationship} must be an array`);
|
|
2734
|
+
}
|
|
2735
|
+
document[relationship] = entries.filter(
|
|
2736
|
+
(entry) => ![...keyIds].some((keyId) => relationshipEntryIs(entry, keyId))
|
|
2737
|
+
);
|
|
2738
|
+
}
|
|
2739
|
+
const manifest = document.deviceManifest;
|
|
2740
|
+
if (!isPlainObject(manifest) || !Array.isArray(manifest.devices)) {
|
|
2741
|
+
throw new DeviceManifestError("deviceManifest.devices must be an array");
|
|
2742
|
+
}
|
|
2743
|
+
manifest.devices = manifest.devices.filter(
|
|
2744
|
+
(entry) => !(isPlainObject(entry) && entry.device_id === device.deviceId)
|
|
2745
|
+
);
|
|
2746
|
+
}
|
|
2747
|
+
function relationshipEntryIs(entry, keyId) {
|
|
2748
|
+
return entry === keyId || isPlainObject(entry) && entry.id === keyId;
|
|
2749
|
+
}
|
|
2750
|
+
function relationshipContains(didDocument, relationship, keyId) {
|
|
2751
|
+
const entries = didDocument[relationship];
|
|
2752
|
+
return Array.isArray(entries) && entries.some((entry) => relationshipEntryIs(entry, keyId));
|
|
2753
|
+
}
|
|
2754
|
+
function requireExactFields(value, expected, subject) {
|
|
2755
|
+
const actual = new Set(Object.keys(value));
|
|
2756
|
+
if (actual.size !== expected.size || [...expected].some((field) => !actual.has(field))) {
|
|
2757
|
+
throw new DeviceManifestError(
|
|
2758
|
+
`${subject} must contain exactly ${[...expected].sort().join(", ")}`
|
|
2759
|
+
);
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
function requireString(value, subject) {
|
|
2763
|
+
if (typeof value !== "string") {
|
|
2764
|
+
throw new DeviceManifestError(`${subject} must be a string`);
|
|
2765
|
+
}
|
|
2766
|
+
return value;
|
|
2767
|
+
}
|
|
2768
|
+
function requireNonEmptyString(value, subject) {
|
|
2769
|
+
const result = requireString(value, subject);
|
|
2770
|
+
if (!result) {
|
|
2771
|
+
throw new DeviceManifestError(`${subject} must be a non-empty string`);
|
|
2772
|
+
}
|
|
2773
|
+
return result;
|
|
2774
|
+
}
|
|
2775
|
+
function validateSameDocumentMethod(did, keyId, methodsById) {
|
|
2776
|
+
if (!keyId.startsWith(`${did}#`) || keyId === `${did}#`) {
|
|
2777
|
+
throw new DeviceManifestError("device key IDs must be DID URLs in the same DID document");
|
|
2778
|
+
}
|
|
2779
|
+
const methods = methodsById.get(keyId) ?? [];
|
|
2780
|
+
if (methods.length !== 1) {
|
|
2781
|
+
throw new DeviceManifestError("device key ID must resolve exactly once in verificationMethod");
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
function requireDependencies(profiles, required, legacyDraft, profileName) {
|
|
2785
|
+
const hasRequired = [...required].every((profile) => profiles.has(profile));
|
|
2786
|
+
const hasLegacy = [...legacyDraft].every((profile) => profiles.has(profile));
|
|
2787
|
+
if (!hasRequired && !hasLegacy) {
|
|
2788
|
+
throw new DeviceManifestError(`${profileName} device profile dependencies are incomplete`);
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
function requireRelationship(didDocument, relationship, keyId, subject) {
|
|
2792
|
+
const entries = didDocument[relationship];
|
|
2793
|
+
if (!Array.isArray(entries)) {
|
|
2794
|
+
throw new DeviceManifestError(`${subject} requires ${relationship}`);
|
|
2795
|
+
}
|
|
2796
|
+
for (const entry of entries) {
|
|
2797
|
+
if (entry === keyId) {
|
|
2798
|
+
return;
|
|
2799
|
+
}
|
|
2800
|
+
if (isPlainObject(entry) && entry.id === keyId) {
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
throw new DeviceManifestError(`${subject} is not authorized by ${relationship}`);
|
|
2805
|
+
}
|
|
2806
|
+
function isPlainObject(value) {
|
|
2807
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2808
|
+
}
|
|
2809
|
+
function encodeRaw(bytes) {
|
|
2810
|
+
return Buffer.from(bytes).toString("hex");
|
|
2811
|
+
}
|
|
2812
|
+
function concatBytes(left, right) {
|
|
2813
|
+
const output = new Uint8Array(left.length + right.length);
|
|
2814
|
+
output.set(left);
|
|
2815
|
+
output.set(right, left.length);
|
|
2816
|
+
return output;
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2066
2819
|
// src/authentication/index.ts
|
|
2067
2820
|
var didDocuments = {
|
|
2068
2821
|
ANP_MESSAGE_SERVICE_TYPE,
|
|
@@ -2093,6 +2846,7 @@ var authentication = {
|
|
|
2093
2846
|
didDocuments,
|
|
2094
2847
|
legacyAuth,
|
|
2095
2848
|
httpSignatures,
|
|
2849
|
+
deviceManifest: device_manifest_exports,
|
|
2096
2850
|
federation: {
|
|
2097
2851
|
verifyRequest: verifyFederatedHttpRequest
|
|
2098
2852
|
},
|
|
@@ -2271,12 +3025,206 @@ function isVerificationMethodAuthorized2(didDocument, verificationMethodId, veri
|
|
|
2271
3025
|
throw new ProofError(`unsupported verification relationship: ${verificationRelationship}`);
|
|
2272
3026
|
}
|
|
2273
3027
|
|
|
3028
|
+
// src/proof/rfc9421-origin.ts
|
|
3029
|
+
var rfc9421_origin_exports = {};
|
|
3030
|
+
__export(rfc9421_origin_exports, {
|
|
3031
|
+
RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS: () => RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS,
|
|
3032
|
+
RFC9421_ORIGIN_PROOF_DEFAULT_LABEL: () => RFC9421_ORIGIN_PROOF_DEFAULT_LABEL,
|
|
3033
|
+
Rfc9421OriginProofError: () => Rfc9421OriginProofError,
|
|
3034
|
+
TARGET_KIND_AGENT: () => TARGET_KIND_AGENT,
|
|
3035
|
+
TARGET_KIND_GROUP: () => TARGET_KIND_GROUP,
|
|
3036
|
+
TARGET_KIND_SERVICE: () => TARGET_KIND_SERVICE,
|
|
3037
|
+
buildLogicalTargetUri: () => buildLogicalTargetUri,
|
|
3038
|
+
buildRfc9421OriginSignatureBase: () => buildRfc9421OriginSignatureBase,
|
|
3039
|
+
buildSignedRequestObject: () => buildSignedRequestObject,
|
|
3040
|
+
canonicalizeSignedRequestObject: () => canonicalizeSignedRequestObject,
|
|
3041
|
+
generateRfc9421OriginProof: () => generateRfc9421OriginProof,
|
|
3042
|
+
quoteRfc3986Unreserved: () => quoteRfc3986Unreserved,
|
|
3043
|
+
verifyRfc9421OriginProof: () => verifyRfc9421OriginProof
|
|
3044
|
+
});
|
|
3045
|
+
var RFC9421_ORIGIN_PROOF_DEFAULT_LABEL = "sig1";
|
|
3046
|
+
var RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS = IM_PROOF_DEFAULT_COMPONENTS;
|
|
3047
|
+
var TARGET_KIND_AGENT = "agent";
|
|
3048
|
+
var TARGET_KIND_GROUP = "group";
|
|
3049
|
+
var TARGET_KIND_SERVICE = "service";
|
|
3050
|
+
var ALLOWED_TARGET_KINDS = /* @__PURE__ */ new Set([TARGET_KIND_AGENT, TARGET_KIND_GROUP, TARGET_KIND_SERVICE]);
|
|
3051
|
+
var Rfc9421OriginProofError = class extends ProofError {
|
|
3052
|
+
constructor(message, cause) {
|
|
3053
|
+
super(message, cause);
|
|
3054
|
+
this.name = "Rfc9421OriginProofError";
|
|
3055
|
+
}
|
|
3056
|
+
};
|
|
3057
|
+
function buildSignedRequestObject(method, meta, body) {
|
|
3058
|
+
if (typeof method !== "string" || !method.trim()) {
|
|
3059
|
+
throw new Rfc9421OriginProofError("method is required");
|
|
3060
|
+
}
|
|
3061
|
+
if (!isPlainObject2(meta)) {
|
|
3062
|
+
throw new Rfc9421OriginProofError("meta must be an object");
|
|
3063
|
+
}
|
|
3064
|
+
if (!isPlainObject2(body)) {
|
|
3065
|
+
throw new Rfc9421OriginProofError("body must be an object");
|
|
3066
|
+
}
|
|
3067
|
+
return {
|
|
3068
|
+
method,
|
|
3069
|
+
meta: cloneJson(meta),
|
|
3070
|
+
body: cloneJson(body)
|
|
3071
|
+
};
|
|
3072
|
+
}
|
|
3073
|
+
function canonicalizeSignedRequestObject(signedRequestObject) {
|
|
3074
|
+
const keys = Object.keys(signedRequestObject);
|
|
3075
|
+
if (keys.length !== 3 || !keys.includes("method") || !keys.includes("meta") || !keys.includes("body")) {
|
|
3076
|
+
throw new Rfc9421OriginProofError(
|
|
3077
|
+
"signed request object must contain only method, meta, and body"
|
|
3078
|
+
);
|
|
3079
|
+
}
|
|
3080
|
+
return canonicalizeJson({
|
|
3081
|
+
method: signedRequestObject.method,
|
|
3082
|
+
meta: signedRequestObject.meta,
|
|
3083
|
+
body: signedRequestObject.body
|
|
3084
|
+
});
|
|
3085
|
+
}
|
|
3086
|
+
function buildLogicalTargetUri(targetKind, targetDid) {
|
|
3087
|
+
const normalizedKind = String(targetKind).trim();
|
|
3088
|
+
if (!ALLOWED_TARGET_KINDS.has(normalizedKind)) {
|
|
3089
|
+
throw new Rfc9421OriginProofError(`unsupported target kind: ${targetKind}`);
|
|
3090
|
+
}
|
|
3091
|
+
const normalizedDid = String(targetDid).trim();
|
|
3092
|
+
if (!normalizedDid) {
|
|
3093
|
+
throw new Rfc9421OriginProofError("target did is required");
|
|
3094
|
+
}
|
|
3095
|
+
return `anp://${normalizedKind}/${quoteRfc3986Unreserved(normalizedDid)}`;
|
|
3096
|
+
}
|
|
3097
|
+
function buildRfc9421OriginSignatureBase(method, logicalTargetUri, contentDigest, signatureInput) {
|
|
3098
|
+
if (typeof method !== "string" || !method.trim()) {
|
|
3099
|
+
throw new Rfc9421OriginProofError("method is required");
|
|
3100
|
+
}
|
|
3101
|
+
if (typeof logicalTargetUri !== "string" || !logicalTargetUri.trim()) {
|
|
3102
|
+
throw new Rfc9421OriginProofError("logical_target_uri is required");
|
|
3103
|
+
}
|
|
3104
|
+
if (typeof contentDigest !== "string" || !contentDigest.trim()) {
|
|
3105
|
+
throw new Rfc9421OriginProofError("content_digest is required");
|
|
3106
|
+
}
|
|
3107
|
+
const parsed = parseImSignatureInput(signatureInput);
|
|
3108
|
+
validateParsedSignatureInput(parsed.label, parsed.components);
|
|
3109
|
+
const componentValues = {
|
|
3110
|
+
"@method": method,
|
|
3111
|
+
"@target-uri": logicalTargetUri,
|
|
3112
|
+
"content-digest": contentDigest
|
|
3113
|
+
};
|
|
3114
|
+
const lines = parsed.components.map(
|
|
3115
|
+
(component) => `"${component}": ${componentValues[component]}`
|
|
3116
|
+
);
|
|
3117
|
+
lines.push(`"@signature-params": ${parsed.signatureParams}`);
|
|
3118
|
+
return new TextEncoder().encode(lines.join("\n"));
|
|
3119
|
+
}
|
|
3120
|
+
function generateRfc9421OriginProof(method, meta, body, privateKey, keyId, options = {}) {
|
|
3121
|
+
const label = options.label ?? RFC9421_ORIGIN_PROOF_DEFAULT_LABEL;
|
|
3122
|
+
validateLabel(label);
|
|
3123
|
+
const signedRequestObject = buildSignedRequestObject(method, meta, body);
|
|
3124
|
+
const canonicalRequest = canonicalizeSignedRequestObject(signedRequestObject);
|
|
3125
|
+
const logicalTargetUri = buildLogicalTargetUriFromMeta(signedRequestObject.meta);
|
|
3126
|
+
const contentDigest = buildImContentDigest(canonicalRequest);
|
|
3127
|
+
const signatureInput = buildImSignatureInput(keyId, {
|
|
3128
|
+
components: [...RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS],
|
|
3129
|
+
label,
|
|
3130
|
+
created: options.created,
|
|
3131
|
+
expires: options.expires,
|
|
3132
|
+
nonce: options.nonce
|
|
3133
|
+
});
|
|
3134
|
+
const signatureBase = buildRfc9421OriginSignatureBase(
|
|
3135
|
+
method,
|
|
3136
|
+
logicalTargetUri,
|
|
3137
|
+
contentDigest,
|
|
3138
|
+
signatureInput
|
|
3139
|
+
);
|
|
3140
|
+
const proof2 = generateImProof(canonicalRequest, signatureBase, privateKey, keyId, {
|
|
3141
|
+
components: [...RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS],
|
|
3142
|
+
label,
|
|
3143
|
+
created: options.created,
|
|
3144
|
+
expires: options.expires,
|
|
3145
|
+
nonce: options.nonce
|
|
3146
|
+
});
|
|
3147
|
+
const parsed = parseImSignatureInput(proof2.signatureInput);
|
|
3148
|
+
validateParsedSignatureInput(parsed.label, parsed.components);
|
|
3149
|
+
return proof2;
|
|
3150
|
+
}
|
|
3151
|
+
function verifyRfc9421OriginProof(originProof, method, meta, body, verification = {}) {
|
|
3152
|
+
const signedRequestObject = buildSignedRequestObject(method, meta, body);
|
|
3153
|
+
const canonicalRequest = canonicalizeSignedRequestObject(signedRequestObject);
|
|
3154
|
+
const logicalTargetUri = buildLogicalTargetUriFromMeta(signedRequestObject.meta);
|
|
3155
|
+
const signatureInput = requireProofField(originProof, "signatureInput");
|
|
3156
|
+
const parsed = parseImSignatureInput(signatureInput);
|
|
3157
|
+
validateParsedSignatureInput(parsed.label, parsed.components);
|
|
3158
|
+
const signatureBase = buildRfc9421OriginSignatureBase(
|
|
3159
|
+
method,
|
|
3160
|
+
logicalTargetUri,
|
|
3161
|
+
requireProofField(originProof, "contentDigest"),
|
|
3162
|
+
signatureInput
|
|
3163
|
+
);
|
|
3164
|
+
return verifyImProof(
|
|
3165
|
+
originProof,
|
|
3166
|
+
canonicalRequest,
|
|
3167
|
+
signatureBase,
|
|
3168
|
+
{
|
|
3169
|
+
didDocument: verification.didDocument,
|
|
3170
|
+
verificationMethod: verification.verificationMethod,
|
|
3171
|
+
verificationRelationship: IM_PROOF_RELATION_AUTHENTICATION
|
|
3172
|
+
},
|
|
3173
|
+
verification.options?.expectedSignerDid
|
|
3174
|
+
);
|
|
3175
|
+
}
|
|
3176
|
+
function buildLogicalTargetUriFromMeta(meta) {
|
|
3177
|
+
const target = meta.target;
|
|
3178
|
+
if (!isPlainObject2(target)) {
|
|
3179
|
+
throw new Rfc9421OriginProofError("meta.target is required");
|
|
3180
|
+
}
|
|
3181
|
+
return buildLogicalTargetUri(String(target.kind), String(target.did));
|
|
3182
|
+
}
|
|
3183
|
+
function validateLabel(label) {
|
|
3184
|
+
if (label !== RFC9421_ORIGIN_PROOF_DEFAULT_LABEL) {
|
|
3185
|
+
throw new Rfc9421OriginProofError("RFC 9421 origin proof requires signature label sig1");
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
function validateParsedSignatureInput(label, components) {
|
|
3189
|
+
validateLabel(label);
|
|
3190
|
+
const expected = [...RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS];
|
|
3191
|
+
if (components.length !== expected.length || components.some((value, index) => value !== expected[index])) {
|
|
3192
|
+
throw new Rfc9421OriginProofError(
|
|
3193
|
+
'RFC 9421 origin proof requires covered components ("@method" "@target-uri" "content-digest")'
|
|
3194
|
+
);
|
|
3195
|
+
}
|
|
3196
|
+
}
|
|
3197
|
+
function requireProofField(proof2, field) {
|
|
3198
|
+
const value = proof2[field];
|
|
3199
|
+
if (!value) {
|
|
3200
|
+
throw new Rfc9421OriginProofError(`missing proof field: ${field}`);
|
|
3201
|
+
}
|
|
3202
|
+
return value;
|
|
3203
|
+
}
|
|
3204
|
+
function isPlainObject2(value) {
|
|
3205
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3206
|
+
}
|
|
3207
|
+
function quoteRfc3986Unreserved(value) {
|
|
3208
|
+
let output = "";
|
|
3209
|
+
for (const char of value) {
|
|
3210
|
+
if (/[A-Za-z0-9\-._~]/.test(char)) {
|
|
3211
|
+
output += char;
|
|
3212
|
+
continue;
|
|
3213
|
+
}
|
|
3214
|
+
for (const byte of new TextEncoder().encode(char)) {
|
|
3215
|
+
output += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
return output;
|
|
3219
|
+
}
|
|
3220
|
+
|
|
2274
3221
|
// src/proof/index.ts
|
|
2275
3222
|
var proof = {
|
|
2276
3223
|
create: generateW3cProof,
|
|
2277
3224
|
verify: verifyW3cProof,
|
|
2278
3225
|
verifyDetailed: verifyW3cProofDetailed,
|
|
2279
|
-
im: im_exports
|
|
3226
|
+
im: im_exports,
|
|
3227
|
+
rfc9421: rfc9421_origin_exports
|
|
2280
3228
|
};
|
|
2281
3229
|
|
|
2282
3230
|
// src/wns/types.ts
|
|
@@ -4879,7 +5827,11 @@ exports.AwikiImError = AwikiImError;
|
|
|
4879
5827
|
exports.CRYPTOSUITE_DIDWBA_SECP256K1_2025 = CRYPTOSUITE_DIDWBA_SECP256K1_2025;
|
|
4880
5828
|
exports.CRYPTOSUITE_EDDSA_JCS_2022 = CRYPTOSUITE_EDDSA_JCS_2022;
|
|
4881
5829
|
exports.CryptoError = CryptoError;
|
|
5830
|
+
exports.DEVICE_MANIFEST_TYPE = DEVICE_MANIFEST_TYPE;
|
|
4882
5831
|
exports.DIDWbaAuthHeader = DIDWbaAuthHeader;
|
|
5832
|
+
exports.DeviceManifest = DeviceManifest;
|
|
5833
|
+
exports.DeviceManifestEntry = DeviceManifestEntry;
|
|
5834
|
+
exports.DeviceManifestError = DeviceManifestError;
|
|
4883
5835
|
exports.DidAuthHeaders = DIDWbaAuthHeader;
|
|
4884
5836
|
exports.DidProfile = DidProfile;
|
|
4885
5837
|
exports.DidWbaVerifier = DidWbaVerifier;
|
|
@@ -4895,19 +5847,36 @@ exports.IM_PROOF_DEFAULT_COMPONENTS = IM_PROOF_DEFAULT_COMPONENTS;
|
|
|
4895
5847
|
exports.IM_PROOF_RELATION_ASSERTION_METHOD = IM_PROOF_RELATION_ASSERTION_METHOD;
|
|
4896
5848
|
exports.IM_PROOF_RELATION_AUTHENTICATION = IM_PROOF_RELATION_AUTHENTICATION;
|
|
4897
5849
|
exports.NetworkError = NetworkError;
|
|
5850
|
+
exports.PROFILE_CORE_BINDING_V1 = PROFILE_CORE_BINDING_V1;
|
|
5851
|
+
exports.PROFILE_CORE_BINDING_V2 = PROFILE_CORE_BINDING_V2;
|
|
5852
|
+
exports.PROFILE_DIRECT_BASE_V1 = PROFILE_DIRECT_BASE_V1;
|
|
5853
|
+
exports.PROFILE_DIRECT_BASE_V2 = PROFILE_DIRECT_BASE_V2;
|
|
5854
|
+
exports.PROFILE_DIRECT_E2EE_V2 = PROFILE_DIRECT_E2EE_V2;
|
|
5855
|
+
exports.PROFILE_GROUP_BASE_V1 = PROFILE_GROUP_BASE_V1;
|
|
5856
|
+
exports.PROFILE_GROUP_BASE_V2 = PROFILE_GROUP_BASE_V2;
|
|
5857
|
+
exports.PROFILE_GROUP_E2EE_V2 = PROFILE_GROUP_E2EE_V2;
|
|
5858
|
+
exports.PROFILE_IDENTITY_DISCOVERY_V1 = PROFILE_IDENTITY_DISCOVERY_V1;
|
|
5859
|
+
exports.PROFILE_IDENTITY_DISCOVERY_V2 = PROFILE_IDENTITY_DISCOVERY_V2;
|
|
4898
5860
|
exports.PROOF_TYPE_DATA_INTEGRITY = PROOF_TYPE_DATA_INTEGRITY;
|
|
4899
5861
|
exports.PROOF_TYPE_ED25519 = PROOF_TYPE_ED25519;
|
|
4900
5862
|
exports.PROOF_TYPE_SECP256K1 = PROOF_TYPE_SECP256K1;
|
|
4901
5863
|
exports.ProofError = ProofError;
|
|
5864
|
+
exports.RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS = RFC9421_ORIGIN_PROOF_DEFAULT_COMPONENTS;
|
|
5865
|
+
exports.RFC9421_ORIGIN_PROOF_DEFAULT_LABEL = RFC9421_ORIGIN_PROOF_DEFAULT_LABEL;
|
|
4902
5866
|
exports.RequestVerifier = DidWbaVerifier;
|
|
4903
5867
|
exports.RequestVerifierError = DidWbaVerifierError;
|
|
5868
|
+
exports.Rfc9421OriginProofError = Rfc9421OriginProofError;
|
|
4904
5869
|
exports.SubjectType = SubjectType;
|
|
5870
|
+
exports.TARGET_KIND_AGENT = TARGET_KIND_AGENT;
|
|
5871
|
+
exports.TARGET_KIND_GROUP = TARGET_KIND_GROUP;
|
|
5872
|
+
exports.TARGET_KIND_SERVICE = TARGET_KIND_SERVICE;
|
|
4905
5873
|
exports.VM_KEY_AUTH = VM_KEY_AUTH;
|
|
4906
5874
|
exports.VM_KEY_E2EE_AGREEMENT = VM_KEY_E2EE_AGREEMENT;
|
|
4907
5875
|
exports.VM_KEY_E2EE_SIGNING = VM_KEY_E2EE_SIGNING;
|
|
4908
5876
|
exports.VerificationMethod = VerificationMethod;
|
|
4909
5877
|
exports.WbaUriParseError = WbaUriParseError;
|
|
4910
5878
|
exports.WnsError = WnsError;
|
|
5879
|
+
exports.addDeviceToDidDocument = addDeviceToDidDocument;
|
|
4911
5880
|
exports.authentication = authentication;
|
|
4912
5881
|
exports.buildAgentMessageService = buildAgentMessageService;
|
|
4913
5882
|
exports.buildAnpMessageService = buildAnpMessageService;
|
|
@@ -4916,10 +5885,15 @@ exports.buildGroupMessageService = buildGroupMessageService;
|
|
|
4916
5885
|
exports.buildHandleServiceEntry = buildHandleServiceEntry;
|
|
4917
5886
|
exports.buildImContentDigest = buildImContentDigest;
|
|
4918
5887
|
exports.buildImSignatureInput = buildImSignatureInput;
|
|
5888
|
+
exports.buildLogicalTargetUri = buildLogicalTargetUri;
|
|
4919
5889
|
exports.buildResolutionUrl = buildResolutionUrl;
|
|
5890
|
+
exports.buildRfc9421OriginSignatureBase = buildRfc9421OriginSignatureBase;
|
|
5891
|
+
exports.buildSignedRequestObject = buildSignedRequestObject;
|
|
4920
5892
|
exports.buildUri = buildWbaUri;
|
|
5893
|
+
exports.buildVnextDidDocument = buildVnextDidDocument;
|
|
4921
5894
|
exports.buildWbaUri = buildWbaUri;
|
|
4922
5895
|
exports.canonicalizeBindingGeneration = canonicalizeBindingGeneration;
|
|
5896
|
+
exports.canonicalizeSignedRequestObject = canonicalizeSignedRequestObject;
|
|
4923
5897
|
exports.compareBindingGenerations = compareBindingGenerations;
|
|
4924
5898
|
exports.computeJwkFingerprint = computeJwkFingerprint;
|
|
4925
5899
|
exports.computeMultikeyFingerprint = computeMultikeyFingerprint;
|
|
@@ -4942,28 +5916,35 @@ exports.extractHandleServiceFromDidDocument = extractHandleServiceFromDidDocumen
|
|
|
4942
5916
|
exports.extractHandleServices = extractHandleServiceFromDidDocument;
|
|
4943
5917
|
exports.extractPublicKey = extractPublicKey;
|
|
4944
5918
|
exports.extractSignatureMetadata = extractSignatureMetadata;
|
|
5919
|
+
exports.findEligibleDevice = findEligibleDevice;
|
|
4945
5920
|
exports.findVerificationMethod = findVerificationMethod;
|
|
4946
5921
|
exports.generateAuthHeader = generateAuthHeader;
|
|
4947
5922
|
exports.generateAuthJson = generateAuthJson;
|
|
4948
5923
|
exports.generateHttpSignatureHeaders = generateHttpSignatureHeaders;
|
|
4949
5924
|
exports.generateImProof = generateImProof;
|
|
5925
|
+
exports.generateRfc9421OriginProof = generateRfc9421OriginProof;
|
|
4950
5926
|
exports.generateW3cProof = generateW3cProof;
|
|
4951
5927
|
exports.httpSignatures = httpSignatures;
|
|
4952
5928
|
exports.isAssertionMethodAuthorized = isAssertionMethodAuthorized;
|
|
4953
5929
|
exports.isAuthenticationAuthorized = isAuthenticationAuthorized;
|
|
4954
5930
|
exports.legacyAuth = legacyAuth;
|
|
4955
5931
|
exports.normalizeHandle = normalizeHandle;
|
|
5932
|
+
exports.parseDeviceManifest = parseDeviceManifest;
|
|
4956
5933
|
exports.parseImSignatureInput = parseImSignatureInput;
|
|
4957
5934
|
exports.parseLegacyAuthHeader = extractAuthHeaderParts;
|
|
4958
5935
|
exports.parseSignatureMetadata = extractSignatureMetadata;
|
|
4959
5936
|
exports.parseUri = parseWbaUri;
|
|
4960
5937
|
exports.parseWbaUri = parseWbaUri;
|
|
4961
5938
|
exports.proof = proof;
|
|
5939
|
+
exports.quoteRfc3986Unreserved = quoteRfc3986Unreserved;
|
|
5940
|
+
exports.removeDeviceFromDidDocument = removeDeviceFromDidDocument;
|
|
4962
5941
|
exports.resolveDidDocument = resolveDidDocument;
|
|
4963
5942
|
exports.resolveDidWbaDocument = resolveDidWbaDocument;
|
|
4964
5943
|
exports.resolveHandle = resolveHandle;
|
|
4965
5944
|
exports.resolveHandleFromUri = resolveHandleFromUri;
|
|
4966
5945
|
exports.resolveUri = resolveHandleFromUri;
|
|
5946
|
+
exports.updateDeviceInDidDocument = updateDeviceInDidDocument;
|
|
5947
|
+
exports.validateDeviceManifest = validateDeviceManifest;
|
|
4967
5948
|
exports.validateDidBinding = validateDidDocumentBinding;
|
|
4968
5949
|
exports.validateDidDocumentBinding = validateDidDocumentBinding;
|
|
4969
5950
|
exports.validateHandle = validateHandle;
|
|
@@ -4983,6 +5964,7 @@ exports.verifyLegacyAuthHeader = verifyAuthHeaderSignature;
|
|
|
4983
5964
|
exports.verifyLegacyAuthPayload = verifyAuthJsonSignature;
|
|
4984
5965
|
exports.verifyProof = verifyW3cProof;
|
|
4985
5966
|
exports.verifyProofDetailed = verifyW3cProofDetailed;
|
|
5967
|
+
exports.verifyRfc9421OriginProof = verifyRfc9421OriginProof;
|
|
4986
5968
|
exports.verifySignatureHeaders = verifyHttpMessageSignature;
|
|
4987
5969
|
exports.verifyW3cProof = verifyW3cProof;
|
|
4988
5970
|
exports.verifyW3cProofDetailed = verifyW3cProofDetailed;
|