@pafi-dev/issuer 0.35.1 → 0.38.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.
@@ -1,6 +1,6 @@
1
1
  import { ExceptionFilter, ArgumentsHost, DynamicModule, FactoryProvider } from '@nestjs/common';
2
2
  import { PafiErrorEnvelope } from '../http/index.cjs';
3
- import { a as IssuerPublicJwk } from '../types-CxVXRHLy.cjs';
3
+ import { b as IssuerPublicJwk } from '../types-DPqLTJk-.cjs';
4
4
  import '@pafi-dev/core';
5
5
  import 'jose';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { ExceptionFilter, ArgumentsHost, DynamicModule, FactoryProvider } from '@nestjs/common';
2
2
  import { PafiErrorEnvelope } from '../http/index.js';
3
- import { a as IssuerPublicJwk } from '../types-CxVXRHLy.js';
3
+ import { b as IssuerPublicJwk } from '../types-DPqLTJk-.js';
4
4
  import '@pafi-dev/core';
5
5
  import 'jose';
6
6
 
@@ -23,6 +23,31 @@ interface IssuerPrivateJwk extends JWK {
23
23
  kid: string;
24
24
  alg?: string;
25
25
  }
26
+ /**
27
+ * Strong identifier the issuer has verified the user owns at the moment
28
+ * of this login. Drives cross-issuer wallet unification in the gateway:
29
+ * `canonical_pafi_user_id = HMAC(pepper, type + ":" + normalized_value)`,
30
+ * so the same email or wallet address used at two different issuers
31
+ * resolves to the same Privy embedded wallet.
32
+ *
33
+ * Issuers MUST only attach an attribute they have actually verified
34
+ * (email OTP confirmed, SIWE signature accepted, OAuth provider returned
35
+ * `email_verified=true`, etc.). The gateway trusts the issuer's claim —
36
+ * attaching unverified values lets users hijack wallets.
37
+ *
38
+ * Normalization rules (gateway enforces, but issuers should mirror to
39
+ * avoid surprising hash mismatches):
40
+ * - `email`: lowercase + trim. No Gmail dot-strip, no plus-tag strip.
41
+ * - `eth_wallet`: lowercase 0x-prefixed 20-byte hex.
42
+ *
43
+ * Omit entirely on logins where no strong attribute is verifiable —
44
+ * gateway falls back to legacy isolated-per-issuer canonical_id.
45
+ */
46
+ type AuthAttributeType = "email" | "eth_wallet";
47
+ interface AuthAttribute {
48
+ type: AuthAttributeType;
49
+ value: string;
50
+ }
26
51
  /**
27
52
  * Parameters for minting an issuer JWT to send to the PAFI gateway.
28
53
  */
@@ -54,11 +79,20 @@ interface SignIssuerJwtParams {
54
79
  * uses this for replay protection — must be unique per request.
55
80
  */
56
81
  jti?: string;
82
+ /**
83
+ * Optional strong identifier the user proved ownership of during this
84
+ * login. Same attribute across issuers = same wallet. See
85
+ * {@link AuthAttribute}. Omit for SIWE-pure issuers, OAuth providers
86
+ * that don't expose verified contacts, etc. — gateway then falls back
87
+ * to legacy per-issuer canonical_id isolation for this login.
88
+ */
89
+ authAttribute?: AuthAttribute;
57
90
  /**
58
91
  * Optional additional claims merged into the payload. Use sparingly —
59
- * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`.
92
+ * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`,
93
+ * and `auth_attribute`.
60
94
  */
61
95
  extra?: Record<string, unknown>;
62
96
  }
63
97
 
64
- export type { IssuerPrivateJwk as I, SignIssuerJwtParams as S, IssuerPublicJwk as a };
98
+ export type { AuthAttribute as A, IssuerPrivateJwk as I, SignIssuerJwtParams as S, AuthAttributeType as a, IssuerPublicJwk as b };
@@ -23,6 +23,31 @@ interface IssuerPrivateJwk extends JWK {
23
23
  kid: string;
24
24
  alg?: string;
25
25
  }
26
+ /**
27
+ * Strong identifier the issuer has verified the user owns at the moment
28
+ * of this login. Drives cross-issuer wallet unification in the gateway:
29
+ * `canonical_pafi_user_id = HMAC(pepper, type + ":" + normalized_value)`,
30
+ * so the same email or wallet address used at two different issuers
31
+ * resolves to the same Privy embedded wallet.
32
+ *
33
+ * Issuers MUST only attach an attribute they have actually verified
34
+ * (email OTP confirmed, SIWE signature accepted, OAuth provider returned
35
+ * `email_verified=true`, etc.). The gateway trusts the issuer's claim —
36
+ * attaching unverified values lets users hijack wallets.
37
+ *
38
+ * Normalization rules (gateway enforces, but issuers should mirror to
39
+ * avoid surprising hash mismatches):
40
+ * - `email`: lowercase + trim. No Gmail dot-strip, no plus-tag strip.
41
+ * - `eth_wallet`: lowercase 0x-prefixed 20-byte hex.
42
+ *
43
+ * Omit entirely on logins where no strong attribute is verifiable —
44
+ * gateway falls back to legacy isolated-per-issuer canonical_id.
45
+ */
46
+ type AuthAttributeType = "email" | "eth_wallet";
47
+ interface AuthAttribute {
48
+ type: AuthAttributeType;
49
+ value: string;
50
+ }
26
51
  /**
27
52
  * Parameters for minting an issuer JWT to send to the PAFI gateway.
28
53
  */
@@ -54,11 +79,20 @@ interface SignIssuerJwtParams {
54
79
  * uses this for replay protection — must be unique per request.
55
80
  */
56
81
  jti?: string;
82
+ /**
83
+ * Optional strong identifier the user proved ownership of during this
84
+ * login. Same attribute across issuers = same wallet. See
85
+ * {@link AuthAttribute}. Omit for SIWE-pure issuers, OAuth providers
86
+ * that don't expose verified contacts, etc. — gateway then falls back
87
+ * to legacy per-issuer canonical_id isolation for this login.
88
+ */
89
+ authAttribute?: AuthAttribute;
57
90
  /**
58
91
  * Optional additional claims merged into the payload. Use sparingly —
59
- * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`.
92
+ * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`,
93
+ * and `auth_attribute`.
60
94
  */
61
95
  extra?: Record<string, unknown>;
62
96
  }
63
97
 
64
- export type { IssuerPrivateJwk as I, SignIssuerJwtParams as S, IssuerPublicJwk as a };
98
+ export type { AuthAttribute as A, IssuerPrivateJwk as I, SignIssuerJwtParams as S, AuthAttributeType as a, IssuerPublicJwk as b };
@@ -38,7 +38,14 @@ async function signIssuerJwt(params) {
38
38
  const key = await (0, import_jose.importJWK)(params.privateJwk, alg);
39
39
  const now = Math.floor(Date.now() / 1e3);
40
40
  const lifetime = params.expiresInSec ?? 60;
41
- const builder = new import_jose.SignJWT({ ...params.extra ?? {} }).setProtectedHeader({ alg, typ: "JWT", kid }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? (0, import_node_crypto.randomUUID)());
41
+ const payload = { ...params.extra ?? {} };
42
+ if (params.authAttribute) {
43
+ payload.auth_attribute = {
44
+ type: params.authAttribute.type,
45
+ value: params.authAttribute.value
46
+ };
47
+ }
48
+ const builder = new import_jose.SignJWT(payload).setProtectedHeader({ alg, typ: "JWT", kid }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? (0, import_node_crypto.randomUUID)());
42
49
  return builder.sign(key);
43
50
  }
44
51
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/wallet-auth/index.ts","../../src/wallet-auth/signIssuerJwt.ts"],"sourcesContent":["/**\n * Wallet-auth helpers — for issuer backends that integrate with the\n * PAFI Wallet Auth Gateway.\n *\n * Sub-modules:\n * - signIssuerJwt : mint an issuer JWT to send to the gateway\n * - types : IssuerPublicJwk, IssuerPrivateJwk, SignIssuerJwtParams\n *\n * NestJS-specific helpers (drop-in JWKS publishing controller) live\n * under `@pafi-dev/issuer/nestjs`.\n */\n\nexport { signIssuerJwt } from \"./signIssuerJwt\";\nexport type {\n IssuerPublicJwk,\n IssuerPrivateJwk,\n SignIssuerJwtParams,\n} from \"./types\";\n","import { importJWK, SignJWT } from \"jose\";\nimport { randomUUID } from \"node:crypto\";\nimport type { SignIssuerJwtParams } from \"./types\";\n\n/**\n * Mint an issuer JWT for the PAFI Wallet Auth Gateway.\n *\n * Returns a compact JWT (header.payload.signature) ready to send as\n * the `issuer_jwt` body field in `POST /v1/token-exchange`.\n *\n * The matching public key must be reachable at the issuer's\n * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the\n * gateway can verify the signature.\n *\n * @example\n * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';\n *\n * const jwt = await signIssuerJwt({\n * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),\n * iss: 'https://gg56.com',\n * sub: 'gg56_user_99',\n * aud: 'pafi-gateway-prod',\n * });\n *\n * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway\n */\nexport async function signIssuerJwt(\n params: SignIssuerJwtParams,\n): Promise<string> {\n const alg = params.alg ?? params.privateJwk.alg ?? \"ES256\";\n const kid = params.privateJwk.kid;\n\n if (!kid) {\n throw new Error(\n \"signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)\",\n );\n }\n\n const key = await importJWK(params.privateJwk, alg);\n const now = Math.floor(Date.now() / 1000);\n const lifetime = params.expiresInSec ?? 60;\n\n const builder = new SignJWT({ ...(params.extra ?? {}) })\n .setProtectedHeader({ alg, typ: \"JWT\", kid })\n .setIssuer(params.iss)\n .setSubject(params.sub)\n .setAudience(params.aud)\n .setIssuedAt(now)\n .setExpirationTime(now + lifetime)\n .setJti(params.jti ?? randomUUID());\n\n return builder.sign(key);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAmC;AACnC,yBAA2B;AAyB3B,eAAsB,cACpB,QACiB;AACjB,QAAM,MAAM,OAAO,OAAO,OAAO,WAAW,OAAO;AACnD,QAAM,MAAM,OAAO,WAAW;AAE9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,UAAM,uBAAU,OAAO,YAAY,GAAG;AAClD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,WAAW,OAAO,gBAAgB;AAExC,QAAM,UAAU,IAAI,oBAAQ,EAAE,GAAI,OAAO,SAAS,CAAC,EAAG,CAAC,EACpD,mBAAmB,EAAE,KAAK,KAAK,OAAO,IAAI,CAAC,EAC3C,UAAU,OAAO,GAAG,EACpB,WAAW,OAAO,GAAG,EACrB,YAAY,OAAO,GAAG,EACtB,YAAY,GAAG,EACf,kBAAkB,MAAM,QAAQ,EAChC,OAAO,OAAO,WAAO,+BAAW,CAAC;AAEpC,SAAO,QAAQ,KAAK,GAAG;AACzB;","names":[]}
1
+ {"version":3,"sources":["../../src/wallet-auth/index.ts","../../src/wallet-auth/signIssuerJwt.ts"],"sourcesContent":["/**\n * Wallet-auth helpers — for issuer backends that integrate with the\n * PAFI Wallet Auth Gateway.\n *\n * Sub-modules:\n * - signIssuerJwt : mint an issuer JWT to send to the gateway\n * - types : IssuerPublicJwk, IssuerPrivateJwk, SignIssuerJwtParams\n *\n * NestJS-specific helpers (drop-in JWKS publishing controller) live\n * under `@pafi-dev/issuer/nestjs`.\n */\n\nexport { signIssuerJwt } from \"./signIssuerJwt\";\nexport type {\n AuthAttribute,\n AuthAttributeType,\n IssuerPublicJwk,\n IssuerPrivateJwk,\n SignIssuerJwtParams,\n} from \"./types\";\n","import { importJWK, SignJWT } from \"jose\";\nimport { randomUUID } from \"node:crypto\";\nimport type { SignIssuerJwtParams } from \"./types\";\n\n/**\n * Mint an issuer JWT for the PAFI Wallet Auth Gateway.\n *\n * Returns a compact JWT (header.payload.signature) ready to send as\n * the `issuer_jwt` body field in `POST /v1/token-exchange`.\n *\n * The matching public key must be reachable at the issuer's\n * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the\n * gateway can verify the signature.\n *\n * @example\n * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';\n *\n * const jwt = await signIssuerJwt({\n * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),\n * iss: 'https://gg56.com',\n * sub: 'gg56_user_99',\n * aud: 'pafi-gateway-prod',\n * });\n *\n * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway\n */\nexport async function signIssuerJwt(\n params: SignIssuerJwtParams,\n): Promise<string> {\n const alg = params.alg ?? params.privateJwk.alg ?? \"ES256\";\n const kid = params.privateJwk.kid;\n\n if (!kid) {\n throw new Error(\n \"signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)\",\n );\n }\n\n const key = await importJWK(params.privateJwk, alg);\n const now = Math.floor(Date.now() / 1000);\n const lifetime = params.expiresInSec ?? 60;\n\n const payload: Record<string, unknown> = { ...(params.extra ?? {}) };\n if (params.authAttribute) {\n payload.auth_attribute = {\n type: params.authAttribute.type,\n value: params.authAttribute.value,\n };\n }\n\n const builder = new SignJWT(payload)\n .setProtectedHeader({ alg, typ: \"JWT\", kid })\n .setIssuer(params.iss)\n .setSubject(params.sub)\n .setAudience(params.aud)\n .setIssuedAt(now)\n .setExpirationTime(now + lifetime)\n .setJti(params.jti ?? randomUUID());\n\n return builder.sign(key);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAAmC;AACnC,yBAA2B;AAyB3B,eAAsB,cACpB,QACiB;AACjB,QAAM,MAAM,OAAO,OAAO,OAAO,WAAW,OAAO;AACnD,QAAM,MAAM,OAAO,WAAW;AAE9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,UAAM,uBAAU,OAAO,YAAY,GAAG;AAClD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,WAAW,OAAO,gBAAgB;AAExC,QAAM,UAAmC,EAAE,GAAI,OAAO,SAAS,CAAC,EAAG;AACnE,MAAI,OAAO,eAAe;AACxB,YAAQ,iBAAiB;AAAA,MACvB,MAAM,OAAO,cAAc;AAAA,MAC3B,OAAO,OAAO,cAAc;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,oBAAQ,OAAO,EAChC,mBAAmB,EAAE,KAAK,KAAK,OAAO,IAAI,CAAC,EAC3C,UAAU,OAAO,GAAG,EACpB,WAAW,OAAO,GAAG,EACrB,YAAY,OAAO,GAAG,EACtB,YAAY,GAAG,EACf,kBAAkB,MAAM,QAAQ,EAChC,OAAO,OAAO,WAAO,+BAAW,CAAC;AAEpC,SAAO,QAAQ,KAAK,GAAG;AACzB;","names":[]}
@@ -1,5 +1,5 @@
1
- import { S as SignIssuerJwtParams } from '../types-CxVXRHLy.cjs';
2
- export { I as IssuerPrivateJwk, a as IssuerPublicJwk } from '../types-CxVXRHLy.cjs';
1
+ import { S as SignIssuerJwtParams } from '../types-DPqLTJk-.cjs';
2
+ export { A as AuthAttribute, a as AuthAttributeType, I as IssuerPrivateJwk, b as IssuerPublicJwk } from '../types-DPqLTJk-.cjs';
3
3
  import 'jose';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { S as SignIssuerJwtParams } from '../types-CxVXRHLy.js';
2
- export { I as IssuerPrivateJwk, a as IssuerPublicJwk } from '../types-CxVXRHLy.js';
1
+ import { S as SignIssuerJwtParams } from '../types-DPqLTJk-.js';
2
+ export { A as AuthAttribute, a as AuthAttributeType, I as IssuerPrivateJwk, b as IssuerPublicJwk } from '../types-DPqLTJk-.js';
3
3
  import 'jose';
4
4
 
5
5
  /**
@@ -14,7 +14,14 @@ async function signIssuerJwt(params) {
14
14
  const key = await importJWK(params.privateJwk, alg);
15
15
  const now = Math.floor(Date.now() / 1e3);
16
16
  const lifetime = params.expiresInSec ?? 60;
17
- const builder = new SignJWT({ ...params.extra ?? {} }).setProtectedHeader({ alg, typ: "JWT", kid }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? randomUUID());
17
+ const payload = { ...params.extra ?? {} };
18
+ if (params.authAttribute) {
19
+ payload.auth_attribute = {
20
+ type: params.authAttribute.type,
21
+ value: params.authAttribute.value
22
+ };
23
+ }
24
+ const builder = new SignJWT(payload).setProtectedHeader({ alg, typ: "JWT", kid }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? randomUUID());
18
25
  return builder.sign(key);
19
26
  }
20
27
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/wallet-auth/signIssuerJwt.ts"],"sourcesContent":["import { importJWK, SignJWT } from \"jose\";\nimport { randomUUID } from \"node:crypto\";\nimport type { SignIssuerJwtParams } from \"./types\";\n\n/**\n * Mint an issuer JWT for the PAFI Wallet Auth Gateway.\n *\n * Returns a compact JWT (header.payload.signature) ready to send as\n * the `issuer_jwt` body field in `POST /v1/token-exchange`.\n *\n * The matching public key must be reachable at the issuer's\n * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the\n * gateway can verify the signature.\n *\n * @example\n * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';\n *\n * const jwt = await signIssuerJwt({\n * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),\n * iss: 'https://gg56.com',\n * sub: 'gg56_user_99',\n * aud: 'pafi-gateway-prod',\n * });\n *\n * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway\n */\nexport async function signIssuerJwt(\n params: SignIssuerJwtParams,\n): Promise<string> {\n const alg = params.alg ?? params.privateJwk.alg ?? \"ES256\";\n const kid = params.privateJwk.kid;\n\n if (!kid) {\n throw new Error(\n \"signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)\",\n );\n }\n\n const key = await importJWK(params.privateJwk, alg);\n const now = Math.floor(Date.now() / 1000);\n const lifetime = params.expiresInSec ?? 60;\n\n const builder = new SignJWT({ ...(params.extra ?? {}) })\n .setProtectedHeader({ alg, typ: \"JWT\", kid })\n .setIssuer(params.iss)\n .setSubject(params.sub)\n .setAudience(params.aud)\n .setIssuedAt(now)\n .setExpirationTime(now + lifetime)\n .setJti(params.jti ?? randomUUID());\n\n return builder.sign(key);\n}\n"],"mappings":";;;AAAA,SAAS,WAAW,eAAe;AACnC,SAAS,kBAAkB;AAyB3B,eAAsB,cACpB,QACiB;AACjB,QAAM,MAAM,OAAO,OAAO,OAAO,WAAW,OAAO;AACnD,QAAM,MAAM,OAAO,WAAW;AAE9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,UAAU,OAAO,YAAY,GAAG;AAClD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,WAAW,OAAO,gBAAgB;AAExC,QAAM,UAAU,IAAI,QAAQ,EAAE,GAAI,OAAO,SAAS,CAAC,EAAG,CAAC,EACpD,mBAAmB,EAAE,KAAK,KAAK,OAAO,IAAI,CAAC,EAC3C,UAAU,OAAO,GAAG,EACpB,WAAW,OAAO,GAAG,EACrB,YAAY,OAAO,GAAG,EACtB,YAAY,GAAG,EACf,kBAAkB,MAAM,QAAQ,EAChC,OAAO,OAAO,OAAO,WAAW,CAAC;AAEpC,SAAO,QAAQ,KAAK,GAAG;AACzB;","names":[]}
1
+ {"version":3,"sources":["../../src/wallet-auth/signIssuerJwt.ts"],"sourcesContent":["import { importJWK, SignJWT } from \"jose\";\nimport { randomUUID } from \"node:crypto\";\nimport type { SignIssuerJwtParams } from \"./types\";\n\n/**\n * Mint an issuer JWT for the PAFI Wallet Auth Gateway.\n *\n * Returns a compact JWT (header.payload.signature) ready to send as\n * the `issuer_jwt` body field in `POST /v1/token-exchange`.\n *\n * The matching public key must be reachable at the issuer's\n * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the\n * gateway can verify the signature.\n *\n * @example\n * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';\n *\n * const jwt = await signIssuerJwt({\n * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),\n * iss: 'https://gg56.com',\n * sub: 'gg56_user_99',\n * aud: 'pafi-gateway-prod',\n * });\n *\n * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway\n */\nexport async function signIssuerJwt(\n params: SignIssuerJwtParams,\n): Promise<string> {\n const alg = params.alg ?? params.privateJwk.alg ?? \"ES256\";\n const kid = params.privateJwk.kid;\n\n if (!kid) {\n throw new Error(\n \"signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)\",\n );\n }\n\n const key = await importJWK(params.privateJwk, alg);\n const now = Math.floor(Date.now() / 1000);\n const lifetime = params.expiresInSec ?? 60;\n\n const payload: Record<string, unknown> = { ...(params.extra ?? {}) };\n if (params.authAttribute) {\n payload.auth_attribute = {\n type: params.authAttribute.type,\n value: params.authAttribute.value,\n };\n }\n\n const builder = new SignJWT(payload)\n .setProtectedHeader({ alg, typ: \"JWT\", kid })\n .setIssuer(params.iss)\n .setSubject(params.sub)\n .setAudience(params.aud)\n .setIssuedAt(now)\n .setExpirationTime(now + lifetime)\n .setJti(params.jti ?? randomUUID());\n\n return builder.sign(key);\n}\n"],"mappings":";;;AAAA,SAAS,WAAW,eAAe;AACnC,SAAS,kBAAkB;AAyB3B,eAAsB,cACpB,QACiB;AACjB,QAAM,MAAM,OAAO,OAAO,OAAO,WAAW,OAAO;AACnD,QAAM,MAAM,OAAO,WAAW;AAE9B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAM,UAAU,OAAO,YAAY,GAAG;AAClD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,WAAW,OAAO,gBAAgB;AAExC,QAAM,UAAmC,EAAE,GAAI,OAAO,SAAS,CAAC,EAAG;AACnE,MAAI,OAAO,eAAe;AACxB,YAAQ,iBAAiB;AAAA,MACvB,MAAM,OAAO,cAAc;AAAA,MAC3B,OAAO,OAAO,cAAc;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,QAAQ,OAAO,EAChC,mBAAmB,EAAE,KAAK,KAAK,OAAO,IAAI,CAAC,EAC3C,UAAU,OAAO,GAAG,EACpB,WAAW,OAAO,GAAG,EACrB,YAAY,OAAO,GAAG,EACtB,YAAY,GAAG,EACf,kBAAkB,MAAM,QAAQ,EAChC,OAAO,OAAO,OAAO,WAAW,CAAC;AAEpC,SAAO,QAAQ,KAAK,GAAG;AACzB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pafi-dev/issuer",
3
- "version": "0.35.1",
3
+ "version": "0.38.0",
4
4
  "description": "Issuer backend API and services for the PAFI point token system",
5
5
  "repository": {
6
6
  "type": "git",
@@ -55,6 +55,16 @@
55
55
  "types": "./dist/wallet-auth/index.d.cts",
56
56
  "default": "./dist/wallet-auth/index.cjs"
57
57
  }
58
+ },
59
+ "./auth-client": {
60
+ "import": {
61
+ "types": "./dist/auth-client/index.d.ts",
62
+ "default": "./dist/auth-client/index.js"
63
+ },
64
+ "require": {
65
+ "types": "./dist/auth-client/index.d.cts",
66
+ "default": "./dist/auth-client/index.cjs"
67
+ }
58
68
  }
59
69
  },
60
70
  "typesVersions": {
@@ -67,15 +77,25 @@
67
77
  ],
68
78
  "wallet-auth": [
69
79
  "./dist/wallet-auth/index.d.ts"
80
+ ],
81
+ "auth-client": [
82
+ "./dist/auth-client/index.d.ts"
70
83
  ]
71
84
  }
72
85
  },
73
86
  "files": [
74
87
  "dist"
75
88
  ],
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "test": "vitest run --passWithNoTests",
92
+ "test:watch": "vitest",
93
+ "test:cov": "vitest run --coverage --passWithNoTests",
94
+ "typecheck": "tsc --noEmit"
95
+ },
76
96
  "dependencies": {
77
- "jose": "^5.9.0",
78
- "@pafi-dev/core": "0.24.0"
97
+ "@pafi-dev/core": "workspace:*",
98
+ "jose": "^5.9.0"
79
99
  },
80
100
  "peerDependencies": {
81
101
  "@nestjs/common": "^10.0.0",
@@ -94,12 +114,5 @@
94
114
  "viem": "^2.21.0",
95
115
  "vitest": "^2.0.0"
96
116
  },
97
- "license": "Apache-2.0",
98
- "scripts": {
99
- "build": "tsup",
100
- "test": "vitest run --passWithNoTests",
101
- "test:watch": "vitest",
102
- "test:cov": "vitest run --coverage --passWithNoTests",
103
- "typecheck": "tsc --noEmit"
104
- }
105
- }
117
+ "license": "Apache-2.0"
118
+ }