@nauth-toolkit/client 0.1.14 → 0.1.17
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/angular/index.d.mts +1023 -0
- package/dist/angular/index.d.ts +1023 -0
- package/dist/index.d.mts +927 -0
- package/dist/index.d.ts +927 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MFA device method type (methods that require device setup).
|
|
3
|
+
* Excludes 'backup' as it's not a device method.
|
|
4
|
+
*/
|
|
1
5
|
type MFADeviceMethod = 'sms' | 'email' | 'totp' | 'passkey';
|
|
6
|
+
/**
|
|
7
|
+
* All MFA methods including backup codes (for verification).
|
|
8
|
+
*/
|
|
2
9
|
type MFAMethod = MFADeviceMethod | 'backup';
|
|
10
|
+
/**
|
|
11
|
+
* MFA challenge method subset (for challenge-data retrieval).
|
|
12
|
+
*/
|
|
3
13
|
type MFAChallengeMethod = 'passkey' | 'sms' | 'email' | 'totp' | 'backup';
|
|
14
|
+
/**
|
|
15
|
+
* MFA status for authenticated user.
|
|
16
|
+
*/
|
|
4
17
|
interface MFAStatus {
|
|
5
18
|
enabled: boolean;
|
|
6
19
|
required: boolean;
|
|
@@ -12,6 +25,9 @@ interface MFAStatus {
|
|
|
12
25
|
mfaExemptReason: string | null;
|
|
13
26
|
mfaExemptGrantedAt: string | Date | null;
|
|
14
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* MFA device information.
|
|
30
|
+
*/
|
|
15
31
|
interface MFADevice {
|
|
16
32
|
id: number;
|
|
17
33
|
type: MFADeviceMethod;
|
|
@@ -20,6 +36,9 @@ interface MFADevice {
|
|
|
20
36
|
isActive: boolean;
|
|
21
37
|
createdAt: string | Date;
|
|
22
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* MFA setup data returned by providers.
|
|
41
|
+
*/
|
|
23
42
|
interface MFASetupData {
|
|
24
43
|
secret?: string;
|
|
25
44
|
qrCode?: string;
|
|
@@ -28,16 +47,30 @@ interface MFASetupData {
|
|
|
28
47
|
challenge?: Record<string, unknown>;
|
|
29
48
|
[key: string]: unknown;
|
|
30
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Response from getSetupData API call.
|
|
52
|
+
* Contains provider-specific MFA setup information.
|
|
53
|
+
*/
|
|
31
54
|
interface GetSetupDataResponse {
|
|
32
55
|
setupData: Record<string, unknown>;
|
|
33
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Response from getChallengeData API call.
|
|
59
|
+
* Contains challenge-specific data (e.g., passkey options).
|
|
60
|
+
*/
|
|
34
61
|
interface GetChallengeDataResponse {
|
|
35
62
|
challengeData: Record<string, unknown>;
|
|
36
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Backup codes response.
|
|
66
|
+
*/
|
|
37
67
|
interface BackupCodesResponse {
|
|
38
68
|
codes: string[];
|
|
39
69
|
}
|
|
40
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Authentication challenge types returned by the backend.
|
|
73
|
+
*/
|
|
41
74
|
declare enum AuthChallenge {
|
|
42
75
|
VERIFY_EMAIL = "VERIFY_EMAIL",
|
|
43
76
|
VERIFY_PHONE = "VERIFY_PHONE",
|
|
@@ -59,6 +92,9 @@ interface AuthResponse {
|
|
|
59
92
|
challengeParameters?: Record<string, unknown>;
|
|
60
93
|
userSub?: string;
|
|
61
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Minimal user information returned inside auth responses.
|
|
97
|
+
*/
|
|
62
98
|
interface AuthUserSummary {
|
|
63
99
|
sub: string;
|
|
64
100
|
email: string;
|
|
@@ -70,12 +106,18 @@ interface AuthUserSummary {
|
|
|
70
106
|
socialProviders?: string[] | null;
|
|
71
107
|
hasPasswordHash?: boolean;
|
|
72
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Token response returned by refresh endpoint.
|
|
111
|
+
*/
|
|
73
112
|
interface TokenResponse {
|
|
74
113
|
accessToken: string;
|
|
75
114
|
refreshToken: string;
|
|
76
115
|
accessTokenExpiresAt: number;
|
|
77
116
|
refreshTokenExpiresAt: number;
|
|
78
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Signup request payload.
|
|
120
|
+
*/
|
|
79
121
|
interface SignupRequest {
|
|
80
122
|
email: string;
|
|
81
123
|
password: string;
|
|
@@ -84,30 +126,58 @@ interface SignupRequest {
|
|
|
84
126
|
phone?: string;
|
|
85
127
|
metadata?: Record<string, unknown>;
|
|
86
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Login request payload.
|
|
131
|
+
*/
|
|
87
132
|
interface LoginRequest {
|
|
88
133
|
identifier: string;
|
|
89
134
|
password: string;
|
|
90
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Logout request payload.
|
|
138
|
+
*/
|
|
91
139
|
interface LogoutRequest {
|
|
92
140
|
sub?: string;
|
|
93
141
|
forgetMe?: boolean;
|
|
94
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Logout all sessions request payload.
|
|
145
|
+
*/
|
|
95
146
|
interface LogoutAllRequest {
|
|
147
|
+
/**
|
|
148
|
+
* Whether to also revoke all trusted devices
|
|
149
|
+
* Default: false (devices remain trusted)
|
|
150
|
+
*/
|
|
96
151
|
forgetDevices?: boolean;
|
|
97
152
|
sub?: string;
|
|
98
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* Resend code request payload.
|
|
156
|
+
*/
|
|
99
157
|
interface ResendCodeRequest {
|
|
100
158
|
session: string;
|
|
101
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* MFA setup data request payload during challenge flows.
|
|
162
|
+
*/
|
|
102
163
|
interface GetSetupDataRequest {
|
|
103
164
|
session: string;
|
|
104
165
|
method: MFAMethod;
|
|
105
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Challenge data request payload (e.g., passkey options).
|
|
169
|
+
*/
|
|
106
170
|
interface GetChallengeDataRequest {
|
|
107
171
|
session: string;
|
|
108
172
|
method: MFAChallengeMethod;
|
|
109
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Unified challenge response discriminated union.
|
|
176
|
+
*/
|
|
110
177
|
type ChallengeResponse = VerifyEmailResponse | VerifyPhoneCollectResponse | VerifyPhoneCodeResponse | MFACodeResponse | MFAPasskeyResponse | MFASetupResponse | ForceChangePasswordResponse;
|
|
178
|
+
/**
|
|
179
|
+
* Base challenge response shape.
|
|
180
|
+
*/
|
|
111
181
|
interface BaseChallengeResponse {
|
|
112
182
|
session: string;
|
|
113
183
|
}
|
|
@@ -143,6 +213,9 @@ interface ForceChangePasswordResponse extends BaseChallengeResponse {
|
|
|
143
213
|
newPassword: string;
|
|
144
214
|
}
|
|
145
215
|
|
|
216
|
+
/**
|
|
217
|
+
* Full user profile returned from profile endpoints.
|
|
218
|
+
*/
|
|
146
219
|
interface AuthUser {
|
|
147
220
|
sub: string;
|
|
148
221
|
email: string;
|
|
@@ -159,51 +232,87 @@ interface AuthUser {
|
|
|
159
232
|
createdAt?: string | Date;
|
|
160
233
|
updatedAt?: string | Date;
|
|
161
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Profile update request.
|
|
237
|
+
*/
|
|
162
238
|
interface UpdateProfileRequest {
|
|
163
239
|
firstName?: string;
|
|
164
240
|
lastName?: string;
|
|
165
241
|
email?: string;
|
|
166
242
|
phone?: string;
|
|
167
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Change password request.
|
|
246
|
+
*/
|
|
168
247
|
interface ChangePasswordRequest {
|
|
169
248
|
currentPassword: string;
|
|
170
249
|
newPassword: string;
|
|
171
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Forgot password request payload.
|
|
253
|
+
*/
|
|
172
254
|
interface ForgotPasswordRequest {
|
|
173
255
|
identifier: string;
|
|
174
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Forgot password response payload.
|
|
259
|
+
*/
|
|
175
260
|
interface ForgotPasswordResponse {
|
|
176
261
|
success: boolean;
|
|
177
262
|
destination?: string;
|
|
178
263
|
deliveryMedium?: 'email' | 'sms';
|
|
179
264
|
expiresIn?: number;
|
|
180
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Confirm forgot password request payload.
|
|
268
|
+
*/
|
|
181
269
|
interface ConfirmForgotPasswordRequest {
|
|
182
270
|
identifier: string;
|
|
183
271
|
code: string;
|
|
184
272
|
newPassword: string;
|
|
185
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Confirm forgot password response payload.
|
|
276
|
+
*/
|
|
186
277
|
interface ConfirmForgotPasswordResponse {
|
|
187
278
|
success: boolean;
|
|
188
279
|
mustChangePassword: boolean;
|
|
189
280
|
}
|
|
190
281
|
|
|
282
|
+
/**
|
|
283
|
+
* Social provider identifiers.
|
|
284
|
+
*/
|
|
191
285
|
type SocialProvider = 'google' | 'apple' | 'facebook';
|
|
286
|
+
/**
|
|
287
|
+
* Request to obtain social auth URL.
|
|
288
|
+
*/
|
|
192
289
|
interface SocialAuthUrlRequest {
|
|
193
290
|
provider: SocialProvider;
|
|
194
291
|
state?: string;
|
|
195
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Response containing social auth URL.
|
|
295
|
+
*/
|
|
196
296
|
interface SocialAuthUrlResponse {
|
|
197
297
|
url: string;
|
|
198
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Social callback parameters.
|
|
301
|
+
*/
|
|
199
302
|
interface SocialCallbackRequest {
|
|
200
303
|
provider: SocialProvider;
|
|
201
304
|
code: string;
|
|
202
305
|
state: string;
|
|
203
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Linked social accounts response.
|
|
309
|
+
*/
|
|
204
310
|
interface LinkedAccountsResponse {
|
|
205
311
|
providers: SocialProvider[];
|
|
206
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Native social verification request (mobile).
|
|
315
|
+
*/
|
|
207
316
|
interface SocialVerifyRequest {
|
|
208
317
|
provider: SocialProvider;
|
|
209
318
|
idToken?: string;
|
|
@@ -211,6 +320,9 @@ interface SocialVerifyRequest {
|
|
|
211
320
|
authorizationCode?: string;
|
|
212
321
|
}
|
|
213
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Standardized error codes mirroring backend AuthErrorCode.
|
|
325
|
+
*/
|
|
214
326
|
declare enum NAuthErrorCode {
|
|
215
327
|
AUTH_INVALID_CREDENTIALS = "AUTH_INVALID_CREDENTIALS",
|
|
216
328
|
AUTH_ACCOUNT_LOCKED = "AUTH_ACCOUNT_LOCKED",
|
|
@@ -268,6 +380,9 @@ declare enum NAuthErrorCode {
|
|
|
268
380
|
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
269
381
|
SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
|
|
270
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* Structured client error.
|
|
385
|
+
*/
|
|
271
386
|
interface NAuthError {
|
|
272
387
|
code: NAuthErrorCode;
|
|
273
388
|
message: string;
|
|
@@ -276,30 +391,121 @@ interface NAuthError {
|
|
|
276
391
|
statusCode?: number;
|
|
277
392
|
}
|
|
278
393
|
|
|
394
|
+
/**
|
|
395
|
+
* Storage adapter interface used by the client SDK.
|
|
396
|
+
*/
|
|
279
397
|
interface NAuthStorageAdapter {
|
|
398
|
+
/**
|
|
399
|
+
* Retrieve a value by key.
|
|
400
|
+
*/
|
|
280
401
|
getItem(key: string): Promise<string | null>;
|
|
402
|
+
/**
|
|
403
|
+
* Persist a value.
|
|
404
|
+
*/
|
|
281
405
|
setItem(key: string, value: string): Promise<void>;
|
|
406
|
+
/**
|
|
407
|
+
* Remove a stored value.
|
|
408
|
+
*/
|
|
282
409
|
removeItem(key: string): Promise<void>;
|
|
283
410
|
}
|
|
284
411
|
|
|
412
|
+
/**
|
|
413
|
+
* HTTP request configuration.
|
|
414
|
+
*
|
|
415
|
+
* Platform-agnostic request format that can be implemented by any HTTP client.
|
|
416
|
+
*/
|
|
285
417
|
interface HttpRequest {
|
|
418
|
+
/**
|
|
419
|
+
* HTTP method
|
|
420
|
+
*/
|
|
286
421
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
422
|
+
/**
|
|
423
|
+
* Full URL (already resolved with baseUrl)
|
|
424
|
+
*/
|
|
287
425
|
url: string;
|
|
426
|
+
/**
|
|
427
|
+
* Request headers
|
|
428
|
+
*/
|
|
288
429
|
headers?: Record<string, string>;
|
|
430
|
+
/**
|
|
431
|
+
* Request body (will be JSON stringified by adapter)
|
|
432
|
+
*/
|
|
289
433
|
body?: unknown;
|
|
434
|
+
/**
|
|
435
|
+
* Credentials mode for cookies
|
|
436
|
+
* - 'include': Send cookies (for cookies mode)
|
|
437
|
+
* - 'omit': Don't send cookies (for JSON mode)
|
|
438
|
+
*/
|
|
290
439
|
credentials?: 'include' | 'omit' | 'same-origin';
|
|
440
|
+
/**
|
|
441
|
+
* Abort signal for request cancellation
|
|
442
|
+
*/
|
|
291
443
|
signal?: AbortSignal;
|
|
292
444
|
}
|
|
445
|
+
/**
|
|
446
|
+
* HTTP response returned by adapter.
|
|
447
|
+
*/
|
|
293
448
|
interface HttpResponse<T> {
|
|
449
|
+
/**
|
|
450
|
+
* Response data (already parsed)
|
|
451
|
+
*/
|
|
294
452
|
data: T;
|
|
453
|
+
/**
|
|
454
|
+
* HTTP status code
|
|
455
|
+
*/
|
|
295
456
|
status: number;
|
|
457
|
+
/**
|
|
458
|
+
* Response headers
|
|
459
|
+
*/
|
|
296
460
|
headers: Record<string, string>;
|
|
297
461
|
}
|
|
462
|
+
/**
|
|
463
|
+
* Platform-agnostic HTTP adapter interface.
|
|
464
|
+
*
|
|
465
|
+
* Implementations:
|
|
466
|
+
* - FetchAdapter: For vanilla JS, Node.js (uses native fetch)
|
|
467
|
+
* - AngularHttpAdapter: For Angular (uses HttpClient)
|
|
468
|
+
* - AxiosAdapter: For React/Vue (uses Axios)
|
|
469
|
+
*
|
|
470
|
+
* @example
|
|
471
|
+
* ```typescript
|
|
472
|
+
* class MyAdapter implements HttpAdapter {
|
|
473
|
+
* async request<T>(config: HttpRequest): Promise<HttpResponse<T>> {
|
|
474
|
+
* // Use any HTTP client
|
|
475
|
+
* const response = await myHttpClient.request(config);
|
|
476
|
+
* return { data: response.data, status: response.status, headers: {} };
|
|
477
|
+
* }
|
|
478
|
+
* }
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
298
481
|
interface HttpAdapter {
|
|
482
|
+
/**
|
|
483
|
+
* Execute an HTTP request.
|
|
484
|
+
*
|
|
485
|
+
* @param config - Request configuration
|
|
486
|
+
* @returns Response with data, status, and headers
|
|
487
|
+
* @throws Error if request fails (adapter should throw descriptive errors)
|
|
488
|
+
*/
|
|
299
489
|
request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
|
|
300
490
|
}
|
|
301
491
|
|
|
492
|
+
/**
|
|
493
|
+
* Token delivery mode for the frontend SDK.
|
|
494
|
+
*
|
|
495
|
+
* - `'cookies'` - For web applications. Tokens sent as httpOnly cookies by backend.
|
|
496
|
+
* Uses `withCredentials`, CSRF tokens, no Authorization header.
|
|
497
|
+
*
|
|
498
|
+
* - `'json'` - For mobile/native apps (Capacitor, React Native). Tokens returned
|
|
499
|
+
* in response body, stored locally, sent via Authorization header.
|
|
500
|
+
*
|
|
501
|
+
* Note: "Hybrid" is a backend deployment pattern (supporting both web and mobile
|
|
502
|
+
* via separate endpoints), not a frontend mode. The frontend chooses ONE mode
|
|
503
|
+
* based on whether it's a web or mobile build.
|
|
504
|
+
*/
|
|
302
505
|
type TokenDeliveryMode = 'json' | 'cookies';
|
|
506
|
+
/**
|
|
507
|
+
* Endpoint paths for the client SDK.
|
|
508
|
+
*/
|
|
303
509
|
interface NAuthEndpoints {
|
|
304
510
|
login: string;
|
|
305
511
|
signup: string;
|
|
@@ -334,35 +540,116 @@ interface NAuthEndpoints {
|
|
|
334
540
|
auditHistory: string;
|
|
335
541
|
updateProfile: string;
|
|
336
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Client configuration.
|
|
545
|
+
*/
|
|
337
546
|
interface NAuthClientConfig {
|
|
547
|
+
/**
|
|
548
|
+
* Base URL for authentication API.
|
|
549
|
+
*
|
|
550
|
+
* For web apps using cookies: `'https://api.example.com/auth'`
|
|
551
|
+
* For mobile apps using JSON: `'https://api.example.com/mobile/auth'`
|
|
552
|
+
*
|
|
553
|
+
* When backend uses hybrid deployment, mobile apps should use a different
|
|
554
|
+
* base URL that points to the JSON-based mobile auth endpoints.
|
|
555
|
+
*/
|
|
338
556
|
baseUrl: string;
|
|
557
|
+
/**
|
|
558
|
+
* How tokens are delivered between client and server.
|
|
559
|
+
*
|
|
560
|
+
* - `'cookies'` - For web apps. Backend sets httpOnly cookies.
|
|
561
|
+
* - `'json'` - For mobile apps. Tokens in response body, stored locally.
|
|
562
|
+
*/
|
|
339
563
|
tokenDelivery: TokenDeliveryMode;
|
|
564
|
+
/** Custom storage adapter. Defaults to localStorage (web) or memory (SSR). */
|
|
340
565
|
storage?: NAuthStorageAdapter;
|
|
566
|
+
/**
|
|
567
|
+
* CSRF configuration (required for cookies mode).
|
|
568
|
+
* Default cookie name: 'csrf_token', header name: 'x-csrf-token'
|
|
569
|
+
*/
|
|
341
570
|
csrf?: {
|
|
342
571
|
cookieName?: string;
|
|
343
572
|
headerName?: string;
|
|
344
573
|
};
|
|
574
|
+
/** Custom endpoint paths (merged with defaults). */
|
|
345
575
|
endpoints?: Partial<NAuthEndpoints>;
|
|
576
|
+
/** Device trust configuration for "remember this device" feature. */
|
|
346
577
|
deviceTrust?: {
|
|
347
578
|
headerName?: string;
|
|
348
579
|
storageKey?: string;
|
|
349
580
|
};
|
|
581
|
+
/** Additional headers to include in all requests. */
|
|
350
582
|
headers?: Record<string, string>;
|
|
583
|
+
/** Request timeout in milliseconds. Default: 30000 */
|
|
351
584
|
timeout?: number;
|
|
585
|
+
/**
|
|
586
|
+
* Redirect URLs for various authentication scenarios.
|
|
587
|
+
* Used by guards and interceptors to handle routing in a platform-agnostic way.
|
|
588
|
+
*/
|
|
352
589
|
redirects?: {
|
|
590
|
+
/**
|
|
591
|
+
* URL to redirect to after successful authentication (login, signup, or OAuth).
|
|
592
|
+
* @default '/'
|
|
593
|
+
*/
|
|
353
594
|
success?: string;
|
|
595
|
+
/**
|
|
596
|
+
* URL to redirect to when session expires (refresh fails with 401).
|
|
597
|
+
* @default '/login'
|
|
598
|
+
*/
|
|
354
599
|
sessionExpired?: string;
|
|
600
|
+
/**
|
|
601
|
+
* URL to redirect to when OAuth authentication fails.
|
|
602
|
+
* @default '/login'
|
|
603
|
+
*/
|
|
355
604
|
oauthError?: string;
|
|
605
|
+
/**
|
|
606
|
+
* Base URL for challenge routes (email verification, MFA, etc.).
|
|
607
|
+
* The challenge type will be appended (e.g., '/auth/challenge/verify-email').
|
|
608
|
+
* @default '/auth/challenge'
|
|
609
|
+
*/
|
|
356
610
|
challengeBase?: string;
|
|
357
611
|
};
|
|
612
|
+
/**
|
|
613
|
+
* Called when session expires (refresh fails with 401).
|
|
614
|
+
*/
|
|
358
615
|
onSessionExpired?: () => void;
|
|
616
|
+
/** Called after successful token refresh. */
|
|
359
617
|
onTokenRefresh?: () => void;
|
|
618
|
+
/** Called when authentication state changes (login/logout). */
|
|
360
619
|
onAuthStateChange?: (user: AuthUser | null) => void;
|
|
620
|
+
/** Called on authentication errors. */
|
|
361
621
|
onError?: (error: NAuthError) => void;
|
|
622
|
+
/** Enable debug logging. */
|
|
362
623
|
debug?: boolean;
|
|
624
|
+
/**
|
|
625
|
+
* HTTP adapter for making requests.
|
|
626
|
+
*
|
|
627
|
+
* - **Auto-provided in Angular**: Uses HttpClient (works with interceptors)
|
|
628
|
+
* - **Manual setup in React/Vue**: Provide AxiosAdapter or custom adapter
|
|
629
|
+
* - **Defaults to FetchAdapter**: If not provided, uses native fetch
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```typescript
|
|
633
|
+
* // Angular (automatic)
|
|
634
|
+
* // AuthService auto-injects AngularHttpAdapter
|
|
635
|
+
*
|
|
636
|
+
* // React with Axios
|
|
637
|
+
* const client = new NAuthClient({
|
|
638
|
+
* httpAdapter: new AxiosAdapter(axiosInstance),
|
|
639
|
+
* });
|
|
640
|
+
*
|
|
641
|
+
* // Vanilla JS (auto-defaults to fetch)
|
|
642
|
+
* const client = new NAuthClient({
|
|
643
|
+
* // httpAdapter auto-defaults to FetchAdapter
|
|
644
|
+
* });
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
363
647
|
httpAdapter?: HttpAdapter;
|
|
364
648
|
}
|
|
365
649
|
|
|
650
|
+
/**
|
|
651
|
+
* Audit event types.
|
|
652
|
+
*/
|
|
366
653
|
declare enum AuthAuditEventType {
|
|
367
654
|
LOGIN_SUCCESS = "LOGIN_SUCCESS",
|
|
368
655
|
LOGIN_FAILED = "LOGIN_FAILED",
|
|
@@ -390,7 +677,13 @@ declare enum AuthAuditEventType {
|
|
|
390
677
|
SOCIAL_LINK_FAILED = "SOCIAL_LINK_FAILED",
|
|
391
678
|
SOCIAL_UNLINK = "SOCIAL_UNLINK"
|
|
392
679
|
}
|
|
680
|
+
/**
|
|
681
|
+
* Audit event status.
|
|
682
|
+
*/
|
|
393
683
|
type AuthAuditEventStatus = 'SUCCESS' | 'FAILURE' | 'INFO' | 'SUSPICIOUS';
|
|
684
|
+
/**
|
|
685
|
+
* Individual audit event record.
|
|
686
|
+
*/
|
|
394
687
|
interface AuthAuditEvent {
|
|
395
688
|
id: number;
|
|
396
689
|
userId: number;
|
|
@@ -419,6 +712,9 @@ interface AuthAuditEvent {
|
|
|
419
712
|
metadata?: Record<string, unknown> | null;
|
|
420
713
|
createdAt: string | Date;
|
|
421
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* Paginated audit history response.
|
|
717
|
+
*/
|
|
422
718
|
interface AuditHistoryResponse {
|
|
423
719
|
data: AuthAuditEvent[];
|
|
424
720
|
total: number;
|
|
@@ -427,21 +723,94 @@ interface AuditHistoryResponse {
|
|
|
427
723
|
totalPages: number;
|
|
428
724
|
}
|
|
429
725
|
|
|
726
|
+
/**
|
|
727
|
+
* Client-side error wrapper for SDK operations.
|
|
728
|
+
*
|
|
729
|
+
* Mirrors the backend NAuthException structure for consistent error handling.
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ```typescript
|
|
733
|
+
* try {
|
|
734
|
+
* await client.login({ identifier: 'user@example.com', password: 'wrong' });
|
|
735
|
+
* } catch (error) {
|
|
736
|
+
* if (error instanceof NAuthClientError) {
|
|
737
|
+
* console.log(error.code); // 'AUTH_INVALID_CREDENTIALS'
|
|
738
|
+
* console.log(error.message); // 'Invalid credentials'
|
|
739
|
+
* console.log(error.timestamp); // '2025-12-06T...'
|
|
740
|
+
*
|
|
741
|
+
* // Check specific error code
|
|
742
|
+
* if (error.isCode(NAuthErrorCode.RATE_LIMIT_LOGIN)) {
|
|
743
|
+
* const retryAfter = error.details?.retryAfter as number;
|
|
744
|
+
* console.log(`Rate limited. Retry in ${retryAfter}s`);
|
|
745
|
+
* }
|
|
746
|
+
* }
|
|
747
|
+
* }
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
430
750
|
declare class NAuthClientError extends Error implements NAuthError {
|
|
431
751
|
readonly code: NAuthErrorCode;
|
|
432
752
|
readonly details?: Record<string, unknown>;
|
|
433
753
|
readonly statusCode?: number;
|
|
434
754
|
readonly timestamp: string;
|
|
435
755
|
readonly isNetworkError: boolean;
|
|
756
|
+
/**
|
|
757
|
+
* Create a new client error.
|
|
758
|
+
*
|
|
759
|
+
* @param code - Error code from NAuthErrorCode enum
|
|
760
|
+
* @param message - Human-readable error message
|
|
761
|
+
* @param options - Optional metadata including details, statusCode, timestamp, and network error flag
|
|
762
|
+
*/
|
|
436
763
|
constructor(code: NAuthErrorCode, message: string, options?: {
|
|
437
764
|
details?: Record<string, unknown>;
|
|
438
765
|
statusCode?: number;
|
|
439
766
|
timestamp?: string;
|
|
440
767
|
isNetworkError?: boolean;
|
|
441
768
|
});
|
|
769
|
+
/**
|
|
770
|
+
* Check if error matches a specific error code.
|
|
771
|
+
*
|
|
772
|
+
* @param code - Error code to check against
|
|
773
|
+
* @returns True if the error code matches
|
|
774
|
+
*
|
|
775
|
+
* @example
|
|
776
|
+
* ```typescript
|
|
777
|
+
* if (error.isCode(NAuthErrorCode.RATE_LIMIT_SMS)) {
|
|
778
|
+
* // Handle SMS rate limit
|
|
779
|
+
* }
|
|
780
|
+
* ```
|
|
781
|
+
*/
|
|
442
782
|
isCode(code: NAuthErrorCode): boolean;
|
|
783
|
+
/**
|
|
784
|
+
* Get error details/metadata.
|
|
785
|
+
*
|
|
786
|
+
* @returns Error details object or undefined
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* ```typescript
|
|
790
|
+
* const details = error.getDetails();
|
|
791
|
+
* if (details?.retryAfter) {
|
|
792
|
+
* console.log(`Retry after ${details.retryAfter} seconds`);
|
|
793
|
+
* }
|
|
794
|
+
* ```
|
|
795
|
+
*/
|
|
443
796
|
getDetails(): Record<string, unknown> | undefined;
|
|
797
|
+
/**
|
|
798
|
+
* Get the error code.
|
|
799
|
+
*
|
|
800
|
+
* @returns The error code enum value
|
|
801
|
+
*/
|
|
444
802
|
getCode(): NAuthErrorCode;
|
|
803
|
+
/**
|
|
804
|
+
* Serialize error to JSON object.
|
|
805
|
+
*
|
|
806
|
+
* @returns Plain object representation
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* ```typescript
|
|
810
|
+
* const errorJson = error.toJSON();
|
|
811
|
+
* // { code: 'AUTH_INVALID_CREDENTIALS', message: '...', timestamp: '...', details: {...} }
|
|
812
|
+
* ```
|
|
813
|
+
*/
|
|
445
814
|
toJSON(): {
|
|
446
815
|
code: string;
|
|
447
816
|
message: string;
|
|
@@ -451,8 +820,22 @@ declare class NAuthClientError extends Error implements NAuthError {
|
|
|
451
820
|
};
|
|
452
821
|
}
|
|
453
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Authentication event types emitted by NAuthClient
|
|
825
|
+
*
|
|
826
|
+
* Events are emitted throughout the authentication lifecycle,
|
|
827
|
+
* allowing applications to react to auth state changes.
|
|
828
|
+
*/
|
|
454
829
|
type AuthEventType = 'auth:login' | 'auth:signup' | 'auth:success' | 'auth:challenge' | 'auth:error' | 'auth:logout' | 'auth:refresh' | 'oauth:started' | 'oauth:callback' | 'oauth:completed' | 'oauth:error';
|
|
830
|
+
/**
|
|
831
|
+
* Discriminated union of all authentication events with type-safe payloads
|
|
832
|
+
*
|
|
833
|
+
* Each event has a specific payload type for better type safety.
|
|
834
|
+
*/
|
|
455
835
|
type AuthEvent = AuthLoginEvent | AuthSignupEvent | AuthSuccessEvent | AuthChallengeEvent | AuthErrorEvent | AuthLogoutEvent | AuthRefreshEvent | OAuthStartedEvent | OAuthCallbackEvent | OAuthCompletedEvent | OAuthErrorEvent;
|
|
836
|
+
/**
|
|
837
|
+
* Login initiated event
|
|
838
|
+
*/
|
|
456
839
|
interface AuthLoginEvent {
|
|
457
840
|
type: 'auth:login';
|
|
458
841
|
data: {
|
|
@@ -460,6 +843,9 @@ interface AuthLoginEvent {
|
|
|
460
843
|
};
|
|
461
844
|
timestamp: number;
|
|
462
845
|
}
|
|
846
|
+
/**
|
|
847
|
+
* Signup initiated event
|
|
848
|
+
*/
|
|
463
849
|
interface AuthSignupEvent {
|
|
464
850
|
type: 'auth:signup';
|
|
465
851
|
data: {
|
|
@@ -467,21 +853,33 @@ interface AuthSignupEvent {
|
|
|
467
853
|
};
|
|
468
854
|
timestamp: number;
|
|
469
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* Successful authentication event
|
|
858
|
+
*/
|
|
470
859
|
interface AuthSuccessEvent {
|
|
471
860
|
type: 'auth:success';
|
|
472
861
|
data: AuthResponse;
|
|
473
862
|
timestamp: number;
|
|
474
863
|
}
|
|
864
|
+
/**
|
|
865
|
+
* Challenge required event
|
|
866
|
+
*/
|
|
475
867
|
interface AuthChallengeEvent {
|
|
476
868
|
type: 'auth:challenge';
|
|
477
869
|
data: AuthResponse;
|
|
478
870
|
timestamp: number;
|
|
479
871
|
}
|
|
872
|
+
/**
|
|
873
|
+
* Authentication error event
|
|
874
|
+
*/
|
|
480
875
|
interface AuthErrorEvent {
|
|
481
876
|
type: 'auth:error';
|
|
482
877
|
data: NAuthClientError;
|
|
483
878
|
timestamp: number;
|
|
484
879
|
}
|
|
880
|
+
/**
|
|
881
|
+
* User logged out event
|
|
882
|
+
*/
|
|
485
883
|
interface AuthLogoutEvent {
|
|
486
884
|
type: 'auth:logout';
|
|
487
885
|
data: {
|
|
@@ -490,6 +888,9 @@ interface AuthLogoutEvent {
|
|
|
490
888
|
};
|
|
491
889
|
timestamp: number;
|
|
492
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Token refreshed event
|
|
893
|
+
*/
|
|
493
894
|
interface AuthRefreshEvent {
|
|
494
895
|
type: 'auth:refresh';
|
|
495
896
|
data: {
|
|
@@ -497,6 +898,9 @@ interface AuthRefreshEvent {
|
|
|
497
898
|
};
|
|
498
899
|
timestamp: number;
|
|
499
900
|
}
|
|
901
|
+
/**
|
|
902
|
+
* OAuth flow started event
|
|
903
|
+
*/
|
|
500
904
|
interface OAuthStartedEvent {
|
|
501
905
|
type: 'oauth:started';
|
|
502
906
|
data: {
|
|
@@ -504,6 +908,9 @@ interface OAuthStartedEvent {
|
|
|
504
908
|
};
|
|
505
909
|
timestamp: number;
|
|
506
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* OAuth callback received event
|
|
913
|
+
*/
|
|
507
914
|
interface OAuthCallbackEvent {
|
|
508
915
|
type: 'oauth:callback';
|
|
509
916
|
data: {
|
|
@@ -511,114 +918,509 @@ interface OAuthCallbackEvent {
|
|
|
511
918
|
};
|
|
512
919
|
timestamp: number;
|
|
513
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* OAuth flow completed event
|
|
923
|
+
*/
|
|
514
924
|
interface OAuthCompletedEvent {
|
|
515
925
|
type: 'oauth:completed';
|
|
516
926
|
data: AuthResponse;
|
|
517
927
|
timestamp: number;
|
|
518
928
|
}
|
|
929
|
+
/**
|
|
930
|
+
* OAuth error event
|
|
931
|
+
*/
|
|
519
932
|
interface OAuthErrorEvent {
|
|
520
933
|
type: 'oauth:error';
|
|
521
934
|
data: NAuthClientError;
|
|
522
935
|
timestamp: number;
|
|
523
936
|
}
|
|
937
|
+
/**
|
|
938
|
+
* Event listener callback function
|
|
939
|
+
*/
|
|
524
940
|
type AuthEventListener = (event: AuthEvent) => void;
|
|
941
|
+
/**
|
|
942
|
+
* Internal event emitter for authentication events
|
|
943
|
+
*
|
|
944
|
+
* Provides pub/sub functionality for auth lifecycle events.
|
|
945
|
+
*
|
|
946
|
+
* @internal
|
|
947
|
+
*/
|
|
525
948
|
declare class EventEmitter {
|
|
526
949
|
private listeners;
|
|
950
|
+
/**
|
|
951
|
+
* Subscribe to an authentication event
|
|
952
|
+
*
|
|
953
|
+
* @param event - Event type or '*' for all events
|
|
954
|
+
* @param listener - Callback function
|
|
955
|
+
* @returns Unsubscribe function
|
|
956
|
+
*
|
|
957
|
+
* @example
|
|
958
|
+
* ```typescript
|
|
959
|
+
* const unsubscribe = emitter.on('auth:success', (event) => {
|
|
960
|
+
* console.log('User logged in:', event.data);
|
|
961
|
+
* });
|
|
962
|
+
*
|
|
963
|
+
* // Later
|
|
964
|
+
* unsubscribe();
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
527
967
|
on(event: AuthEventType | '*', listener: AuthEventListener): () => void;
|
|
968
|
+
/**
|
|
969
|
+
* Unsubscribe from an authentication event
|
|
970
|
+
*
|
|
971
|
+
* @param event - Event type or '*'
|
|
972
|
+
* @param listener - Callback function to remove
|
|
973
|
+
*/
|
|
528
974
|
off(event: AuthEventType | '*', listener: AuthEventListener): void;
|
|
975
|
+
/**
|
|
976
|
+
* Emit an authentication event
|
|
977
|
+
*
|
|
978
|
+
* Notifies all listeners for the specific event type and wildcard listeners.
|
|
979
|
+
*
|
|
980
|
+
* @param event - Event to emit
|
|
981
|
+
* @internal
|
|
982
|
+
*/
|
|
529
983
|
emit(event: AuthEvent): void;
|
|
984
|
+
/**
|
|
985
|
+
* Remove all listeners
|
|
986
|
+
*
|
|
987
|
+
* @internal
|
|
988
|
+
*/
|
|
530
989
|
clear(): void;
|
|
531
990
|
}
|
|
532
991
|
|
|
992
|
+
/**
|
|
993
|
+
* Primary client for interacting with nauth-toolkit backend.
|
|
994
|
+
*/
|
|
533
995
|
declare class NAuthClient {
|
|
534
996
|
private readonly config;
|
|
535
997
|
private readonly tokenManager;
|
|
536
998
|
private readonly eventEmitter;
|
|
537
999
|
private currentUser;
|
|
1000
|
+
/**
|
|
1001
|
+
* Create a new client instance.
|
|
1002
|
+
*
|
|
1003
|
+
* @param userConfig - Client configuration
|
|
1004
|
+
*/
|
|
538
1005
|
constructor(userConfig: NAuthClientConfig);
|
|
1006
|
+
/**
|
|
1007
|
+
* Clean up resources.
|
|
1008
|
+
*/
|
|
539
1009
|
dispose(): void;
|
|
1010
|
+
/**
|
|
1011
|
+
* Login with identifier and password.
|
|
1012
|
+
*/
|
|
540
1013
|
login(identifier: string, password: string): Promise<AuthResponse>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Signup with credentials.
|
|
1016
|
+
*/
|
|
541
1017
|
signup(payload: SignupRequest): Promise<AuthResponse>;
|
|
1018
|
+
/**
|
|
1019
|
+
* Refresh tokens manually.
|
|
1020
|
+
*/
|
|
542
1021
|
refreshTokens(): Promise<TokenResponse>;
|
|
1022
|
+
/**
|
|
1023
|
+
* Logout current session.
|
|
1024
|
+
*
|
|
1025
|
+
* Uses GET request to avoid CSRF token issues.
|
|
1026
|
+
*
|
|
1027
|
+
* @param forgetDevice - If true, also untrust the device (require MFA on next login)
|
|
1028
|
+
*/
|
|
543
1029
|
logout(forgetDevice?: boolean): Promise<void>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Logout all sessions.
|
|
1032
|
+
*
|
|
1033
|
+
* Revokes all active sessions for the current user across all devices.
|
|
1034
|
+
* Optionally revokes all trusted devices if forgetDevices is true.
|
|
1035
|
+
*
|
|
1036
|
+
* @param forgetDevices - If true, also revokes all trusted devices (default: false)
|
|
1037
|
+
* @returns Number of sessions revoked
|
|
1038
|
+
*/
|
|
544
1039
|
logoutAll(forgetDevices?: boolean): Promise<{
|
|
545
1040
|
revokedCount: number;
|
|
546
1041
|
}>;
|
|
1042
|
+
/**
|
|
1043
|
+
* Respond to a challenge.
|
|
1044
|
+
*
|
|
1045
|
+
* Validates challenge response data before sending to backend.
|
|
1046
|
+
* Provides helpful error messages for common validation issues.
|
|
1047
|
+
*
|
|
1048
|
+
* @param response - Challenge response data
|
|
1049
|
+
* @returns Auth response from backend
|
|
1050
|
+
* @throws {NAuthClientError} If validation fails
|
|
1051
|
+
*/
|
|
547
1052
|
respondToChallenge(response: ChallengeResponse): Promise<AuthResponse>;
|
|
1053
|
+
/**
|
|
1054
|
+
* Resend a challenge code.
|
|
1055
|
+
*/
|
|
548
1056
|
resendCode(session: string): Promise<{
|
|
549
1057
|
destination: string;
|
|
550
1058
|
}>;
|
|
1059
|
+
/**
|
|
1060
|
+
* Get setup data for MFA.
|
|
1061
|
+
*
|
|
1062
|
+
* Returns method-specific setup information:
|
|
1063
|
+
* - TOTP: { secret, qrCode, manualEntryKey }
|
|
1064
|
+
* - SMS: { maskedPhone }
|
|
1065
|
+
* - Email: { maskedEmail }
|
|
1066
|
+
* - Passkey: WebAuthn registration options
|
|
1067
|
+
*
|
|
1068
|
+
* @param session - Challenge session token
|
|
1069
|
+
* @param method - MFA method to set up
|
|
1070
|
+
* @returns Setup data wrapped in GetSetupDataResponse
|
|
1071
|
+
*/
|
|
551
1072
|
getSetupData(session: string, method: GetSetupDataRequest['method']): Promise<GetSetupDataResponse>;
|
|
1073
|
+
/**
|
|
1074
|
+
* Get challenge data (e.g., WebAuthn options).
|
|
1075
|
+
*
|
|
1076
|
+
* Returns challenge-specific data for verification flows.
|
|
1077
|
+
*
|
|
1078
|
+
* @param session - Challenge session token
|
|
1079
|
+
* @param method - Challenge method to get data for
|
|
1080
|
+
* @returns Challenge data wrapped in GetChallengeDataResponse
|
|
1081
|
+
*/
|
|
552
1082
|
getChallengeData(session: string, method: GetChallengeDataRequest['method']): Promise<GetChallengeDataResponse>;
|
|
1083
|
+
/**
|
|
1084
|
+
* Get current user profile.
|
|
1085
|
+
*/
|
|
553
1086
|
getProfile(): Promise<AuthUser>;
|
|
1087
|
+
/**
|
|
1088
|
+
* Update user profile.
|
|
1089
|
+
*/
|
|
554
1090
|
updateProfile(updates: UpdateProfileRequest): Promise<AuthUser>;
|
|
1091
|
+
/**
|
|
1092
|
+
* Change user password.
|
|
1093
|
+
*/
|
|
555
1094
|
changePassword(oldPassword: string, newPassword: string): Promise<void>;
|
|
1095
|
+
/**
|
|
1096
|
+
* Request a password reset code (forgot password).
|
|
1097
|
+
*/
|
|
556
1098
|
forgotPassword(identifier: string): Promise<ForgotPasswordResponse>;
|
|
1099
|
+
/**
|
|
1100
|
+
* Confirm a password reset code and set a new password.
|
|
1101
|
+
*/
|
|
557
1102
|
confirmForgotPassword(identifier: string, code: string, newPassword: string): Promise<ConfirmForgotPasswordResponse>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Request password change (must change on next login).
|
|
1105
|
+
*/
|
|
558
1106
|
requestPasswordChange(): Promise<void>;
|
|
1107
|
+
/**
|
|
1108
|
+
* Get MFA status.
|
|
1109
|
+
*/
|
|
559
1110
|
getMfaStatus(): Promise<MFAStatus>;
|
|
1111
|
+
/**
|
|
1112
|
+
* Get MFA devices.
|
|
1113
|
+
*/
|
|
560
1114
|
getMfaDevices(): Promise<unknown[]>;
|
|
1115
|
+
/**
|
|
1116
|
+
* Setup MFA device (authenticated user).
|
|
1117
|
+
*/
|
|
561
1118
|
setupMfaDevice(method: string): Promise<unknown>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Verify MFA setup (authenticated user).
|
|
1121
|
+
*/
|
|
562
1122
|
verifyMfaSetup(method: string, setupData: Record<string, unknown>, deviceName?: string): Promise<{
|
|
563
1123
|
deviceId: number;
|
|
564
1124
|
}>;
|
|
1125
|
+
/**
|
|
1126
|
+
* Remove MFA method.
|
|
1127
|
+
*/
|
|
565
1128
|
removeMfaDevice(method: string): Promise<{
|
|
566
1129
|
message: string;
|
|
567
1130
|
}>;
|
|
1131
|
+
/**
|
|
1132
|
+
* Set preferred MFA method.
|
|
1133
|
+
*
|
|
1134
|
+
* @param method - Device method to set as preferred ('totp', 'sms', 'email', or 'passkey'). Cannot be 'backup'.
|
|
1135
|
+
* @returns Success message
|
|
1136
|
+
*/
|
|
568
1137
|
setPreferredMfaMethod(method: 'totp' | 'sms' | 'email' | 'passkey'): Promise<{
|
|
569
1138
|
message: string;
|
|
570
1139
|
}>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Generate backup codes.
|
|
1142
|
+
*/
|
|
571
1143
|
generateBackupCodes(): Promise<string[]>;
|
|
1144
|
+
/**
|
|
1145
|
+
* Set MFA exemption (admin/test scenarios).
|
|
1146
|
+
*/
|
|
572
1147
|
setMfaExemption(exempt: boolean, reason?: string): Promise<void>;
|
|
1148
|
+
/**
|
|
1149
|
+
* Subscribe to authentication events.
|
|
1150
|
+
*
|
|
1151
|
+
* Emits events throughout the auth lifecycle for custom logic, analytics, or UI updates.
|
|
1152
|
+
*
|
|
1153
|
+
* @param event - Event type to listen for, or '*' for all events
|
|
1154
|
+
* @param listener - Callback function to handle the event
|
|
1155
|
+
* @returns Unsubscribe function
|
|
1156
|
+
*
|
|
1157
|
+
* @example
|
|
1158
|
+
* ```typescript
|
|
1159
|
+
* // Listen to successful authentication
|
|
1160
|
+
* const unsubscribe = client.on('auth:success', (event) => {
|
|
1161
|
+
* console.log('User logged in:', event.data.user);
|
|
1162
|
+
* analytics.track('login_success');
|
|
1163
|
+
* });
|
|
1164
|
+
*
|
|
1165
|
+
* // Listen to all events
|
|
1166
|
+
* client.on('*', (event) => {
|
|
1167
|
+
* console.log('Auth event:', event.type, event.data);
|
|
1168
|
+
* });
|
|
1169
|
+
*
|
|
1170
|
+
* // Unsubscribe when done
|
|
1171
|
+
* unsubscribe();
|
|
1172
|
+
* ```
|
|
1173
|
+
*/
|
|
573
1174
|
on(event: AuthEventType | '*', listener: AuthEventListener): () => void;
|
|
1175
|
+
/**
|
|
1176
|
+
* Unsubscribe from authentication events.
|
|
1177
|
+
*
|
|
1178
|
+
* @param event - Event type
|
|
1179
|
+
* @param listener - Callback function to remove
|
|
1180
|
+
*/
|
|
574
1181
|
off(event: AuthEventType | '*', listener: AuthEventListener): void;
|
|
1182
|
+
/**
|
|
1183
|
+
* Start social OAuth flow with automatic state management.
|
|
1184
|
+
*
|
|
1185
|
+
* Generates a secure state token, stores OAuth context, and redirects to the OAuth provider.
|
|
1186
|
+
* After OAuth callback, use `handleOAuthCallback()` to complete authentication.
|
|
1187
|
+
*
|
|
1188
|
+
* @param provider - OAuth provider ('google', 'apple', 'facebook')
|
|
1189
|
+
* @param options - Optional configuration
|
|
1190
|
+
*
|
|
1191
|
+
* @example
|
|
1192
|
+
* ```typescript
|
|
1193
|
+
* // Simple usage
|
|
1194
|
+
* await client.loginWithSocial('google');
|
|
1195
|
+
*
|
|
1196
|
+
* // With custom redirect URI
|
|
1197
|
+
* await client.loginWithSocial('apple', {
|
|
1198
|
+
* redirectUri: 'https://example.com/auth/callback'
|
|
1199
|
+
* });
|
|
1200
|
+
* ```
|
|
1201
|
+
*/
|
|
575
1202
|
loginWithSocial(provider: SocialProvider, _options?: {
|
|
576
1203
|
redirectUri?: string;
|
|
577
1204
|
}): Promise<void>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Auto-detect and handle OAuth callback.
|
|
1207
|
+
*
|
|
1208
|
+
* Call this on app initialization or in callback route.
|
|
1209
|
+
* Returns null if not an OAuth callback (no provider/code params).
|
|
1210
|
+
*
|
|
1211
|
+
* The SDK validates the state token, completes authentication via backend,
|
|
1212
|
+
* and emits appropriate events.
|
|
1213
|
+
*
|
|
1214
|
+
* @param urlOrParams - Optional URL string or URLSearchParams (auto-detects from window.location if not provided)
|
|
1215
|
+
* @returns AuthResponse if OAuth callback detected, null otherwise
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```typescript
|
|
1219
|
+
* // Auto-detect on app init
|
|
1220
|
+
* const response = await client.handleOAuthCallback();
|
|
1221
|
+
* if (response) {
|
|
1222
|
+
* if (response.challengeName) {
|
|
1223
|
+
* router.navigate(['/challenge', response.challengeName]);
|
|
1224
|
+
* } else {
|
|
1225
|
+
* router.navigate(['/']); // Navigate to your app's home route
|
|
1226
|
+
* }
|
|
1227
|
+
* }
|
|
1228
|
+
*
|
|
1229
|
+
* // In callback route
|
|
1230
|
+
* const response = await client.handleOAuthCallback(window.location.search);
|
|
1231
|
+
* ```
|
|
1232
|
+
*/
|
|
578
1233
|
handleOAuthCallback(urlOrParams?: string | URLSearchParams): Promise<AuthResponse | null>;
|
|
1234
|
+
/**
|
|
1235
|
+
* Get social auth URL (low-level API).
|
|
1236
|
+
*
|
|
1237
|
+
* For most cases, use `loginWithSocial()` which handles state management automatically.
|
|
1238
|
+
*/
|
|
579
1239
|
getSocialAuthUrl(request: SocialAuthUrlRequest): Promise<{
|
|
580
1240
|
url: string;
|
|
581
1241
|
}>;
|
|
1242
|
+
/**
|
|
1243
|
+
* Handle social callback.
|
|
1244
|
+
*/
|
|
582
1245
|
handleSocialCallback(request: SocialCallbackRequest): Promise<AuthResponse>;
|
|
1246
|
+
/**
|
|
1247
|
+
* Verify native social token (mobile).
|
|
1248
|
+
*/
|
|
583
1249
|
verifyNativeSocial(request: SocialVerifyRequest): Promise<AuthResponse>;
|
|
1250
|
+
/**
|
|
1251
|
+
* Get linked accounts.
|
|
1252
|
+
*/
|
|
584
1253
|
getLinkedAccounts(): Promise<LinkedAccountsResponse>;
|
|
1254
|
+
/**
|
|
1255
|
+
* Link social account.
|
|
1256
|
+
*/
|
|
585
1257
|
linkSocialAccount(provider: string, code: string, state: string): Promise<{
|
|
586
1258
|
message: string;
|
|
587
1259
|
}>;
|
|
1260
|
+
/**
|
|
1261
|
+
* Unlink social account.
|
|
1262
|
+
*/
|
|
588
1263
|
unlinkSocialAccount(provider: string): Promise<{
|
|
589
1264
|
message: string;
|
|
590
1265
|
}>;
|
|
1266
|
+
/**
|
|
1267
|
+
* Trust current device.
|
|
1268
|
+
*/
|
|
591
1269
|
trustDevice(): Promise<{
|
|
592
1270
|
deviceToken: string;
|
|
593
1271
|
}>;
|
|
1272
|
+
/**
|
|
1273
|
+
* Check if the current device is trusted.
|
|
1274
|
+
*
|
|
1275
|
+
* Returns whether the current device is trusted based on the device token
|
|
1276
|
+
* (from cookie in cookies mode, or header in JSON mode).
|
|
1277
|
+
*
|
|
1278
|
+
* This performs a server-side validation of the device token and checks:
|
|
1279
|
+
* - Device token exists and is valid
|
|
1280
|
+
* - Device token matches a trusted device record in the database
|
|
1281
|
+
* - Trust has not expired
|
|
1282
|
+
*
|
|
1283
|
+
* @returns Object with trusted status
|
|
1284
|
+
*
|
|
1285
|
+
* @example
|
|
1286
|
+
* ```typescript
|
|
1287
|
+
* const result = await client.isTrustedDevice();
|
|
1288
|
+
* if (result.trusted) {
|
|
1289
|
+
* console.log('This device is trusted');
|
|
1290
|
+
* }
|
|
1291
|
+
* ```
|
|
1292
|
+
*/
|
|
594
1293
|
isTrustedDevice(): Promise<{
|
|
595
1294
|
trusted: boolean;
|
|
596
1295
|
}>;
|
|
1296
|
+
/**
|
|
1297
|
+
* Get paginated audit history for the current user.
|
|
1298
|
+
*
|
|
1299
|
+
* Returns authentication and security events with full audit details including:
|
|
1300
|
+
* - Event type (login, logout, MFA, etc.)
|
|
1301
|
+
* - Event status (success, failure, suspicious)
|
|
1302
|
+
* - Device information, location, risk factors
|
|
1303
|
+
*
|
|
1304
|
+
* @param params - Query parameters for filtering and pagination
|
|
1305
|
+
* @returns Paginated audit history response
|
|
1306
|
+
*
|
|
1307
|
+
* @example
|
|
1308
|
+
* ```typescript
|
|
1309
|
+
* const history = await client.getAuditHistory({
|
|
1310
|
+
* page: 1,
|
|
1311
|
+
* limit: 20,
|
|
1312
|
+
* eventType: 'LOGIN_SUCCESS'
|
|
1313
|
+
* });
|
|
1314
|
+
* ```
|
|
1315
|
+
*/
|
|
597
1316
|
getAuditHistory(params?: Record<string, string | number | boolean>): Promise<AuditHistoryResponse>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Initialize client by hydrating state from storage.
|
|
1319
|
+
* Call this on app startup to restore auth state.
|
|
1320
|
+
*/
|
|
598
1321
|
initialize(): Promise<void>;
|
|
1322
|
+
/**
|
|
1323
|
+
* Determine if user is authenticated (async - checks tokens).
|
|
1324
|
+
*/
|
|
599
1325
|
isAuthenticated(): Promise<boolean>;
|
|
1326
|
+
/**
|
|
1327
|
+
* Determine if user is authenticated (sync - checks cached user).
|
|
1328
|
+
* Use this for guards and sync checks. Use `isAuthenticated()` for definitive check.
|
|
1329
|
+
*/
|
|
600
1330
|
isAuthenticatedSync(): boolean;
|
|
1331
|
+
/**
|
|
1332
|
+
* Get current access token (may be null).
|
|
1333
|
+
*/
|
|
601
1334
|
getAccessToken(): Promise<string | null>;
|
|
1335
|
+
/**
|
|
1336
|
+
* Get current user (cached, sync).
|
|
1337
|
+
*/
|
|
602
1338
|
getCurrentUser(): AuthUser | null;
|
|
1339
|
+
/**
|
|
1340
|
+
* Get stored challenge session (for resuming challenge flows).
|
|
1341
|
+
*/
|
|
603
1342
|
getStoredChallenge(): Promise<AuthResponse | null>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Clear stored challenge session.
|
|
1345
|
+
*/
|
|
604
1346
|
clearStoredChallenge(): Promise<void>;
|
|
1347
|
+
/**
|
|
1348
|
+
* Internal: handle auth response (tokens or challenge).
|
|
1349
|
+
*
|
|
1350
|
+
* In cookies mode: Tokens are set as httpOnly cookies by backend, not stored in client storage.
|
|
1351
|
+
* In JSON mode: Tokens are stored in tokenManager for Authorization header.
|
|
1352
|
+
*/
|
|
605
1353
|
private handleAuthResponse;
|
|
1354
|
+
/**
|
|
1355
|
+
* Persist challenge state.
|
|
1356
|
+
*/
|
|
606
1357
|
private persistChallenge;
|
|
1358
|
+
/**
|
|
1359
|
+
* Clear challenge state.
|
|
1360
|
+
*/
|
|
607
1361
|
private clearChallenge;
|
|
1362
|
+
/**
|
|
1363
|
+
* Persist user.
|
|
1364
|
+
*/
|
|
608
1365
|
private setUser;
|
|
1366
|
+
/**
|
|
1367
|
+
* Clear all auth state.
|
|
1368
|
+
*
|
|
1369
|
+
* @param forgetDevice - If true, also clear device token (for JSON mode)
|
|
1370
|
+
*/
|
|
609
1371
|
private clearAuthState;
|
|
1372
|
+
/**
|
|
1373
|
+
* Persist device token (json mode mobile).
|
|
1374
|
+
*/
|
|
610
1375
|
private setDeviceToken;
|
|
1376
|
+
/**
|
|
1377
|
+
* Determine token delivery mode for this environment.
|
|
1378
|
+
*/
|
|
611
1379
|
private getTokenDeliveryMode;
|
|
1380
|
+
/**
|
|
1381
|
+
* Build request URL by combining baseUrl with path.
|
|
1382
|
+
* @private
|
|
1383
|
+
*/
|
|
612
1384
|
private buildUrl;
|
|
1385
|
+
/**
|
|
1386
|
+
* Build request headers for authentication.
|
|
1387
|
+
* @private
|
|
1388
|
+
*/
|
|
613
1389
|
private buildHeaders;
|
|
1390
|
+
/**
|
|
1391
|
+
* Get CSRF token from cookie (browser only).
|
|
1392
|
+
* @private
|
|
1393
|
+
*/
|
|
614
1394
|
private getCsrfToken;
|
|
1395
|
+
/**
|
|
1396
|
+
* Execute GET request.
|
|
1397
|
+
* Note: 401 refresh is handled by framework interceptors (Angular) or manually.
|
|
1398
|
+
*/
|
|
615
1399
|
private get;
|
|
1400
|
+
/**
|
|
1401
|
+
* Execute POST request.
|
|
1402
|
+
* Note: 401 refresh is handled by framework interceptors (Angular) or manually.
|
|
1403
|
+
*/
|
|
616
1404
|
private post;
|
|
1405
|
+
/**
|
|
1406
|
+
* Execute PUT request.
|
|
1407
|
+
* Note: 401 refresh is handled by framework interceptors (Angular) or manually.
|
|
1408
|
+
*/
|
|
617
1409
|
private put;
|
|
1410
|
+
/**
|
|
1411
|
+
* Execute DELETE request.
|
|
1412
|
+
* Note: 401 refresh is handled by framework interceptors (Angular) or manually.
|
|
1413
|
+
*/
|
|
618
1414
|
private delete;
|
|
1415
|
+
/**
|
|
1416
|
+
* Handle cross-tab storage updates.
|
|
1417
|
+
*/
|
|
619
1418
|
private readonly handleStorageEvent;
|
|
620
1419
|
}
|
|
621
1420
|
|
|
1421
|
+
/**
|
|
1422
|
+
* Fully resolved configuration with all defaults applied.
|
|
1423
|
+
*/
|
|
622
1424
|
type ResolvedNAuthClientConfig = Omit<NAuthClientConfig, 'endpoints' | 'storage' | 'tokenDelivery' | 'httpAdapter'> & {
|
|
623
1425
|
tokenDelivery: TokenDeliveryMode;
|
|
624
1426
|
endpoints: NAuthEndpoints;
|
|
@@ -635,23 +1437,122 @@ type ResolvedNAuthClientConfig = Omit<NAuthClientConfig, 'endpoints' | 'storage'
|
|
|
635
1437
|
headers: Record<string, string>;
|
|
636
1438
|
timeout: number;
|
|
637
1439
|
};
|
|
1440
|
+
/**
|
|
1441
|
+
* Default endpoint paths matching backend controller.
|
|
1442
|
+
*/
|
|
638
1443
|
declare const defaultEndpoints: NAuthEndpoints;
|
|
1444
|
+
/**
|
|
1445
|
+
* Normalize user config with defaults.
|
|
1446
|
+
*
|
|
1447
|
+
* @param config - User supplied config
|
|
1448
|
+
* @param defaultAdapter - Default HTTP adapter (FetchAdapter for vanilla, AngularHttpAdapter for Angular)
|
|
1449
|
+
* @returns Resolved config with defaults applied
|
|
1450
|
+
*/
|
|
639
1451
|
declare const resolveConfig: (config: NAuthClientConfig, defaultAdapter: HttpAdapter) => ResolvedNAuthClientConfig;
|
|
640
1452
|
|
|
1453
|
+
/**
|
|
1454
|
+
* Helper utilities for working with authentication challenges.
|
|
1455
|
+
*
|
|
1456
|
+
* These utilities reduce boilerplate in consumer applications by providing
|
|
1457
|
+
* type-safe access to challenge parameters and state detection.
|
|
1458
|
+
*/
|
|
1459
|
+
/**
|
|
1460
|
+
* Check if a challenge requires phone collection (user has no phone number).
|
|
1461
|
+
*
|
|
1462
|
+
* @param challenge - Auth response with challenge
|
|
1463
|
+
* @returns True if phone collection is required
|
|
1464
|
+
*
|
|
1465
|
+
* @example
|
|
1466
|
+
* ```typescript
|
|
1467
|
+
* const challenge = auth.getCurrentChallenge();
|
|
1468
|
+
* if (challenge && requiresPhoneCollection(challenge)) {
|
|
1469
|
+
* // Show phone input form
|
|
1470
|
+
* }
|
|
1471
|
+
* ```
|
|
1472
|
+
*/
|
|
641
1473
|
declare function requiresPhoneCollection(challenge: AuthResponse): boolean;
|
|
1474
|
+
/**
|
|
1475
|
+
* Get masked destination (email or phone) from challenge parameters.
|
|
1476
|
+
*
|
|
1477
|
+
* For VERIFY_EMAIL/VERIFY_PHONE challenges, returns `codeDeliveryDestination`.
|
|
1478
|
+
* For MFA_REQUIRED challenges, returns `maskedEmail` or `maskedPhone` based on method.
|
|
1479
|
+
*
|
|
1480
|
+
* @param challenge - Auth response with challenge
|
|
1481
|
+
* @returns Masked destination string or null if not available
|
|
1482
|
+
*
|
|
1483
|
+
* @example
|
|
1484
|
+
* ```typescript
|
|
1485
|
+
* const destination = getMaskedDestination(challenge);
|
|
1486
|
+
* if (destination) {
|
|
1487
|
+
* console.log(`Code sent to ${destination}`);
|
|
1488
|
+
* }
|
|
1489
|
+
* ```
|
|
1490
|
+
*/
|
|
642
1491
|
declare function getMaskedDestination(challenge: AuthResponse): string | null;
|
|
1492
|
+
/**
|
|
1493
|
+
* Get preferred MFA method from challenge parameters.
|
|
1494
|
+
*
|
|
1495
|
+
* @param challenge - Auth response with MFA_REQUIRED challenge
|
|
1496
|
+
* @returns MFA method or undefined if not available
|
|
1497
|
+
*
|
|
1498
|
+
* @example
|
|
1499
|
+
* ```typescript
|
|
1500
|
+
* const method = getMFAMethod(challenge);
|
|
1501
|
+
* if (method === 'totp') {
|
|
1502
|
+
* // Show TOTP input
|
|
1503
|
+
* }
|
|
1504
|
+
* ```
|
|
1505
|
+
*/
|
|
643
1506
|
declare function getMFAMethod(challenge: AuthResponse): MFAMethod | undefined;
|
|
1507
|
+
/**
|
|
1508
|
+
* Get challenge instructions from challenge parameters.
|
|
1509
|
+
*
|
|
1510
|
+
* @param challenge - Auth response with challenge
|
|
1511
|
+
* @returns Instructions string or undefined if not available
|
|
1512
|
+
*
|
|
1513
|
+
* @example
|
|
1514
|
+
* ```typescript
|
|
1515
|
+
* const instructions = getChallengeInstructions(challenge);
|
|
1516
|
+
* if (instructions) {
|
|
1517
|
+
* console.log(instructions);
|
|
1518
|
+
* }
|
|
1519
|
+
* ```
|
|
1520
|
+
*/
|
|
644
1521
|
declare function getChallengeInstructions(challenge: AuthResponse): string | undefined;
|
|
1522
|
+
/**
|
|
1523
|
+
* Check if challenge is OTP-based (requires code input).
|
|
1524
|
+
*
|
|
1525
|
+
* @param challenge - Auth response with challenge
|
|
1526
|
+
* @returns True if challenge requires OTP code
|
|
1527
|
+
*
|
|
1528
|
+
* @example
|
|
1529
|
+
* ```typescript
|
|
1530
|
+
* if (isOTPChallenge(challenge)) {
|
|
1531
|
+
* // Show OTP input component
|
|
1532
|
+
* }
|
|
1533
|
+
* ```
|
|
1534
|
+
*/
|
|
645
1535
|
declare function isOTPChallenge(challenge: AuthResponse): boolean;
|
|
646
1536
|
|
|
1537
|
+
/**
|
|
1538
|
+
* Browser storage adapter wrapping localStorage or sessionStorage.
|
|
1539
|
+
*/
|
|
647
1540
|
declare class BrowserStorage implements NAuthStorageAdapter {
|
|
648
1541
|
private readonly storage;
|
|
1542
|
+
/**
|
|
1543
|
+
* Create a browser storage adapter.
|
|
1544
|
+
*
|
|
1545
|
+
* @param storage - Storage implementation (localStorage by default)
|
|
1546
|
+
*/
|
|
649
1547
|
constructor(storage?: Storage);
|
|
650
1548
|
getItem(key: string): Promise<string | null>;
|
|
651
1549
|
setItem(key: string, value: string): Promise<void>;
|
|
652
1550
|
removeItem(key: string): Promise<void>;
|
|
653
1551
|
}
|
|
654
1552
|
|
|
1553
|
+
/**
|
|
1554
|
+
* In-memory storage adapter for SSR, tests, or environments without Web Storage.
|
|
1555
|
+
*/
|
|
655
1556
|
declare class InMemoryStorage implements NAuthStorageAdapter {
|
|
656
1557
|
private readonly store;
|
|
657
1558
|
getItem(key: string): Promise<string | null>;
|
|
@@ -659,7 +1560,33 @@ declare class InMemoryStorage implements NAuthStorageAdapter {
|
|
|
659
1560
|
removeItem(key: string): Promise<void>;
|
|
660
1561
|
}
|
|
661
1562
|
|
|
1563
|
+
/**
|
|
1564
|
+
* HTTP adapter using native fetch API.
|
|
1565
|
+
*
|
|
1566
|
+
* Suitable for:
|
|
1567
|
+
* - Vanilla JavaScript/TypeScript
|
|
1568
|
+
* - Node.js (with fetch polyfill or Node 18+)
|
|
1569
|
+
* - Environments without framework-specific HTTP clients
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```typescript
|
|
1573
|
+
* import { NAuthClient } from '@nauth-toolkit/client';
|
|
1574
|
+
* import { FetchAdapter } from '@nauth-toolkit/client/adapters/fetch';
|
|
1575
|
+
*
|
|
1576
|
+
* const client = new NAuthClient({
|
|
1577
|
+
* baseUrl: 'https://api.example.com/auth',
|
|
1578
|
+
* httpAdapter: new FetchAdapter(),
|
|
1579
|
+
* });
|
|
1580
|
+
* ```
|
|
1581
|
+
*/
|
|
662
1582
|
declare class FetchAdapter implements HttpAdapter {
|
|
1583
|
+
/**
|
|
1584
|
+
* Execute HTTP request using native fetch.
|
|
1585
|
+
*
|
|
1586
|
+
* @param config - Request configuration
|
|
1587
|
+
* @returns Response with parsed data
|
|
1588
|
+
* @throws NAuthClientError if request fails
|
|
1589
|
+
*/
|
|
663
1590
|
request<T>(config: HttpRequest): Promise<HttpResponse<T>>;
|
|
664
1591
|
}
|
|
665
1592
|
|