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