@metalabel/dfos-protocol 0.26.0 → 0.27.0
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/dist/chain/index.d.ts +68 -3
- package/dist/chain/index.js +18 -4
- package/dist/{chunk-PGFHCBGH.js → chunk-6HVYO5OS.js} +3 -0
- package/dist/{chunk-3USIENKC.js → chunk-Q376VG5Z.js} +266 -2
- package/dist/credentials/index.d.ts +1 -1
- package/dist/credentials/index.js +1 -1
- package/dist/{dfos-credential-CAYCqUCP.d.ts → dfos-credential-DFZRl0FD.d.ts} +37 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +18 -4
- package/package.json +1 -1
package/dist/chain/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { I as IdentityOperation,
|
|
2
|
-
export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, g as CreditClaimPayload, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as
|
|
1
|
+
import { I as IdentityOperation, t as Signer, v as VerifiedIdentity, S as ServiceEntry, d as ContentOperation, R as RevocationChecker, e as CountersignPayload, a as ArtifactPayload } from '../dfos-credential-DFZRl0FD.js';
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, C as CONTENT_ID_ANCHOR_RE, g as CreditClaimPayload, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MAX_SIGN_REQUEST_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_SIZE, p as MultikeyPublicKey, q as RevocationPayload, r as ServicesArray, s as SignRequestPayload, B as parseProtocolTimestampUnix } from '../dfos-credential-DFZRl0FD.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
|
|
5
5
|
/** Ed25519 public key multicodec value */
|
|
@@ -437,4 +437,69 @@ declare const verifyCreditEntry: (entry: CreditEntry, options: {
|
|
|
437
437
|
contentId: string;
|
|
438
438
|
}) => Promise<VerifiedCreditEntry>;
|
|
439
439
|
|
|
440
|
-
|
|
440
|
+
interface VerifiedSignRequest {
|
|
441
|
+
/** Requester DID */
|
|
442
|
+
did: string;
|
|
443
|
+
/** The one identity being asked to sign */
|
|
444
|
+
subject: string;
|
|
445
|
+
/** JWS typ the produced artifact must carry */
|
|
446
|
+
payloadTyp: string;
|
|
447
|
+
/** Exact decoded target bytes; never re-serialized by the envelope path */
|
|
448
|
+
payloadBytes: Uint8Array;
|
|
449
|
+
createdAt: string;
|
|
450
|
+
expiresAt: string;
|
|
451
|
+
/** kid from the JWS header */
|
|
452
|
+
signerKeyId: string;
|
|
453
|
+
/** CID of the sign-request payload */
|
|
454
|
+
requestCID: string;
|
|
455
|
+
}
|
|
456
|
+
type SignRequestFailureReason = 'invalid' | 'unverifiable';
|
|
457
|
+
/**
|
|
458
|
+
* Thrown by sign-request verification and canonical-payload refusal paths.
|
|
459
|
+
* Consumers branch on `reason`, never on diagnostic message text.
|
|
460
|
+
*/
|
|
461
|
+
declare class SignRequestVerifyError extends Error {
|
|
462
|
+
readonly reason: SignRequestFailureReason;
|
|
463
|
+
constructor(reason: SignRequestFailureReason, message: string);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Build a sign-request envelope around exact target bytes.
|
|
467
|
+
*
|
|
468
|
+
* The kid is derived from `did` + `keyId`, so a requester mismatch is
|
|
469
|
+
* unrepresentable on the build path. Both timestamps, including overrides, are
|
|
470
|
+
* floor-normalized to whole seconds before signing.
|
|
471
|
+
*/
|
|
472
|
+
declare const buildSignRequest: (input: {
|
|
473
|
+
did: string;
|
|
474
|
+
subject: string;
|
|
475
|
+
payloadTyp: string;
|
|
476
|
+
payload: Uint8Array;
|
|
477
|
+
expiresAt: string;
|
|
478
|
+
createdAt?: string;
|
|
479
|
+
signer: Signer;
|
|
480
|
+
keyId: string;
|
|
481
|
+
}) => Promise<{
|
|
482
|
+
jwsToken: string;
|
|
483
|
+
requestCID: string;
|
|
484
|
+
}>;
|
|
485
|
+
/**
|
|
486
|
+
* Verify a sign-request envelope in SIGNING.md's exact 1–9 order.
|
|
487
|
+
*
|
|
488
|
+
* `resolveIdentity` supplies CURRENT identity state. A missing identity or
|
|
489
|
+
* resolver failure is `unverifiable`; a deleted identity, missing current key,
|
|
490
|
+
* or any checked-and-failed condition is `invalid`.
|
|
491
|
+
*/
|
|
492
|
+
declare const verifySignRequest: (jwsToken: string, options: {
|
|
493
|
+
resolveIdentity: (did: string) => Promise<VerifiedIdentity | undefined>;
|
|
494
|
+
/** Unix milliseconds; defaults to Date.now() */
|
|
495
|
+
now?: number;
|
|
496
|
+
}) => Promise<VerifiedSignRequest>;
|
|
497
|
+
/**
|
|
498
|
+
* Assert that exact target bytes are the unique canonical representation the
|
|
499
|
+
* signer understands. SIGNING 0.1 implements only `did:dfos:credit-claim`.
|
|
500
|
+
*/
|
|
501
|
+
declare const assertCanonicalSignRequestPayload: (payloadTyp: string, payloadBytes: Uint8Array, context: {
|
|
502
|
+
subject: string;
|
|
503
|
+
}) => void;
|
|
504
|
+
|
|
505
|
+
export { type AnchorKind, ArtifactPayload, ContentOperation, CountersignPayload, type CreditClaimFailureReason, CreditClaimVerifyError, type CreditEntry, type CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, IdentityOperation, RECOGNIZED_SERVICE_TYPES, ServiceEntry, type SignRequestFailureReason, SignRequestVerifyError, Signer, type VerifiedArtifact, type VerifiedContentChain, type VerifiedCountersignature, type VerifiedCreditClaim, type VerifiedCreditEntry, VerifiedIdentity, type VerifiedRevocation, type VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest };
|
package/dist/chain/index.js
CHANGED
|
@@ -13,14 +13,20 @@ import {
|
|
|
13
13
|
MAX_OPERATION_SIZE,
|
|
14
14
|
MAX_SERVICES_ENTRIES,
|
|
15
15
|
MAX_SERVICES_PAYLOAD_SIZE,
|
|
16
|
+
MAX_SIGN_REQUEST_PAYLOAD_SIZE,
|
|
17
|
+
MAX_SIGN_REQUEST_SIZE,
|
|
16
18
|
MultikeyPublicKey,
|
|
17
19
|
RECOGNIZED_SERVICE_TYPES,
|
|
18
20
|
RevocationPayload,
|
|
19
21
|
ServiceEntry,
|
|
20
22
|
ServicesArray,
|
|
23
|
+
SignRequestPayload,
|
|
24
|
+
SignRequestVerifyError,
|
|
21
25
|
VerifiedIdentity,
|
|
22
26
|
anchorsByLabel,
|
|
27
|
+
assertCanonicalSignRequestPayload,
|
|
23
28
|
assertServicesWithinCap,
|
|
29
|
+
buildSignRequest,
|
|
24
30
|
classifyAnchor,
|
|
25
31
|
deriveChainIdentifier,
|
|
26
32
|
deriveContentId,
|
|
@@ -41,14 +47,15 @@ import {
|
|
|
41
47
|
verifyCreditEntry,
|
|
42
48
|
verifyIdentityChain,
|
|
43
49
|
verifyIdentityExtensionFromTrustedState,
|
|
44
|
-
verifyRevocation
|
|
45
|
-
|
|
50
|
+
verifyRevocation,
|
|
51
|
+
verifySignRequest
|
|
52
|
+
} from "../chunk-Q376VG5Z.js";
|
|
46
53
|
import {
|
|
47
54
|
ED25519_PRIV_MULTICODEC,
|
|
48
55
|
ED25519_PUB_MULTICODEC,
|
|
49
56
|
decodeMultikey,
|
|
50
57
|
encodeEd25519Multikey
|
|
51
|
-
} from "../chunk-
|
|
58
|
+
} from "../chunk-6HVYO5OS.js";
|
|
52
59
|
import "../chunk-4QQ5HK5M.js";
|
|
53
60
|
export {
|
|
54
61
|
ARTIFACT_CID_ANCHOR_RE,
|
|
@@ -67,14 +74,20 @@ export {
|
|
|
67
74
|
MAX_OPERATION_SIZE,
|
|
68
75
|
MAX_SERVICES_ENTRIES,
|
|
69
76
|
MAX_SERVICES_PAYLOAD_SIZE,
|
|
77
|
+
MAX_SIGN_REQUEST_PAYLOAD_SIZE,
|
|
78
|
+
MAX_SIGN_REQUEST_SIZE,
|
|
70
79
|
MultikeyPublicKey,
|
|
71
80
|
RECOGNIZED_SERVICE_TYPES,
|
|
72
81
|
RevocationPayload,
|
|
73
82
|
ServiceEntry,
|
|
74
83
|
ServicesArray,
|
|
84
|
+
SignRequestPayload,
|
|
85
|
+
SignRequestVerifyError,
|
|
75
86
|
VerifiedIdentity,
|
|
76
87
|
anchorsByLabel,
|
|
88
|
+
assertCanonicalSignRequestPayload,
|
|
77
89
|
assertServicesWithinCap,
|
|
90
|
+
buildSignRequest,
|
|
78
91
|
classifyAnchor,
|
|
79
92
|
decodeMultikey,
|
|
80
93
|
deriveChainIdentifier,
|
|
@@ -97,5 +110,6 @@ export {
|
|
|
97
110
|
verifyCreditEntry,
|
|
98
111
|
verifyIdentityChain,
|
|
99
112
|
verifyIdentityExtensionFromTrustedState,
|
|
100
|
-
verifyRevocation
|
|
113
|
+
verifyRevocation,
|
|
114
|
+
verifySignRequest
|
|
101
115
|
};
|
|
@@ -323,6 +323,9 @@ var isAttenuated = (parentAtt, childAtt) => {
|
|
|
323
323
|
if (childRes.type === "chain" && parentRes.type === "chain") {
|
|
324
324
|
return childRes.id === parentRes.id;
|
|
325
325
|
}
|
|
326
|
+
if (childRes.type !== "chain" && parentRes.type !== "chain") {
|
|
327
|
+
return childEntry.resource === parentEntry.resource;
|
|
328
|
+
}
|
|
326
329
|
return false;
|
|
327
330
|
});
|
|
328
331
|
});
|
|
@@ -5,8 +5,11 @@ import {
|
|
|
5
5
|
matchesResource,
|
|
6
6
|
verifyDFOSCredential,
|
|
7
7
|
verifyDelegationChain
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-6HVYO5OS.js";
|
|
9
9
|
import {
|
|
10
|
+
assertJwsProfile,
|
|
11
|
+
base64urlDecode,
|
|
12
|
+
base64urlEncode,
|
|
10
13
|
createJws,
|
|
11
14
|
dagCborCanonicalEncode,
|
|
12
15
|
decodeJwsUnsafe,
|
|
@@ -174,6 +177,18 @@ var CreditClaimPayload = z.looseObject({
|
|
|
174
177
|
createdAt: Iso8601,
|
|
175
178
|
asOfDocumentCID: CIDString.min(1, "asOfDocumentCID must be non-empty when present").optional()
|
|
176
179
|
});
|
|
180
|
+
var MAX_SIGN_REQUEST_SIZE = 8192;
|
|
181
|
+
var MAX_SIGN_REQUEST_PAYLOAD_SIZE = 4096;
|
|
182
|
+
var SignRequestPayload = z.looseObject({
|
|
183
|
+
version: z.literal(1),
|
|
184
|
+
type: z.literal("sign-request"),
|
|
185
|
+
did: z.string().regex(/^did:/, "did must be a DID (did: prefix)"),
|
|
186
|
+
subject: z.string().regex(/^did:/, "subject must be a DID (did: prefix)"),
|
|
187
|
+
payloadTyp: z.string().min(1),
|
|
188
|
+
payload: z.string().min(1),
|
|
189
|
+
createdAt: Iso8601,
|
|
190
|
+
expiresAt: Iso8601
|
|
191
|
+
});
|
|
177
192
|
|
|
178
193
|
// src/chain/derivation.ts
|
|
179
194
|
var deriveChainIdentifier = (cidBytes, prefix) => {
|
|
@@ -1045,6 +1060,248 @@ var verifyCreditEntry = async (entry, options) => {
|
|
|
1045
1060
|
};
|
|
1046
1061
|
};
|
|
1047
1062
|
|
|
1063
|
+
// src/chain/sign-request.ts
|
|
1064
|
+
var SignRequestVerifyError = class extends Error {
|
|
1065
|
+
reason;
|
|
1066
|
+
constructor(reason, message) {
|
|
1067
|
+
super(message);
|
|
1068
|
+
this.name = "SignRequestVerifyError";
|
|
1069
|
+
this.reason = reason;
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
var invalid2 = (message) => new SignRequestVerifyError("invalid", message);
|
|
1073
|
+
var unverifiable2 = (message) => new SignRequestVerifyError("unverifiable", message);
|
|
1074
|
+
var normalizeSignRequestTimestamp = (value, field) => {
|
|
1075
|
+
if (value === void 0) {
|
|
1076
|
+
return (/* @__PURE__ */ new Date()).toISOString().replace(/\d{3}Z$/, "000Z");
|
|
1077
|
+
}
|
|
1078
|
+
const ms = Date.parse(value);
|
|
1079
|
+
if (Number.isNaN(ms)) {
|
|
1080
|
+
throw new Error(`invalid sign request payload: unparseable ${field}: ${value}`);
|
|
1081
|
+
}
|
|
1082
|
+
return new Date(Math.floor(ms / 1e3) * 1e3).toISOString();
|
|
1083
|
+
};
|
|
1084
|
+
var assertTemporalWindow = (createdAt, expiresAt, makeError) => {
|
|
1085
|
+
const createdMs = Date.parse(createdAt);
|
|
1086
|
+
const expiresMs = Date.parse(expiresAt);
|
|
1087
|
+
if (expiresMs <= createdMs) {
|
|
1088
|
+
throw makeError("sign request expiresAt must be strictly after createdAt");
|
|
1089
|
+
}
|
|
1090
|
+
if (expiresMs - createdMs > 6048e5) {
|
|
1091
|
+
throw makeError("sign request validity window exceeds 604800 seconds");
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
var decodeTargetPayload = (encoded) => {
|
|
1095
|
+
if (!/^[A-Za-z0-9_-]+$/.test(encoded)) {
|
|
1096
|
+
throw invalid2("sign request payload must be unpadded base64url");
|
|
1097
|
+
}
|
|
1098
|
+
let decoded;
|
|
1099
|
+
try {
|
|
1100
|
+
decoded = base64urlDecode(encoded);
|
|
1101
|
+
} catch {
|
|
1102
|
+
throw invalid2("sign request payload is not valid base64url");
|
|
1103
|
+
}
|
|
1104
|
+
if (base64urlEncode(decoded) !== encoded) {
|
|
1105
|
+
throw invalid2("sign request payload is not canonical unpadded base64url");
|
|
1106
|
+
}
|
|
1107
|
+
if (decoded.length === 0) {
|
|
1108
|
+
throw invalid2("sign request payload must decode to non-empty bytes");
|
|
1109
|
+
}
|
|
1110
|
+
if (decoded.length > MAX_SIGN_REQUEST_PAYLOAD_SIZE) {
|
|
1111
|
+
throw invalid2(
|
|
1112
|
+
`sign request payload exceeds max decoded size: ${decoded.length} > ${MAX_SIGN_REQUEST_PAYLOAD_SIZE}`
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
return decoded;
|
|
1116
|
+
};
|
|
1117
|
+
var resolveCurrentKey = (identity, kid) => {
|
|
1118
|
+
const hashIdx = kid.indexOf("#");
|
|
1119
|
+
if (hashIdx < 0) throw invalid2("sign request kid must be a DID URL");
|
|
1120
|
+
const keyId = kid.substring(hashIdx + 1);
|
|
1121
|
+
const key = [...identity.authKeys, ...identity.assertKeys, ...identity.controllerKeys].find(
|
|
1122
|
+
(candidate) => candidate.id === keyId
|
|
1123
|
+
);
|
|
1124
|
+
if (!key) throw invalid2(`key ${keyId} not found on current identity ${identity.did}`);
|
|
1125
|
+
try {
|
|
1126
|
+
return decodeMultikey(key.publicKeyMultibase).keyBytes;
|
|
1127
|
+
} catch {
|
|
1128
|
+
throw invalid2(`key ${keyId} on identity ${identity.did} is not a valid Ed25519 multikey`);
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
var buildSignRequest = async (input) => {
|
|
1132
|
+
if (input.payload.length === 0) {
|
|
1133
|
+
throw new Error("invalid sign request payload: target payload must be non-empty");
|
|
1134
|
+
}
|
|
1135
|
+
if (input.payload.length > MAX_SIGN_REQUEST_PAYLOAD_SIZE) {
|
|
1136
|
+
throw new Error(
|
|
1137
|
+
`sign request payload exceeds max decoded size: ${input.payload.length} > ${MAX_SIGN_REQUEST_PAYLOAD_SIZE}`
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
const createdAt = normalizeSignRequestTimestamp(input.createdAt, "createdAt");
|
|
1141
|
+
const expiresAt = normalizeSignRequestTimestamp(input.expiresAt, "expiresAt");
|
|
1142
|
+
assertTemporalWindow(createdAt, expiresAt, (message) => new Error(message));
|
|
1143
|
+
const payload = {
|
|
1144
|
+
version: 1,
|
|
1145
|
+
type: "sign-request",
|
|
1146
|
+
did: input.did,
|
|
1147
|
+
subject: input.subject,
|
|
1148
|
+
payloadTyp: input.payloadTyp,
|
|
1149
|
+
payload: base64urlEncode(input.payload),
|
|
1150
|
+
createdAt,
|
|
1151
|
+
expiresAt
|
|
1152
|
+
};
|
|
1153
|
+
const parsed = SignRequestPayload.safeParse(payload);
|
|
1154
|
+
if (!parsed.success) {
|
|
1155
|
+
const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
|
|
1156
|
+
throw new Error(`invalid sign request payload: ${messages}`);
|
|
1157
|
+
}
|
|
1158
|
+
const encoded = await dagCborCanonicalEncode(payload);
|
|
1159
|
+
const requestCID = encoded.cid.toString();
|
|
1160
|
+
const jwsToken = await createJws({
|
|
1161
|
+
header: {
|
|
1162
|
+
alg: "EdDSA",
|
|
1163
|
+
typ: "did:dfos:sign-request",
|
|
1164
|
+
kid: `${input.did}#${input.keyId}`,
|
|
1165
|
+
cid: requestCID
|
|
1166
|
+
},
|
|
1167
|
+
payload,
|
|
1168
|
+
sign: input.signer
|
|
1169
|
+
});
|
|
1170
|
+
if (new TextEncoder().encode(jwsToken).length > MAX_SIGN_REQUEST_SIZE) {
|
|
1171
|
+
throw new Error(
|
|
1172
|
+
`sign request exceeds max size: ${new TextEncoder().encode(jwsToken).length} > ${MAX_SIGN_REQUEST_SIZE}`
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
return { jwsToken, requestCID };
|
|
1176
|
+
};
|
|
1177
|
+
var verifySignRequest = async (jwsToken, options) => {
|
|
1178
|
+
try {
|
|
1179
|
+
const tokenSize = new TextEncoder().encode(jwsToken).length;
|
|
1180
|
+
if (tokenSize > MAX_SIGN_REQUEST_SIZE) {
|
|
1181
|
+
throw invalid2(`sign request exceeds max size: ${tokenSize} > ${MAX_SIGN_REQUEST_SIZE}`);
|
|
1182
|
+
}
|
|
1183
|
+
const decoded = decodeJwsUnsafe(jwsToken);
|
|
1184
|
+
if (!decoded) throw invalid2("failed to decode sign request JWS");
|
|
1185
|
+
const rawHeader = decoded.header;
|
|
1186
|
+
if (typeof rawHeader !== "object" || rawHeader === null || Array.isArray(rawHeader)) {
|
|
1187
|
+
throw invalid2("sign request protected header must be an object");
|
|
1188
|
+
}
|
|
1189
|
+
assertJwsProfile(rawHeader, invalid2);
|
|
1190
|
+
if (typeof rawHeader["typ"] !== "string" || typeof rawHeader["kid"] !== "string") {
|
|
1191
|
+
throw invalid2("sign request header must carry a string typ and kid");
|
|
1192
|
+
}
|
|
1193
|
+
if (decoded.header.typ !== "did:dfos:sign-request") {
|
|
1194
|
+
throw invalid2(`invalid sign request typ: ${decoded.header.typ}`);
|
|
1195
|
+
}
|
|
1196
|
+
const parsed = SignRequestPayload.safeParse(decoded.payload);
|
|
1197
|
+
if (!parsed.success) {
|
|
1198
|
+
const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
|
|
1199
|
+
throw invalid2(`invalid sign request payload: ${messages}`);
|
|
1200
|
+
}
|
|
1201
|
+
const payload = parsed.data;
|
|
1202
|
+
const payloadBytes = decodeTargetPayload(payload.payload);
|
|
1203
|
+
const kid = decoded.header.kid;
|
|
1204
|
+
const hashIdx = kid.indexOf("#");
|
|
1205
|
+
if (hashIdx < 0) throw invalid2("sign request kid must be a DID URL");
|
|
1206
|
+
if (kid.substring(0, hashIdx) !== payload.did) {
|
|
1207
|
+
throw invalid2("sign request kid DID does not match payload did");
|
|
1208
|
+
}
|
|
1209
|
+
let identity;
|
|
1210
|
+
try {
|
|
1211
|
+
identity = await options.resolveIdentity(payload.did);
|
|
1212
|
+
} catch (error) {
|
|
1213
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1214
|
+
throw unverifiable2(`could not resolve requester identity ${payload.did}: ${detail}`);
|
|
1215
|
+
}
|
|
1216
|
+
if (!identity) throw unverifiable2(`requester identity not found: ${payload.did}`);
|
|
1217
|
+
if (identity.isDeleted) throw invalid2(`requester identity is deleted: ${payload.did}`);
|
|
1218
|
+
const publicKey = resolveCurrentKey(identity, kid);
|
|
1219
|
+
try {
|
|
1220
|
+
verifyJws({ token: jwsToken, publicKey });
|
|
1221
|
+
} catch {
|
|
1222
|
+
throw invalid2("invalid sign request signature");
|
|
1223
|
+
}
|
|
1224
|
+
let encoded;
|
|
1225
|
+
try {
|
|
1226
|
+
encoded = await dagCborCanonicalEncode(payload);
|
|
1227
|
+
} catch (error) {
|
|
1228
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1229
|
+
throw invalid2(`failed to derive sign request CID: ${detail}`);
|
|
1230
|
+
}
|
|
1231
|
+
const requestCID = encoded.cid.toString();
|
|
1232
|
+
if (decoded.header.cid !== requestCID) throw invalid2("sign request cid mismatch");
|
|
1233
|
+
assertTemporalWindow(payload.createdAt, payload.expiresAt, invalid2);
|
|
1234
|
+
if ((options.now ?? Date.now()) >= Date.parse(payload.expiresAt)) {
|
|
1235
|
+
throw invalid2("sign request is expired");
|
|
1236
|
+
}
|
|
1237
|
+
return {
|
|
1238
|
+
did: payload.did,
|
|
1239
|
+
subject: payload.subject,
|
|
1240
|
+
payloadTyp: payload.payloadTyp,
|
|
1241
|
+
payloadBytes,
|
|
1242
|
+
createdAt: payload.createdAt,
|
|
1243
|
+
expiresAt: payload.expiresAt,
|
|
1244
|
+
signerKeyId: kid,
|
|
1245
|
+
requestCID
|
|
1246
|
+
};
|
|
1247
|
+
} catch (error) {
|
|
1248
|
+
if (error instanceof SignRequestVerifyError) throw error;
|
|
1249
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
1250
|
+
throw unverifiable2(`sign request verification could not complete: ${detail}`);
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
var assertCanonicalSignRequestPayload = (payloadTyp, payloadBytes, context) => {
|
|
1254
|
+
if (payloadTyp !== "did:dfos:credit-claim") {
|
|
1255
|
+
throw invalid2(`unsupported sign request payloadTyp: ${payloadTyp}`);
|
|
1256
|
+
}
|
|
1257
|
+
let source;
|
|
1258
|
+
try {
|
|
1259
|
+
source = new TextDecoder("utf-8", { fatal: true }).decode(payloadBytes);
|
|
1260
|
+
} catch {
|
|
1261
|
+
throw invalid2("sign request payload is not valid UTF-8 JSON");
|
|
1262
|
+
}
|
|
1263
|
+
if (source.startsWith("\uFEFF")) {
|
|
1264
|
+
throw invalid2("sign request payload must not carry a UTF-8 BOM");
|
|
1265
|
+
}
|
|
1266
|
+
let raw;
|
|
1267
|
+
try {
|
|
1268
|
+
raw = JSON.parse(source);
|
|
1269
|
+
} catch {
|
|
1270
|
+
throw invalid2("sign request payload is not valid JSON");
|
|
1271
|
+
}
|
|
1272
|
+
const parsed = CreditClaimPayload.strict().safeParse(raw);
|
|
1273
|
+
if (!parsed.success) {
|
|
1274
|
+
const messages = parsed.error.issues.map((issue) => issue.message).join(", ");
|
|
1275
|
+
throw invalid2(`invalid canonical credit-claim payload: ${messages}`);
|
|
1276
|
+
}
|
|
1277
|
+
const payload = parsed.data;
|
|
1278
|
+
if (!payload.createdAt.endsWith(".000Z")) {
|
|
1279
|
+
throw invalid2("credit-claim createdAt must be normalized to whole seconds");
|
|
1280
|
+
}
|
|
1281
|
+
if (payload.asOfDocumentCID !== void 0 && payload.asOfDocumentCID.length === 0) {
|
|
1282
|
+
throw invalid2("credit-claim asOfDocumentCID must be non-empty when present");
|
|
1283
|
+
}
|
|
1284
|
+
if (payload.did !== context.subject) {
|
|
1285
|
+
throw invalid2("credit-claim payload did does not match sign request subject");
|
|
1286
|
+
}
|
|
1287
|
+
if (/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/.test(payload.role)) {
|
|
1288
|
+
throw invalid2("credit-claim role is not well-formed unicode (lone surrogate)");
|
|
1289
|
+
}
|
|
1290
|
+
const canonical = JSON.stringify({
|
|
1291
|
+
version: payload.version,
|
|
1292
|
+
type: payload.type,
|
|
1293
|
+
contentId: payload.contentId,
|
|
1294
|
+
did: payload.did,
|
|
1295
|
+
role: payload.role,
|
|
1296
|
+
createdAt: payload.createdAt,
|
|
1297
|
+
...payload.asOfDocumentCID !== void 0 ? { asOfDocumentCID: payload.asOfDocumentCID } : {}
|
|
1298
|
+
});
|
|
1299
|
+
const canonicalBytes = new TextEncoder().encode(canonical);
|
|
1300
|
+
if (canonicalBytes.length !== payloadBytes.length || !canonicalBytes.every((byte, index) => byte === payloadBytes[index])) {
|
|
1301
|
+
throw invalid2("credit-claim payload bytes are not canonical");
|
|
1302
|
+
}
|
|
1303
|
+
};
|
|
1304
|
+
|
|
1048
1305
|
export {
|
|
1049
1306
|
MAX_SERVICES_ENTRIES,
|
|
1050
1307
|
MAX_SERVICES_PAYLOAD_SIZE,
|
|
@@ -1065,6 +1322,9 @@ export {
|
|
|
1065
1322
|
RevocationPayload,
|
|
1066
1323
|
MAX_CREDIT_CLAIM_SIZE,
|
|
1067
1324
|
CreditClaimPayload,
|
|
1325
|
+
MAX_SIGN_REQUEST_SIZE,
|
|
1326
|
+
MAX_SIGN_REQUEST_PAYLOAD_SIZE,
|
|
1327
|
+
SignRequestPayload,
|
|
1068
1328
|
deriveChainIdentifier,
|
|
1069
1329
|
deriveContentId,
|
|
1070
1330
|
assertServicesWithinCap,
|
|
@@ -1088,5 +1348,9 @@ export {
|
|
|
1088
1348
|
CreditClaimVerifyError,
|
|
1089
1349
|
signCreditClaim,
|
|
1090
1350
|
verifyCreditClaim,
|
|
1091
|
-
verifyCreditEntry
|
|
1351
|
+
verifyCreditEntry,
|
|
1352
|
+
SignRequestVerifyError,
|
|
1353
|
+
buildSignRequest,
|
|
1354
|
+
verifySignRequest,
|
|
1355
|
+
assertCanonicalSignRequestPayload
|
|
1092
1356
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { b as Attenuation, c as AuthTokenClaims, f as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as RevocationChecker, V as VerifiedDFOSCredential,
|
|
1
|
+
export { b as Attenuation, c as AuthTokenClaims, f as CredentialVerificationError, D as DFOSCredentialPayload, i as MAX_CREDENTIAL_SIZE, R as RevocationChecker, V as VerifiedDFOSCredential, u as VerifiedDelegationChain, w as createDFOSCredential, x as decodeDFOSCredentialUnsafe, y as isAttenuated, z as matchesResource, E as verifyDFOSCredential, F as verifyDelegationChain } from '../dfos-credential-DFZRl0FD.js';
|
|
2
2
|
import 'zod';
|
|
3
3
|
|
|
4
4
|
interface AuthTokenCreateOptions {
|
|
@@ -295,6 +295,37 @@ declare const CreditClaimPayload: z.ZodObject<{
|
|
|
295
295
|
asOfDocumentCID: z.ZodOptional<z.ZodString>;
|
|
296
296
|
}, z.core.$loose>;
|
|
297
297
|
type CreditClaimPayload = z.infer<typeof CreditClaimPayload>;
|
|
298
|
+
/**
|
|
299
|
+
* Max byte length of a sign-request JWS token. Checked before any decode on the
|
|
300
|
+
* verify path and after construction on the build path. VALIDITY-determining:
|
|
301
|
+
* MUST match maxSignRequestSize in the Go reference.
|
|
302
|
+
*/
|
|
303
|
+
declare const MAX_SIGN_REQUEST_SIZE = 8192;
|
|
304
|
+
/**
|
|
305
|
+
* Max decoded byte length of the exact target payload carried by a sign request.
|
|
306
|
+
* This is the single aggregate cap on target bytes; there are no per-field caps.
|
|
307
|
+
* VALIDITY-determining: MUST match maxSignRequestPayloadSize in Go.
|
|
308
|
+
*/
|
|
309
|
+
declare const MAX_SIGN_REQUEST_PAYLOAD_SIZE = 4096;
|
|
310
|
+
/**
|
|
311
|
+
* Sign request: a requester's signed ask that one subject sign exact target bytes
|
|
312
|
+
* as one named artifact type before a bounded deadline.
|
|
313
|
+
*
|
|
314
|
+
* Unknown envelope fields are preserved-and-ignored, matching every other wire
|
|
315
|
+
* payload in this file. The signer-side target-payload check is deliberately
|
|
316
|
+
* strict instead: a signer refuses fields it cannot render (see SIGNING.md).
|
|
317
|
+
*/
|
|
318
|
+
declare const SignRequestPayload: z.ZodObject<{
|
|
319
|
+
version: z.ZodLiteral<1>;
|
|
320
|
+
type: z.ZodLiteral<"sign-request">;
|
|
321
|
+
did: z.ZodString;
|
|
322
|
+
subject: z.ZodString;
|
|
323
|
+
payloadTyp: z.ZodString;
|
|
324
|
+
payload: z.ZodString;
|
|
325
|
+
createdAt: z.ZodISODateTime;
|
|
326
|
+
expiresAt: z.ZodISODateTime;
|
|
327
|
+
}, z.core.$loose>;
|
|
328
|
+
type SignRequestPayload = z.infer<typeof SignRequestPayload>;
|
|
298
329
|
|
|
299
330
|
/**
|
|
300
331
|
* Max byte length of a credential JWS token — the credential's analog of
|
|
@@ -462,6 +493,11 @@ declare const verifyDelegationChain: (credential: VerifiedDFOSCredential, option
|
|
|
462
493
|
* - `chain:X` covered by `chain:*` (narrowing from wildcard — valid)
|
|
463
494
|
* - `chain:*` covered by `chain:*` (exact match)
|
|
464
495
|
* - `chain:*` NOT covered by `chain:X` (widening — invalid)
|
|
496
|
+
* - Non-`chain` types (`mailbox:<id>`, and any form a future capability
|
|
497
|
+
* registers): exact byte equality of the full resource string, nothing else.
|
|
498
|
+
* The wildcard is a `chain:`-only concept — a literal `*` id in any other
|
|
499
|
+
* type is an ordinary id covering only itself — and coverage never crosses
|
|
500
|
+
* resource types. See CREDENTIALS.md "Resource Types".
|
|
465
501
|
* - Actions: child action set must be a subset of parent action set
|
|
466
502
|
*/
|
|
467
503
|
declare const isAttenuated: (parentAtt: Attenuation[], childAtt: Attenuation[]) => boolean;
|
|
@@ -490,4 +526,4 @@ declare class CredentialVerificationError extends Error {
|
|
|
490
526
|
constructor(message: string);
|
|
491
527
|
}
|
|
492
528
|
|
|
493
|
-
export { ARTIFACT_CID_ANCHOR_RE as A, CONTENT_ID_ANCHOR_RE as C, DFOSCredentialPayload as D, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, type RevocationChecker as R, ServiceEntry as S, type VerifiedDFOSCredential as V, ArtifactPayload as a, Attenuation as b, AuthTokenClaims as c, ContentOperation as d, CountersignPayload as e, CredentialVerificationError as f, CreditClaimPayload as g, Iso8601 as h, MAX_CREDENTIAL_SIZE as i, MAX_CREDIT_CLAIM_SIZE as j, MAX_OPERATION_SIZE as k, MAX_SERVICES_ENTRIES as l, MAX_SERVICES_PAYLOAD_SIZE as m,
|
|
529
|
+
export { ARTIFACT_CID_ANCHOR_RE as A, parseProtocolTimestampUnix as B, CONTENT_ID_ANCHOR_RE as C, DFOSCredentialPayload as D, verifyDFOSCredential as E, verifyDelegationChain as F, IdentityOperation as I, MAX_ARTIFACT_PAYLOAD_SIZE as M, type RevocationChecker as R, ServiceEntry as S, type VerifiedDFOSCredential as V, ArtifactPayload as a, Attenuation as b, AuthTokenClaims as c, ContentOperation as d, CountersignPayload as e, CredentialVerificationError as f, CreditClaimPayload as g, Iso8601 as h, MAX_CREDENTIAL_SIZE as i, MAX_CREDIT_CLAIM_SIZE as j, MAX_OPERATION_SIZE as k, MAX_SERVICES_ENTRIES as l, MAX_SERVICES_PAYLOAD_SIZE as m, MAX_SIGN_REQUEST_PAYLOAD_SIZE as n, MAX_SIGN_REQUEST_SIZE as o, MultikeyPublicKey as p, RevocationPayload as q, ServicesArray as r, SignRequestPayload as s, type Signer as t, type VerifiedDelegationChain as u, VerifiedIdentity as v, createDFOSCredential as w, decodeDFOSCredentialUnsafe as x, isAttenuated as y, matchesResource as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { JwsHeader, JwsVerificationError, JwtClaims, JwtCreateOptions, JwtHeader, JwtVerificationError, JwtVerifyOptions, PrefixedID, assertJwsProfile, base64urlDecode, base64urlEncode, createJws, createJwt, createNewEd25519Keypair, dagCborCanonicalEncode, decodeJwsUnsafe, decodeJwtUnsafe, generateId, generateIdNoPrefix, importEd25519Keypair, isCanonicallyEqual, isValidEd25519Signature, isValidId, normalizedId, parseDagCborCID, signPayloadEd25519, verifyJws, verifyJwt } from './crypto/index.js';
|
|
2
|
-
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, c as AuthTokenClaims, C as CONTENT_ID_ANCHOR_RE, d as ContentOperation, e as CountersignPayload, f as CredentialVerificationError, g as CreditClaimPayload, D as DFOSCredentialPayload, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MultikeyPublicKey, R as RevocationChecker,
|
|
3
|
-
export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, anchorsByLabel, assertServicesWithinCap, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation } from './chain/index.js';
|
|
2
|
+
export { A as ARTIFACT_CID_ANCHOR_RE, a as ArtifactPayload, b as Attenuation, c as AuthTokenClaims, C as CONTENT_ID_ANCHOR_RE, d as ContentOperation, e as CountersignPayload, f as CredentialVerificationError, g as CreditClaimPayload, D as DFOSCredentialPayload, I as IdentityOperation, h as Iso8601, M as MAX_ARTIFACT_PAYLOAD_SIZE, i as MAX_CREDENTIAL_SIZE, j as MAX_CREDIT_CLAIM_SIZE, k as MAX_OPERATION_SIZE, l as MAX_SERVICES_ENTRIES, m as MAX_SERVICES_PAYLOAD_SIZE, n as MAX_SIGN_REQUEST_PAYLOAD_SIZE, o as MAX_SIGN_REQUEST_SIZE, p as MultikeyPublicKey, R as RevocationChecker, q as RevocationPayload, S as ServiceEntry, r as ServicesArray, s as SignRequestPayload, t as Signer, V as VerifiedDFOSCredential, u as VerifiedDelegationChain, v as VerifiedIdentity, w as createDFOSCredential, x as decodeDFOSCredentialUnsafe, y as isAttenuated, z as matchesResource, B as parseProtocolTimestampUnix, E as verifyDFOSCredential, F as verifyDelegationChain } from './dfos-credential-DFZRl0FD.js';
|
|
3
|
+
export { AnchorKind, CreditClaimFailureReason, CreditClaimVerifyError, CreditEntry, CreditEntryState, ED25519_PRIV_MULTICODEC, ED25519_PUB_MULTICODEC, RECOGNIZED_SERVICE_TYPES, SignRequestFailureReason, SignRequestVerifyError, VerifiedArtifact, VerifiedContentChain, VerifiedCountersignature, VerifiedCreditClaim, VerifiedCreditEntry, VerifiedRevocation, VerifiedSignRequest, anchorsByLabel, assertCanonicalSignRequestPayload, assertServicesWithinCap, buildSignRequest, classifyAnchor, decodeMultikey, deriveChainIdentifier, deriveContentId, encodeEd25519Multikey, isRecognizedServiceType, relayEndpoints, signArtifact, signContentOperation, signCountersignature, signCreditClaim, signIdentityOperation, signRevocation, verifyArtifact, verifyContentChain, verifyContentExtensionFromTrustedState, verifyCountersignature, verifyCreditClaim, verifyCreditEntry, verifyIdentityChain, verifyIdentityExtensionFromTrustedState, verifyRevocation, verifySignRequest } from './chain/index.js';
|
|
4
4
|
export { AuthTokenCreateOptions, AuthTokenVerificationError, AuthTokenVerifyOptions, VerifiedAuthToken, createAuthToken, verifyAuthToken } from './credentials/index.js';
|
|
5
5
|
export { FoldOperation, INDEX_V1_SCHEMA, IndexDelta, IndexDocument, IndexEntry, LwwDelta, OrderKey, byteCompare, compareHeadPreference, compareLinear, foldIndexV1, foldLwwMap, linearize } from './fold/index.js';
|
|
6
6
|
import 'multiformats';
|
package/dist/index.js
CHANGED
|
@@ -13,14 +13,20 @@ import {
|
|
|
13
13
|
MAX_OPERATION_SIZE,
|
|
14
14
|
MAX_SERVICES_ENTRIES,
|
|
15
15
|
MAX_SERVICES_PAYLOAD_SIZE,
|
|
16
|
+
MAX_SIGN_REQUEST_PAYLOAD_SIZE,
|
|
17
|
+
MAX_SIGN_REQUEST_SIZE,
|
|
16
18
|
MultikeyPublicKey,
|
|
17
19
|
RECOGNIZED_SERVICE_TYPES,
|
|
18
20
|
RevocationPayload,
|
|
19
21
|
ServiceEntry,
|
|
20
22
|
ServicesArray,
|
|
23
|
+
SignRequestPayload,
|
|
24
|
+
SignRequestVerifyError,
|
|
21
25
|
VerifiedIdentity,
|
|
22
26
|
anchorsByLabel,
|
|
27
|
+
assertCanonicalSignRequestPayload,
|
|
23
28
|
assertServicesWithinCap,
|
|
29
|
+
buildSignRequest,
|
|
24
30
|
classifyAnchor,
|
|
25
31
|
deriveChainIdentifier,
|
|
26
32
|
deriveContentId,
|
|
@@ -41,8 +47,9 @@ import {
|
|
|
41
47
|
verifyCreditEntry,
|
|
42
48
|
verifyIdentityChain,
|
|
43
49
|
verifyIdentityExtensionFromTrustedState,
|
|
44
|
-
verifyRevocation
|
|
45
|
-
|
|
50
|
+
verifyRevocation,
|
|
51
|
+
verifySignRequest
|
|
52
|
+
} from "./chunk-Q376VG5Z.js";
|
|
46
53
|
import {
|
|
47
54
|
Attenuation,
|
|
48
55
|
AuthTokenClaims,
|
|
@@ -62,7 +69,7 @@ import {
|
|
|
62
69
|
verifyAuthToken,
|
|
63
70
|
verifyDFOSCredential,
|
|
64
71
|
verifyDelegationChain
|
|
65
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-6HVYO5OS.js";
|
|
66
73
|
import {
|
|
67
74
|
JwsVerificationError,
|
|
68
75
|
JwtVerificationError,
|
|
@@ -122,17 +129,23 @@ export {
|
|
|
122
129
|
MAX_OPERATION_SIZE,
|
|
123
130
|
MAX_SERVICES_ENTRIES,
|
|
124
131
|
MAX_SERVICES_PAYLOAD_SIZE,
|
|
132
|
+
MAX_SIGN_REQUEST_PAYLOAD_SIZE,
|
|
133
|
+
MAX_SIGN_REQUEST_SIZE,
|
|
125
134
|
MultikeyPublicKey,
|
|
126
135
|
RECOGNIZED_SERVICE_TYPES,
|
|
127
136
|
RevocationPayload,
|
|
128
137
|
ServiceEntry,
|
|
129
138
|
ServicesArray,
|
|
139
|
+
SignRequestPayload,
|
|
140
|
+
SignRequestVerifyError,
|
|
130
141
|
VerifiedIdentity,
|
|
131
142
|
anchorsByLabel,
|
|
143
|
+
assertCanonicalSignRequestPayload,
|
|
132
144
|
assertJwsProfile,
|
|
133
145
|
assertServicesWithinCap,
|
|
134
146
|
base64urlDecode,
|
|
135
147
|
base64urlEncode,
|
|
148
|
+
buildSignRequest,
|
|
136
149
|
byteCompare,
|
|
137
150
|
classifyAnchor,
|
|
138
151
|
compareHeadPreference,
|
|
@@ -186,5 +199,6 @@ export {
|
|
|
186
199
|
verifyIdentityExtensionFromTrustedState,
|
|
187
200
|
verifyJws,
|
|
188
201
|
verifyJwt,
|
|
189
|
-
verifyRevocation
|
|
202
|
+
verifyRevocation,
|
|
203
|
+
verifySignRequest
|
|
190
204
|
};
|