@pafi-dev/issuer 0.39.2 → 0.40.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.
@@ -5,21 +5,29 @@ import {
5
5
  payloadFromGenericError,
6
6
  payloadFromHttpException,
7
7
  payloadFromPafiSdkError
8
- } from "../chunk-QLNGNH4A.js";
8
+ } from "../chunk-RNQQYJIB.js";
9
9
  import {
10
- __decorateClass,
11
- __decorateParam
12
- } from "../chunk-BRKEJJFQ.js";
10
+ __name
11
+ } from "../chunk-7QVYU63E.js";
13
12
 
14
13
  // src/nestjs/httpExceptionFilter.ts
15
- import {
16
- Catch,
17
- HttpException,
18
- HttpStatus,
19
- Logger
20
- } from "@nestjs/common";
14
+ import { Catch, HttpException, HttpStatus, Logger } from "@nestjs/common";
21
15
  import { randomUUID } from "crypto";
16
+ function _ts_decorate(decorators, target, key, desc) {
17
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
18
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
19
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
21
+ }
22
+ __name(_ts_decorate, "_ts_decorate");
23
+ function _ts_metadata(k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ }
26
+ __name(_ts_metadata, "_ts_metadata");
22
27
  var PafiHttpExceptionFilter = class {
28
+ static {
29
+ __name(this, "PafiHttpExceptionFilter");
30
+ }
23
31
  logger = new Logger("PafiHttpExceptionFilter");
24
32
  opts;
25
33
  constructor(options = {}) {
@@ -37,31 +45,33 @@ var PafiHttpExceptionFilter = class {
37
45
  const normCtx = {
38
46
  path: request?.url ?? "",
39
47
  requestId,
40
- ...this.opts.now ? { now: this.opts.now } : {}
48
+ ...this.opts.now ? {
49
+ now: this.opts.now
50
+ } : {}
41
51
  };
42
52
  const { status, payload } = this.normalize(exception);
43
- const envelope = buildErrorEnvelope({ status, payload, ctx: normCtx });
53
+ const envelope = buildErrorEnvelope({
54
+ status,
55
+ payload,
56
+ ctx: normCtx
57
+ });
44
58
  if (this.opts.onError) {
45
59
  try {
46
60
  this.opts.onError(envelope, exception);
47
61
  } catch (hookErr) {
48
- this.logger.warn(
49
- { err: hookErr instanceof Error ? hookErr.message : String(hookErr) },
50
- "onError hook threw; continuing"
51
- );
62
+ this.logger.warn({
63
+ err: hookErr instanceof Error ? hookErr.message : String(hookErr)
64
+ }, "onError hook threw; continuing");
52
65
  }
53
66
  }
54
67
  if (status >= 500) {
55
- this.logger.error(
56
- {
57
- err: exception instanceof Error ? exception.message : String(exception),
58
- stack: exception instanceof Error ? exception.stack : void 0,
59
- name: exception instanceof Error ? exception.name : void 0,
60
- path: normCtx.path,
61
- requestId
62
- },
63
- "Unhandled error in PafiHttpExceptionFilter"
64
- );
68
+ this.logger.error({
69
+ err: exception instanceof Error ? exception.message : String(exception),
70
+ stack: exception instanceof Error ? exception.stack : void 0,
71
+ name: exception instanceof Error ? exception.name : void 0,
72
+ path: normCtx.path,
73
+ requestId
74
+ }, "Unhandled error in PafiHttpExceptionFilter");
65
75
  }
66
76
  response.status(status).json(envelope);
67
77
  }
@@ -114,58 +124,92 @@ var PafiHttpExceptionFilter = class {
114
124
  };
115
125
  }
116
126
  };
117
- PafiHttpExceptionFilter = __decorateClass([
118
- Catch()
127
+ PafiHttpExceptionFilter = _ts_decorate([
128
+ Catch(),
129
+ _ts_metadata("design:type", Function),
130
+ _ts_metadata("design:paramtypes", [
131
+ typeof PafiHttpExceptionFilterOptions === "undefined" ? Object : PafiHttpExceptionFilterOptions
132
+ ])
119
133
  ], PafiHttpExceptionFilter);
120
134
 
121
135
  // src/nestjs/walletAuthJwks.module.ts
122
- import {
123
- Module
124
- } from "@nestjs/common";
136
+ import { Module } from "@nestjs/common";
125
137
 
126
138
  // src/nestjs/walletAuthJwks.controller.ts
127
- import {
128
- Controller,
129
- Get,
130
- HttpCode,
131
- HttpStatus as HttpStatus2,
132
- Inject,
133
- Logger as Logger2
134
- } from "@nestjs/common";
139
+ import { Controller, Get, HttpCode, HttpStatus as HttpStatus2, Inject, Logger as Logger2 } from "@nestjs/common";
135
140
 
136
141
  // src/nestjs/walletAuthJwks.tokens.ts
137
142
  var WALLET_AUTH_JWKS_KEYS = /* @__PURE__ */ Symbol("WALLET_AUTH_JWKS_KEYS");
138
143
 
139
144
  // src/nestjs/walletAuthJwks.controller.ts
140
- var WalletAuthJwksController = class {
141
- logger = new Logger2(WalletAuthJwksController.name);
145
+ function _ts_decorate2(decorators, target, key, desc) {
146
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
147
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
148
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
149
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
150
+ }
151
+ __name(_ts_decorate2, "_ts_decorate");
152
+ function _ts_metadata2(k, v) {
153
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
154
+ }
155
+ __name(_ts_metadata2, "_ts_metadata");
156
+ function _ts_param(paramIndex, decorator) {
157
+ return function(target, key) {
158
+ decorator(target, key, paramIndex);
159
+ };
160
+ }
161
+ __name(_ts_param, "_ts_param");
162
+ var WalletAuthJwksController = class _WalletAuthJwksController {
163
+ static {
164
+ __name(this, "WalletAuthJwksController");
165
+ }
166
+ logger = new Logger2(_WalletAuthJwksController.name);
142
167
  jwks;
143
168
  constructor(keys) {
144
- this.jwks = { keys };
169
+ this.jwks = {
170
+ keys
171
+ };
145
172
  const kids = keys.map((k) => k.kid).join(", ");
146
- this.logger.log(
147
- `JWKS endpoint ready \u2014 ${keys.length} key(s) published: ${kids || "(empty)"}`
148
- );
173
+ this.logger.log(`JWKS endpoint ready \u2014 ${keys.length} key(s) published: ${kids || "(empty)"}`);
149
174
  }
150
175
  getJwks() {
151
176
  return this.jwks;
152
177
  }
153
178
  };
154
- __decorateClass([
179
+ _ts_decorate2([
155
180
  Get("jwks.json"),
156
- HttpCode(HttpStatus2.OK)
157
- ], WalletAuthJwksController.prototype, "getJwks", 1);
158
- WalletAuthJwksController = __decorateClass([
181
+ HttpCode(HttpStatus2.OK),
182
+ _ts_metadata2("design:type", Function),
183
+ _ts_metadata2("design:paramtypes", []),
184
+ _ts_metadata2("design:returntype", Object)
185
+ ], WalletAuthJwksController.prototype, "getJwks", null);
186
+ WalletAuthJwksController = _ts_decorate2([
159
187
  Controller(".well-known"),
160
- __decorateParam(0, Inject(WALLET_AUTH_JWKS_KEYS))
188
+ _ts_param(0, Inject(WALLET_AUTH_JWKS_KEYS)),
189
+ _ts_metadata2("design:type", Function),
190
+ _ts_metadata2("design:paramtypes", [
191
+ Array
192
+ ])
161
193
  ], WalletAuthJwksController);
162
194
 
163
195
  // src/nestjs/walletAuthJwks.module.ts
164
- var WalletAuthJwksModule = class {
196
+ function _ts_decorate3(decorators, target, key, desc) {
197
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
198
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
199
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
200
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
201
+ }
202
+ __name(_ts_decorate3, "_ts_decorate");
203
+ var WalletAuthJwksModule = class _WalletAuthJwksModule {
204
+ static {
205
+ __name(this, "WalletAuthJwksModule");
206
+ }
165
207
  static forRoot(options) {
166
208
  return {
167
- module: WalletAuthJwksModule,
168
- controllers: [WalletAuthJwksController],
209
+ module: _WalletAuthJwksModule,
210
+ controllers: [
211
+ WalletAuthJwksController
212
+ ],
169
213
  providers: [
170
214
  {
171
215
  provide: WALLET_AUTH_JWKS_KEYS,
@@ -176,23 +220,25 @@ var WalletAuthJwksModule = class {
176
220
  }
177
221
  static forRootAsync(options) {
178
222
  return {
179
- module: WalletAuthJwksModule,
223
+ module: _WalletAuthJwksModule,
180
224
  imports: options.imports ?? [],
181
- controllers: [WalletAuthJwksController],
225
+ controllers: [
226
+ WalletAuthJwksController
227
+ ],
182
228
  providers: [
183
229
  {
184
230
  provide: WALLET_AUTH_JWKS_KEYS,
185
231
  inject: options.inject ?? [],
186
- useFactory: async (...args) => {
232
+ useFactory: /* @__PURE__ */ __name(async (...args) => {
187
233
  const opts = await options.useFactory(...args);
188
234
  return validateKeys(opts.keys);
189
- }
235
+ }, "useFactory")
190
236
  }
191
237
  ]
192
238
  };
193
239
  }
194
240
  };
195
- WalletAuthJwksModule = __decorateClass([
241
+ WalletAuthJwksModule = _ts_decorate3([
196
242
  Module({})
197
243
  ], WalletAuthJwksModule);
198
244
  function validateKeys(keys) {
@@ -207,13 +253,12 @@ function validateKeys(keys) {
207
253
  throw new Error("WalletAuthJwksModule: each key must have a `kty` field");
208
254
  }
209
255
  if (!k.kid) {
210
- throw new Error(
211
- "WalletAuthJwksModule: each key must have a `kid` field \u2014 PAFI gateway uses kid to look up the verification key"
212
- );
256
+ throw new Error("WalletAuthJwksModule: each key must have a `kid` field \u2014 PAFI gateway uses kid to look up the verification key");
213
257
  }
214
258
  }
215
259
  return keys;
216
260
  }
261
+ __name(validateKeys, "validateKeys");
217
262
  export {
218
263
  PafiHttpExceptionFilter,
219
264
  WALLET_AUTH_JWKS_KEYS,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/nestjs/httpExceptionFilter.ts","../../src/nestjs/walletAuthJwks.module.ts","../../src/nestjs/walletAuthJwks.controller.ts","../../src/nestjs/walletAuthJwks.tokens.ts"],"sourcesContent":["/**\n * NestJS global exception filter that emits the PAFI Stripe-style\n * envelope (see `@pafi-dev/issuer/http`).\n *\n * Wire it once in your bootstrap:\n *\n * ```ts\n * import { PafiHttpExceptionFilter } from \"@pafi-dev/issuer/nestjs\";\n *\n * app.useGlobalFilters(new PafiHttpExceptionFilter());\n * ```\n *\n * Catches every thrown value:\n * - `PafiSdkError` (and subclasses) → typed envelope from `httpStatus`/\n * `code`/`type`/`safeToRetry`/`param`/`metadata`.\n * - `HttpException` (NestJS) → respected status; SDK-shaped body is\n * passed through, plain bodies + ValidationPipe arrays normalized.\n * - any other `Error` → `server_error` 500 with sanitized message.\n *\n * `@nestjs/common` is an optional peer dependency — only required when\n * importing this sub-export.\n */\nimport {\n ArgumentsHost,\n Catch,\n ExceptionFilter,\n HttpException,\n HttpStatus,\n Logger,\n} from \"@nestjs/common\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { PafiSdkError, SDK_ERROR_HTTP_STATUS_CODE } from \"../errors\";\nimport {\n buildErrorEnvelope,\n payloadFromGenericError,\n payloadFromHttpException,\n payloadFromPafiSdkError,\n type NormalizeContext,\n type PafiErrorEnvelope,\n type PafiErrorPayload,\n} from \"../http/errorEnvelope\";\n\ninterface MinimalHttpRequest {\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\ninterface MinimalHttpResponse {\n status(code: number): MinimalHttpResponse;\n json(body: unknown): unknown;\n}\n\n/** Customization knobs. None required — sensible defaults baked in. */\nexport interface PafiHttpExceptionFilterOptions {\n /**\n * Header to read for the request id, lowercase. Default `\"x-request-id\"`.\n * If absent, a UUIDv4 is generated per request.\n */\n requestIdHeader?: string;\n /**\n * Override `Date` for deterministic tests.\n */\n now?: () => Date;\n /**\n * Hook to record normalized errors before sending. Useful for\n * Sentry / Datadog / Pino. Throws are swallowed so a logging bug\n * never masks the real error response.\n */\n onError?: (envelope: PafiErrorEnvelope, raw: unknown) => void;\n}\n\n@Catch()\nexport class PafiHttpExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(\"PafiHttpExceptionFilter\");\n private readonly opts: Required<\n Pick<PafiHttpExceptionFilterOptions, \"requestIdHeader\">\n > &\n PafiHttpExceptionFilterOptions;\n\n constructor(options: PafiHttpExceptionFilterOptions = {}) {\n this.opts = {\n requestIdHeader: options.requestIdHeader ?? \"x-request-id\",\n ...options,\n };\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<MinimalHttpResponse>();\n const request = ctx.getRequest<MinimalHttpRequest>();\n\n const headerValue = request?.headers?.[this.opts.requestIdHeader];\n const requestId =\n (Array.isArray(headerValue) ? headerValue[0] : headerValue) ??\n randomUUID();\n\n const normCtx: NormalizeContext = {\n path: request?.url ?? \"\",\n requestId,\n ...(this.opts.now ? { now: this.opts.now } : {}),\n };\n\n const { status, payload } = this.normalize(exception);\n const envelope = buildErrorEnvelope({ status, payload, ctx: normCtx });\n\n if (this.opts.onError) {\n try {\n this.opts.onError(envelope, exception);\n } catch (hookErr) {\n this.logger.warn(\n { err: hookErr instanceof Error ? hookErr.message : String(hookErr) },\n \"onError hook threw; continuing\",\n );\n }\n }\n\n if (status >= 500) {\n this.logger.error(\n {\n err:\n exception instanceof Error\n ? exception.message\n : String(exception),\n stack: exception instanceof Error ? exception.stack : undefined,\n name: exception instanceof Error ? exception.name : undefined,\n path: normCtx.path,\n requestId,\n },\n \"Unhandled error in PafiHttpExceptionFilter\",\n );\n }\n\n response.status(status).json(envelope);\n }\n\n private normalize(exception: unknown): {\n status: number;\n payload: PafiErrorPayload;\n } {\n if (exception instanceof PafiSdkError) {\n return {\n status: SDK_ERROR_HTTP_STATUS_CODE[exception.httpStatus],\n payload: payloadFromPafiSdkError(exception),\n };\n }\n\n if (exception instanceof HttpException) {\n return {\n status: exception.getStatus(),\n payload: payloadFromHttpException({\n statusCode: exception.getStatus(),\n responseBody: exception.getResponse(),\n exceptionName: exception.name,\n fallbackMessage: exception.message,\n }),\n };\n }\n\n if (exception instanceof Error) {\n // Duck-typing for HttpException instances that fail `instanceof`\n // when multiple `@nestjs/common` copies exist in the dep tree.\n const maybeStatus = (exception as { status?: unknown }).status;\n const maybeGetResponse = (\n exception as { getResponse?: () => unknown }\n ).getResponse;\n if (\n typeof maybeStatus === \"number\" &&\n typeof maybeGetResponse === \"function\"\n ) {\n return {\n status: maybeStatus,\n payload: payloadFromHttpException({\n statusCode: maybeStatus,\n responseBody: maybeGetResponse.call(exception),\n exceptionName: exception.name,\n fallbackMessage: exception.message,\n }),\n };\n }\n const maybeStatusOnly =\n typeof maybeStatus === \"number\"\n ? maybeStatus\n : HttpStatus.INTERNAL_SERVER_ERROR;\n return {\n status: maybeStatusOnly,\n payload: payloadFromGenericError(exception),\n };\n }\n\n return {\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n payload: {\n type: \"server_error\",\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"An unexpected error occurred\",\n safeToRetry: false,\n },\n };\n }\n}\n","import {\n Module,\n type DynamicModule,\n type FactoryProvider,\n} from \"@nestjs/common\";\nimport type { IssuerPublicJwk } from \"../wallet-auth/types\";\nimport { WalletAuthJwksController } from \"./walletAuthJwks.controller\";\nimport { WALLET_AUTH_JWKS_KEYS } from \"./walletAuthJwks.tokens\";\n\nexport interface WalletAuthJwksOptions {\n /**\n * One or more public JWKs to publish. During key rotation, include\n * BOTH the active and previous keys so JWTs signed with the older\n * kid can still be verified by the PAFI gateway until the rotation\n * window closes.\n */\n keys: IssuerPublicJwk[];\n}\n\nexport interface WalletAuthJwksAsyncOptions {\n /** Modules to import for the factory's DI. */\n imports?: NonNullable<DynamicModule[\"imports\"]>;\n /** Providers to inject into useFactory — same shape as FactoryProvider.inject. */\n inject?: FactoryProvider[\"inject\"];\n /** Builds options at runtime — read env, decrypt secrets, etc. */\n useFactory: (...args: any[]) => Promise<WalletAuthJwksOptions> | WalletAuthJwksOptions;\n}\n\n/**\n * Drop-in NestJS module that publishes the issuer's public signing\n * key set at GET /.well-known/jwks.json.\n *\n * Every issuer backend integrating with the PAFI Wallet Auth Gateway\n * needs this endpoint so the gateway can fetch their public key and\n * verify issuer JWT signatures.\n *\n * @example Sync registration\n * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';\n *\n * @Module({\n * imports: [\n * WalletAuthJwksModule.forRoot({\n * keys: [JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON!)],\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @example Async registration (read from ConfigService)\n * import { ConfigModule, ConfigService } from '@nestjs/config';\n * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';\n *\n * @Module({\n * imports: [\n * WalletAuthJwksModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * keys: [JSON.parse(config.getOrThrow('ISSUER_PUBLIC_JWK_JSON'))],\n * }),\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @example Rotation window — publish 2 keys simultaneously\n * keys: [\n * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_ACTIVE!),\n * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_PREVIOUS!),\n * ]\n */\n@Module({})\nexport class WalletAuthJwksModule {\n static forRoot(options: WalletAuthJwksOptions): DynamicModule {\n return {\n module: WalletAuthJwksModule,\n controllers: [WalletAuthJwksController],\n providers: [\n {\n provide: WALLET_AUTH_JWKS_KEYS,\n useValue: validateKeys(options.keys),\n },\n ],\n };\n }\n\n static forRootAsync(options: WalletAuthJwksAsyncOptions): DynamicModule {\n return {\n module: WalletAuthJwksModule,\n imports: options.imports ?? [],\n controllers: [WalletAuthJwksController],\n providers: [\n {\n provide: WALLET_AUTH_JWKS_KEYS,\n inject: options.inject ?? [],\n useFactory: async (...args: unknown[]) => {\n const opts = await options.useFactory(...args);\n return validateKeys(opts.keys);\n },\n },\n ],\n };\n }\n}\n\n/**\n * Reject misconfiguration loudly at boot rather than serving an\n * invalid JWKS. Missing `kid` would mean the gateway can't match\n * the key against inbound JWT headers.\n */\nfunction validateKeys(keys: IssuerPublicJwk[]): IssuerPublicJwk[] {\n if (!Array.isArray(keys)) {\n throw new Error(\"WalletAuthJwksModule: `keys` must be an array\");\n }\n for (const k of keys) {\n if (!k || typeof k !== \"object\") {\n throw new Error(\"WalletAuthJwksModule: each key must be an object\");\n }\n if (!k.kty) {\n throw new Error(\"WalletAuthJwksModule: each key must have a `kty` field\");\n }\n if (!k.kid) {\n throw new Error(\n \"WalletAuthJwksModule: each key must have a `kid` field — PAFI gateway uses kid to look up the verification key\",\n );\n }\n }\n return keys;\n}\n","import {\n Controller,\n Get,\n HttpCode,\n HttpStatus,\n Inject,\n Logger,\n} from \"@nestjs/common\";\nimport type { IssuerPublicJwk } from \"../wallet-auth/types\";\nimport { WALLET_AUTH_JWKS_KEYS } from \"./walletAuthJwks.tokens\";\n\n/**\n * Publishes the issuer's public signing key set as RFC 7517 JWKS.\n *\n * The PAFI Wallet Auth Gateway fetches this URL to verify signatures\n * on issuer JWTs that this backend mints (the JWT travelling in\n * /v1/token-exchange's `issuer_jwt` body field).\n *\n * Mounted at GET /.well-known/jwks.json — no auth, public by design.\n */\n@Controller(\".well-known\")\nexport class WalletAuthJwksController {\n private readonly logger = new Logger(WalletAuthJwksController.name);\n private readonly jwks: { keys: IssuerPublicJwk[] };\n\n constructor(\n @Inject(WALLET_AUTH_JWKS_KEYS)\n keys: IssuerPublicJwk[],\n ) {\n this.jwks = { keys };\n const kids = keys.map((k) => k.kid).join(\", \");\n this.logger.log(\n `JWKS endpoint ready — ${keys.length} key(s) published: ${kids || \"(empty)\"}`,\n );\n }\n\n @Get(\"jwks.json\")\n @HttpCode(HttpStatus.OK)\n getJwks(): { keys: IssuerPublicJwk[] } {\n return this.jwks;\n }\n}\n","/** DI token: array of public JWKs to publish at /.well-known/jwks.json. */\nexport const WALLET_AUTH_JWKS_KEYS = Symbol(\"WALLET_AUTH_JWKS_KEYS\");\n"],"mappings":";;;;;;;;;;;;;;AAsBA;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AA0CpB,IAAM,0BAAN,MAAyD;AAAA,EAC7C,SAAS,IAAI,OAAO,yBAAyB;AAAA,EAC7C;AAAA,EAKjB,YAAY,UAA0C,CAAC,GAAG;AACxD,SAAK,OAAO;AAAA,MACV,iBAAiB,QAAQ,mBAAmB;AAAA,MAC5C,GAAG;AAAA,IACL;AAAA,EACF;AAAA,EAEA,MAAM,WAAoB,MAA2B;AACnD,UAAM,MAAM,KAAK,aAAa;AAC9B,UAAM,WAAW,IAAI,YAAiC;AACtD,UAAM,UAAU,IAAI,WAA+B;AAEnD,UAAM,cAAc,SAAS,UAAU,KAAK,KAAK,eAAe;AAChE,UAAM,aACH,MAAM,QAAQ,WAAW,IAAI,YAAY,CAAC,IAAI,gBAC/C,WAAW;AAEb,UAAM,UAA4B;AAAA,MAChC,MAAM,SAAS,OAAO;AAAA,MACtB;AAAA,MACA,GAAI,KAAK,KAAK,MAAM,EAAE,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IAChD;AAEA,UAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK,UAAU,SAAS;AACpD,UAAM,WAAW,mBAAmB,EAAE,QAAQ,SAAS,KAAK,QAAQ,CAAC;AAErE,QAAI,KAAK,KAAK,SAAS;AACrB,UAAI;AACF,aAAK,KAAK,QAAQ,UAAU,SAAS;AAAA,MACvC,SAAS,SAAS;AAChB,aAAK,OAAO;AAAA,UACV,EAAE,KAAK,mBAAmB,QAAQ,QAAQ,UAAU,OAAO,OAAO,EAAE;AAAA,UACpE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,UAAU,KAAK;AACjB,WAAK,OAAO;AAAA,QACV;AAAA,UACE,KACE,qBAAqB,QACjB,UAAU,UACV,OAAO,SAAS;AAAA,UACtB,OAAO,qBAAqB,QAAQ,UAAU,QAAQ;AAAA,UACtD,MAAM,qBAAqB,QAAQ,UAAU,OAAO;AAAA,UACpD,MAAM,QAAQ;AAAA,UACd;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,aAAS,OAAO,MAAM,EAAE,KAAK,QAAQ;AAAA,EACvC;AAAA,EAEQ,UAAU,WAGhB;AACA,QAAI,qBAAqB,cAAc;AACrC,aAAO;AAAA,QACL,QAAQ,2BAA2B,UAAU,UAAU;AAAA,QACvD,SAAS,wBAAwB,SAAS;AAAA,MAC5C;AAAA,IACF;AAEA,QAAI,qBAAqB,eAAe;AACtC,aAAO;AAAA,QACL,QAAQ,UAAU,UAAU;AAAA,QAC5B,SAAS,yBAAyB;AAAA,UAChC,YAAY,UAAU,UAAU;AAAA,UAChC,cAAc,UAAU,YAAY;AAAA,UACpC,eAAe,UAAU;AAAA,UACzB,iBAAiB,UAAU;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,qBAAqB,OAAO;AAG9B,YAAM,cAAe,UAAmC;AACxD,YAAM,mBACJ,UACA;AACF,UACE,OAAO,gBAAgB,YACvB,OAAO,qBAAqB,YAC5B;AACA,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS,yBAAyB;AAAA,YAChC,YAAY;AAAA,YACZ,cAAc,iBAAiB,KAAK,SAAS;AAAA,YAC7C,eAAe,UAAU;AAAA,YACzB,iBAAiB,UAAU;AAAA,UAC7B,CAAC;AAAA,QACH;AAAA,MACF;AACA,YAAM,kBACJ,OAAO,gBAAgB,WACnB,cACA,WAAW;AACjB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,wBAAwB,SAAS;AAAA,MAC5C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,QAAQ,WAAW;AAAA,MACnB,SAAS;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AA/Ha,0BAAN;AAAA,EADN,MAAM;AAAA,GACM;;;ACxEb;AAAA,EACE;AAAA,OAGK;;;ACJP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAAA;AAAA,EACA;AAAA,EACA,UAAAC;AAAA,OACK;;;ACNA,IAAM,wBAAwB,uBAAO,uBAAuB;;;ADoB5D,IAAM,2BAAN,MAA+B;AAAA,EACnB,SAAS,IAAIC,QAAO,yBAAyB,IAAI;AAAA,EACjD;AAAA,EAEjB,YAEE,MACA;AACA,SAAK,OAAO,EAAE,KAAK;AACnB,UAAM,OAAO,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI;AAC7C,SAAK,OAAO;AAAA,MACV,8BAAyB,KAAK,MAAM,sBAAsB,QAAQ,SAAS;AAAA,IAC7E;AAAA,EACF;AAAA,EAIA,UAAuC;AACrC,WAAO,KAAK;AAAA,EACd;AACF;AAHE;AAAA,EAFC,IAAI,WAAW;AAAA,EACf,SAASC,YAAW,EAAE;AAAA,GAhBZ,yBAiBX;AAjBW,2BAAN;AAAA,EADN,WAAW,aAAa;AAAA,EAMpB,0BAAO,qBAAqB;AAAA,GALpB;;;ADmDN,IAAM,uBAAN,MAA2B;AAAA,EAChC,OAAO,QAAQ,SAA+C;AAC5D,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,aAAa,CAAC,wBAAwB;AAAA,MACtC,WAAW;AAAA,QACT;AAAA,UACE,SAAS;AAAA,UACT,UAAU,aAAa,QAAQ,IAAI;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,aAAa,SAAoD;AACtE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,QAAQ,WAAW,CAAC;AAAA,MAC7B,aAAa,CAAC,wBAAwB;AAAA,MACtC,WAAW;AAAA,QACT;AAAA,UACE,SAAS;AAAA,UACT,QAAQ,QAAQ,UAAU,CAAC;AAAA,UAC3B,YAAY,UAAU,SAAoB;AACxC,kBAAM,OAAO,MAAM,QAAQ,WAAW,GAAG,IAAI;AAC7C,mBAAO,aAAa,KAAK,IAAI;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AA/Ba,uBAAN;AAAA,EADN,OAAO,CAAC,CAAC;AAAA,GACG;AAsCb,SAAS,aAAa,MAA4C;AAChE,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,aAAW,KAAK,MAAM;AACpB,QAAI,CAAC,KAAK,OAAO,MAAM,UAAU;AAC/B,YAAM,IAAI,MAAM,kDAAkD;AAAA,IACpE;AACA,QAAI,CAAC,EAAE,KAAK;AACV,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AACA,QAAI,CAAC,EAAE,KAAK;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":["HttpStatus","Logger","Logger","HttpStatus"]}
1
+ {"version":3,"sources":["../../src/nestjs/httpExceptionFilter.ts","../../src/nestjs/walletAuthJwks.module.ts","../../src/nestjs/walletAuthJwks.controller.ts","../../src/nestjs/walletAuthJwks.tokens.ts"],"sourcesContent":["/**\n * NestJS global exception filter that emits the PAFI Stripe-style\n * envelope (see `@pafi-dev/issuer/http`).\n *\n * Wire it once in your bootstrap:\n *\n * ```ts\n * import { PafiHttpExceptionFilter } from \"@pafi-dev/issuer/nestjs\";\n *\n * app.useGlobalFilters(new PafiHttpExceptionFilter());\n * ```\n *\n * Catches every thrown value:\n * - `PafiSdkError` (and subclasses) → typed envelope from `httpStatus`/\n * `code`/`type`/`safeToRetry`/`param`/`metadata`.\n * - `HttpException` (NestJS) → respected status; SDK-shaped body is\n * passed through, plain bodies + ValidationPipe arrays normalized.\n * - any other `Error` → `server_error` 500 with sanitized message.\n *\n * `@nestjs/common` is an optional peer dependency — only required when\n * importing this sub-export.\n */\nimport {\n ArgumentsHost,\n Catch,\n ExceptionFilter,\n HttpException,\n HttpStatus,\n Logger,\n} from \"@nestjs/common\";\nimport { randomUUID } from \"node:crypto\";\n\nimport { PafiSdkError, SDK_ERROR_HTTP_STATUS_CODE } from \"../errors\";\nimport {\n buildErrorEnvelope,\n payloadFromGenericError,\n payloadFromHttpException,\n payloadFromPafiSdkError,\n type NormalizeContext,\n type PafiErrorEnvelope,\n type PafiErrorPayload,\n} from \"../http/errorEnvelope\";\n\ninterface MinimalHttpRequest {\n url?: string;\n headers?: Record<string, string | string[] | undefined>;\n}\ninterface MinimalHttpResponse {\n status(code: number): MinimalHttpResponse;\n json(body: unknown): unknown;\n}\n\n/** Customization knobs. None required — sensible defaults baked in. */\nexport interface PafiHttpExceptionFilterOptions {\n /**\n * Header to read for the request id, lowercase. Default `\"x-request-id\"`.\n * If absent, a UUIDv4 is generated per request.\n */\n requestIdHeader?: string;\n /**\n * Override `Date` for deterministic tests.\n */\n now?: () => Date;\n /**\n * Hook to record normalized errors before sending. Useful for\n * Sentry / Datadog / Pino. Throws are swallowed so a logging bug\n * never masks the real error response.\n */\n onError?: (envelope: PafiErrorEnvelope, raw: unknown) => void;\n}\n\n@Catch()\nexport class PafiHttpExceptionFilter implements ExceptionFilter {\n private readonly logger = new Logger(\"PafiHttpExceptionFilter\");\n private readonly opts: Required<\n Pick<PafiHttpExceptionFilterOptions, \"requestIdHeader\">\n > &\n PafiHttpExceptionFilterOptions;\n\n constructor(options: PafiHttpExceptionFilterOptions = {}) {\n this.opts = {\n requestIdHeader: options.requestIdHeader ?? \"x-request-id\",\n ...options,\n };\n }\n\n catch(exception: unknown, host: ArgumentsHost): void {\n const ctx = host.switchToHttp();\n const response = ctx.getResponse<MinimalHttpResponse>();\n const request = ctx.getRequest<MinimalHttpRequest>();\n\n const headerValue = request?.headers?.[this.opts.requestIdHeader];\n const requestId =\n (Array.isArray(headerValue) ? headerValue[0] : headerValue) ??\n randomUUID();\n\n const normCtx: NormalizeContext = {\n path: request?.url ?? \"\",\n requestId,\n ...(this.opts.now ? { now: this.opts.now } : {}),\n };\n\n const { status, payload } = this.normalize(exception);\n const envelope = buildErrorEnvelope({ status, payload, ctx: normCtx });\n\n if (this.opts.onError) {\n try {\n this.opts.onError(envelope, exception);\n } catch (hookErr) {\n this.logger.warn(\n { err: hookErr instanceof Error ? hookErr.message : String(hookErr) },\n \"onError hook threw; continuing\",\n );\n }\n }\n\n if (status >= 500) {\n this.logger.error(\n {\n err:\n exception instanceof Error\n ? exception.message\n : String(exception),\n stack: exception instanceof Error ? exception.stack : undefined,\n name: exception instanceof Error ? exception.name : undefined,\n path: normCtx.path,\n requestId,\n },\n \"Unhandled error in PafiHttpExceptionFilter\",\n );\n }\n\n response.status(status).json(envelope);\n }\n\n private normalize(exception: unknown): {\n status: number;\n payload: PafiErrorPayload;\n } {\n if (exception instanceof PafiSdkError) {\n return {\n status: SDK_ERROR_HTTP_STATUS_CODE[exception.httpStatus],\n payload: payloadFromPafiSdkError(exception),\n };\n }\n\n if (exception instanceof HttpException) {\n return {\n status: exception.getStatus(),\n payload: payloadFromHttpException({\n statusCode: exception.getStatus(),\n responseBody: exception.getResponse(),\n exceptionName: exception.name,\n fallbackMessage: exception.message,\n }),\n };\n }\n\n if (exception instanceof Error) {\n // Duck-typing for HttpException instances that fail `instanceof`\n // when multiple `@nestjs/common` copies exist in the dep tree.\n const maybeStatus = (exception as { status?: unknown }).status;\n const maybeGetResponse = (\n exception as { getResponse?: () => unknown }\n ).getResponse;\n if (\n typeof maybeStatus === \"number\" &&\n typeof maybeGetResponse === \"function\"\n ) {\n return {\n status: maybeStatus,\n payload: payloadFromHttpException({\n statusCode: maybeStatus,\n responseBody: maybeGetResponse.call(exception),\n exceptionName: exception.name,\n fallbackMessage: exception.message,\n }),\n };\n }\n const maybeStatusOnly =\n typeof maybeStatus === \"number\"\n ? maybeStatus\n : HttpStatus.INTERNAL_SERVER_ERROR;\n return {\n status: maybeStatusOnly,\n payload: payloadFromGenericError(exception),\n };\n }\n\n return {\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n payload: {\n type: \"server_error\",\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"An unexpected error occurred\",\n safeToRetry: false,\n },\n };\n }\n}\n","import {\n Module,\n type DynamicModule,\n type FactoryProvider,\n} from \"@nestjs/common\";\nimport type { IssuerPublicJwk } from \"../wallet-auth/types\";\nimport { WalletAuthJwksController } from \"./walletAuthJwks.controller\";\nimport { WALLET_AUTH_JWKS_KEYS } from \"./walletAuthJwks.tokens\";\n\nexport interface WalletAuthJwksOptions {\n /**\n * One or more public JWKs to publish. During key rotation, include\n * BOTH the active and previous keys so JWTs signed with the older\n * kid can still be verified by the PAFI gateway until the rotation\n * window closes.\n */\n keys: IssuerPublicJwk[];\n}\n\nexport interface WalletAuthJwksAsyncOptions {\n /** Modules to import for the factory's DI. */\n imports?: NonNullable<DynamicModule[\"imports\"]>;\n /** Providers to inject into useFactory — same shape as FactoryProvider.inject. */\n inject?: FactoryProvider[\"inject\"];\n /** Builds options at runtime — read env, decrypt secrets, etc. */\n useFactory: (...args: any[]) => Promise<WalletAuthJwksOptions> | WalletAuthJwksOptions;\n}\n\n/**\n * Drop-in NestJS module that publishes the issuer's public signing\n * key set at GET /.well-known/jwks.json.\n *\n * Every issuer backend integrating with the PAFI Wallet Auth Gateway\n * needs this endpoint so the gateway can fetch their public key and\n * verify issuer JWT signatures.\n *\n * @example Sync registration\n * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';\n *\n * @Module({\n * imports: [\n * WalletAuthJwksModule.forRoot({\n * keys: [JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON!)],\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @example Async registration (read from ConfigService)\n * import { ConfigModule, ConfigService } from '@nestjs/config';\n * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';\n *\n * @Module({\n * imports: [\n * WalletAuthJwksModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * keys: [JSON.parse(config.getOrThrow('ISSUER_PUBLIC_JWK_JSON'))],\n * }),\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * @example Rotation window — publish 2 keys simultaneously\n * keys: [\n * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_ACTIVE!),\n * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_PREVIOUS!),\n * ]\n */\n@Module({})\nexport class WalletAuthJwksModule {\n static forRoot(options: WalletAuthJwksOptions): DynamicModule {\n return {\n module: WalletAuthJwksModule,\n controllers: [WalletAuthJwksController],\n providers: [\n {\n provide: WALLET_AUTH_JWKS_KEYS,\n useValue: validateKeys(options.keys),\n },\n ],\n };\n }\n\n static forRootAsync(options: WalletAuthJwksAsyncOptions): DynamicModule {\n return {\n module: WalletAuthJwksModule,\n imports: options.imports ?? [],\n controllers: [WalletAuthJwksController],\n providers: [\n {\n provide: WALLET_AUTH_JWKS_KEYS,\n inject: options.inject ?? [],\n useFactory: async (...args: unknown[]) => {\n const opts = await options.useFactory(...args);\n return validateKeys(opts.keys);\n },\n },\n ],\n };\n }\n}\n\n/**\n * Reject misconfiguration loudly at boot rather than serving an\n * invalid JWKS. Missing `kid` would mean the gateway can't match\n * the key against inbound JWT headers.\n */\nfunction validateKeys(keys: IssuerPublicJwk[]): IssuerPublicJwk[] {\n if (!Array.isArray(keys)) {\n throw new Error(\"WalletAuthJwksModule: `keys` must be an array\");\n }\n for (const k of keys) {\n if (!k || typeof k !== \"object\") {\n throw new Error(\"WalletAuthJwksModule: each key must be an object\");\n }\n if (!k.kty) {\n throw new Error(\"WalletAuthJwksModule: each key must have a `kty` field\");\n }\n if (!k.kid) {\n throw new Error(\n \"WalletAuthJwksModule: each key must have a `kid` field — PAFI gateway uses kid to look up the verification key\",\n );\n }\n }\n return keys;\n}\n","import {\n Controller,\n Get,\n HttpCode,\n HttpStatus,\n Inject,\n Logger,\n} from \"@nestjs/common\";\nimport type { IssuerPublicJwk } from \"../wallet-auth/types\";\nimport { WALLET_AUTH_JWKS_KEYS } from \"./walletAuthJwks.tokens\";\n\n/**\n * Publishes the issuer's public signing key set as RFC 7517 JWKS.\n *\n * The PAFI Wallet Auth Gateway fetches this URL to verify signatures\n * on issuer JWTs that this backend mints (the JWT travelling in\n * /v1/token-exchange's `issuer_jwt` body field).\n *\n * Mounted at GET /.well-known/jwks.json — no auth, public by design.\n */\n@Controller(\".well-known\")\nexport class WalletAuthJwksController {\n private readonly logger = new Logger(WalletAuthJwksController.name);\n private readonly jwks: { keys: IssuerPublicJwk[] };\n\n constructor(\n @Inject(WALLET_AUTH_JWKS_KEYS)\n keys: IssuerPublicJwk[],\n ) {\n this.jwks = { keys };\n const kids = keys.map((k) => k.kid).join(\", \");\n this.logger.log(\n `JWKS endpoint ready — ${keys.length} key(s) published: ${kids || \"(empty)\"}`,\n );\n }\n\n @Get(\"jwks.json\")\n @HttpCode(HttpStatus.OK)\n getJwks(): { keys: IssuerPublicJwk[] } {\n return this.jwks;\n }\n}\n","/** DI token: array of public JWKs to publish at /.well-known/jwks.json. */\nexport const WALLET_AUTH_JWKS_KEYS = Symbol(\"WALLET_AUTH_JWKS_KEYS\");\n"],"mappings":"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","names":["Catch","HttpException","HttpStatus","Logger","randomUUID","PafiHttpExceptionFilter","logger","Logger","opts","options","requestIdHeader","catch","exception","host","ctx","switchToHttp","response","getResponse","request","getRequest","headerValue","headers","requestId","Array","isArray","randomUUID","normCtx","path","url","now","status","payload","normalize","envelope","buildErrorEnvelope","onError","hookErr","warn","err","Error","message","String","error","stack","undefined","name","json","PafiSdkError","SDK_ERROR_HTTP_STATUS_CODE","httpStatus","payloadFromPafiSdkError","HttpException","getStatus","payloadFromHttpException","statusCode","responseBody","exceptionName","fallbackMessage","maybeStatus","maybeGetResponse","call","maybeStatusOnly","HttpStatus","INTERNAL_SERVER_ERROR","payloadFromGenericError","type","code","safeToRetry","Module","Controller","Get","HttpCode","HttpStatus","Inject","Logger","WALLET_AUTH_JWKS_KEYS","Symbol","WalletAuthJwksController","logger","Logger","name","jwks","keys","kids","map","k","kid","join","log","length","getJwks","OK","WalletAuthJwksModule","forRoot","options","module","controllers","WalletAuthJwksController","providers","provide","WALLET_AUTH_JWKS_KEYS","useValue","validateKeys","keys","forRootAsync","imports","inject","useFactory","args","opts","Array","isArray","Error","k","kty","kid"]}
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -31,23 +32,28 @@ async function signIssuerJwt(params) {
31
32
  const alg = params.alg ?? params.privateJwk.alg ?? "ES256";
32
33
  const kid = params.privateJwk.kid;
33
34
  if (!kid) {
34
- throw new Error(
35
- "signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)"
36
- );
35
+ throw new Error("signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)");
37
36
  }
38
37
  const key = await (0, import_jose.importJWK)(params.privateJwk, alg);
39
38
  const now = Math.floor(Date.now() / 1e3);
40
39
  const lifetime = params.expiresInSec ?? 60;
41
- const payload = { ...params.extra ?? {} };
40
+ const payload = {
41
+ ...params.extra ?? {}
42
+ };
42
43
  if (params.authAttribute) {
43
44
  payload.auth_attribute = {
44
45
  type: params.authAttribute.type,
45
46
  value: params.authAttribute.value
46
47
  };
47
48
  }
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)());
49
+ const builder = new import_jose.SignJWT(payload).setProtectedHeader({
50
+ alg,
51
+ typ: "JWT",
52
+ kid
53
+ }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? (0, import_node_crypto.randomUUID)());
49
54
  return builder.sign(key);
50
55
  }
56
+ __name(signIssuerJwt, "signIssuerJwt");
51
57
  // Annotate the CommonJS export names for ESM import in node:
52
58
  0 && (module.exports = {
53
59
  signIssuerJwt
@@ -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 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
+ {"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;;;;;;;ACAA,kBAAmC;AACnC,yBAA2B;AAyB3B,eAAsBA,cACpBC,QAA2B;AAE3B,QAAMC,MAAMD,OAAOC,OAAOD,OAAOE,WAAWD,OAAO;AACnD,QAAME,MAAMH,OAAOE,WAAWC;AAE9B,MAAI,CAACA,KAAK;AACR,UAAM,IAAIC,MACR,8FAAA;EAEJ;AAEA,QAAMC,MAAM,UAAMC,uBAAUN,OAAOE,YAAYD,GAAAA;AAC/C,QAAMM,MAAMC,KAAKC,MAAMC,KAAKH,IAAG,IAAK,GAAA;AACpC,QAAMI,WAAWX,OAAOY,gBAAgB;AAExC,QAAMC,UAAmC;IAAE,GAAIb,OAAOc,SAAS,CAAC;EAAG;AACnE,MAAId,OAAOe,eAAe;AACxBF,YAAQG,iBAAiB;MACvBC,MAAMjB,OAAOe,cAAcE;MAC3BC,OAAOlB,OAAOe,cAAcG;IAC9B;EACF;AAEA,QAAMC,UAAU,IAAIC,oBAAQP,OAAAA,EACzBQ,mBAAmB;IAAEpB;IAAKqB,KAAK;IAAOnB;EAAI,CAAA,EAC1CoB,UAAUvB,OAAOwB,GAAG,EACpBC,WAAWzB,OAAO0B,GAAG,EACrBC,YAAY3B,OAAO4B,GAAG,EACtBC,YAAYtB,GAAAA,EACZuB,kBAAkBvB,MAAMI,QAAAA,EACxBoB,OAAO/B,OAAOgC,WAAOC,+BAAAA,CAAAA;AAExB,SAAOd,QAAQe,KAAK7B,GAAAA;AACtB;AAlCsBN;","names":["signIssuerJwt","params","alg","privateJwk","kid","Error","key","importJWK","now","Math","floor","Date","lifetime","expiresInSec","payload","extra","authAttribute","auth_attribute","type","value","builder","SignJWT","setProtectedHeader","typ","setIssuer","iss","setSubject","sub","setAudience","aud","setIssuedAt","setExpirationTime","setJti","jti","randomUUID","sign"]}
@@ -1,4 +1,6 @@
1
- import "../chunk-BRKEJJFQ.js";
1
+ import {
2
+ __name
3
+ } from "../chunk-7QVYU63E.js";
2
4
 
3
5
  // src/wallet-auth/signIssuerJwt.ts
4
6
  import { importJWK, SignJWT } from "jose";
@@ -7,23 +9,28 @@ async function signIssuerJwt(params) {
7
9
  const alg = params.alg ?? params.privateJwk.alg ?? "ES256";
8
10
  const kid = params.privateJwk.kid;
9
11
  if (!kid) {
10
- throw new Error(
11
- "signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)"
12
- );
12
+ throw new Error("signIssuerJwt: privateJwk.kid is required (gateway uses kid to look up the verification key)");
13
13
  }
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 payload = { ...params.extra ?? {} };
17
+ const payload = {
18
+ ...params.extra ?? {}
19
+ };
18
20
  if (params.authAttribute) {
19
21
  payload.auth_attribute = {
20
22
  type: params.authAttribute.type,
21
23
  value: params.authAttribute.value
22
24
  };
23
25
  }
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());
26
+ const builder = new SignJWT(payload).setProtectedHeader({
27
+ alg,
28
+ typ: "JWT",
29
+ kid
30
+ }).setIssuer(params.iss).setSubject(params.sub).setAudience(params.aud).setIssuedAt(now).setExpirationTime(now + lifetime).setJti(params.jti ?? randomUUID());
25
31
  return builder.sign(key);
26
32
  }
33
+ __name(signIssuerJwt, "signIssuerJwt");
27
34
  export {
28
35
  signIssuerJwt
29
36
  };
@@ -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 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":[]}
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,SAASA,WAAWC,eAAe;AACnC,SAASC,kBAAkB;AAyB3B,eAAsBC,cACpBC,QAA2B;AAE3B,QAAMC,MAAMD,OAAOC,OAAOD,OAAOE,WAAWD,OAAO;AACnD,QAAME,MAAMH,OAAOE,WAAWC;AAE9B,MAAI,CAACA,KAAK;AACR,UAAM,IAAIC,MACR,8FAAA;EAEJ;AAEA,QAAMC,MAAM,MAAMC,UAAUN,OAAOE,YAAYD,GAAAA;AAC/C,QAAMM,MAAMC,KAAKC,MAAMC,KAAKH,IAAG,IAAK,GAAA;AACpC,QAAMI,WAAWX,OAAOY,gBAAgB;AAExC,QAAMC,UAAmC;IAAE,GAAIb,OAAOc,SAAS,CAAC;EAAG;AACnE,MAAId,OAAOe,eAAe;AACxBF,YAAQG,iBAAiB;MACvBC,MAAMjB,OAAOe,cAAcE;MAC3BC,OAAOlB,OAAOe,cAAcG;IAC9B;EACF;AAEA,QAAMC,UAAU,IAAIC,QAAQP,OAAAA,EACzBQ,mBAAmB;IAAEpB;IAAKqB,KAAK;IAAOnB;EAAI,CAAA,EAC1CoB,UAAUvB,OAAOwB,GAAG,EACpBC,WAAWzB,OAAO0B,GAAG,EACrBC,YAAY3B,OAAO4B,GAAG,EACtBC,YAAYtB,GAAAA,EACZuB,kBAAkBvB,MAAMI,QAAAA,EACxBoB,OAAO/B,OAAOgC,OAAOC,WAAAA,CAAAA;AAExB,SAAOd,QAAQe,KAAK7B,GAAAA;AACtB;AAlCsBN;","names":["importJWK","SignJWT","randomUUID","signIssuerJwt","params","alg","privateJwk","kid","Error","key","importJWK","now","Math","floor","Date","lifetime","expiresInSec","payload","extra","authAttribute","auth_attribute","type","value","builder","SignJWT","setProtectedHeader","typ","setIssuer","iss","setSubject","sub","setAudience","aud","setIssuedAt","setExpirationTime","setJti","jti","randomUUID","sign"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pafi-dev/issuer",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
4
4
  "description": "Issuer backend API and services for the PAFI point token system",
5
5
  "repository": {
6
6
  "type": "git",
@@ -101,13 +101,13 @@
101
101
  ],
102
102
  "dependencies": {
103
103
  "jose": "^5.9.0",
104
- "@pafi-dev/core": "0.24.0"
104
+ "@pafi-dev/core": "0.25.0"
105
105
  },
106
106
  "peerDependencies": {
107
107
  "@nestjs/common": "^10.0.0",
108
108
  "@nestjs/swagger": "^7.0.0 || ^8.0.0",
109
- "class-validator": "^0.14.0",
110
109
  "class-transformer": "^0.5.0",
110
+ "class-validator": "^0.14.0",
111
111
  "reflect-metadata": "^0.1.13 || ^0.2.0",
112
112
  "viem": "^2.0.0"
113
113
  },
@@ -131,11 +131,13 @@
131
131
  "devDependencies": {
132
132
  "@nestjs/common": "^10.0.0",
133
133
  "@nestjs/swagger": "^7.0.0",
134
+ "@swc/core": "^1.15.43",
134
135
  "@vitest/coverage-v8": "^2.1.0",
135
136
  "class-validator": "^0.14.0",
136
137
  "reflect-metadata": "^0.2.0",
137
138
  "tsup": "^8.0.0",
138
139
  "typescript": "^5.5.0",
140
+ "unplugin-swc": "^1.5.9",
139
141
  "viem": "^2.21.0",
140
142
  "vitest": "^2.0.0"
141
143
  },
@@ -1,17 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result) __defProp(target, key, result);
9
- return result;
10
- };
11
- var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
12
-
13
- export {
14
- __decorateClass,
15
- __decorateParam
16
- };
17
- //# sourceMappingURL=chunk-BRKEJJFQ.js.map