@pafi-dev/issuer 0.38.0 → 0.39.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.
- package/dist/auth-client/index.d.cts +2 -140
- package/dist/auth-client/index.d.ts +2 -140
- package/dist/auth-client/index.js +5 -176
- package/dist/auth-client/index.js.map +1 -1
- package/dist/chunk-7VEYSL2C.js +180 -0
- package/dist/chunk-7VEYSL2C.js.map +1 -0
- package/dist/direct-auth/index.cjs +657 -0
- package/dist/direct-auth/index.cjs.map +1 -0
- package/dist/direct-auth/index.d.cts +405 -0
- package/dist/direct-auth/index.d.ts +405 -0
- package/dist/direct-auth/index.js +458 -0
- package/dist/direct-auth/index.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/pafi-auth-client-DzHd_Ts_.d.cts +142 -0
- package/dist/pafi-auth-client-DzHd_Ts_.d.ts +142 -0
- package/package.json +44 -12
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { Type, DynamicModule, OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { JWK, JWTPayload } from 'jose';
|
|
3
|
+
import { P as PafiAuthClient } from '../pafi-auth-client-DzHd_Ts_.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Issuer-side abstraction for "make sure the local user row exists,
|
|
7
|
+
* keyed by the canonical_pafi_user_id the gateway just resolved."
|
|
8
|
+
*
|
|
9
|
+
* The SDK can't own this because each issuer has a different
|
|
10
|
+
* `users` table schema (gg56 has `wallet_address`, lotteria doesn't,
|
|
11
|
+
* future issuers might add `phone_number` / `kyc_status` / etc.).
|
|
12
|
+
* Each consuming issuer backend implements `IUserStore` once and
|
|
13
|
+
* passes the class to `PafiDirectAuthModule.forRoot({ userStore })`.
|
|
14
|
+
*
|
|
15
|
+
* Idempotency contract: callers invoke this on every successful
|
|
16
|
+
* direct-auth flow (email OTP / Google / Kakao). Implementation MUST
|
|
17
|
+
* be idempotent — re-calling with the same args is a no-op, NOT an
|
|
18
|
+
* error.
|
|
19
|
+
*
|
|
20
|
+
* Lookup precedence (recommended): canonical_id first, fall back to
|
|
21
|
+
* email. Same canonical across issuers = cross-issuer wallet merge.
|
|
22
|
+
*
|
|
23
|
+
* Race-safety: parallel requests for the same brand-new canonical
|
|
24
|
+
* should be tolerated. The SDK assumes the underlying DB enforces a
|
|
25
|
+
* unique constraint on canonical_id; on conflict, treat as "row
|
|
26
|
+
* already exists" rather than re-throwing.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* @Injectable()
|
|
31
|
+
* class Gg56UserStore implements IUserStore {
|
|
32
|
+
* constructor(
|
|
33
|
+
* @InjectRepository(UserEntity)
|
|
34
|
+
* private readonly users: Repository<UserEntity>,
|
|
35
|
+
* ) {}
|
|
36
|
+
*
|
|
37
|
+
* async upsertByCanonicalAndEmail(args: {
|
|
38
|
+
* canonicalId: string;
|
|
39
|
+
* verifiedEmail?: string;
|
|
40
|
+
* }): Promise<void> {
|
|
41
|
+
* const byCanonical = await this.users.findOne({
|
|
42
|
+
* where: { canonicalId: args.canonicalId },
|
|
43
|
+
* });
|
|
44
|
+
* if (byCanonical) return;
|
|
45
|
+
* // ... fall back to email, create row, race-handle, etc.
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
interface IUserStore {
|
|
51
|
+
upsertByCanonicalAndEmail(args: {
|
|
52
|
+
/** canonical_pafi_user_id the gateway just minted. Always present. */
|
|
53
|
+
canonicalId: string;
|
|
54
|
+
/**
|
|
55
|
+
* Verified email when the auth method exposed one (email OTP +
|
|
56
|
+
* Google always; Kakao only if user shared email at consent).
|
|
57
|
+
* Issuer may use to display profile, NOT for primary user lookup
|
|
58
|
+
* (canonicalId is the stable id).
|
|
59
|
+
*/
|
|
60
|
+
verifiedEmail?: string;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
/** DI token for IUserStore. Use with `@Inject(USER_STORE)`. */
|
|
64
|
+
declare const USER_STORE: unique symbol;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Issuer-side abstraction for "mint an issuer-native session token
|
|
68
|
+
* the FE will Bearer-auth with for all subsequent /api calls."
|
|
69
|
+
*
|
|
70
|
+
* The SDK can't own this because:
|
|
71
|
+
* - Each issuer signs with their own `JWT_SECRET` (HS256) OR with
|
|
72
|
+
* their own RSA/ECDSA key — SDK shouldn't see secrets
|
|
73
|
+
* - Token shape may differ (sub format, scope claims, extra claims
|
|
74
|
+
* like role/tier specific to the issuer's app)
|
|
75
|
+
* - Lifetime may differ (24h default, but some issuers want shorter)
|
|
76
|
+
* - Existing JwtGuard / SessionTokenGuard in the issuer backend
|
|
77
|
+
* expects a specific shape — SDK can't predict it
|
|
78
|
+
*
|
|
79
|
+
* The SDK orchestrator calls `mint()` once per successful direct-auth
|
|
80
|
+
* flow, BEFORE returning the bundled response to the issuer's HTTP
|
|
81
|
+
* controller. The minter is responsible for:
|
|
82
|
+
* 1. Producing a token the issuer's existing guards accept
|
|
83
|
+
* 2. Embedding `authAttribute: {type, value}` if the issuer's
|
|
84
|
+
* /wallet/exchange-pafi-jwt refresh path needs it (most do — see
|
|
85
|
+
* ISSUER_INTEGRATION_GUIDE.md §9 refresh path)
|
|
86
|
+
* 3. Computing absolute expiry timestamp the FE can show
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* @Injectable()
|
|
91
|
+
* class Gg56SessionMinter implements ISessionTokenMinter {
|
|
92
|
+
* private readonly secret: Uint8Array;
|
|
93
|
+
* constructor(config: ConfigService) {
|
|
94
|
+
* this.secret = new TextEncoder().encode(
|
|
95
|
+
* config.getOrThrow('JWT_SECRET'),
|
|
96
|
+
* );
|
|
97
|
+
* }
|
|
98
|
+
*
|
|
99
|
+
* async mint(args: {
|
|
100
|
+
* canonicalId: string;
|
|
101
|
+
* verifiedEmail?: string;
|
|
102
|
+
* }): Promise<{ token: string; expiresAt: string }> {
|
|
103
|
+
* const now = Math.floor(Date.now() / 1000);
|
|
104
|
+
* const exp = now + 86400;
|
|
105
|
+
* const token = await new SignJWT({
|
|
106
|
+
* userKey: args.canonicalId,
|
|
107
|
+
* loginType: 'pafi-direct',
|
|
108
|
+
* scope: 'pafi-session',
|
|
109
|
+
* ...(args.verifiedEmail
|
|
110
|
+
* ? { authAttribute: { type: 'email', value: args.verifiedEmail } }
|
|
111
|
+
* : {}),
|
|
112
|
+
* })
|
|
113
|
+
* .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
|
|
114
|
+
* .setSubject(args.canonicalId)
|
|
115
|
+
* .setIssuedAt(now)
|
|
116
|
+
* .setExpirationTime(exp)
|
|
117
|
+
* .sign(this.secret);
|
|
118
|
+
* return { token, expiresAt: new Date(exp * 1000).toISOString() };
|
|
119
|
+
* }
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
interface ISessionTokenMinter {
|
|
124
|
+
mint(args: {
|
|
125
|
+
/** canonical_pafi_user_id, use as `sub` so downstream identifies user uniformly. */
|
|
126
|
+
canonicalId: string;
|
|
127
|
+
/**
|
|
128
|
+
* Verified email when available. Implementations SHOULD embed this
|
|
129
|
+
* as `authAttribute: { type: 'email', value }` in the JWT body so
|
|
130
|
+
* the legacy /wallet/exchange-pafi-jwt refresh path keeps deriving
|
|
131
|
+
* the same canonical_id from the same attribute across refreshes.
|
|
132
|
+
*/
|
|
133
|
+
verifiedEmail?: string;
|
|
134
|
+
}): Promise<{
|
|
135
|
+
/** The signed session token (any JWT shape — issuer guards must accept). */
|
|
136
|
+
token: string;
|
|
137
|
+
/** ISO 8601 absolute expiry timestamp. Returned to FE so it can show "expires at X". */
|
|
138
|
+
expiresAt: string;
|
|
139
|
+
}>;
|
|
140
|
+
}
|
|
141
|
+
/** DI token for ISessionTokenMinter. Use with `@Inject(SESSION_TOKEN_MINTER)`. */
|
|
142
|
+
declare const SESSION_TOKEN_MINTER: unique symbol;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Options consumed by `PafiDirectAuthModule.forRoot(options)`. The
|
|
146
|
+
* host (issuer backend) supplies:
|
|
147
|
+
*
|
|
148
|
+
* - Gateway credentials (URL, issuer_id, client_id, private JWK)
|
|
149
|
+
* - Issuer-specific implementations of IUserStore + ISessionTokenMinter
|
|
150
|
+
*
|
|
151
|
+
* Typically read from `ConfigService` in the issuer backend. Use
|
|
152
|
+
* `forRootAsync()` (planned) when config needs `inject: [ConfigService]`.
|
|
153
|
+
*/
|
|
154
|
+
interface PafiDirectAuthModuleOptions {
|
|
155
|
+
/** Base URL of the PAFI gateway (e.g. `https://id-dev.pacificfinance.org`). */
|
|
156
|
+
gatewayUrl: string;
|
|
157
|
+
/** Issuer identifier registered with the gateway (e.g. `gg56`). */
|
|
158
|
+
issuerId: string;
|
|
159
|
+
/**
|
|
160
|
+
* Gateway client_id assigned at issuer onboarding. Also acts as the
|
|
161
|
+
* `iss`/`sub` of the client_assertion JWT (RFC 7523 §3).
|
|
162
|
+
*/
|
|
163
|
+
clientId: string;
|
|
164
|
+
/**
|
|
165
|
+
* Private JWK the issuer uses to sign client_assertion. MUST include
|
|
166
|
+
* `kid` — gateway looks up the matching public JWK by kid.
|
|
167
|
+
*/
|
|
168
|
+
clientPrivateJwk: JWK & {
|
|
169
|
+
kid: string;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Issuer-implemented user-row upsert. SDK calls this on every
|
|
173
|
+
* successful direct-auth flow to ensure the local users row exists
|
|
174
|
+
* keyed by canonical_id. See `IUserStore` for contract details.
|
|
175
|
+
*/
|
|
176
|
+
userStore: Type<IUserStore>;
|
|
177
|
+
/**
|
|
178
|
+
* Issuer-implemented session-token minter. SDK calls this once per
|
|
179
|
+
* successful direct-auth flow to wrap the gateway-returned canonical
|
|
180
|
+
* + verified email into the issuer's own session JWT. See
|
|
181
|
+
* `ISessionTokenMinter` for contract details.
|
|
182
|
+
*/
|
|
183
|
+
sessionTokenMinter: Type<ISessionTokenMinter>;
|
|
184
|
+
}
|
|
185
|
+
/** DI token for the resolved options. Use with `@Inject(PAFI_DIRECT_AUTH_MODULE_OPTIONS)`. */
|
|
186
|
+
declare const PAFI_DIRECT_AUTH_MODULE_OPTIONS: unique symbol;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* NestJS module wiring the direct-auth surface (`/auth/v2/*`
|
|
190
|
+
* controller, orchestrator service, gateway client, session
|
|
191
|
+
* verifier).
|
|
192
|
+
*
|
|
193
|
+
* Issuer backends mount this once at the root module with their
|
|
194
|
+
* gateway credentials + their `IUserStore` and `ISessionTokenMinter`
|
|
195
|
+
* implementations:
|
|
196
|
+
*
|
|
197
|
+
* ```ts
|
|
198
|
+
* @Module({
|
|
199
|
+
* imports: [
|
|
200
|
+
* ConfigModule.forRoot(),
|
|
201
|
+
* TypeOrmModule.forFeature([UserEntity]),
|
|
202
|
+
* PafiDirectAuthModule.forRoot({
|
|
203
|
+
* gatewayUrl: process.env.PAFI_GATEWAY_URL!,
|
|
204
|
+
* issuerId: process.env.PAFI_GATEWAY_ISSUER_ID!,
|
|
205
|
+
* clientId: process.env.PAFI_GATEWAY_CLIENT_ID!,
|
|
206
|
+
* clientPrivateJwk: JSON.parse(
|
|
207
|
+
* process.env.PAFI_GATEWAY_CLIENT_PRIVATE_JWK_JSON!,
|
|
208
|
+
* ) as JWK & { kid: string },
|
|
209
|
+
* userStore: Gg56UserStore,
|
|
210
|
+
* sessionTokenMinter: Gg56SessionMinter,
|
|
211
|
+
* }),
|
|
212
|
+
* ],
|
|
213
|
+
* providers: [Gg56UserStore, Gg56SessionMinter],
|
|
214
|
+
* })
|
|
215
|
+
* export class AuthModule {}
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* The `IUserStore` + `ISessionTokenMinter` classes MUST be provided
|
|
219
|
+
* separately in the host module's `providers:` array (NestJS needs to
|
|
220
|
+
* see them to instantiate via DI). This module wires them to the
|
|
221
|
+
* orchestrator via the `USER_STORE` + `SESSION_TOKEN_MINTER` injection
|
|
222
|
+
* tokens.
|
|
223
|
+
*
|
|
224
|
+
* For ConfigService-based async setup, use `forRootAsync()` (TODO).
|
|
225
|
+
*/
|
|
226
|
+
declare class PafiDirectAuthModule {
|
|
227
|
+
static forRoot(options: PafiDirectAuthModuleOptions): DynamicModule;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Thin DI wrapper around {@link PafiAuthClient}. Constructs a single
|
|
232
|
+
* client at boot using the issuer's gateway credentials and exposes it
|
|
233
|
+
* to services that need to call the direct-auth endpoints.
|
|
234
|
+
*
|
|
235
|
+
* One instance per process — the SDK client is stateless and the
|
|
236
|
+
* client_assertion is signed on every call (no warm-up needed).
|
|
237
|
+
*
|
|
238
|
+
* Config comes from `PafiDirectAuthModule.forRoot(options)` (see
|
|
239
|
+
* `pafi-direct-auth.module.ts`). The host app supplies `gatewayUrl`,
|
|
240
|
+
* `issuerId`, `clientId`, and `clientPrivateJwk` either as literal
|
|
241
|
+
* values OR as a factory that resolves them from NestJS ConfigService
|
|
242
|
+
* (`forRootAsync` variant).
|
|
243
|
+
*/
|
|
244
|
+
declare class PafiAuthClientProvider implements OnModuleInit {
|
|
245
|
+
private readonly options;
|
|
246
|
+
private _client;
|
|
247
|
+
constructor(options: PafiDirectAuthModuleOptions);
|
|
248
|
+
onModuleInit(): void;
|
|
249
|
+
get client(): PafiAuthClient;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
interface PafiSessionClaims {
|
|
253
|
+
sub: string;
|
|
254
|
+
scope: "pafi-session";
|
|
255
|
+
/** Verified attribute the gateway used to derive canonical_id. */
|
|
256
|
+
verifiedAttribute?: {
|
|
257
|
+
type: string;
|
|
258
|
+
valueHash?: string;
|
|
259
|
+
};
|
|
260
|
+
/** Issuer that originated the auth (must equal our PAFI_GATEWAY_ISSUER_ID). */
|
|
261
|
+
issuerId?: string;
|
|
262
|
+
exp: number;
|
|
263
|
+
iat: number;
|
|
264
|
+
raw: JWTPayload;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Verifies the long-lived `pafi_session_token` returned by the
|
|
268
|
+
* gateway's direct-auth endpoints. Defense-in-depth: the gateway just
|
|
269
|
+
* minted this token, so the chance of forgery is near zero — BUT
|
|
270
|
+
* verifying it locally guarantees we never trust an attacker-supplied
|
|
271
|
+
* "fake gateway response" that bypassed the network call (e.g. a
|
|
272
|
+
* compromised inbound proxy injecting an arbitrary JSON body). One
|
|
273
|
+
* audit line for a millisecond of crypto work.
|
|
274
|
+
*
|
|
275
|
+
* Uses the gateway's published JWKS (`/.well-known/jwks.json`) — same
|
|
276
|
+
* key set Privy uses when verifying the short-lived `pafi_jwt`. The
|
|
277
|
+
* remote JWKS is cached + auto-refreshed by jose.
|
|
278
|
+
*/
|
|
279
|
+
declare class PafiSessionVerifierService {
|
|
280
|
+
private readonly jwks;
|
|
281
|
+
private readonly expectedIssuer;
|
|
282
|
+
constructor(options: PafiDirectAuthModuleOptions);
|
|
283
|
+
verify(token: string): Promise<PafiSessionClaims>;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
interface DirectAuthResult {
|
|
287
|
+
sessionToken: string;
|
|
288
|
+
sessionExpiresAt: string;
|
|
289
|
+
pafiJwt: string;
|
|
290
|
+
pafiSessionToken: string;
|
|
291
|
+
canonicalId: string;
|
|
292
|
+
isFirstLogin: boolean;
|
|
293
|
+
verifiedEmail?: string;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Orchestrates the gateway-owned auth flows for an issuer backend. The
|
|
297
|
+
* gateway is the sole verifier (it ran the OTP check / verified the
|
|
298
|
+
* Google id_token / exchanged the Kakao code); this service is a thin
|
|
299
|
+
* adapter that:
|
|
300
|
+
*
|
|
301
|
+
* 1. Forwards the call via {@link PafiAuthClient} (RFC 7523
|
|
302
|
+
* client_assertion signed by the issuer's private JWK)
|
|
303
|
+
* 2. Verifies the returned `pafi_session_token` against the gateway's
|
|
304
|
+
* JWKS (defense in depth — see {@link PafiSessionVerifierService})
|
|
305
|
+
* 3. Upserts the local user row via {@link IUserStore} (issuer
|
|
306
|
+
* implements; SDK doesn't know the DB schema)
|
|
307
|
+
* 4. Mints an issuer-native session token via
|
|
308
|
+
* {@link ISessionTokenMinter} (issuer implements; SDK doesn't see
|
|
309
|
+
* the issuer's JWT_SECRET)
|
|
310
|
+
*
|
|
311
|
+
* The returned `sessionToken.sub` is the canonical_id — the same value
|
|
312
|
+
* the gateway uses for the PAFI JWT's `sub`. This means downstream
|
|
313
|
+
* services that need a stable user id can use it without caring which
|
|
314
|
+
* auth method produced it.
|
|
315
|
+
*
|
|
316
|
+
* Extracted from per-issuer boilerplate code in 2026-06-30 SDK refactor.
|
|
317
|
+
* Previously copy-pasted (~260 lines per issuer); now ~60 lines per
|
|
318
|
+
* issuer (UserStore + SessionMinter + module wiring).
|
|
319
|
+
*/
|
|
320
|
+
declare class PafiDirectAuthService {
|
|
321
|
+
private readonly clientProvider;
|
|
322
|
+
private readonly sessionVerifier;
|
|
323
|
+
private readonly userStore;
|
|
324
|
+
private readonly sessionTokenMinter;
|
|
325
|
+
private readonly logger;
|
|
326
|
+
constructor(clientProvider: PafiAuthClientProvider, sessionVerifier: PafiSessionVerifierService, userStore: IUserStore, sessionTokenMinter: ISessionTokenMinter);
|
|
327
|
+
startEmail(args: {
|
|
328
|
+
email: string;
|
|
329
|
+
correlationId?: string;
|
|
330
|
+
}): Promise<{
|
|
331
|
+
challengeId: string;
|
|
332
|
+
expiresInSec: number;
|
|
333
|
+
}>;
|
|
334
|
+
verifyEmail(args: {
|
|
335
|
+
challengeId: string;
|
|
336
|
+
otpCode: string;
|
|
337
|
+
correlationId?: string;
|
|
338
|
+
}): Promise<DirectAuthResult>;
|
|
339
|
+
exchangeGoogle(args: {
|
|
340
|
+
idToken: string;
|
|
341
|
+
correlationId?: string;
|
|
342
|
+
}): Promise<DirectAuthResult>;
|
|
343
|
+
exchangeKakao(args: {
|
|
344
|
+
code: string;
|
|
345
|
+
redirectUri?: string;
|
|
346
|
+
correlationId?: string;
|
|
347
|
+
}): Promise<DirectAuthResult>;
|
|
348
|
+
private finalize;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
declare class EmailStartRequestDto {
|
|
352
|
+
email: string;
|
|
353
|
+
}
|
|
354
|
+
declare class EmailVerifyRequestDto {
|
|
355
|
+
challengeId: string;
|
|
356
|
+
otpCode: string;
|
|
357
|
+
}
|
|
358
|
+
declare class GoogleExchangeRequestDto {
|
|
359
|
+
idToken: string;
|
|
360
|
+
}
|
|
361
|
+
declare class KakaoExchangeRequestDto {
|
|
362
|
+
code: string;
|
|
363
|
+
redirectUri?: string;
|
|
364
|
+
}
|
|
365
|
+
declare class EmailStartResponseDto {
|
|
366
|
+
challengeId: string;
|
|
367
|
+
expiresInSec: number;
|
|
368
|
+
}
|
|
369
|
+
declare class PafiAuthSuccessDto {
|
|
370
|
+
sessionToken: string;
|
|
371
|
+
sessionExpiresAt: string;
|
|
372
|
+
pafiJwt: string;
|
|
373
|
+
pafiSessionToken: string;
|
|
374
|
+
canonicalId: string;
|
|
375
|
+
isFirstLogin: boolean;
|
|
376
|
+
verifiedEmail?: string;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* `/auth/v2/*` — gateway-owned auth endpoints (2026-06-30 direct-auth
|
|
381
|
+
* surface, shipped by `@pafi-dev/issuer/direct-auth`).
|
|
382
|
+
*
|
|
383
|
+
* Issuer backend no longer verifies OTP codes, OAuth id_tokens, or
|
|
384
|
+
* holds OAuth client_secrets. All of that lives at the PAFI gateway.
|
|
385
|
+
* These endpoints are thin proxies that forward user input via
|
|
386
|
+
* {@link PafiDirectAuthService}, then upsert the local user row (via
|
|
387
|
+
* the issuer-provided {@link IUserStore}) + mint an issuer-native
|
|
388
|
+
* session token (via the issuer-provided {@link ISessionTokenMinter})
|
|
389
|
+
* wrapping the gateway-assigned canonical_id.
|
|
390
|
+
*
|
|
391
|
+
* Mounted automatically by `PafiDirectAuthModule.forRoot(options)`.
|
|
392
|
+
* Issuer apps that want to layer extra auth-error handling (e.g. a
|
|
393
|
+
* custom `AuthErrorFilter`) can wrap the controller's routes via a
|
|
394
|
+
* NestJS global filter — no per-route `@UseFilters` needed here.
|
|
395
|
+
*/
|
|
396
|
+
declare class PafiDirectAuthController {
|
|
397
|
+
private readonly directAuth;
|
|
398
|
+
constructor(directAuth: PafiDirectAuthService);
|
|
399
|
+
startEmail(body: EmailStartRequestDto): Promise<EmailStartResponseDto>;
|
|
400
|
+
verifyEmail(body: EmailVerifyRequestDto): Promise<PafiAuthSuccessDto>;
|
|
401
|
+
exchangeGoogle(body: GoogleExchangeRequestDto): Promise<PafiAuthSuccessDto>;
|
|
402
|
+
exchangeKakao(body: KakaoExchangeRequestDto): Promise<PafiAuthSuccessDto>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export { type DirectAuthResult, EmailStartRequestDto, EmailStartResponseDto, EmailVerifyRequestDto, GoogleExchangeRequestDto, type ISessionTokenMinter, type IUserStore, KakaoExchangeRequestDto, PAFI_DIRECT_AUTH_MODULE_OPTIONS, PafiAuthClientProvider, PafiAuthSuccessDto, PafiDirectAuthController, PafiDirectAuthModule, type PafiDirectAuthModuleOptions, PafiDirectAuthService, type PafiSessionClaims, PafiSessionVerifierService, SESSION_TOKEN_MINTER, USER_STORE };
|