@thurinlabs/identity-kit 1.3.7 → 1.4.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/core.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  ARWEAVE_GATEWAY,
3
3
  AUTHORIZATION_TYPES,
4
+ CLAIM_CHECK_LABEL,
4
5
  EIP712_NAME,
5
6
  EIP712_VERSION,
6
7
  ENS_HINT_KEY,
@@ -23,17 +24,23 @@ import {
23
24
  avatarUrl,
24
25
  bytesToFingerprint,
25
26
  chainFor,
27
+ claimCheckText,
28
+ claimFateText,
29
+ claimFates,
26
30
  decodeRecord,
27
31
  displayUrl,
28
32
  encodeRecord,
29
33
  ensHintFor,
30
34
  ensHintValue,
31
35
  ensHintWrite,
36
+ expiresSoon,
37
+ expiresSoonText,
32
38
  fetchEFPGraph,
33
39
  fetchEnsHint,
34
40
  fetchRecords,
35
41
  fingerprintHash,
36
42
  fingerprintToBytes,
43
+ formatClaimDate,
37
44
  getRegistry,
38
45
  hasEmailUserID,
39
46
  identifyProof,
@@ -62,10 +69,11 @@ import {
62
69
  verifyAttestation,
63
70
  verifyClearsigned,
64
71
  verifyProof
65
- } from "./chunk-ROQWHCHP.js";
72
+ } from "./chunk-ZAQ2EPF5.js";
66
73
  export {
67
74
  ARWEAVE_GATEWAY,
68
75
  AUTHORIZATION_TYPES,
76
+ CLAIM_CHECK_LABEL,
69
77
  EIP712_NAME,
70
78
  EIP712_VERSION,
71
79
  ENS_HINT_KEY,
@@ -88,17 +96,23 @@ export {
88
96
  avatarUrl,
89
97
  bytesToFingerprint,
90
98
  chainFor,
99
+ claimCheckText,
100
+ claimFateText,
101
+ claimFates,
91
102
  decodeRecord,
92
103
  displayUrl,
93
104
  encodeRecord,
94
105
  ensHintFor,
95
106
  ensHintValue,
96
107
  ensHintWrite,
108
+ expiresSoon,
109
+ expiresSoonText,
97
110
  fetchEFPGraph,
98
111
  fetchEnsHint,
99
112
  fetchRecords,
100
113
  fingerprintHash,
101
114
  fingerprintToBytes,
115
+ formatClaimDate,
102
116
  getRegistry,
103
117
  hasEmailUserID,
104
118
  identifyProof,
@@ -31342,6 +31342,61 @@ ${prettyStateOverride(stateOverride)}`;
31342
31342
  return { verified: false, reason: err instanceof Error ? err.message : "Verification failed", text: "" };
31343
31343
  }
31344
31344
  }
31345
+ var REVOCATION_REASON = {
31346
+ // 0 = "no reason specified", gpg's default: say nothing rather than "(reason: no reason given)"
31347
+ 1: "replaced by a newer key",
31348
+ 2: "compromised",
31349
+ 3: "no longer used",
31350
+ 32: "a user ID is no longer valid"
31351
+ };
31352
+ var iso = (d2) => d2 instanceof Date ? d2.toISOString() : typeof d2 === "number" && Number.isFinite(d2) ? new Date(d2).toISOString() : null;
31353
+ function revocationOf(sigs) {
31354
+ const sig = [...sigs ?? []].sort((a2, b2) => (b2.created?.getTime?.() ?? 0) - (a2.created?.getTime?.() ?? 0))[0];
31355
+ const flag = sig?.reasonForRevocationFlag ?? null;
31356
+ return {
31357
+ at: iso(sig?.created),
31358
+ compromised: flag === 2,
31359
+ revocationReason: sig?.reasonForRevocationString || (flag !== null ? REVOCATION_REASON[flag] ?? null : null)
31360
+ };
31361
+ }
31362
+ async function keyLife(openpgp, key, clearsigned, config) {
31363
+ const now = /* @__PURE__ */ new Date();
31364
+ let issuer = null;
31365
+ try {
31366
+ issuer = (await openpgp.readCleartextMessage({ cleartextMessage: clearsigned })).signature.packets[0]?.issuerKeyID ?? null;
31367
+ } catch {
31368
+ }
31369
+ const signer = issuer && !key.getKeyID().equals(issuer) ? key.subkeys.find((s2) => s2.getKeyID().equals(issuer)) ?? null : key;
31370
+ const signingKey = signer ? signer.getFingerprint().toUpperCase() : null;
31371
+ const safe = async (f2, fallback2) => {
31372
+ try {
31373
+ return await f2();
31374
+ } catch {
31375
+ return fallback2;
31376
+ }
31377
+ };
31378
+ const keyRevoked = await safe(() => key.isRevoked(void 0, void 0, now, config), false);
31379
+ const keyExp = await safe(() => key.getExpirationTime(void 0, config), null);
31380
+ const isSub = signer && signer !== key;
31381
+ const subRevoked = isSub ? await safe(() => signer.isRevoked(null, key.keyPacket, now, config), false) : false;
31382
+ const subExp = isSub ? await safe(() => signer.getExpirationTime(null, config), null) : null;
31383
+ const finite = (d2) => d2 instanceof Date && Number.isFinite(d2.getTime()) ? d2 : null;
31384
+ const kExp = finite(keyExp), sExp = finite(subExp);
31385
+ let problem = null;
31386
+ if (keyRevoked) {
31387
+ const r2 = revocationOf(key.revocationSignatures);
31388
+ problem = { kind: r2.compromised ? "compromised" : "revoked", at: r2.at, revocationReason: r2.revocationReason };
31389
+ } else if (kExp && kExp <= now) {
31390
+ problem = { kind: "expired", at: kExp.toISOString() };
31391
+ } else if (subRevoked) {
31392
+ const r2 = revocationOf(signer.revocationSignatures);
31393
+ problem = { kind: r2.compromised ? "compromised" : "signing-key-revoked", at: r2.at, revocationReason: r2.revocationReason };
31394
+ } else if (sExp && sExp <= now) {
31395
+ problem = { kind: "signing-key-expired", at: sExp.toISOString() };
31396
+ }
31397
+ const earliest = [kExp, sExp].filter(Boolean).sort((a2, b2) => a2 - b2)[0];
31398
+ return { problem, signingKey, expiresAt: earliest ? earliest.toISOString() : null, algorithm: algorithmName(signer ?? key) };
31399
+ }
31345
31400
  async function verifyAttestation({
31346
31401
  pgpPublicKey,
31347
31402
  pgpSignature,
@@ -31350,24 +31405,31 @@ ${prettyStateOverride(stateOverride)}`;
31350
31405
  }) {
31351
31406
  try {
31352
31407
  if (!pgpPublicKey || !pgpSignature) {
31353
- return { verified: false, reason: "Missing PGP data" };
31408
+ return { verified: false, reason: "Missing PGP data", kind: "bad-signature" };
31354
31409
  }
31355
31410
  const openpgp = await Promise.resolve().then(() => (init_openpgp_min(), openpgp_min_exports));
31356
31411
  const { readKey } = openpgp;
31357
31412
  const publicKey = await readKey({ armoredKey: pgpPublicKey });
31358
31413
  const keyFingerprint = publicKey.getFingerprint().toUpperCase();
31359
31414
  if (keyFingerprint !== fingerprint.toUpperCase()) {
31360
- return { verified: false, reason: "Key fingerprint mismatch" };
31415
+ return { verified: false, reason: "Key fingerprint mismatch", kind: "bad-signature" };
31361
31416
  }
31417
+ const life = await keyLife(openpgp, publicKey, pgpSignature, pgpConfig(openpgp));
31362
31418
  const v2 = await verifyClearsigned({ armoredKey: pgpPublicKey, clearsigned: pgpSignature });
31363
- if (!v2.verified) return { verified: false, reason: v2.reason };
31419
+ if (!v2.verified) {
31420
+ if (life.problem) return { verified: false, reason: v2.reason, signingKey: life.signingKey, ...life.problem };
31421
+ if (/too weak|reject|unsupported|not supported|unknown (curve|algorithm)/i.test(v2.reason || "")) {
31422
+ return { verified: false, reason: v2.reason, kind: "unsupported", algorithm: life.algorithm, signingKey: life.signingKey };
31423
+ }
31424
+ return { verified: false, reason: v2.reason, kind: "bad-signature", signingKey: life.signingKey };
31425
+ }
31364
31426
  const signedText = v2.text;
31365
31427
  if (!signedText.toLowerCase().includes(ethAddress.toLowerCase())) {
31366
- return { verified: false, reason: "Signed message does not contain ETH address" };
31428
+ return { verified: false, reason: "Signed message does not contain ETH address", kind: "bad-signature", signingKey: life.signingKey };
31367
31429
  }
31368
- return { verified: true };
31430
+ return { verified: true, kind: "verified", signingKey: life.signingKey, expiresAt: life.expiresAt };
31369
31431
  } catch {
31370
- return { verified: false, reason: "Signature verification failed" };
31432
+ return { verified: false, reason: "Signature verification failed", kind: "bad-signature" };
31371
31433
  }
31372
31434
  }
31373
31435