@ministryofmany/client 0.1.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.
@@ -0,0 +1,206 @@
1
+ import {
2
+ badgeTypeOf,
3
+ getBadgeClaimSchema
4
+ } from "./chunk-U2JFQKFV.js";
5
+
6
+ // src/did.ts
7
+ function buildDid(domain) {
8
+ return `did:web:${domain}`;
9
+ }
10
+ function didFromIssuer(issuer) {
11
+ const url = new URL(issuer);
12
+ const host = url.port ? `${url.hostname}%3A${url.port}` : url.hostname;
13
+ return buildDid(host);
14
+ }
15
+
16
+ // src/errors.ts
17
+ var VcVerificationError = class extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "VcVerificationError";
21
+ }
22
+ };
23
+ var OidcError = class extends Error {
24
+ constructor(message) {
25
+ super(message);
26
+ this.name = "OidcError";
27
+ }
28
+ };
29
+ var MinisterTokenError = class extends Error {
30
+ constructor(message) {
31
+ super(message);
32
+ this.name = "MinisterTokenError";
33
+ }
34
+ };
35
+
36
+ // src/verify-badge.ts
37
+ import { createRemoteJWKSet } from "jose";
38
+
39
+ // src/jwt.ts
40
+ import {
41
+ jwtVerify
42
+ } from "jose";
43
+ function verifyJwt(jwt, key, options) {
44
+ if (typeof key === "function") {
45
+ return jwtVerify(jwt, key, options);
46
+ }
47
+ return jwtVerify(jwt, key, options);
48
+ }
49
+
50
+ // src/verify-badge.ts
51
+ var jwksCache = /* @__PURE__ */ new Map();
52
+ function remoteJwksFor(issuer) {
53
+ let set = jwksCache.get(issuer);
54
+ if (!set) {
55
+ set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));
56
+ jwksCache.set(issuer, set);
57
+ }
58
+ return set;
59
+ }
60
+ async function verifyMinisterBadge(vcJwt, options) {
61
+ const issuer = options.issuer.replace(/\/$/, "");
62
+ const expectedIss = didFromIssuer(issuer);
63
+ const key = options.key ?? remoteJwksFor(issuer);
64
+ let payload;
65
+ try {
66
+ const result = await verifyJwt(vcJwt, key, {
67
+ issuer: expectedIss,
68
+ algorithms: ["EdDSA"],
69
+ typ: "vc+jwt",
70
+ requiredClaims: ["exp"]
71
+ });
72
+ payload = result.payload;
73
+ } catch (cause) {
74
+ throw new VcVerificationError(
75
+ cause instanceof Error ? cause.message : String(cause)
76
+ );
77
+ }
78
+ if (typeof payload.sub !== "string" || payload.sub.length === 0) {
79
+ throw new VcVerificationError("VC payload missing string `sub`");
80
+ }
81
+ const vc = payload.vc;
82
+ if (!vc || typeof vc !== "object") {
83
+ throw new VcVerificationError("VC payload missing `vc` envelope");
84
+ }
85
+ if (!Array.isArray(vc.type) || !vc.type.every((t) => typeof t === "string")) {
86
+ throw new VcVerificationError("VC `type` must be a string array");
87
+ }
88
+ if (!vc.credentialSubject || typeof vc.credentialSubject !== "object" || Array.isArray(vc.credentialSubject)) {
89
+ throw new VcVerificationError("VC missing `credentialSubject` object");
90
+ }
91
+ const credentialSubject = vc.credentialSubject;
92
+ const subjectId = credentialSubject["id"];
93
+ if (typeof subjectId !== "string" || subjectId.length === 0) {
94
+ throw new VcVerificationError("VC `credentialSubject.id` missing");
95
+ }
96
+ if (subjectId !== payload.sub) {
97
+ throw new VcVerificationError(
98
+ "VC `credentialSubject.id` does not match `sub`"
99
+ );
100
+ }
101
+ const slug = badgeTypeOf(vc.type);
102
+ if (!slug) {
103
+ throw new VcVerificationError(
104
+ `Unknown Minister badge type: ${vc.type.join(",")}`
105
+ );
106
+ }
107
+ const { id: _id, ...rawClaims } = credentialSubject;
108
+ const schema = getBadgeClaimSchema(slug);
109
+ let claims;
110
+ try {
111
+ claims = schema ? schema.parse(rawClaims) : rawClaims;
112
+ } catch (cause) {
113
+ throw new VcVerificationError(
114
+ `Badge ${slug} claims failed validation: ${cause instanceof Error ? cause.message : String(cause)}`
115
+ );
116
+ }
117
+ return { type: slug, claims, subject: payload.sub, raw: vcJwt };
118
+ }
119
+
120
+ // src/verify-id-token.ts
121
+ import { createRemoteJWKSet as createRemoteJWKSet2 } from "jose";
122
+ var jwksCache2 = /* @__PURE__ */ new Map();
123
+ function remoteJwksFor2(issuer) {
124
+ let set = jwksCache2.get(issuer);
125
+ if (!set) {
126
+ set = createRemoteJWKSet2(new URL(`${issuer}/.well-known/jwks.json`));
127
+ jwksCache2.set(issuer, set);
128
+ }
129
+ return set;
130
+ }
131
+ async function verifyIdTokenPayload(idToken, options) {
132
+ const issuer = options.issuer.replace(/\/$/, "");
133
+ const key = options.key ?? remoteJwksFor2(issuer);
134
+ let payload;
135
+ try {
136
+ const result = await verifyJwt(idToken, key, {
137
+ issuer,
138
+ algorithms: ["EdDSA"],
139
+ requiredClaims: ["exp", "iat"],
140
+ clockTolerance: "30s",
141
+ ...options.clientId ? { audience: options.clientId } : {}
142
+ });
143
+ payload = result.payload;
144
+ } catch (cause) {
145
+ throw new MinisterTokenError(cause instanceof Error ? cause.message : String(cause));
146
+ }
147
+ if (options.nonce !== void 0 && payload["nonce"] !== options.nonce) {
148
+ throw new MinisterTokenError("id_token `nonce` mismatch");
149
+ }
150
+ if (typeof payload.sub !== "string" || payload.sub.length === 0) {
151
+ throw new MinisterTokenError("id_token missing string `sub`");
152
+ }
153
+ return payload;
154
+ }
155
+ function claimsFromPayload(payload, raw) {
156
+ return {
157
+ sub: payload.sub,
158
+ name: typeof payload["name"] === "string" ? payload["name"] : void 0,
159
+ picture: typeof payload["picture"] === "string" ? payload["picture"] : void 0,
160
+ raw
161
+ };
162
+ }
163
+ async function verifyMinisterIdToken(idToken, options) {
164
+ const payload = await verifyIdTokenPayload(idToken, options);
165
+ return claimsFromPayload(payload, idToken);
166
+ }
167
+
168
+ // src/verify-badges.ts
169
+ async function verifyMinisterBadges(tokenOrPayload, options) {
170
+ const payload = typeof tokenOrPayload === "string" ? await verifyIdTokenPayload(tokenOrPayload, options) : tokenOrPayload;
171
+ const raw = payload["minister_badges"];
172
+ if (raw === void 0 || raw === null) return { badges: [], rejected: [] };
173
+ if (!Array.isArray(raw)) {
174
+ return { badges: [], rejected: [{ raw: String(raw), error: new VcVerificationError("minister_badges is not an array") }] };
175
+ }
176
+ const result = { badges: [], rejected: [] };
177
+ for (const entry of raw) {
178
+ if (typeof entry !== "string") {
179
+ result.rejected.push({ raw: String(entry), error: new VcVerificationError("badge entry is not a JWT string") });
180
+ continue;
181
+ }
182
+ try {
183
+ result.badges.push(await verifyMinisterBadge(entry, { issuer: options.issuer, key: options.key }));
184
+ } catch (cause) {
185
+ result.rejected.push({
186
+ raw: entry,
187
+ error: cause instanceof VcVerificationError ? cause : new VcVerificationError(String(cause))
188
+ });
189
+ }
190
+ }
191
+ return result;
192
+ }
193
+
194
+ export {
195
+ buildDid,
196
+ didFromIssuer,
197
+ VcVerificationError,
198
+ OidcError,
199
+ MinisterTokenError,
200
+ verifyMinisterBadge,
201
+ verifyIdTokenPayload,
202
+ claimsFromPayload,
203
+ verifyMinisterIdToken,
204
+ verifyMinisterBadges
205
+ };
206
+ //# sourceMappingURL=chunk-CSD6YO64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/did.ts","../src/errors.ts","../src/verify-badge.ts","../src/jwt.ts","../src/verify-id-token.ts","../src/verify-badges.ts"],"sourcesContent":["// did:web identifier for a domain. Per the W3C did:web spec the DID\n// document is served at https://<domain>/.well-known/did.json. Mirrors\n// `@minister/vc`'s `buildDid` so the VC `iss` this SDK expects matches\n// exactly what Minister stamps when issuing.\nexport function buildDid(domain: string): string {\n return `did:web:${domain}`;\n}\n\n// Derive the issuer DID from a Minister origin (the OIDC `issuer`).\n// Minister signs VCs with `iss = did:web:<host>` where <host> is the\n// origin's host (including a non-default port, encoded per did:web as\n// `host%3Aport`). e.g. \"https://ministry.id\" -> \"did:web:ministry.id\".\nexport function didFromIssuer(issuer: string): string {\n const url = new URL(issuer);\n // did:web encodes a port by percent-encoding the colon.\n const host = url.port ? `${url.hostname}%3A${url.port}` : url.hostname;\n return buildDid(host);\n}\n","// Thrown when a verifiable-credential badge fails verification — bad\n// signature, wrong issuer, malformed envelope, or a subject-binding\n// mismatch. Mirrors `@minister/vc`'s `VcVerificationError`.\n// Its message may include VC-derived text; do not reflect it to untrusted output.\nexport class VcVerificationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"VcVerificationError\";\n }\n}\n\n// Thrown when the OIDC flow fails for a non-token reason - missing client\n// config, discovery, the token-exchange request, or a malformed token\n// response. id_token verification failures throw MinisterTokenError;\n// individual bad badges are reported in BadgesResult.rejected, not thrown.\nexport class OidcError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OidcError\";\n }\n}\n\n// Thrown when an id_token itself fails verification - signature, issuer,\n// audience, expiry, or nonce. The token is the trust root, so this is a\n// hard failure (distinct from an individual bad badge, which is reported\n// in BadgesResult.rejected rather than thrown).\n// Its message may include token-derived text; do not reflect it to untrusted output.\nexport class MinisterTokenError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"MinisterTokenError\";\n }\n}\n","import { createRemoteJWKSet } from \"jose\";\n\nimport { badgeTypeOf, getBadgeClaimSchema } from \"./badges/helpers\";\nimport { didFromIssuer } from \"./did\";\nimport { verifyJwt } from \"./jwt\";\nimport { VcVerificationError } from \"./errors\";\nimport type { KeyInput, VerifiedBadge } from \"./types\";\n\n// Verify a Minister-issued verifiable credential against Minister's\n// PUBLIC keys. Unlike `@minister/vc`'s `verifyVc` (which threads a full\n// Issuer carrying the private key), an RP only ever holds public\n// material — the JWKS Minister serves at /.well-known/jwks.json.\n\n// Cache one remote JWKS per issuer for the process lifetime. The set\n// fetches lazily and rotates keys on its own.\n// Cache key is the trusted RP-config issuer (not request input), so this stays bounded.\nconst jwksCache = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\n\nfunction remoteJwksFor(issuer: string): ReturnType<typeof createRemoteJWKSet> {\n let set = jwksCache.get(issuer);\n if (!set) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));\n jwksCache.set(issuer, set);\n }\n return set;\n}\n\nexport interface VerifyBadgeOptions {\n // Minister origin, e.g. \"https://ministry.id\".\n issuer: string;\n // Inject the verification key (defaults to the remote JWKS). Pass a\n // public JWK in tests so verification never touches the network.\n key?: KeyInput;\n}\n\n// Verify a received VC JWT.\n//\n// Beyond `@minister/vc`'s structural checks, this ALSO asserts\n// `credentialSubject.id === payload.sub` — the holder-binding invariant\n// `@minister/vc` does not currently enforce. Without it, a VC's claims\n// could be presented as bound to a subject other than the one the\n// issuer signed them for.\nexport async function verifyMinisterBadge(\n vcJwt: string,\n options: VerifyBadgeOptions,\n): Promise<VerifiedBadge> {\n const issuer = options.issuer.replace(/\\/$/, \"\");\n const expectedIss = didFromIssuer(issuer);\n const key = options.key ?? remoteJwksFor(issuer);\n\n let payload;\n try {\n const result = await verifyJwt(vcJwt, key, {\n issuer: expectedIss,\n algorithms: [\"EdDSA\"],\n typ: \"vc+jwt\",\n requiredClaims: [\"exp\"],\n });\n payload = result.payload;\n } catch (cause) {\n throw new VcVerificationError(\n cause instanceof Error ? cause.message : String(cause),\n );\n }\n\n if (typeof payload.sub !== \"string\" || payload.sub.length === 0) {\n throw new VcVerificationError(\"VC payload missing string `sub`\");\n }\n\n const vc = payload.vc as\n | { type?: unknown; credentialSubject?: unknown }\n | undefined;\n if (!vc || typeof vc !== \"object\") {\n throw new VcVerificationError(\"VC payload missing `vc` envelope\");\n }\n if (!Array.isArray(vc.type) || !vc.type.every((t) => typeof t === \"string\")) {\n throw new VcVerificationError(\"VC `type` must be a string array\");\n }\n if (\n !vc.credentialSubject ||\n typeof vc.credentialSubject !== \"object\" ||\n Array.isArray(vc.credentialSubject)\n ) {\n throw new VcVerificationError(\"VC missing `credentialSubject` object\");\n }\n\n const credentialSubject = vc.credentialSubject as Record<string, unknown>;\n const subjectId = credentialSubject[\"id\"];\n if (typeof subjectId !== \"string\" || subjectId.length === 0) {\n throw new VcVerificationError(\"VC `credentialSubject.id` missing\");\n }\n\n // Holder-binding invariant: the JWT subject must equal the credential\n // subject the issuer signed. (Additional check beyond @minister/vc.)\n if (subjectId !== payload.sub) {\n throw new VcVerificationError(\n \"VC `credentialSubject.id` does not match `sub`\",\n );\n }\n\n // Map the VC type to a known Minister badge slug.\n const slug = badgeTypeOf(vc.type as string[]);\n if (!slug) {\n throw new VcVerificationError(\n `Unknown Minister badge type: ${(vc.type as string[]).join(\",\")}`,\n );\n }\n\n // Validate the claims against that badge type's schema. `id` is\n // stripped — it's redundant with `sub` and not part of the claims.\n const { id: _id, ...rawClaims } = credentialSubject;\n const schema = getBadgeClaimSchema(slug);\n let claims: Record<string, unknown>;\n try {\n claims = schema\n ? (schema.parse(rawClaims) as Record<string, unknown>)\n : rawClaims;\n } catch (cause) {\n throw new VcVerificationError(\n `Badge ${slug} claims failed validation: ${\n cause instanceof Error ? cause.message : String(cause)\n }`,\n );\n }\n\n return { type: slug, claims, subject: payload.sub, raw: vcJwt };\n}\n\n// Test seam: drop the cached remote JWKS for an issuer (or all issuers).\nexport function _resetBadgeJwksCache(issuer?: string): void {\n if (issuer) jwksCache.delete(issuer.replace(/\\/$/, \"\"));\n else jwksCache.clear();\n}\n","import {\n jwtVerify,\n type JWTPayload,\n type JWTVerifyOptions,\n type JWTVerifyResult,\n} from \"jose\";\n\nimport type { KeyInput } from \"./types\";\n\n// jose's `jwtVerify` is overloaded: one signature takes a resolved key\n// (KeyLike/Uint8Array), the other a key-resolver function (e.g.\n// createRemoteJWKSet). `KeyInput` is the union of both, which doesn't\n// match either overload directly. Narrow on `typeof key` and dispatch to\n// the right call so the rest of the SDK can pass a single injectable\n// key source.\nexport function verifyJwt(\n jwt: string,\n key: KeyInput,\n options: JWTVerifyOptions,\n): Promise<JWTVerifyResult<JWTPayload>> {\n if (typeof key === \"function\") {\n return jwtVerify(jwt, key, options);\n }\n return jwtVerify(jwt, key, options);\n}\n","import { createRemoteJWKSet, type JWTPayload } from \"jose\";\nimport { verifyJwt } from \"./jwt\";\nimport { MinisterTokenError } from \"./errors\";\nimport type { KeyInput, MinisterClaims } from \"./types\";\n\n// Cache key is the trusted RP-config issuer (not request input), so this stays bounded.\nconst jwksCache = new Map<string, ReturnType<typeof createRemoteJWKSet>>();\nfunction remoteJwksFor(issuer: string) {\n let set = jwksCache.get(issuer);\n if (!set) {\n set = createRemoteJWKSet(new URL(`${issuer}/.well-known/jwks.json`));\n jwksCache.set(issuer, set);\n }\n return set;\n}\n\nexport interface VerifyIdTokenOptions {\n issuer: string;\n // When set, the id_token `aud` must equal it. Omit only to skip audience enforcement.\n clientId?: string;\n // Replay nonce; when set, must equal the id_token `nonce`.\n nonce?: string;\n // Inject the verification key (defaults to the remote JWKS).\n key?: KeyInput;\n}\n\n// Internal: verify the id_token and return the full payload (callers that\n// need minister_badges use this; verifyMinisterIdToken maps to claims).\nexport async function verifyIdTokenPayload(idToken: string, options: VerifyIdTokenOptions): Promise<JWTPayload> {\n const issuer = options.issuer.replace(/\\/$/, \"\");\n const key = options.key ?? remoteJwksFor(issuer);\n let payload: JWTPayload;\n try {\n const result = await verifyJwt(idToken, key, {\n issuer,\n algorithms: [\"EdDSA\"],\n requiredClaims: [\"exp\", \"iat\"],\n clockTolerance: \"30s\",\n ...(options.clientId ? { audience: options.clientId } : {}),\n });\n payload = result.payload;\n } catch (cause) {\n throw new MinisterTokenError(cause instanceof Error ? cause.message : String(cause));\n }\n if (options.nonce !== undefined && payload[\"nonce\"] !== options.nonce) {\n throw new MinisterTokenError(\"id_token `nonce` mismatch\");\n }\n if (typeof payload.sub !== \"string\" || payload.sub.length === 0) {\n throw new MinisterTokenError(\"id_token missing string `sub`\");\n }\n return payload;\n}\n\n// Map a verified id_token payload to the public identity claims. Shared by\n// verifyMinisterIdToken and the flow client so the mapping lives in one place.\nexport function claimsFromPayload(payload: JWTPayload, raw: string): MinisterClaims {\n return {\n sub: payload.sub as string,\n name: typeof payload[\"name\"] === \"string\" ? (payload[\"name\"] as string) : undefined,\n picture: typeof payload[\"picture\"] === \"string\" ? (payload[\"picture\"] as string) : undefined,\n raw,\n };\n}\n\n// Verify a Minister id_token and return its identity claims.\nexport async function verifyMinisterIdToken(idToken: string, options: VerifyIdTokenOptions): Promise<MinisterClaims> {\n const payload = await verifyIdTokenPayload(idToken, options);\n return claimsFromPayload(payload, idToken);\n}\n\nexport function _resetIdTokenJwksCache(issuer?: string): void {\n if (issuer) jwksCache.delete(issuer.replace(/\\/$/, \"\"));\n else jwksCache.clear();\n}\n","import type { JWTPayload } from \"jose\";\nimport { verifyMinisterBadge } from \"./verify-badge\";\nimport { verifyIdTokenPayload } from \"./verify-id-token\";\nimport { VcVerificationError } from \"./errors\";\nimport type { KeyInput, BadgesResult } from \"./types\";\n\nexport interface VerifyBadgesOptions {\n issuer: string;\n // Needed only when a raw id_token string is passed (to verify the wrapper).\n clientId?: string;\n key?: KeyInput;\n}\n\n// Verify the `minister_badges` carried by a token.\n//\n// - Given a raw id_token STRING, the wrapper is verified first (throws\n// MinisterTokenError if it fails), then its badges are read.\n// - Given an already-verified PAYLOAD object (e.g. Auth.js's profile, or\n// a prior verifyIdToken result), the wrapper is trusted and only the\n// badges are verified.\n//\n// Individual bad badges never throw — they are returned in `rejected`.\nexport async function verifyMinisterBadges(\n tokenOrPayload: string | JWTPayload,\n options: VerifyBadgesOptions,\n): Promise<BadgesResult> {\n // For the string path, the whole `options` object is forwarded to the\n // id_token verifier, so its `clientId` (audience) and `key` are honored\n // when verifying the wrapper. Do not narrow this to `{ issuer }` - that\n // would silently drop audience enforcement on the string path.\n const payload =\n typeof tokenOrPayload === \"string\"\n ? await verifyIdTokenPayload(tokenOrPayload, options)\n : tokenOrPayload;\n\n const raw = (payload as Record<string, unknown>)[\"minister_badges\"];\n if (raw === undefined || raw === null) return { badges: [], rejected: [] };\n if (!Array.isArray(raw)) {\n return { badges: [], rejected: [{ raw: String(raw), error: new VcVerificationError(\"minister_badges is not an array\") }] };\n }\n\n const result: BadgesResult = { badges: [], rejected: [] };\n for (const entry of raw) {\n if (typeof entry !== \"string\") {\n result.rejected.push({ raw: String(entry), error: new VcVerificationError(\"badge entry is not a JWT string\") });\n continue;\n }\n try {\n result.badges.push(await verifyMinisterBadge(entry, { issuer: options.issuer, key: options.key }));\n } catch (cause) {\n result.rejected.push({\n raw: entry,\n error: cause instanceof VcVerificationError ? cause : new VcVerificationError(String(cause)),\n });\n }\n }\n return result;\n}\n"],"mappings":"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","names":["createRemoteJWKSet","jwksCache","remoteJwksFor","createRemoteJWKSet"]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-R4XGCZVA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,105 @@
1
+ // src/badges/schemas.ts
2
+ import { z } from "zod";
3
+ var EmailDomainClaims = z.object({
4
+ domain: z.string().min(1).toLowerCase().regex(/^[a-z0-9.-]+\.[a-z]{2,}$/u, "Not a valid domain")
5
+ });
6
+ var EmailExactClaims = z.object({ email: z.string().email().toLowerCase() });
7
+ var OAUTH_PROVIDERS = ["github", "google", "discord"];
8
+ var OAuthAccountClaims = z.object({
9
+ provider: z.enum(OAUTH_PROVIDERS),
10
+ accountId: z.string().min(1),
11
+ handle: z.string().min(1).optional()
12
+ });
13
+ var AGE_THRESHOLDS = [16, 18, 21, 25, 30, 35, 40, 45, 55, 65];
14
+ var AgeOverClaimsFor = (threshold) => z.object({ threshold: z.literal(threshold) });
15
+ var COUNTRY_RE = /^[A-Z]{2}$/u;
16
+ var ResidencyCountryClaims = z.object({ country: z.string().regex(COUNTRY_RE) });
17
+ var ResidencyStateClaims = z.object({
18
+ country: z.string().regex(COUNTRY_RE),
19
+ state: z.string().min(1)
20
+ });
21
+ var ResidencyCityClaims = z.object({
22
+ country: z.string().regex(COUNTRY_RE),
23
+ state: z.string().min(1),
24
+ city: z.string().min(1)
25
+ });
26
+ var InviteCodeClaims = z.object({ label: z.string().min(1) });
27
+ var TlsnAttestationClaims = z.object({
28
+ domain: z.string().min(1),
29
+ claim: z.string().min(1)
30
+ }).strict();
31
+
32
+ // src/badges/registry.ts
33
+ function defineBadgeType(input) {
34
+ return { ...input, scope: `badge:${input.slug}` };
35
+ }
36
+ var ENTRIES = [
37
+ defineBadgeType({ slug: "email-domain", credentialType: "MinisterEmailDomainCredential", claims: EmailDomainClaims }),
38
+ defineBadgeType({ slug: "email-exact", credentialType: "MinisterEmailExactCredential", claims: EmailExactClaims }),
39
+ defineBadgeType({ slug: "oauth-account", credentialType: "MinisterOauthAccountCredential", claims: OAuthAccountClaims }),
40
+ defineBadgeType({ slug: "residency-country", credentialType: "MinisterResidencyCountryCredential", claims: ResidencyCountryClaims }),
41
+ defineBadgeType({ slug: "residency-state", credentialType: "MinisterResidencyStateCredential", claims: ResidencyStateClaims }),
42
+ defineBadgeType({ slug: "residency-city", credentialType: "MinisterResidencyCityCredential", claims: ResidencyCityClaims }),
43
+ defineBadgeType({ slug: "invite-code", credentialType: "MinisterInviteCodeCredential", claims: InviteCodeClaims }),
44
+ defineBadgeType({ slug: "tlsn-attestation", credentialType: "MinisterTlsnAttestationCredential", claims: TlsnAttestationClaims }),
45
+ ...AGE_THRESHOLDS.map(
46
+ (t) => defineBadgeType({
47
+ slug: `age-over-${t}`,
48
+ credentialType: `MinisterAgeOver${t}Credential`,
49
+ claims: AgeOverClaimsFor(t)
50
+ })
51
+ )
52
+ ];
53
+ var BADGE_TYPES = Object.fromEntries(
54
+ ENTRIES.map((d) => [d.slug, d])
55
+ );
56
+ var CREDENTIAL_TYPE_INDEX = Object.fromEntries(
57
+ ENTRIES.map((d) => [d.credentialType, d.slug])
58
+ );
59
+ function slugForCredentialType(credentialType) {
60
+ return CREDENTIAL_TYPE_INDEX[credentialType];
61
+ }
62
+
63
+ // src/badges/helpers.ts
64
+ function badgeScope(slug) {
65
+ return `badge:${slug}`;
66
+ }
67
+ function badgeScopes(slugs) {
68
+ return slugs.map(badgeScope);
69
+ }
70
+ function badgeTypeOf(vcType) {
71
+ for (const t of vcType) {
72
+ const slug = slugForCredentialType(t);
73
+ if (slug) return slug;
74
+ }
75
+ return void 0;
76
+ }
77
+ function getBadgeClaimSchema(slug) {
78
+ return BADGE_TYPES[slug]?.claims;
79
+ }
80
+ function knownBadgeTypes() {
81
+ return Object.keys(BADGE_TYPES);
82
+ }
83
+
84
+ export {
85
+ EmailDomainClaims,
86
+ EmailExactClaims,
87
+ OAUTH_PROVIDERS,
88
+ OAuthAccountClaims,
89
+ AGE_THRESHOLDS,
90
+ AgeOverClaimsFor,
91
+ ResidencyCountryClaims,
92
+ ResidencyStateClaims,
93
+ ResidencyCityClaims,
94
+ InviteCodeClaims,
95
+ TlsnAttestationClaims,
96
+ defineBadgeType,
97
+ BADGE_TYPES,
98
+ slugForCredentialType,
99
+ badgeScope,
100
+ badgeScopes,
101
+ badgeTypeOf,
102
+ getBadgeClaimSchema,
103
+ knownBadgeTypes
104
+ };
105
+ //# sourceMappingURL=chunk-U2JFQKFV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/badges/schemas.ts","../src/badges/registry.ts","../src/badges/helpers.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const EmailDomainClaims = z.object({\n domain: z\n .string()\n .min(1)\n .toLowerCase()\n .regex(/^[a-z0-9.-]+\\.[a-z]{2,}$/u, \"Not a valid domain\"),\n});\nexport type EmailDomainClaims = z.infer<typeof EmailDomainClaims>;\n\nexport const EmailExactClaims = z.object({ email: z.string().email().toLowerCase() });\nexport type EmailExactClaims = z.infer<typeof EmailExactClaims>;\n\nexport const OAUTH_PROVIDERS = [\"github\", \"google\", \"discord\"] as const;\nexport const OAuthAccountClaims = z.object({\n provider: z.enum(OAUTH_PROVIDERS),\n accountId: z.string().min(1),\n handle: z.string().min(1).optional(),\n});\nexport type OAuthAccountClaims = z.infer<typeof OAuthAccountClaims>;\n\nexport const AGE_THRESHOLDS = [16, 18, 21, 25, 30, 35, 40, 45, 55, 65] as const;\nexport type AgeThreshold = (typeof AGE_THRESHOLDS)[number];\nexport const AgeOverClaimsFor = (threshold: AgeThreshold) =>\n z.object({ threshold: z.literal(threshold) });\n\nconst COUNTRY_RE = /^[A-Z]{2}$/u; // ISO 3166-1 alpha-2\nexport const ResidencyCountryClaims = z.object({ country: z.string().regex(COUNTRY_RE) });\nexport const ResidencyStateClaims = z.object({\n country: z.string().regex(COUNTRY_RE),\n state: z.string().min(1),\n});\nexport const ResidencyCityClaims = z.object({\n country: z.string().regex(COUNTRY_RE),\n state: z.string().min(1),\n city: z.string().min(1),\n});\nexport type ResidencyCountryClaims = z.infer<typeof ResidencyCountryClaims>;\nexport type ResidencyStateClaims = z.infer<typeof ResidencyStateClaims>;\nexport type ResidencyCityClaims = z.infer<typeof ResidencyCityClaims>;\n\n// The label identifies the invite campaign/cohort, not the code - the\n// code string itself never appears in claims.\nexport const InviteCodeClaims = z.object({ label: z.string().min(1) });\nexport type InviteCodeClaims = z.infer<typeof InviteCodeClaims>;\n\n// Generic TLSNotary attestation: domain plus a single structured claim.\n// Strict (no `.passthrough()`): unknown keys are rejected.\nexport const TlsnAttestationClaims = z\n .object({\n domain: z.string().min(1),\n claim: z.string().min(1),\n })\n .strict();\nexport type TlsnAttestationClaims = z.infer<typeof TlsnAttestationClaims>;\n","import type { z } from \"zod\";\nimport {\n EmailDomainClaims,\n EmailExactClaims,\n OAuthAccountClaims,\n ResidencyCountryClaims,\n ResidencyStateClaims,\n ResidencyCityClaims,\n InviteCodeClaims,\n TlsnAttestationClaims,\n AGE_THRESHOLDS,\n AgeOverClaimsFor,\n} from \"./schemas\";\n\n// One self-describing badge type. Adding a Minister badge type to this\n// SDK is a single `defineBadgeType(...)` entry; every helper, scope, and\n// the verifier's type->slug mapping derive from BADGE_TYPES.\nexport interface BadgeTypeDef {\n // Minister badge slug, e.g. \"email-domain\".\n slug: string;\n // The VC `type[]` entry Minister stamps, e.g. \"MinisterEmailDomainCredential\".\n credentialType: string;\n // The OIDC scope a relying party requests to ask for this badge.\n scope: string;\n // Zod schema for the credentialSubject claims (excluding `id`).\n claims: z.ZodType<unknown>;\n}\n\n// Build a BadgeTypeDef, deriving `scope` from the slug.\nexport function defineBadgeType(input: {\n slug: string;\n credentialType: string;\n claims: z.ZodType<unknown>;\n}): BadgeTypeDef {\n return { ...input, scope: `badge:${input.slug}` };\n}\n\n// NOTE: `credentialType` values must match Minister's @minister/shared\n// `ministerCredentialType(slug)` output exactly. If a future Minister slug\n// uses irregular casing, fix the literal here (this file is the one place\n// to do it). The planned drift-check will assert these against @minister/shared.\nconst ENTRIES: BadgeTypeDef[] = [\n defineBadgeType({ slug: \"email-domain\", credentialType: \"MinisterEmailDomainCredential\", claims: EmailDomainClaims }),\n defineBadgeType({ slug: \"email-exact\", credentialType: \"MinisterEmailExactCredential\", claims: EmailExactClaims }),\n defineBadgeType({ slug: \"oauth-account\", credentialType: \"MinisterOauthAccountCredential\", claims: OAuthAccountClaims }),\n defineBadgeType({ slug: \"residency-country\", credentialType: \"MinisterResidencyCountryCredential\", claims: ResidencyCountryClaims }),\n defineBadgeType({ slug: \"residency-state\", credentialType: \"MinisterResidencyStateCredential\", claims: ResidencyStateClaims }),\n defineBadgeType({ slug: \"residency-city\", credentialType: \"MinisterResidencyCityCredential\", claims: ResidencyCityClaims }),\n defineBadgeType({ slug: \"invite-code\", credentialType: \"MinisterInviteCodeCredential\", claims: InviteCodeClaims }),\n defineBadgeType({ slug: \"tlsn-attestation\", credentialType: \"MinisterTlsnAttestationCredential\", claims: TlsnAttestationClaims }),\n ...AGE_THRESHOLDS.map((t) =>\n defineBadgeType({\n slug: `age-over-${t}`,\n credentialType: `MinisterAgeOver${t}Credential`,\n claims: AgeOverClaimsFor(t),\n }),\n ),\n];\n\n// slug -> def\nexport const BADGE_TYPES: Record<string, BadgeTypeDef> = Object.fromEntries(\n ENTRIES.map((d) => [d.slug, d]),\n);\n\n// credentialType -> slug (reverse index for badgeTypeOf)\nconst CREDENTIAL_TYPE_INDEX: Record<string, string> = Object.fromEntries(\n ENTRIES.map((d) => [d.credentialType, d.slug]),\n);\n\n// The Minister badge slug for a VC credentialType, or undefined if unknown.\nexport function slugForCredentialType(credentialType: string): string | undefined {\n return CREDENTIAL_TYPE_INDEX[credentialType];\n}\n","import type { z } from \"zod\";\nimport { BADGE_TYPES, slugForCredentialType } from \"./registry\";\n\n// The OIDC scope a relying party requests to ask for a badge type.\nexport function badgeScope(slug: string): string {\n return `badge:${slug}`;\n}\n\n// Map an array of slugs to their scope strings.\nexport function badgeScopes(slugs: string[]): string[] {\n return slugs.map(badgeScope);\n}\n\n// Given a VC `type` array, return the Minister badge slug it represents,\n// or undefined if it is not a known Minister badge type.\nexport function badgeTypeOf(vcType: string[]): string | undefined {\n for (const t of vcType) {\n const slug = slugForCredentialType(t);\n if (slug) return slug;\n }\n return undefined;\n}\n\n// The Zod claim schema for a badge slug, or undefined if unknown.\nexport function getBadgeClaimSchema(slug: string): z.ZodType<unknown> | undefined {\n return BADGE_TYPES[slug]?.claims;\n}\n\n// Every badge slug this SDK knows.\nexport function knownBadgeTypes(): string[] {\n return Object.keys(BADGE_TYPES);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,75 @@
1
+ import { K as KeyInput, V as VerifiedBadge, E as ExchangeResult, P as PkcePair, M as MinisterClientConfig, a as MinisterClaims, B as BadgesResult } from './types-BHY-mOJf.js';
2
+ export { b as MinisterTokenError, O as OidcError, c as OidcFlowState, R as RejectedBadge, d as VcVerificationError } from './types-BHY-mOJf.js';
3
+ import { JWTPayload } from 'jose';
4
+ export { AGE_THRESHOLDS, AgeOverClaimsFor, AgeThreshold, BADGE_TYPES, BadgeTypeDef, EmailDomainClaims, EmailExactClaims, InviteCodeClaims, OAUTH_PROVIDERS, OAuthAccountClaims, ResidencyCityClaims, ResidencyCountryClaims, ResidencyStateClaims, TlsnAttestationClaims, badgeScope, badgeScopes, badgeTypeOf, defineBadgeType, getBadgeClaimSchema, knownBadgeTypes, slugForCredentialType } from './badges/index.js';
5
+ import 'zod';
6
+
7
+ interface GetAuthorizationUrlArgs {
8
+ scopes: string[];
9
+ state: string;
10
+ nonce: string;
11
+ codeChallenge: string;
12
+ extraParams?: Record<string, string>;
13
+ }
14
+ interface ExchangeCodeArgs {
15
+ code: string;
16
+ codeVerifier: string;
17
+ expectedNonce: string;
18
+ idTokenKey?: KeyInput;
19
+ badgeKey?: KeyInput;
20
+ }
21
+
22
+ interface VerifyBadgeOptions {
23
+ issuer: string;
24
+ key?: KeyInput;
25
+ }
26
+ declare function verifyMinisterBadge(vcJwt: string, options: VerifyBadgeOptions): Promise<VerifiedBadge>;
27
+
28
+ interface MinisterClient {
29
+ getAuthorizationUrl(args: GetAuthorizationUrlArgs): Promise<string>;
30
+ exchangeCode(args: ExchangeCodeArgs): Promise<ExchangeResult>;
31
+ verifyMinisterBadge(vcJwt: string, options?: {
32
+ key?: KeyInput;
33
+ }): ReturnType<typeof verifyMinisterBadge>;
34
+ generatePkce(): Promise<PkcePair>;
35
+ randomToken(bytes?: number): string;
36
+ badgeScope(slug: string): string;
37
+ }
38
+ declare function createMinisterClient(config: MinisterClientConfig): MinisterClient;
39
+
40
+ declare function generatePkce(): Promise<PkcePair>;
41
+ declare function randomUrlToken(bytes?: number): string;
42
+
43
+ declare function buildDid(domain: string): string;
44
+ declare function didFromIssuer(issuer: string): string;
45
+
46
+ interface MinisterVerifierConfig {
47
+ issuer: string;
48
+ clientId?: string;
49
+ jwks?: KeyInput;
50
+ }
51
+ interface MinisterVerifier {
52
+ verifyIdToken(idToken: string, opts?: {
53
+ nonce?: string;
54
+ }): Promise<MinisterClaims>;
55
+ verifyBadges(tokenOrPayload: string | JWTPayload): Promise<BadgesResult>;
56
+ verifyBadge(vcJwt: string): Promise<VerifiedBadge>;
57
+ }
58
+ declare function createMinisterVerifier(config: MinisterVerifierConfig): MinisterVerifier;
59
+
60
+ interface VerifyIdTokenOptions {
61
+ issuer: string;
62
+ clientId?: string;
63
+ nonce?: string;
64
+ key?: KeyInput;
65
+ }
66
+ declare function verifyMinisterIdToken(idToken: string, options: VerifyIdTokenOptions): Promise<MinisterClaims>;
67
+
68
+ interface VerifyBadgesOptions {
69
+ issuer: string;
70
+ clientId?: string;
71
+ key?: KeyInput;
72
+ }
73
+ declare function verifyMinisterBadges(tokenOrPayload: string | JWTPayload, options: VerifyBadgesOptions): Promise<BadgesResult>;
74
+
75
+ export { BadgesResult, type ExchangeCodeArgs, ExchangeResult, type GetAuthorizationUrlArgs, KeyInput, MinisterClaims, type MinisterClient, MinisterClientConfig, type MinisterVerifier, type MinisterVerifierConfig, PkcePair, VerifiedBadge, type VerifyBadgeOptions, type VerifyBadgesOptions, type VerifyIdTokenOptions, buildDid, createMinisterClient, createMinisterVerifier, didFromIssuer, generatePkce, randomUrlToken, verifyMinisterBadge, verifyMinisterBadges, verifyMinisterIdToken };