@thurinlabs/identity-kit 1.0.0 → 1.0.2
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/README.md +5 -1
- package/dist/embed.global.js +32 -2
- package/dist/embed.global.js.map +1 -1
- package/dist/index.cjs +41 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +32 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -1339,6 +1339,7 @@ function keyIdToBytes(keyId) {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
|
|
1341
1341
|
// src/core/pgp.ts
|
|
1342
|
+
var PGP_CONFIG = { rejectCurves: /* @__PURE__ */ new Set() };
|
|
1342
1343
|
function algorithmName(keyOrSubkey) {
|
|
1343
1344
|
try {
|
|
1344
1345
|
const info = keyOrSubkey.getAlgorithmInfo();
|
|
@@ -1379,7 +1380,9 @@ async function parsePgpKey(armoredKey) {
|
|
|
1379
1380
|
await cert.verify(
|
|
1380
1381
|
key.keyPacket,
|
|
1381
1382
|
cert.signatureType,
|
|
1382
|
-
{ userID: user.userID, key: key.keyPacket }
|
|
1383
|
+
{ userID: user.userID, key: key.keyPacket },
|
|
1384
|
+
void 0,
|
|
1385
|
+
PGP_CONFIG
|
|
1383
1386
|
);
|
|
1384
1387
|
} catch (e3) {
|
|
1385
1388
|
continue;
|
|
@@ -1430,7 +1433,7 @@ async function verifyAttestation({
|
|
|
1430
1433
|
return { verified: false, reason: "Key fingerprint mismatch" };
|
|
1431
1434
|
}
|
|
1432
1435
|
const message = await readCleartextMessage({ cleartextMessage: pgpSignature });
|
|
1433
|
-
const { signatures } = await verify({ message, verificationKeys: publicKey });
|
|
1436
|
+
const { signatures } = await verify({ message, verificationKeys: publicKey, config: PGP_CONFIG });
|
|
1434
1437
|
await signatures[0].verified;
|
|
1435
1438
|
const signedText = message.getText();
|
|
1436
1439
|
if (!signedText.toLowerCase().includes(ethAddress.toLowerCase())) {
|
|
@@ -1625,6 +1628,14 @@ var PROVIDERS = [
|
|
|
1625
1628
|
pattern: /^https:\/\/gist\.github\.com\/([^/]+)\/([a-f0-9]+)$/i,
|
|
1626
1629
|
parse: (m) => ({ user: m[1], gistId: m[2] })
|
|
1627
1630
|
},
|
|
1631
|
+
{
|
|
1632
|
+
// A repository's description — the form an organisation can use, since
|
|
1633
|
+
// gists belong to user accounts only. Same shape as the Codeberg proof.
|
|
1634
|
+
provider: "github",
|
|
1635
|
+
label: "GitHub",
|
|
1636
|
+
pattern: /^https:\/\/github\.com\/([A-Za-z0-9-]+)\/([A-Za-z0-9._-]+)$/i,
|
|
1637
|
+
parse: (m) => ({ user: m[1], repo: m[2] })
|
|
1638
|
+
},
|
|
1628
1639
|
{
|
|
1629
1640
|
provider: "dns",
|
|
1630
1641
|
label: "DNS",
|
|
@@ -1696,6 +1707,7 @@ function containsFingerprintUrl(text, fingerprint) {
|
|
|
1696
1707
|
return text.toUpperCase().includes(fingerprint.toUpperCase());
|
|
1697
1708
|
}
|
|
1698
1709
|
async function verifyGitHub(proof, fingerprint) {
|
|
1710
|
+
if (proof.repo) return verifyGitHubRepo(proof, fingerprint);
|
|
1699
1711
|
try {
|
|
1700
1712
|
const resp = await fetch(`https://api.github.com/gists/${proof.gistId}`);
|
|
1701
1713
|
if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
|
|
@@ -1713,6 +1725,24 @@ async function verifyGitHub(proof, fingerprint) {
|
|
|
1713
1725
|
return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
|
|
1714
1726
|
}
|
|
1715
1727
|
}
|
|
1728
|
+
async function verifyGitHubRepo(proof, fingerprint) {
|
|
1729
|
+
try {
|
|
1730
|
+
const resp = await fetch(
|
|
1731
|
+
`https://api.github.com/repos/${encodeURIComponent(proof.user)}/${encodeURIComponent(proof.repo)}`
|
|
1732
|
+
);
|
|
1733
|
+
if (!resp.ok) return { verified: false, reason: `GitHub API returned ${resp.status}` };
|
|
1734
|
+
const data = await resp.json();
|
|
1735
|
+
if (_optionalChain([data, 'access', _26 => _26.owner, 'optionalAccess', _27 => _27.login, 'optionalAccess', _28 => _28.toLowerCase, 'call', _29 => _29()]) !== proof.user.toLowerCase()) {
|
|
1736
|
+
return { verified: false, reason: "Repository owner does not match claimed account" };
|
|
1737
|
+
}
|
|
1738
|
+
if (data.description && containsFingerprint(data.description, fingerprint)) {
|
|
1739
|
+
return { verified: true };
|
|
1740
|
+
}
|
|
1741
|
+
return { verified: false, reason: "Fingerprint token not found in repository description" };
|
|
1742
|
+
} catch (err) {
|
|
1743
|
+
return { verified: false, reason: `GitHub fetch failed: ${err.message}` };
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1716
1746
|
async function verifyDNS(proof, fingerprint) {
|
|
1717
1747
|
try {
|
|
1718
1748
|
const resp = await fetch(
|
|
@@ -1758,7 +1788,7 @@ async function verifyFarcaster(proof, fingerprint, neynarApiKey) {
|
|
|
1758
1788
|
const data = await resp.json();
|
|
1759
1789
|
for (const msg of data.messages || []) {
|
|
1760
1790
|
if (msg.hash && msg.hash.startsWith(proof.castHash)) {
|
|
1761
|
-
const text = _optionalChain([msg, 'access',
|
|
1791
|
+
const text = _optionalChain([msg, 'access', _30 => _30.data, 'optionalAccess', _31 => _31.castAddBody, 'optionalAccess', _32 => _32.text]) || "";
|
|
1762
1792
|
if (containsFingerprint(text, fingerprint)) {
|
|
1763
1793
|
return { verified: true };
|
|
1764
1794
|
}
|
|
@@ -1834,7 +1864,7 @@ function usePGPProofs(fingerprint, armoredKey) {
|
|
|
1834
1864
|
const { data } = _reactquery.useQuery.call(void 0, {
|
|
1835
1865
|
// The key is large; key the query on its length + fingerprint, which
|
|
1836
1866
|
// changes whenever a different attestation's key is supplied.
|
|
1837
|
-
queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess',
|
|
1867
|
+
queryKey: ["pgp-proofs", fingerprint, _nullishCoalesce(_optionalChain([armoredKey, 'optionalAccess', _33 => _33.length]), () => ( 0))],
|
|
1838
1868
|
queryFn: async () => {
|
|
1839
1869
|
if (!fingerprint || !armoredKey) return { keyInfo: null, proofs: [] };
|
|
1840
1870
|
const keyInfo = await parsePgpKey(armoredKey);
|
|
@@ -1869,8 +1899,8 @@ function usePGPProofs(fingerprint, armoredKey) {
|
|
|
1869
1899
|
staleTime: 3e5
|
|
1870
1900
|
});
|
|
1871
1901
|
return {
|
|
1872
|
-
keyInfo: _nullishCoalesce(_optionalChain([data, 'optionalAccess',
|
|
1873
|
-
proofs: _nullishCoalesce(_optionalChain([data, 'optionalAccess',
|
|
1902
|
+
keyInfo: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _34 => _34.keyInfo]), () => ( null)),
|
|
1903
|
+
proofs: _nullishCoalesce(_optionalChain([data, 'optionalAccess', _35 => _35.proofs]), () => ( [])),
|
|
1874
1904
|
// Report loading whenever a fingerprint is set but its proofs haven't
|
|
1875
1905
|
// resolved yet. Using react-query's own isLoading leaves a gap while the
|
|
1876
1906
|
// query is enabling (fingerprint just became known), during which the card
|
|
@@ -1919,13 +1949,13 @@ function useThurinIdentity(ensOrAddress) {
|
|
|
1919
1949
|
isLoading: claimsLoading
|
|
1920
1950
|
} = useAttestations(address);
|
|
1921
1951
|
const currentClaim = [...claims].reverse().find(
|
|
1922
|
-
(c) => !c.revoked && _optionalChain([c, 'access',
|
|
1952
|
+
(c) => !c.revoked && _optionalChain([c, 'access', _36 => _36.verification, 'optionalAccess', _37 => _37.verified]) && c.fingerprint === currentFingerprint
|
|
1923
1953
|
);
|
|
1924
1954
|
const {
|
|
1925
1955
|
keyInfo: pgpKeyInfo,
|
|
1926
1956
|
proofs,
|
|
1927
1957
|
isLoading: proofsLoading
|
|
1928
|
-
} = usePGPProofs(currentFingerprint, _nullishCoalesce(_optionalChain([currentClaim, 'optionalAccess',
|
|
1958
|
+
} = usePGPProofs(currentFingerprint, _nullishCoalesce(_optionalChain([currentClaim, 'optionalAccess', _38 => _38.pgpPublicKey]), () => ( null)));
|
|
1929
1959
|
const { efp, isLoading: efpLoading } = useEFPGraph(address);
|
|
1930
1960
|
return {
|
|
1931
1961
|
address,
|
|
@@ -1964,7 +1994,7 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
|
1964
1994
|
}
|
|
1965
1995
|
const displayAddress = identity.address || null;
|
|
1966
1996
|
const verifiedProofs = identity.proofs.filter((p) => p.status === "verified").length;
|
|
1967
|
-
const hasVerifiedPgp = identity.claims.some((c) => _optionalChain([c, 'access',
|
|
1997
|
+
const hasVerifiedPgp = identity.claims.some((c) => _optionalChain([c, 'access', _39 => _39.verification, 'optionalAccess', _40 => _40.verified]) && !c.revoked);
|
|
1968
1998
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card", "data-thurin-theme": theme, children: [
|
|
1969
1999
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "a", { className: "thurin-card-header", href: profileUrl || void 0, target: "_blank", rel: "noopener noreferrer", children: [
|
|
1970
2000
|
identity.ensAvatar ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -1990,13 +2020,13 @@ function ThurinCard({ ens, address, theme = "thurin" }) {
|
|
|
1990
2020
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-label", children: "Proofs" })
|
|
1991
2021
|
] }),
|
|
1992
2022
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card-stat", children: [
|
|
1993
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-value", children: _nullishCoalesce(_optionalChain([identity, 'access',
|
|
2023
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-value", children: _nullishCoalesce(_optionalChain([identity, 'access', _41 => _41.efp, 'optionalAccess', _42 => _42.followers]), () => ( 0)) }),
|
|
1994
2024
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-stat-label", children: "Followers" })
|
|
1995
2025
|
] })
|
|
1996
2026
|
] }),
|
|
1997
2027
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "thurin-card-badges", children: [
|
|
1998
2028
|
hasVerifiedPgp && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-badge thurin-card-badge--verified", children: "PGP Verified" }),
|
|
1999
|
-
_optionalChain([identity, 'access',
|
|
2029
|
+
_optionalChain([identity, 'access', _43 => _43.efp, 'optionalAccess', _44 => _44.hasEfp]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "thurin-card-badge thurin-card-badge--verified", children: "EFP" }),
|
|
2000
2030
|
identity.proofs.map((p, i) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2001
2031
|
"span",
|
|
2002
2032
|
{
|