@agentunion/fastaun 0.5.26 → 0.5.27
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 +41 -0
- package/_packed_docs/CHANGELOG.md +41 -0
- package/_packed_docs/INDEX.md +22 -14
- package/_packed_docs/KITE_DOCS_GUIDE.md +11 -6
- package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +16 -1
- package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +37 -9
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +20 -9
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +57 -12
- package/_packed_docs/cli//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241CLI/345/274/200/345/217/221/344/270/216/344/275/277/347/224/250/346/214/207/345/215/227.md +869 -0
- package/_packed_docs/sdk/0.5.22-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +2 -2
- package/_packed_docs/sdk/0.5.27-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +408 -0
- package/_packed_docs/sdk/0.5.27-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +410 -0
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +2 -2
- package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +187 -73
- package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +1 -1
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -9
- package/_packed_docs/sdk/INDEX.md +21 -13
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +973 -266
- package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +950 -242
- package/dist/agent-md-schema.js +1 -1
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.js +5 -0
- package/dist/agent-md.js.map +1 -1
- package/dist/aid.js +3 -3
- package/dist/aid.js.map +1 -1
- package/dist/auth.js +21 -19
- package/dist/auth.js.map +1 -1
- package/dist/cert-utils.d.ts +1 -1
- package/dist/cert-utils.js +4 -4
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/lifecycle.d.ts +1 -1
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.js +8 -1
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.js +7 -0
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +12 -0
- package/dist/client.js +305 -29
- package/dist/client.js.map +1 -1
- package/dist/facades.d.ts +38 -0
- package/dist/facades.js +49 -5
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/org-protocol.d.ts +1 -0
- package/dist/org-protocol.js +39 -36
- package/dist/org-protocol.js.map +1 -1
- package/dist/ownership-v21.js +7 -7
- package/dist/ownership-v21.js.map +1 -1
- package/dist/register-flow.js +2 -2
- package/dist/register-flow.js.map +1 -1
- package/dist/semantic-facade.d.ts +176 -0
- package/dist/semantic-facade.js +611 -0
- package/dist/semantic-facade.js.map +1 -0
- package/dist/semantic-protocol.d.ts +810 -0
- package/dist/semantic-protocol.js +894 -0
- package/dist/semantic-protocol.js.map +1 -0
- package/dist/tools/cross-sdk-agent.d.ts +11 -1
- package/dist/tools/cross-sdk-agent.js +388 -7
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +1 -0
- package/dist/transport.js +28 -2
- package/dist/transport.js.map +1 -1
- package/dist/v2/e2ee/decrypt.d.ts +5 -0
- package/dist/v2/e2ee/decrypt.js +22 -2
- package/dist/v2/e2ee/decrypt.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/org-protocol.js
CHANGED
|
@@ -133,7 +133,7 @@ export class CredentialRenewal {
|
|
|
133
133
|
if (proof.ver !== 'aun-membership-status/1' || proof.org_id !== credential.iss || proof.member_aid !== actor || proof.credential_cid !== credential.cid
|
|
134
134
|
|| proof.membership_id !== binding.membership_id || proof.role !== binding.role || proof.version !== member.version
|
|
135
135
|
|| proof.status !== 'active' || proof.credential_status !== 'active' || proof.responder !== service || proof.target !== actor || proof.request_id !== query.request_id || proof.nonce !== query.nonce
|
|
136
|
-
|| !isInt(proof.as_of) || proof.as_of > now + 300 || !isInt(proof.expires_at) || proof.expires_at
|
|
136
|
+
|| !isInt(proof.as_of) || proof.as_of > now + 300 || !isInt(proof.expires_at) || now > proof.expires_at + 300 || proof.expires_at <= proof.as_of || proof.expires_at > proof.as_of + 300
|
|
137
137
|
|| !isRecord(proof.signature) || proof.signature.timestamp !== proof.as_of)
|
|
138
138
|
throw invalid('current membership proof does not match the query');
|
|
139
139
|
const cert = await this.ports.certificate(service, String(proof.signature.cert_fingerprint));
|
|
@@ -231,9 +231,9 @@ export class CredentialRenewal {
|
|
|
231
231
|
verifyMembershipBinding(binding, resolve, now, String(orgSigner), true);
|
|
232
232
|
check();
|
|
233
233
|
const service = 'credential.' + String(payload.org_id).split('.').slice(1).join('.');
|
|
234
|
-
if (!isInt(receipt.registered_at) || !isInt(receipt.exp) || receipt.exp > receipt.registered_at + 300 || receipt.registered_at > now)
|
|
234
|
+
if (!isInt(receipt.registered_at) || !isInt(receipt.exp) || receipt.exp > receipt.registered_at + 300 || receipt.registered_at > now + 300)
|
|
235
235
|
throw invalid('membership receipt window is invalid');
|
|
236
|
-
const late = now
|
|
236
|
+
const late = now > receipt.exp + 300;
|
|
237
237
|
verifyRegistrationReceipt(receipt, credential, { request_id: binding.request_id, nonce: binding.nonce, registrar_aid: payload.org_id }, resolve, service, late ? receipt.registered_at : now);
|
|
238
238
|
check();
|
|
239
239
|
const validUntil = Math.min(Number(credential.exp), late ? await this.status(credential, actor, false, receipt.registered_at) : receipt.exp);
|
|
@@ -245,7 +245,7 @@ export class CredentialRenewal {
|
|
|
245
245
|
return;
|
|
246
246
|
const issuerCertificate = certificates.get(String(credential.signature.cert_fingerprint));
|
|
247
247
|
await this.rememberNow(credential, { membership_binding: binding, registrationReceipt: receipt, terms, version: payload.version,
|
|
248
|
-
service_aid: 'org.' + String(payload.org_id).split('.').slice(1).join('.'), long_term: credential.exp === Math.floor(Date.parse(new X509Certificate(issuerCertificate).validTo) / 1000) }, actor, { ...guard, current: () => guard.current() && Date.now() / 1000
|
|
248
|
+
service_aid: 'org.' + String(payload.org_id).split('.').slice(1).join('.'), long_term: credential.exp === Math.floor(Date.parse(new X509Certificate(issuerCertificate).validTo) / 1000) }, actor, { ...guard, current: () => guard.current() && Date.now() / 1000 <= validUntil + 300 });
|
|
249
249
|
});
|
|
250
250
|
}
|
|
251
251
|
observe(method, params, result) {
|
|
@@ -298,7 +298,7 @@ export class CredentialRenewal {
|
|
|
298
298
|
}
|
|
299
299
|
if (initial.submission && initial.received_result && !initial.successor_cid)
|
|
300
300
|
await this.receiveNow(String(initial.credential.iss), initial.received_result, undefined, true);
|
|
301
|
-
else if (initial.incoming
|
|
301
|
+
else if (initial.incoming && Math.trunc(Date.now() / 1000) <= initial.incoming.payload.exp + 300)
|
|
302
302
|
await this.receiveNow(initial.incoming.from, initial.incoming.payload);
|
|
303
303
|
const record = (await this.ports.load(actor))[cid];
|
|
304
304
|
if (record.commit_pending)
|
|
@@ -370,7 +370,7 @@ export class CredentialRenewal {
|
|
|
370
370
|
}
|
|
371
371
|
async verifyEnvelope(from, payload, expected, replay = false) {
|
|
372
372
|
const now = Math.trunc(Date.now() / 1000);
|
|
373
|
-
if (from !== expected || payload.ver !== 'aun-credential-renewal/1' || !isInt(payload.iat) || !isInt(payload.exp) || payload.iat
|
|
373
|
+
if (from !== expected || payload.ver !== 'aun-credential-renewal/1' || !isInt(payload.iat) || !isInt(payload.exp) || payload.exp <= payload.iat || !replay && (now < payload.iat - 300 || now > payload.exp + 300) || payload.exp > payload.iat + 300 || !isRecord(payload.signature))
|
|
374
374
|
throw invalid('renewal message identity or validity is invalid');
|
|
375
375
|
const cert = await this.ports.certificate(expected, String(payload.signature.cert_fingerprint));
|
|
376
376
|
const unsigned = { ...payload };
|
|
@@ -395,7 +395,7 @@ export class CredentialRenewal {
|
|
|
395
395
|
if (!isRecord(proof) || proof.ver !== 'aun-credential-status/1' || proof.credentialCid !== credential.cid || proof.credential_hash !== digest(credential)
|
|
396
396
|
|| proof.issuerAid !== credential.iss || proof.subjectAid !== credential.sub || proof.expiresAt !== credential.exp || proof.responder !== target
|
|
397
397
|
|| proof.request_id !== query.request_id || proof.nonce !== query.nonce || proof.target !== actor
|
|
398
|
-
|| !isInt(proof.asOf) || !isInt(proof.proofExpiresAt) || proof.asOf > now + 300 || proof.proofExpiresAt <= proof.asOf || proof.proofExpiresAt
|
|
398
|
+
|| !isInt(proof.asOf) || !isInt(proof.proofExpiresAt) || proof.asOf > now + 300 || proof.proofExpiresAt <= proof.asOf || now > proof.proofExpiresAt + 300 || proof.proofExpiresAt > proof.asOf + 300
|
|
399
399
|
|| !isRecord(proof.signature) || proof.signature.timestamp !== proof.asOf)
|
|
400
400
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'renewal status proof does not match the query');
|
|
401
401
|
const cert = await this.ports.certificate(target, String(proof.signature.cert_fingerprint));
|
|
@@ -404,7 +404,7 @@ export class CredentialRenewal {
|
|
|
404
404
|
verifyAgentSignature(proof.signature, unsigned, target, () => cert, now, false);
|
|
405
405
|
if (proof.status !== 'active' && !(allowExpired && proof.status === 'expired' && proof.credentialStatus === 'expired' && Array.isArray(proof.chain) && proof.chain.every((item) => item.status === 'active')))
|
|
406
406
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'renewal credential is not active');
|
|
407
|
-
if (registrationConfirmedAt !== undefined && (proof.asOf < requestedAt || proof.asOf > now || !isInt(proof.registrationConfirmedAt) || proof.registrationConfirmedAt < registrationConfirmedAt || proof.registrationConfirmedAt > proof.asOf || proof.credentialStatus !== 'active' ||
|
|
407
|
+
if (registrationConfirmedAt !== undefined && (proof.asOf < requestedAt - 300 || proof.asOf > now + 300 || !isInt(proof.registrationConfirmedAt) || proof.registrationConfirmedAt < registrationConfirmedAt - 300 || proof.registrationConfirmedAt > proof.asOf || proof.credentialStatus !== 'active' || Math.trunc(Date.now() / 1000) > proof.proofExpiresAt + 300))
|
|
408
408
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'membership registration confirmation is invalid');
|
|
409
409
|
if (confirmation)
|
|
410
410
|
Object.assign(confirmation, structuredClone(proof));
|
|
@@ -414,7 +414,7 @@ export class CredentialRenewal {
|
|
|
414
414
|
if (!isRecord(value) || !['credential.renewal.request', 'credential.renewal.result'].includes(String(value.type)))
|
|
415
415
|
return false;
|
|
416
416
|
const payload = value;
|
|
417
|
-
if (!replay && isInt(payload.exp) &&
|
|
417
|
+
if (!replay && isInt(payload.exp) && Math.trunc(Date.now() / 1000) > payload.exp + 300)
|
|
418
418
|
return true;
|
|
419
419
|
const isRequest = payload.type === 'credential.renewal.request';
|
|
420
420
|
const actor = localIssuer ?? this.ports.currentAid();
|
|
@@ -614,8 +614,8 @@ export class CredentialRenewal {
|
|
|
614
614
|
if (!isRecord(proof) || proof.ver !== 'aun-membership-status/1' || proof.org_id !== credential.iss || proof.member_aid !== actor || proof.credential_cid !== credential.cid
|
|
615
615
|
|| proof.membership_id !== params.membership_binding.membership_id || proof.role !== params.membership_binding.role || proof.version !== Number(params.expected_version) + 1
|
|
616
616
|
|| proof.status !== 'active' || proof.credential_status !== 'active' || proof.responder !== record.service_aid || proof.target !== actor || proof.request_id !== query.request_id || proof.nonce !== query.nonce
|
|
617
|
-
|| !isInt(proof.as_of) || proof.as_of < Number(query.request_binding.iat) || proof.as_of > now || !isInt(proof.expires_at) || proof.expires_at
|
|
618
|
-
|| !isRecord(proof.signature) || proof.signature.timestamp !== proof.as_of || proofExpiresAt
|
|
617
|
+
|| !isInt(proof.as_of) || proof.as_of < Number(query.request_binding.iat) - 300 || proof.as_of > now + 300 || !isInt(proof.expires_at) || now > proof.expires_at + 300 || proof.expires_at > proof.as_of + 300
|
|
618
|
+
|| !isRecord(proof.signature) || proof.signature.timestamp !== proof.as_of || now > proofExpiresAt + 300)
|
|
619
619
|
throw invalid('renewal membership confirmation is invalid');
|
|
620
620
|
const cert = await this.ports.certificate(record.service_aid, String(proof.signature.cert_fingerprint));
|
|
621
621
|
const unsigned = { ...proof };
|
|
@@ -660,7 +660,7 @@ export class CredentialRenewal {
|
|
|
660
660
|
records[cid].successor_cid = credential.cid;
|
|
661
661
|
records[cid].response = structuredClone(payload);
|
|
662
662
|
records[cid].commit_pending = true;
|
|
663
|
-
const recoveryGuard = { current: () => Date.now() / 1000 >= Number(credential.nbf) && Date.now() / 1000
|
|
663
|
+
const recoveryGuard = { current: () => Date.now() / 1000 >= Number(credential.nbf) - 300 && Date.now() / 1000 <= Math.min(recoveryValidUntil, Number(credential.exp)) + 300 };
|
|
664
664
|
if (!recoveryGuard.current())
|
|
665
665
|
throw invalid('renewal recovery confirmation has expired');
|
|
666
666
|
await this.ports.save(actor, records, recoveryGuard);
|
|
@@ -687,7 +687,7 @@ export class CredentialRenewal {
|
|
|
687
687
|
const validUntil = await this.status(credential, actor, false, record.registration_submitted_at, confirmation);
|
|
688
688
|
records[String(credential.cid)] = { credential: structuredClone(credential), long_term: true, issued: true };
|
|
689
689
|
records[cid].registration_confirmation = confirmation;
|
|
690
|
-
const guard = { current: () => Date.now() / 1000 >= Number(credential.nbf) && Date.now() / 1000
|
|
690
|
+
const guard = { current: () => Date.now() / 1000 >= Number(credential.nbf) - 300 && Date.now() / 1000 <= Math.min(validUntil, Number(credential.exp)) + 300 };
|
|
691
691
|
if (!guard.current())
|
|
692
692
|
throw invalid('registration recovery confirmation has expired');
|
|
693
693
|
await this.ports.save(actor, records, guard);
|
|
@@ -782,7 +782,7 @@ export class CredentialRenewal {
|
|
|
782
782
|
return Promise.resolve();
|
|
783
783
|
return this.serial(async () => {
|
|
784
784
|
const actor = this.ports.currentAid();
|
|
785
|
-
const current = () => this.ports.currentAid() === actor && guard.current() && Date.now() / 1000
|
|
785
|
+
const current = () => this.ports.currentAid() === actor && guard.current() && Date.now() / 1000 <= Number(payload.expires_at) + 300;
|
|
786
786
|
if (!current())
|
|
787
787
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'credential revocation event was superseded');
|
|
788
788
|
const list = payload.type === 'credential.revocationList';
|
|
@@ -831,7 +831,7 @@ export class CredentialRenewal {
|
|
|
831
831
|
check();
|
|
832
832
|
const records = await this.ports.load(actor);
|
|
833
833
|
check();
|
|
834
|
-
const authorities = new Set();
|
|
834
|
+
const authorities = new Set(Object.keys(state.authorities));
|
|
835
835
|
for (const record of Object.values(records)) {
|
|
836
836
|
if (!isRecord(record) || !isRecord(record.credential))
|
|
837
837
|
continue;
|
|
@@ -869,7 +869,7 @@ export class CredentialRenewal {
|
|
|
869
869
|
const now = Math.trunc(Date.now() / 1000);
|
|
870
870
|
if (!isRecord(proof) || proof.responder !== authority || proof.target !== actor || proof.request_id !== query.request_id || proof.nonce !== query.nonce || proof.issuer_aid !== ''
|
|
871
871
|
|| !Array.isArray(proof.events) || proof.events.length > 1000 || typeof proof.next_cursor !== 'string'
|
|
872
|
-
|| !isInt(proof.as_of) || proof.as_of <= 0 || proof.as_of > now + 300 || !isInt(proof.expires_at) || proof.expires_at
|
|
872
|
+
|| !isInt(proof.as_of) || proof.as_of <= 0 || proof.as_of > now + 300 || !isInt(proof.expires_at) || now > proof.expires_at + 300 || proof.expires_at <= proof.as_of || proof.expires_at > proof.as_of + 300
|
|
873
873
|
|| !isRecord(proof.signature) || proof.signature.timestamp !== proof.as_of)
|
|
874
874
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'revocation list does not match the query');
|
|
875
875
|
let last = since;
|
|
@@ -893,7 +893,7 @@ export class CredentialRenewal {
|
|
|
893
893
|
Object.defineProperty(revoked, String(event.cid), { value: Math.max(Object.hasOwn(revoked, String(event.cid)) ? Number(revoked[String(event.cid)]) : 0, Number(event.event_seq)), enumerable: true, configurable: true, writable: true });
|
|
894
894
|
next.authorities[authority] = { revoked, since_event_seq: proof.next_cursor === '' ? last : Number(proof.next_cursor), cursor: proof.next_cursor, as_of: proof.as_of, expires_at: proof.expires_at };
|
|
895
895
|
expiresAt = Math.min(expiresAt, Number(proof.expires_at), Date.parse(new X509Certificate(certificate).validTo) / 1000);
|
|
896
|
-
const commitGuard = { ...guard, current: () => epoch === this.queryEpoch && scope === this.queryScope() && this.ports.currentAid() === actor && (!guard || guard.current()) && Date.now() / 1000
|
|
896
|
+
const commitGuard = { ...guard, current: () => epoch === this.queryEpoch && scope === this.queryScope() && this.ports.currentAid() === actor && (!guard || guard.current()) && Date.now() / 1000 <= expiresAt + 300 };
|
|
897
897
|
if (!commitGuard.current())
|
|
898
898
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'revocation list expired before persistence');
|
|
899
899
|
await this.ports.saveRevocations(actor, next, commitGuard);
|
|
@@ -928,7 +928,7 @@ export async function verifyServiceEvent(eventName, payload, context) {
|
|
|
928
928
|
if (typeof context.targetAid !== 'string' || !AID_RE.test(context.targetAid))
|
|
929
929
|
throw invalid('service event target is invalid');
|
|
930
930
|
const now = context.now ?? Math.trunc(Date.now() / 1000);
|
|
931
|
-
if (!isInt(now) || !isInt(payload.as_of) || !isInt(payload.expires_at) || payload.as_of <= 0 || payload.expires_at <= payload.as_of || payload.expires_at > payload.as_of + 300 || payload.as_of > now + 300 || now
|
|
931
|
+
if (!isInt(now) || !isInt(payload.as_of) || !isInt(payload.expires_at) || payload.as_of <= 0 || payload.expires_at <= payload.as_of || payload.expires_at > payload.as_of + 300 || payload.as_of > now + 300 || now > payload.expires_at + 300)
|
|
932
932
|
throw invalid('service event time window is invalid');
|
|
933
933
|
if (!Array.isArray(payload.target_aids) || !payload.target_aids.length || payload.target_aids.some((target) => typeof target !== 'string' || !AID_RE.test(target)))
|
|
934
934
|
throw invalid('service event target is invalid');
|
|
@@ -970,7 +970,7 @@ export async function verifyServiceEvent(eventName, payload, context) {
|
|
|
970
970
|
catch {
|
|
971
971
|
throw new ProtocolError('CREDENTIAL_SIGNATURE_INVALID', 'service event signature is invalid');
|
|
972
972
|
}
|
|
973
|
-
if ((context.now ?? Math.trunc(Date.now() / 1000))
|
|
973
|
+
if ((context.now ?? Math.trunc(Date.now() / 1000)) > payload.expires_at + 300)
|
|
974
974
|
throw invalid('service event time window is invalid');
|
|
975
975
|
return { signature_valid: true, credential_known: known };
|
|
976
976
|
}
|
|
@@ -1232,7 +1232,7 @@ function validConstraintRegex(value) {
|
|
|
1232
1232
|
}
|
|
1233
1233
|
return !inside;
|
|
1234
1234
|
}
|
|
1235
|
-
function validateCapability(capability) {
|
|
1235
|
+
export function validateCapability(capability) {
|
|
1236
1236
|
const constraints = capability.constraints;
|
|
1237
1237
|
if (!Array.isArray(constraints) || constraints.length > 64)
|
|
1238
1238
|
throw invalid('capability constraints are invalid');
|
|
@@ -1547,7 +1547,7 @@ export function createRepresentationProof(credential, params, binding, signer, p
|
|
|
1547
1547
|
return proof;
|
|
1548
1548
|
}
|
|
1549
1549
|
export function signTransferAcceptance(proposal, signer) {
|
|
1550
|
-
if (!isRecord(proposal) || proposal.ver !== 'aun-org-transfer/1' || proposal.target_member_aid !== signer.aid || !isInt(proposal.exp) ||
|
|
1550
|
+
if (!isRecord(proposal) || proposal.ver !== 'aun-org-transfer/1' || proposal.target_member_aid !== signer.aid || !isInt(proposal.exp) || Math.trunc(Date.now() / 1000) > proposal.exp + 300)
|
|
1551
1551
|
throw invalid('transfer proposal does not match the accepting identity');
|
|
1552
1552
|
const payload = { ...proposal };
|
|
1553
1553
|
delete payload.signature;
|
|
@@ -1739,9 +1739,9 @@ export function prepareOrganizationRequest(method, params, target, signer, optio
|
|
|
1739
1739
|
throw representationBindingInvalid('invitation rejection requires a distinct action identity');
|
|
1740
1740
|
value.credentials = credentials;
|
|
1741
1741
|
const now = Math.trunc(Date.now() / 1000);
|
|
1742
|
-
if (now
|
|
1742
|
+
if (now > Number(binding.exp) + 300)
|
|
1743
1743
|
throw representationBindingInvalid('membership binding has expired');
|
|
1744
|
-
let exp =
|
|
1744
|
+
let exp = Number(binding.exp);
|
|
1745
1745
|
for (const field of ['credential_template', 'registration_authorization'])
|
|
1746
1746
|
if (field in value) {
|
|
1747
1747
|
const material = value[field];
|
|
@@ -1749,8 +1749,8 @@ export function prepareOrganizationRequest(method, params, target, signer, optio
|
|
|
1749
1749
|
throw invalid('admission material expiry is invalid');
|
|
1750
1750
|
exp = Math.min(exp, material.exp);
|
|
1751
1751
|
}
|
|
1752
|
-
const request = Object.hasOwn(value, 'request_binding') ? value.request_binding : { ver: 'aun-membership-admission-request/1', request_id: value.request_id, nonce: value.nonce, target, method, params_hash: digest(orgRequestBindingParams(method, value)), membership_id: binding.membership_id, iat: now, exp };
|
|
1753
|
-
if (!isRecord(request) || Object.keys(request).length !== 9 || Object.keys(request).some((key) => !['ver', 'request_id', 'nonce', 'target', 'method', 'params_hash', 'membership_id', 'iat', 'exp'].includes(key)) || request.ver !== 'aun-membership-admission-request/1' || request.request_id !== value.request_id || request.nonce !== value.nonce || request.target !== target || request.method !== method || request.membership_id !== binding.membership_id || request.params_hash !== digest(orgRequestBindingParams(method, value)) || !isInt(request.iat) || !isInt(request.exp) || request.iat < 0 || request.iat > now || request.iat < Number(binding.iat) || request.exp <= now || request.exp > request.iat + 300 || request.exp > exp)
|
|
1752
|
+
const request = Object.hasOwn(value, 'request_binding') ? value.request_binding : { ver: 'aun-membership-admission-request/1', request_id: value.request_id, nonce: value.nonce, target, method, params_hash: digest(orgRequestBindingParams(method, value)), membership_id: binding.membership_id, iat: now, exp: Math.min(now + 300, exp) };
|
|
1753
|
+
if (!isRecord(request) || Object.keys(request).length !== 9 || Object.keys(request).some((key) => !['ver', 'request_id', 'nonce', 'target', 'method', 'params_hash', 'membership_id', 'iat', 'exp'].includes(key)) || request.ver !== 'aun-membership-admission-request/1' || request.request_id !== value.request_id || request.nonce !== value.nonce || request.target !== target || request.method !== method || request.membership_id !== binding.membership_id || request.params_hash !== digest(orgRequestBindingParams(method, value)) || !isInt(request.iat) || !isInt(request.exp) || request.iat < 0 || request.iat > now + 300 || request.iat < Number(binding.iat) || request.exp <= request.iat || now > request.exp + 300 || request.exp > request.iat + 300 || request.exp > exp)
|
|
1754
1754
|
throw representationBindingInvalid('admission request binding does not match request');
|
|
1755
1755
|
value.request_binding = request;
|
|
1756
1756
|
if (value.for === undefined || value.for === signer.aid)
|
|
@@ -1847,7 +1847,7 @@ export function verifyCredential(credential, context) {
|
|
|
1847
1847
|
if (isRecord(proof))
|
|
1848
1848
|
statusProofs.push(proof);
|
|
1849
1849
|
if (proof != null || document !== value) {
|
|
1850
|
-
if (!isRecord(proof) || proof.ver !== 'aun-credential-status/1' || typeof proof.credentialCid !== 'string' || !proof.credentialCid || typeof proof.credential_hash !== 'string' || !DIGEST_RE.test(proof.credential_hash) || !isInt(proof.asOf) || !isInt(proof.proofExpiresAt) || proof.asOf > now + 300 || proof.proofExpiresAt <= proof.asOf || proof.proofExpiresAt > proof.asOf + 300 || now
|
|
1850
|
+
if (!isRecord(proof) || proof.ver !== 'aun-credential-status/1' || typeof proof.credentialCid !== 'string' || !proof.credentialCid || typeof proof.credential_hash !== 'string' || !DIGEST_RE.test(proof.credential_hash) || !isInt(proof.asOf) || !isInt(proof.proofExpiresAt) || proof.asOf > now + 300 || proof.proofExpiresAt <= proof.asOf || proof.proofExpiresAt > proof.asOf + 300 || now > proof.proofExpiresAt + 300)
|
|
1851
1851
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'trusted credential status proof is invalid');
|
|
1852
1852
|
if (typeof proof.responder !== 'string' || !AID_RE.test(proof.responder) || !proof.responder.startsWith('credential.') || typeof proof.request_id !== 'string' || !proof.request_id || typeof proof.nonce !== 'string' || !proof.nonce || typeof proof.target !== 'string' || !AID_RE.test(proof.target) || !isRecord(proof.signature) || proof.signature.timestamp !== proof.asOf)
|
|
1853
1853
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'trusted credential status proof is incomplete');
|
|
@@ -1934,17 +1934,17 @@ export function verifyCredential(credential, context) {
|
|
|
1934
1934
|
validateCredentialCapability(credential, { ns: context.ns, action: context.action, resource: context.resource, params: context.params, units: context.units, now: completedAt, client_ip: context.clientIp, proof_chain: context.proofChain }, () => true);
|
|
1935
1935
|
validateRequestBinding(context.requestBinding, context.method, context.target, context.params ?? {}, String(value.cid), context.nonce ?? '', context.requestId ?? '', completedAt);
|
|
1936
1936
|
for (const proof of statusProofs) {
|
|
1937
|
-
if (proof.asOf > completedAt + 300 || completedAt
|
|
1937
|
+
if (proof.asOf > completedAt + 300 || completedAt > proof.proofExpiresAt + 300)
|
|
1938
1938
|
throw new ProtocolError('CREDENTIAL_STATUS_UNKNOWN', 'trusted credential status proof is invalid');
|
|
1939
1939
|
}
|
|
1940
1940
|
for (const material of resolvedCertificates) {
|
|
1941
1941
|
const certificate = new X509Certificate(certificatePem(material));
|
|
1942
|
-
if (completedAt < new Date(certificate.validFrom).getTime() / 1000 || completedAt > new Date(certificate.validTo).getTime() / 1000)
|
|
1942
|
+
if (completedAt < new Date(certificate.validFrom).getTime() / 1000 - 300 || completedAt > new Date(certificate.validTo).getTime() / 1000 + 300)
|
|
1943
1943
|
throw new ProtocolError('CREDENTIAL_SIGNATURE_INVALID', 'certificate is not valid');
|
|
1944
1944
|
}
|
|
1945
1945
|
if (verifiedRepresentation) {
|
|
1946
1946
|
const { proof, request } = verifiedRepresentation;
|
|
1947
|
-
if (completedAt < proof.iat || completedAt
|
|
1947
|
+
if (completedAt < proof.iat - 300 || completedAt > proof.exp + 300)
|
|
1948
1948
|
throw representationBindingInvalid('representation time window is invalid');
|
|
1949
1949
|
validateRepresentationContext(proof, value, request, completedAt);
|
|
1950
1950
|
}
|
|
@@ -1958,7 +1958,7 @@ export function validateCredentialAt(credential, now, audience, proofChain) {
|
|
|
1958
1958
|
const value = credential;
|
|
1959
1959
|
const nbf = value.nbf;
|
|
1960
1960
|
const exp = value.exp;
|
|
1961
|
-
if (!isInt(nbf) || !isInt(exp) || now < nbf || now
|
|
1961
|
+
if (!isInt(nbf) || !isInt(exp) || now < nbf - 300 || now > exp + 300)
|
|
1962
1962
|
throw new ProtocolError('CREDENTIAL_EXPIRED', 'credential is outside its validity window');
|
|
1963
1963
|
if (audience !== undefined) {
|
|
1964
1964
|
if (!Array.isArray(value.aud) || !value.aud.includes(audience))
|
|
@@ -2146,7 +2146,10 @@ function capabilitiesNarrower(child, parent, subject, depth) {
|
|
|
2146
2146
|
function verifyAgentSignature(signatureValue, payload, expectedAid, resolveCertificate, now, enforceWindow = true) {
|
|
2147
2147
|
const certPem = certificatePem(resolveCertificate(String(signatureValue.cert_fingerprint)));
|
|
2148
2148
|
const lower = payload.iat ?? payload.registered_at;
|
|
2149
|
-
|
|
2149
|
+
const outsideWindow = typeof lower === 'number' && (payload.ver === 'aun-org-transfer/1'
|
|
2150
|
+
? Number(signatureValue.timestamp) < lower - 300 || Number(signatureValue.timestamp) > Number(payload.exp) + 300
|
|
2151
|
+
: Number(signatureValue.timestamp) < lower || Number(signatureValue.timestamp) >= Number(payload.exp));
|
|
2152
|
+
if (enforceWindow && outsideWindow)
|
|
2150
2153
|
throw new Error('signature timestamp is outside the signed object window');
|
|
2151
2154
|
if (!certPem)
|
|
2152
2155
|
throw new Error('certificate is missing');
|
|
@@ -2285,7 +2288,7 @@ export function validateMembershipBindingAt(binding, now, expectedRole) {
|
|
|
2285
2288
|
const value = binding;
|
|
2286
2289
|
const iat = value.iat;
|
|
2287
2290
|
const exp = value.exp;
|
|
2288
|
-
if (!isInt(now) || !isInt(iat) || !isInt(exp) || now < iat || now
|
|
2291
|
+
if (!isInt(now) || !isInt(iat) || !isInt(exp) || now < iat - 300 || now > exp + 300)
|
|
2289
2292
|
throw new ProtocolError('CREDENTIAL_REQUEST_BINDING_INVALID', 'membership binding is outside its validity window');
|
|
2290
2293
|
if (expectedRole !== undefined && value.role !== expectedRole)
|
|
2291
2294
|
throw invalid('membership role is invalid');
|
|
@@ -2341,7 +2344,7 @@ export function validateRegistrationReceipt(receipt, credential, request, expect
|
|
|
2341
2344
|
throw new ProtocolError('CREDENTIAL_REGISTRATION_RECEIPT_MISMATCH', 'receipt registrar does not match request');
|
|
2342
2345
|
if (expectedServiceAid !== undefined && receipt.service_aid !== expectedServiceAid)
|
|
2343
2346
|
throw new ProtocolError('CREDENTIAL_REGISTRATION_RECEIPT_INVALID', 'receipt service AID mismatch');
|
|
2344
|
-
if (now !== undefined && (!isInt(now) || now < receipt.registered_at || now
|
|
2347
|
+
if (now !== undefined && (!isInt(now) || now < receipt.registered_at - 300 || now > receipt.exp + 300))
|
|
2345
2348
|
throw new ProtocolError('CREDENTIAL_REGISTRATION_RECEIPT_INVALID', 'receipt is outside its validity window');
|
|
2346
2349
|
signature(receipt.signature);
|
|
2347
2350
|
}
|
|
@@ -2410,7 +2413,7 @@ export function validateRequestBinding(binding, method, target, params, credenti
|
|
|
2410
2413
|
throw new ProtocolError('CREDENTIAL_REQUEST_BINDING_INVALID', 'request binding is invalid');
|
|
2411
2414
|
if (binding.request_id !== requestId || binding.nonce !== nonce || binding.target !== target || binding.method !== method || binding.credential_cid !== credentialCid || binding.params_hash !== digest(orgRequestBindingParams(method, params)))
|
|
2412
2415
|
throw new ProtocolError('CREDENTIAL_REQUEST_BINDING_INVALID', 'request binding does not match request');
|
|
2413
|
-
if (!isInt(binding.iat) || !isInt(binding.exp) || binding.exp <= binding.iat || binding.exp > binding.iat + 300 || !isInt(now) || now < binding.iat || now
|
|
2416
|
+
if (!isInt(binding.iat) || !isInt(binding.exp) || binding.exp <= binding.iat || binding.exp > binding.iat + 300 || !isInt(now) || now < binding.iat - 300 || now > binding.exp + 300)
|
|
2414
2417
|
throw new ProtocolError('CREDENTIAL_REQUEST_BINDING_INVALID', 'request binding is outside its validity window');
|
|
2415
2418
|
}
|
|
2416
2419
|
function representationBindingInvalid(message) {
|
|
@@ -2467,7 +2470,7 @@ export function verifyRepresentationProof(proof, credential, request, resolveCer
|
|
|
2467
2470
|
throw representationBindingInvalid('representation proof AID is invalid');
|
|
2468
2471
|
if (!DIGEST_RE.test(proof.params_hash))
|
|
2469
2472
|
throw representationBindingInvalid('representation params_hash is invalid');
|
|
2470
|
-
if (!isInt(proof.iat) || !isInt(proof.exp) || proof.exp <= proof.iat || !isInt(now) || now < proof.iat || now
|
|
2473
|
+
if (!isInt(proof.iat) || !isInt(proof.exp) || proof.exp <= proof.iat || !isInt(now) || now < proof.iat - 300 || now > proof.exp + 300)
|
|
2471
2474
|
throw representationBindingInvalid('representation time window is invalid');
|
|
2472
2475
|
validateRepresentationSignature(proof.signature);
|
|
2473
2476
|
if (!isRecord(credential))
|
|
@@ -2490,7 +2493,7 @@ export function verifyRepresentationProof(proof, credential, request, resolveCer
|
|
|
2490
2493
|
const timestamp = proof.signature.timestamp;
|
|
2491
2494
|
if (timestamp > now + 300 || timestamp < proof.iat || timestamp >= proof.exp)
|
|
2492
2495
|
throw new Error('representation signature timestamp is outside its window');
|
|
2493
|
-
if (timestamp < Math.floor(new Date(cert.validFrom).getTime() / 1000) || timestamp > Math.floor(new Date(cert.validTo).getTime() / 1000) || now < Math.floor(new Date(cert.validFrom).getTime() / 1000) || now > Math.floor(new Date(cert.validTo).getTime() / 1000))
|
|
2496
|
+
if (timestamp < Math.floor(new Date(cert.validFrom).getTime() / 1000) || timestamp > Math.floor(new Date(cert.validTo).getTime() / 1000) || now < Math.floor(new Date(cert.validFrom).getTime() / 1000) - 300 || now > Math.floor(new Date(cert.validTo).getTime() / 1000) + 300)
|
|
2494
2497
|
throw new Error('certificate is not valid at signature or verification time');
|
|
2495
2498
|
const payload = { ...proof };
|
|
2496
2499
|
delete payload.signature;
|