@pafi-dev/issuer 0.33.0 → 0.35.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,142 +0,0 @@
1
- import { ExceptionFilter, ArgumentsHost, DynamicModule, FactoryProvider } from '@nestjs/common';
2
- import { PafiErrorEnvelope } from '../http/index.cjs';
3
- import { a as IssuerPublicJwk } from '../types-CxVXRHLy.cjs';
4
- import '@pafi-dev/core';
5
- import 'jose';
6
-
7
- /**
8
- * NestJS global exception filter that emits the PAFI Stripe-style
9
- * envelope (see `@pafi-dev/issuer/http`).
10
- *
11
- * Wire it once in your bootstrap:
12
- *
13
- * ```ts
14
- * import { PafiHttpExceptionFilter } from "@pafi-dev/issuer/nestjs";
15
- *
16
- * app.useGlobalFilters(new PafiHttpExceptionFilter());
17
- * ```
18
- *
19
- * Catches every thrown value:
20
- * - `PafiSdkError` (and subclasses) → typed envelope from `httpStatus`/
21
- * `code`/`type`/`safeToRetry`/`param`/`metadata`.
22
- * - `HttpException` (NestJS) → respected status; SDK-shaped body is
23
- * passed through, plain bodies + ValidationPipe arrays normalized.
24
- * - any other `Error` → `server_error` 500 with sanitized message.
25
- *
26
- * `@nestjs/common` is an optional peer dependency — only required when
27
- * importing this sub-export.
28
- */
29
-
30
- /** Customization knobs. None required — sensible defaults baked in. */
31
- interface PafiHttpExceptionFilterOptions {
32
- /**
33
- * Header to read for the request id, lowercase. Default `"x-request-id"`.
34
- * If absent, a UUIDv4 is generated per request.
35
- */
36
- requestIdHeader?: string;
37
- /**
38
- * Override `Date` for deterministic tests.
39
- */
40
- now?: () => Date;
41
- /**
42
- * Hook to record/audit normalized errors before sending. Useful for
43
- * Sentry / Datadog / Pino. Throws are swallowed so a logging bug
44
- * never masks the real error response.
45
- */
46
- onError?: (envelope: PafiErrorEnvelope, raw: unknown) => void;
47
- }
48
- declare class PafiHttpExceptionFilter implements ExceptionFilter {
49
- private readonly logger;
50
- private readonly opts;
51
- constructor(options?: PafiHttpExceptionFilterOptions);
52
- catch(exception: unknown, host: ArgumentsHost): void;
53
- private normalize;
54
- }
55
-
56
- interface WalletAuthJwksOptions {
57
- /**
58
- * One or more public JWKs to publish. During key rotation, include
59
- * BOTH the active and previous keys so JWTs signed with the older
60
- * kid can still be verified by the PAFI gateway until the rotation
61
- * window closes.
62
- */
63
- keys: IssuerPublicJwk[];
64
- }
65
- interface WalletAuthJwksAsyncOptions {
66
- /** Modules to import for the factory's DI. */
67
- imports?: NonNullable<DynamicModule["imports"]>;
68
- /** Providers to inject into useFactory — same shape as FactoryProvider.inject. */
69
- inject?: FactoryProvider["inject"];
70
- /** Builds options at runtime — read env, decrypt secrets, etc. */
71
- useFactory: (...args: any[]) => Promise<WalletAuthJwksOptions> | WalletAuthJwksOptions;
72
- }
73
- /**
74
- * Drop-in NestJS module that publishes the issuer's public signing
75
- * key set at GET /.well-known/jwks.json.
76
- *
77
- * Every issuer backend integrating with the PAFI Wallet Auth Gateway
78
- * needs this endpoint so the gateway can fetch their public key and
79
- * verify issuer JWT signatures.
80
- *
81
- * @example Sync registration
82
- * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';
83
- *
84
- * @Module({
85
- * imports: [
86
- * WalletAuthJwksModule.forRoot({
87
- * keys: [JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON!)],
88
- * }),
89
- * ],
90
- * })
91
- * export class AppModule {}
92
- *
93
- * @example Async registration (read from ConfigService)
94
- * import { ConfigModule, ConfigService } from '@nestjs/config';
95
- * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';
96
- *
97
- * @Module({
98
- * imports: [
99
- * WalletAuthJwksModule.forRootAsync({
100
- * imports: [ConfigModule],
101
- * inject: [ConfigService],
102
- * useFactory: (config: ConfigService) => ({
103
- * keys: [JSON.parse(config.getOrThrow('ISSUER_PUBLIC_JWK_JSON'))],
104
- * }),
105
- * }),
106
- * ],
107
- * })
108
- * export class AppModule {}
109
- *
110
- * @example Rotation window — publish 2 keys simultaneously
111
- * keys: [
112
- * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_ACTIVE!),
113
- * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_PREVIOUS!),
114
- * ]
115
- */
116
- declare class WalletAuthJwksModule {
117
- static forRoot(options: WalletAuthJwksOptions): DynamicModule;
118
- static forRootAsync(options: WalletAuthJwksAsyncOptions): DynamicModule;
119
- }
120
-
121
- /**
122
- * Publishes the issuer's public signing key set as RFC 7517 JWKS.
123
- *
124
- * The PAFI Wallet Auth Gateway fetches this URL to verify signatures
125
- * on issuer JWTs that this backend mints (the JWT travelling in
126
- * /v1/token-exchange's `issuer_jwt` body field).
127
- *
128
- * Mounted at GET /.well-known/jwks.json — no auth, public by design.
129
- */
130
- declare class WalletAuthJwksController {
131
- private readonly logger;
132
- private readonly jwks;
133
- constructor(keys: IssuerPublicJwk[]);
134
- getJwks(): {
135
- keys: IssuerPublicJwk[];
136
- };
137
- }
138
-
139
- /** DI token: array of public JWKs to publish at /.well-known/jwks.json. */
140
- declare const WALLET_AUTH_JWKS_KEYS: unique symbol;
141
-
142
- export { PafiHttpExceptionFilter, type PafiHttpExceptionFilterOptions, WALLET_AUTH_JWKS_KEYS, type WalletAuthJwksAsyncOptions, WalletAuthJwksController, WalletAuthJwksModule, type WalletAuthJwksOptions };
@@ -1,142 +0,0 @@
1
- import { ExceptionFilter, ArgumentsHost, DynamicModule, FactoryProvider } from '@nestjs/common';
2
- import { PafiErrorEnvelope } from '../http/index.js';
3
- import { a as IssuerPublicJwk } from '../types-CxVXRHLy.js';
4
- import '@pafi-dev/core';
5
- import 'jose';
6
-
7
- /**
8
- * NestJS global exception filter that emits the PAFI Stripe-style
9
- * envelope (see `@pafi-dev/issuer/http`).
10
- *
11
- * Wire it once in your bootstrap:
12
- *
13
- * ```ts
14
- * import { PafiHttpExceptionFilter } from "@pafi-dev/issuer/nestjs";
15
- *
16
- * app.useGlobalFilters(new PafiHttpExceptionFilter());
17
- * ```
18
- *
19
- * Catches every thrown value:
20
- * - `PafiSdkError` (and subclasses) → typed envelope from `httpStatus`/
21
- * `code`/`type`/`safeToRetry`/`param`/`metadata`.
22
- * - `HttpException` (NestJS) → respected status; SDK-shaped body is
23
- * passed through, plain bodies + ValidationPipe arrays normalized.
24
- * - any other `Error` → `server_error` 500 with sanitized message.
25
- *
26
- * `@nestjs/common` is an optional peer dependency — only required when
27
- * importing this sub-export.
28
- */
29
-
30
- /** Customization knobs. None required — sensible defaults baked in. */
31
- interface PafiHttpExceptionFilterOptions {
32
- /**
33
- * Header to read for the request id, lowercase. Default `"x-request-id"`.
34
- * If absent, a UUIDv4 is generated per request.
35
- */
36
- requestIdHeader?: string;
37
- /**
38
- * Override `Date` for deterministic tests.
39
- */
40
- now?: () => Date;
41
- /**
42
- * Hook to record/audit normalized errors before sending. Useful for
43
- * Sentry / Datadog / Pino. Throws are swallowed so a logging bug
44
- * never masks the real error response.
45
- */
46
- onError?: (envelope: PafiErrorEnvelope, raw: unknown) => void;
47
- }
48
- declare class PafiHttpExceptionFilter implements ExceptionFilter {
49
- private readonly logger;
50
- private readonly opts;
51
- constructor(options?: PafiHttpExceptionFilterOptions);
52
- catch(exception: unknown, host: ArgumentsHost): void;
53
- private normalize;
54
- }
55
-
56
- interface WalletAuthJwksOptions {
57
- /**
58
- * One or more public JWKs to publish. During key rotation, include
59
- * BOTH the active and previous keys so JWTs signed with the older
60
- * kid can still be verified by the PAFI gateway until the rotation
61
- * window closes.
62
- */
63
- keys: IssuerPublicJwk[];
64
- }
65
- interface WalletAuthJwksAsyncOptions {
66
- /** Modules to import for the factory's DI. */
67
- imports?: NonNullable<DynamicModule["imports"]>;
68
- /** Providers to inject into useFactory — same shape as FactoryProvider.inject. */
69
- inject?: FactoryProvider["inject"];
70
- /** Builds options at runtime — read env, decrypt secrets, etc. */
71
- useFactory: (...args: any[]) => Promise<WalletAuthJwksOptions> | WalletAuthJwksOptions;
72
- }
73
- /**
74
- * Drop-in NestJS module that publishes the issuer's public signing
75
- * key set at GET /.well-known/jwks.json.
76
- *
77
- * Every issuer backend integrating with the PAFI Wallet Auth Gateway
78
- * needs this endpoint so the gateway can fetch their public key and
79
- * verify issuer JWT signatures.
80
- *
81
- * @example Sync registration
82
- * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';
83
- *
84
- * @Module({
85
- * imports: [
86
- * WalletAuthJwksModule.forRoot({
87
- * keys: [JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON!)],
88
- * }),
89
- * ],
90
- * })
91
- * export class AppModule {}
92
- *
93
- * @example Async registration (read from ConfigService)
94
- * import { ConfigModule, ConfigService } from '@nestjs/config';
95
- * import { WalletAuthJwksModule } from '@pafi-dev/issuer/nestjs';
96
- *
97
- * @Module({
98
- * imports: [
99
- * WalletAuthJwksModule.forRootAsync({
100
- * imports: [ConfigModule],
101
- * inject: [ConfigService],
102
- * useFactory: (config: ConfigService) => ({
103
- * keys: [JSON.parse(config.getOrThrow('ISSUER_PUBLIC_JWK_JSON'))],
104
- * }),
105
- * }),
106
- * ],
107
- * })
108
- * export class AppModule {}
109
- *
110
- * @example Rotation window — publish 2 keys simultaneously
111
- * keys: [
112
- * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_ACTIVE!),
113
- * JSON.parse(process.env.ISSUER_PUBLIC_JWK_JSON_PREVIOUS!),
114
- * ]
115
- */
116
- declare class WalletAuthJwksModule {
117
- static forRoot(options: WalletAuthJwksOptions): DynamicModule;
118
- static forRootAsync(options: WalletAuthJwksAsyncOptions): DynamicModule;
119
- }
120
-
121
- /**
122
- * Publishes the issuer's public signing key set as RFC 7517 JWKS.
123
- *
124
- * The PAFI Wallet Auth Gateway fetches this URL to verify signatures
125
- * on issuer JWTs that this backend mints (the JWT travelling in
126
- * /v1/token-exchange's `issuer_jwt` body field).
127
- *
128
- * Mounted at GET /.well-known/jwks.json — no auth, public by design.
129
- */
130
- declare class WalletAuthJwksController {
131
- private readonly logger;
132
- private readonly jwks;
133
- constructor(keys: IssuerPublicJwk[]);
134
- getJwks(): {
135
- keys: IssuerPublicJwk[];
136
- };
137
- }
138
-
139
- /** DI token: array of public JWKs to publish at /.well-known/jwks.json. */
140
- declare const WALLET_AUTH_JWKS_KEYS: unique symbol;
141
-
142
- export { PafiHttpExceptionFilter, type PafiHttpExceptionFilterOptions, WALLET_AUTH_JWKS_KEYS, type WalletAuthJwksAsyncOptions, WalletAuthJwksController, WalletAuthJwksModule, type WalletAuthJwksOptions };
@@ -1,64 +0,0 @@
1
- import { JWK } from 'jose';
2
-
3
- /**
4
- * Public JWK shape — what an issuer publishes at /.well-known/jwks.json
5
- * for the PAFI Wallet Auth Gateway to fetch and verify signatures.
6
- *
7
- * Must include `kid` so the gateway can match it against the `kid`
8
- * header in inbound issuer JWTs (multiple keys can be published
9
- * simultaneously during a rotation window).
10
- */
11
- interface IssuerPublicJwk extends JWK {
12
- kty: string;
13
- kid: string;
14
- alg?: string;
15
- use?: string;
16
- }
17
- /**
18
- * Private JWK — held by the issuer backend, never published.
19
- * Used by `signIssuerJwt` to mint JWTs the gateway can verify.
20
- */
21
- interface IssuerPrivateJwk extends JWK {
22
- kty: string;
23
- kid: string;
24
- alg?: string;
25
- }
26
- /**
27
- * Parameters for minting an issuer JWT to send to the PAFI gateway.
28
- */
29
- interface SignIssuerJwtParams {
30
- /** Private signing key (ES256 / ES384 / RS256 / RS384 / RS512 / EdDSA). */
31
- privateJwk: IssuerPrivateJwk;
32
- /** Stable identifier for the user being attested (issuer's internal user id). */
33
- sub: string;
34
- /** This issuer backend's identity URL — must match `expected_iss` in PAFI's `issuers` row. */
35
- iss: string;
36
- /**
37
- * Expected audience — PAFI gateway's per-env audience claim
38
- * (e.g. `pafi-gateway-prod` / `pafi-gateway-staging` / `pafi-gateway-dev`).
39
- * Provided by PAFI ops at onboarding time.
40
- */
41
- aud: string;
42
- /**
43
- * Optional algorithm override. Defaults to private JWK's `alg`, then `ES256`.
44
- * Must match a value in PAFI gateway's algorithm whitelist.
45
- */
46
- alg?: "ES256" | "ES384" | "RS256" | "RS384" | "RS512" | "EdDSA";
47
- /**
48
- * Lifetime in seconds. Default 60 — keep short. PAFI gateway also
49
- * enforces `max_token_age_sec` (default 60) regardless of `exp`.
50
- */
51
- expiresInSec?: number;
52
- /**
53
- * Optional unique JWT id. Defaults to a random UUID. PAFI gateway
54
- * uses this for replay protection — must be unique per request.
55
- */
56
- jti?: string;
57
- /**
58
- * Optional additional claims merged into the payload. Use sparingly —
59
- * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`.
60
- */
61
- extra?: Record<string, unknown>;
62
- }
63
-
64
- export type { IssuerPrivateJwk as I, SignIssuerJwtParams as S, IssuerPublicJwk as a };
@@ -1,64 +0,0 @@
1
- import { JWK } from 'jose';
2
-
3
- /**
4
- * Public JWK shape — what an issuer publishes at /.well-known/jwks.json
5
- * for the PAFI Wallet Auth Gateway to fetch and verify signatures.
6
- *
7
- * Must include `kid` so the gateway can match it against the `kid`
8
- * header in inbound issuer JWTs (multiple keys can be published
9
- * simultaneously during a rotation window).
10
- */
11
- interface IssuerPublicJwk extends JWK {
12
- kty: string;
13
- kid: string;
14
- alg?: string;
15
- use?: string;
16
- }
17
- /**
18
- * Private JWK — held by the issuer backend, never published.
19
- * Used by `signIssuerJwt` to mint JWTs the gateway can verify.
20
- */
21
- interface IssuerPrivateJwk extends JWK {
22
- kty: string;
23
- kid: string;
24
- alg?: string;
25
- }
26
- /**
27
- * Parameters for minting an issuer JWT to send to the PAFI gateway.
28
- */
29
- interface SignIssuerJwtParams {
30
- /** Private signing key (ES256 / ES384 / RS256 / RS384 / RS512 / EdDSA). */
31
- privateJwk: IssuerPrivateJwk;
32
- /** Stable identifier for the user being attested (issuer's internal user id). */
33
- sub: string;
34
- /** This issuer backend's identity URL — must match `expected_iss` in PAFI's `issuers` row. */
35
- iss: string;
36
- /**
37
- * Expected audience — PAFI gateway's per-env audience claim
38
- * (e.g. `pafi-gateway-prod` / `pafi-gateway-staging` / `pafi-gateway-dev`).
39
- * Provided by PAFI ops at onboarding time.
40
- */
41
- aud: string;
42
- /**
43
- * Optional algorithm override. Defaults to private JWK's `alg`, then `ES256`.
44
- * Must match a value in PAFI gateway's algorithm whitelist.
45
- */
46
- alg?: "ES256" | "ES384" | "RS256" | "RS384" | "RS512" | "EdDSA";
47
- /**
48
- * Lifetime in seconds. Default 60 — keep short. PAFI gateway also
49
- * enforces `max_token_age_sec` (default 60) regardless of `exp`.
50
- */
51
- expiresInSec?: number;
52
- /**
53
- * Optional unique JWT id. Defaults to a random UUID. PAFI gateway
54
- * uses this for replay protection — must be unique per request.
55
- */
56
- jti?: string;
57
- /**
58
- * Optional additional claims merged into the payload. Use sparingly —
59
- * PAFI gateway only reads `iss`, `sub`, `aud`, `iat`, `exp`, `jti`.
60
- */
61
- extra?: Record<string, unknown>;
62
- }
63
-
64
- export type { IssuerPrivateJwk as I, SignIssuerJwtParams as S, IssuerPublicJwk as a };
@@ -1,29 +0,0 @@
1
- import { S as SignIssuerJwtParams } from '../types-CxVXRHLy.cjs';
2
- export { I as IssuerPrivateJwk, a as IssuerPublicJwk } from '../types-CxVXRHLy.cjs';
3
- import 'jose';
4
-
5
- /**
6
- * Mint an issuer JWT for the PAFI Wallet Auth Gateway.
7
- *
8
- * Returns a compact JWT (header.payload.signature) ready to send as
9
- * the `issuer_jwt` body field in `POST /v1/token-exchange`.
10
- *
11
- * The matching public key must be reachable at the issuer's
12
- * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the
13
- * gateway can verify the signature.
14
- *
15
- * @example
16
- * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';
17
- *
18
- * const jwt = await signIssuerJwt({
19
- * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),
20
- * iss: 'https://gg56.com',
21
- * sub: 'gg56_user_99',
22
- * aud: 'pafi-gateway-prod',
23
- * });
24
- *
25
- * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway
26
- */
27
- declare function signIssuerJwt(params: SignIssuerJwtParams): Promise<string>;
28
-
29
- export { SignIssuerJwtParams, signIssuerJwt };
@@ -1,29 +0,0 @@
1
- import { S as SignIssuerJwtParams } from '../types-CxVXRHLy.js';
2
- export { I as IssuerPrivateJwk, a as IssuerPublicJwk } from '../types-CxVXRHLy.js';
3
- import 'jose';
4
-
5
- /**
6
- * Mint an issuer JWT for the PAFI Wallet Auth Gateway.
7
- *
8
- * Returns a compact JWT (header.payload.signature) ready to send as
9
- * the `issuer_jwt` body field in `POST /v1/token-exchange`.
10
- *
11
- * The matching public key must be reachable at the issuer's
12
- * `/.well-known/jwks.json` (see `WalletAuthJwksModule`) so the
13
- * gateway can verify the signature.
14
- *
15
- * @example
16
- * import { signIssuerJwt } from '@pafi-dev/issuer/wallet-auth';
17
- *
18
- * const jwt = await signIssuerJwt({
19
- * privateJwk: JSON.parse(process.env.ISSUER_PRIVATE_JWK_JSON!),
20
- * iss: 'https://gg56.com',
21
- * sub: 'gg56_user_99',
22
- * aud: 'pafi-gateway-prod',
23
- * });
24
- *
25
- * // POST { issuer_id: 'GG56', issuer_jwt: jwt } to gateway
26
- */
27
- declare function signIssuerJwt(params: SignIssuerJwtParams): Promise<string>;
28
-
29
- export { SignIssuerJwtParams, signIssuerJwt };