win-portal-auth-sdk 1.5.0 → 1.5.1
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/client/api/auth.api.d.ts +14 -3
- package/dist/client/api/auth.api.d.ts.map +1 -1
- package/dist/client/api/auth.api.js +12 -4
- package/dist/client/auth-client.d.ts +16 -5
- package/dist/client/auth-client.d.ts.map +1 -1
- package/dist/client/auth-client.js +70 -44
- package/dist/middleware/express.middleware.d.ts +1 -1
- package/dist/middleware/express.middleware.d.ts.map +1 -1
- package/dist/middleware/express.middleware.js +19 -92
- package/dist/middleware/nestjs.guard.d.ts.map +1 -1
- package/dist/middleware/nestjs.guard.js +24 -114
- package/dist/middleware/shared/auth-service.d.ts +36 -0
- package/dist/middleware/shared/auth-service.d.ts.map +1 -0
- package/dist/middleware/shared/auth-service.js +98 -0
- package/dist/middleware/shared/index.d.ts +7 -0
- package/dist/middleware/shared/index.d.ts.map +1 -0
- package/dist/middleware/shared/index.js +22 -0
- package/dist/middleware/shared/token-extractor.d.ts +15 -0
- package/dist/middleware/shared/token-extractor.d.ts.map +1 -0
- package/dist/middleware/shared/token-extractor.js +47 -0
- package/dist/middleware/shared/user-cache.d.ts +51 -0
- package/dist/middleware/shared/user-cache.d.ts.map +1 -0
- package/dist/middleware/shared/user-cache.js +81 -0
- package/dist/types/event-log.types.d.ts +103 -1
- package/dist/types/event-log.types.d.ts.map +1 -1
- package/dist/types/event-log.types.js +5 -1
- package/dist/types/index.d.ts +30 -29
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -3
- package/dist/types/system-config.types.d.ts +2 -5
- package/dist/types/system-config.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/types/event-log.interfaces.d.ts +0 -108
- package/dist/types/event-log.interfaces.d.ts.map +0 -1
- package/dist/types/event-log.interfaces.js +0 -7
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - TOTP (Two-Factor Authentication)
|
|
10
10
|
*/
|
|
11
11
|
import { AuthClient } from '../auth-client';
|
|
12
|
-
import { AuthSession, User
|
|
12
|
+
import { AuthSession, User } from '../../types';
|
|
13
13
|
export declare class AuthAPI {
|
|
14
14
|
private client;
|
|
15
15
|
constructor(client: AuthClient);
|
|
@@ -29,9 +29,20 @@ export declare class AuthAPI {
|
|
|
29
29
|
profile(): Promise<User>;
|
|
30
30
|
/**
|
|
31
31
|
* Refresh access token using session (for web portal)
|
|
32
|
-
* Uses current
|
|
32
|
+
* Uses current access token from Authorization header to refresh
|
|
33
|
+
* This endpoint doesn't require refresh_token - it uses the session from the current token
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Token is already set in client
|
|
38
|
+
* authClient.setToken(accessToken);
|
|
39
|
+
* const result = await authClient.auth.refreshSession();
|
|
40
|
+
* authClient.setToken(result.token);
|
|
41
|
+
* ```
|
|
33
42
|
*/
|
|
34
|
-
|
|
43
|
+
refreshSession(): Promise<{
|
|
44
|
+
token: string;
|
|
45
|
+
}>;
|
|
35
46
|
/**
|
|
36
47
|
* Refresh access token using refresh token (for mobile apps and long-lived sessions)
|
|
37
48
|
* This endpoint uses refresh token flow and supports token rotation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.api.d.ts","sourceRoot":"","sources":["../../../src/client/api/auth.api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAEL,WAAW,EACX,IAAI,
|
|
1
|
+
{"version":3,"file":"auth.api.d.ts","sourceRoot":"","sources":["../../../src/client/api/auth.api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAEL,WAAW,EACX,IAAI,EAGL,MAAM,aAAa,CAAC;AAErB,qBAAa,OAAO;IACN,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAEtC;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAMlE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAK5C;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;;;;;;;;;;;OAYG;IACG,cAAc,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAKlD;;;;;;;;;;;;;;;;;OAiBG;IACG,gBAAgB,CACpB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;QACR,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC,WAAW,CAAC;IAevB;;;OAGG;IACG,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7C,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAcF;;OAEG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAKpE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC;QAC7B,UAAU,EAAE,OAAO,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,YAAY,CAAC,EAAE,IAAI,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAeF;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAK/D;;;OAGG;IACG,eAAe,CACnB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;IASvB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAKnD;;;OAGG;IACG,yBAAyB,IAAI,OAAO,CAAC;QACzC,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CASH"}
|
|
@@ -39,11 +39,19 @@ class AuthAPI {
|
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Refresh access token using session (for web portal)
|
|
42
|
-
* Uses current
|
|
42
|
+
* Uses current access token from Authorization header to refresh
|
|
43
|
+
* This endpoint doesn't require refresh_token - it uses the session from the current token
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* // Token is already set in client
|
|
48
|
+
* authClient.setToken(accessToken);
|
|
49
|
+
* const result = await authClient.auth.refreshSession();
|
|
50
|
+
* authClient.setToken(result.token);
|
|
51
|
+
* ```
|
|
43
52
|
*/
|
|
44
|
-
async
|
|
45
|
-
const
|
|
46
|
-
const response = await this.client.post('/auth/refresh', payload);
|
|
53
|
+
async refreshSession() {
|
|
54
|
+
const response = await this.client.post('/auth/refresh');
|
|
47
55
|
return response.data.data;
|
|
48
56
|
}
|
|
49
57
|
/**
|
|
@@ -52,11 +52,15 @@ export interface AutomaticRefreshOptions {
|
|
|
52
52
|
/**
|
|
53
53
|
* Storage key for refresh token (SDK will manage localStorage automatically)
|
|
54
54
|
* If provided, SDK will handle localStorage operations automatically
|
|
55
|
+
*
|
|
56
|
+
* Note: If login doesn't return refresh_token, SDK will use session-based refresh instead
|
|
55
57
|
*/
|
|
56
58
|
refreshTokenKey?: string;
|
|
57
59
|
/**
|
|
58
60
|
* Custom callbacks (use if you need custom storage or want to override default behavior)
|
|
59
61
|
* If refreshTokenKey is provided, these will be ignored
|
|
62
|
+
*
|
|
63
|
+
* Note: If not provided and no refreshTokenKey, SDK will use session-based refresh (no refresh token needed)
|
|
60
64
|
*/
|
|
61
65
|
callbacks?: RefreshTokenCallbacks;
|
|
62
66
|
/**
|
|
@@ -220,17 +224,23 @@ export declare class AuthClient {
|
|
|
220
224
|
* Enable automatic token refresh
|
|
221
225
|
* Call this after user is authenticated to enable automatic refresh
|
|
222
226
|
*
|
|
223
|
-
* @param options - Options for automatic refresh
|
|
227
|
+
* @param options - Options for automatic refresh (optional - SDK will use session-based refresh if not provided)
|
|
224
228
|
*
|
|
225
229
|
* @example
|
|
226
230
|
* ```typescript
|
|
227
|
-
* //
|
|
231
|
+
* // Option 1: Session-based refresh (default - no refresh token needed)
|
|
232
|
+
* // Works when login only returns access_token
|
|
233
|
+
* await authClient.enableAutomaticRefresh({
|
|
234
|
+
* onRefreshFailure: () => window.location.href = '/login'
|
|
235
|
+
* });
|
|
236
|
+
*
|
|
237
|
+
* // Option 2: With refresh token (if login returns refresh_token)
|
|
228
238
|
* await authClient.enableAutomaticRefresh({
|
|
229
239
|
* refreshTokenKey: 'refresh_token',
|
|
230
240
|
* onRefreshFailure: () => window.location.href = '/login'
|
|
231
241
|
* });
|
|
232
242
|
*
|
|
233
|
-
* //
|
|
243
|
+
* // Option 3: Custom callbacks
|
|
234
244
|
* await authClient.enableAutomaticRefresh({
|
|
235
245
|
* callbacks: {
|
|
236
246
|
* getRefreshToken: () => customStorage.get('refresh_token'),
|
|
@@ -241,7 +251,7 @@ export declare class AuthClient {
|
|
|
241
251
|
* });
|
|
242
252
|
* ```
|
|
243
253
|
*/
|
|
244
|
-
enableAutomaticRefresh(options
|
|
254
|
+
enableAutomaticRefresh(options?: AutomaticRefreshOptions): Promise<void>;
|
|
245
255
|
/**
|
|
246
256
|
* Disable automatic token refresh
|
|
247
257
|
*/
|
|
@@ -260,6 +270,7 @@ export declare class AuthClient {
|
|
|
260
270
|
private performRefresh;
|
|
261
271
|
/**
|
|
262
272
|
* Execute refresh token request
|
|
273
|
+
* Supports both session-based refresh (no refresh token needed) and refresh token flow
|
|
263
274
|
*/
|
|
264
275
|
private doRefresh;
|
|
265
276
|
/**
|
|
@@ -315,7 +326,7 @@ export declare class AuthClient {
|
|
|
315
326
|
*
|
|
316
327
|
* Note: ใช้ token expiration time เป็นตัวประมาณ session expiration
|
|
317
328
|
* เพราะเราไม่มี session creation time หรือ last activity time ใน SDK
|
|
318
|
-
* Token expiration จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
329
|
+
* Token expiration จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
319
330
|
*/
|
|
320
331
|
private checkSessionExpiration;
|
|
321
332
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/client/auth-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAc,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAA8B,MAAM,OAAO,CAAC;AAC5G,OAAO,EAAE,aAAa,EAA8C,MAAM,UAAU,CAAC;AACrF,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,EACf,QAAQ,EACR,WAAW,EACX,UAAU,EACV,QAAQ,EACR,WAAW,EACX,OAAO,EACP,OAAO,EACR,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/client/auth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -324,17 +324,23 @@ class AuthClient {
|
|
|
324
324
|
* Enable automatic token refresh
|
|
325
325
|
* Call this after user is authenticated to enable automatic refresh
|
|
326
326
|
*
|
|
327
|
-
* @param options - Options for automatic refresh
|
|
327
|
+
* @param options - Options for automatic refresh (optional - SDK will use session-based refresh if not provided)
|
|
328
328
|
*
|
|
329
329
|
* @example
|
|
330
330
|
* ```typescript
|
|
331
|
-
* //
|
|
331
|
+
* // Option 1: Session-based refresh (default - no refresh token needed)
|
|
332
|
+
* // Works when login only returns access_token
|
|
333
|
+
* await authClient.enableAutomaticRefresh({
|
|
334
|
+
* onRefreshFailure: () => window.location.href = '/login'
|
|
335
|
+
* });
|
|
336
|
+
*
|
|
337
|
+
* // Option 2: With refresh token (if login returns refresh_token)
|
|
332
338
|
* await authClient.enableAutomaticRefresh({
|
|
333
339
|
* refreshTokenKey: 'refresh_token',
|
|
334
340
|
* onRefreshFailure: () => window.location.href = '/login'
|
|
335
341
|
* });
|
|
336
342
|
*
|
|
337
|
-
* //
|
|
343
|
+
* // Option 3: Custom callbacks
|
|
338
344
|
* await authClient.enableAutomaticRefresh({
|
|
339
345
|
* callbacks: {
|
|
340
346
|
* getRefreshToken: () => customStorage.get('refresh_token'),
|
|
@@ -346,7 +352,16 @@ class AuthClient {
|
|
|
346
352
|
* ```
|
|
347
353
|
*/
|
|
348
354
|
async enableAutomaticRefresh(options) {
|
|
349
|
-
|
|
355
|
+
// If no options provided, use session-based refresh (no refresh token needed)
|
|
356
|
+
if (!options) {
|
|
357
|
+
this.refreshTokenCallbacks = {
|
|
358
|
+
getRefreshToken: () => null, // No refresh token available
|
|
359
|
+
setRefreshToken: () => { }, // No-op
|
|
360
|
+
clearRefreshToken: () => { }, // No-op
|
|
361
|
+
onRefreshFailure: undefined,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
else if (options.refreshTokenKey) {
|
|
350
365
|
// Use localStorage with provided key
|
|
351
366
|
const key = options.refreshTokenKey;
|
|
352
367
|
this.refreshTokenCallbacks = {
|
|
@@ -376,7 +391,13 @@ class AuthClient {
|
|
|
376
391
|
};
|
|
377
392
|
}
|
|
378
393
|
else {
|
|
379
|
-
|
|
394
|
+
// No refresh token callbacks - use session-based refresh
|
|
395
|
+
this.refreshTokenCallbacks = {
|
|
396
|
+
getRefreshToken: () => null,
|
|
397
|
+
setRefreshToken: () => { },
|
|
398
|
+
clearRefreshToken: () => { },
|
|
399
|
+
onRefreshFailure: options.onRefreshFailure,
|
|
400
|
+
};
|
|
380
401
|
}
|
|
381
402
|
await this.loadJwtConfig();
|
|
382
403
|
}
|
|
@@ -438,48 +459,54 @@ class AuthClient {
|
|
|
438
459
|
}
|
|
439
460
|
/**
|
|
440
461
|
* Execute refresh token request
|
|
462
|
+
* Supports both session-based refresh (no refresh token needed) and refresh token flow
|
|
441
463
|
*/
|
|
442
464
|
async doRefresh() {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
465
|
+
// Strategy 1: Try session-based refresh first (works without refresh token)
|
|
466
|
+
// This is the default for web portal login that only returns access_token
|
|
467
|
+
if (this.token) {
|
|
468
|
+
try {
|
|
469
|
+
logger_1.logger.debug('Attempting session-based refresh...');
|
|
470
|
+
const result = await this.auth.refreshSession();
|
|
471
|
+
const newAccessToken = result.token;
|
|
472
|
+
// Update token in client
|
|
473
|
+
this.token = newAccessToken;
|
|
474
|
+
logger_1.logger.debug('Token refreshed successfully (session-based)');
|
|
475
|
+
return newAccessToken;
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
// If session-based refresh fails (e.g., session expired), try refresh token flow
|
|
479
|
+
logger_1.logger.debug('Session-based refresh failed, trying refresh token flow...', {
|
|
480
|
+
status: error.response?.status,
|
|
481
|
+
message: error.message,
|
|
482
|
+
});
|
|
459
483
|
}
|
|
460
|
-
logger_1.logger.debug('Token refreshed successfully');
|
|
461
|
-
return newAccessToken;
|
|
462
484
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
485
|
+
// Strategy 2: Use refresh token flow (for mobile apps or when refresh token is available)
|
|
486
|
+
if (this.refreshTokenCallbacks) {
|
|
487
|
+
const refreshToken = await this.refreshTokenCallbacks.getRefreshToken();
|
|
488
|
+
if (refreshToken) {
|
|
466
489
|
try {
|
|
467
|
-
|
|
468
|
-
const
|
|
490
|
+
// Try refreshWithToken first (for mobile apps with refresh token)
|
|
491
|
+
const session = await this.auth.refreshWithToken(refreshToken);
|
|
492
|
+
const newAccessToken = session.access_token;
|
|
493
|
+
// Update token in client
|
|
469
494
|
this.token = newAccessToken;
|
|
470
|
-
if
|
|
471
|
-
|
|
495
|
+
// Save new refresh token if rotated
|
|
496
|
+
if (session.refresh_token) {
|
|
497
|
+
await this.refreshTokenCallbacks.setRefreshToken(session.refresh_token);
|
|
472
498
|
}
|
|
473
|
-
logger_1.logger.debug('Token refreshed successfully (
|
|
499
|
+
logger_1.logger.debug('Token refreshed successfully (refresh token flow)');
|
|
474
500
|
return newAccessToken;
|
|
475
501
|
}
|
|
476
|
-
catch (
|
|
477
|
-
logger_1.logger.error('
|
|
478
|
-
throw
|
|
502
|
+
catch (error) {
|
|
503
|
+
logger_1.logger.error('Refresh token flow failed:', error);
|
|
504
|
+
throw error;
|
|
479
505
|
}
|
|
480
506
|
}
|
|
481
|
-
throw error;
|
|
482
507
|
}
|
|
508
|
+
// If both strategies fail
|
|
509
|
+
throw new Error('No refresh method available: token expired and no refresh token configured');
|
|
483
510
|
}
|
|
484
511
|
/**
|
|
485
512
|
* Reload JWT config (for when config changes)
|
|
@@ -549,10 +576,10 @@ class AuthClient {
|
|
|
549
576
|
this.sessionManagementConfig = config;
|
|
550
577
|
logger_1.logger.debug('Session management config loaded:', {
|
|
551
578
|
inactivityEnabled: config.inactivity.enabled,
|
|
552
|
-
|
|
579
|
+
inactivityTimeoutMinutes: config.inactivity.timeout_minutes,
|
|
553
580
|
inactivityWarningMinutes: config.inactivity.warning_minutes,
|
|
554
581
|
lifetimeEnabled: config.lifetime.enabled,
|
|
555
|
-
|
|
582
|
+
lifetimeMaxDays: config.lifetime.enabled ? config.lifetime.max_lifetime_days : 'N/A',
|
|
556
583
|
});
|
|
557
584
|
}
|
|
558
585
|
catch (error) {
|
|
@@ -589,7 +616,7 @@ class AuthClient {
|
|
|
589
616
|
*
|
|
590
617
|
* Note: ใช้ token expiration time เป็นตัวประมาณ session expiration
|
|
591
618
|
* เพราะเราไม่มี session creation time หรือ last activity time ใน SDK
|
|
592
|
-
* Token expiration จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
619
|
+
* Token expiration จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
593
620
|
*/
|
|
594
621
|
checkSessionExpiration() {
|
|
595
622
|
if (!this.token || !this.sessionExpirationCallbacks || !this.sessionManagementConfig) {
|
|
@@ -607,7 +634,7 @@ class AuthClient {
|
|
|
607
634
|
return;
|
|
608
635
|
}
|
|
609
636
|
// ใช้ token expiration time เป็นตัวประมาณ session expiration
|
|
610
|
-
// เพราะ token จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
637
|
+
// เพราะ token จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
611
638
|
// ดังนั้น token expiration time จะสะท้อน session expiration time ได้ดีพอสมควร
|
|
612
639
|
// ตรวจสอบว่า session expiration monitoring เปิดใช้งานหรือไม่
|
|
613
640
|
const inactivityEnabled = this.sessionManagementConfig.inactivity.enabled;
|
|
@@ -623,10 +650,10 @@ class AuthClient {
|
|
|
623
650
|
}
|
|
624
651
|
// คำนวณ session expiration times จาก config
|
|
625
652
|
const inactivityTimeoutMinutes = inactivityEnabled
|
|
626
|
-
?
|
|
653
|
+
? this.sessionManagementConfig.inactivity.timeout_minutes
|
|
627
654
|
: null;
|
|
628
|
-
const lifetimeMaxMinutes = lifetimeEnabled
|
|
629
|
-
?
|
|
655
|
+
const lifetimeMaxMinutes = lifetimeEnabled && this.sessionManagementConfig.lifetime.max_lifetime_days
|
|
656
|
+
? this.sessionManagementConfig.lifetime.max_lifetime_days * 24 * 60 // Convert days to minutes
|
|
630
657
|
: null;
|
|
631
658
|
// ใช้ token expiration time เป็นตัวประมาณ session expiration
|
|
632
659
|
// เพราะ token จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
|
|
@@ -710,8 +737,7 @@ class AuthClient {
|
|
|
710
737
|
}
|
|
711
738
|
else if (this.sessionManagementConfig?.inactivity.enabled) {
|
|
712
739
|
// Use session management config
|
|
713
|
-
this.inactivityTimeoutSeconds =
|
|
714
|
-
(0, token_utils_1.convertDurationToMinutes)(this.sessionManagementConfig.inactivity.timeout_duration, this.sessionManagementConfig.inactivity.timeout_unit) * 60; // Convert to seconds
|
|
740
|
+
this.inactivityTimeoutSeconds = this.sessionManagementConfig.inactivity.timeout_minutes * 60; // Convert minutes to seconds
|
|
715
741
|
}
|
|
716
742
|
else {
|
|
717
743
|
// Default: 30 minutes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/express.middleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"express.middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/express.middleware.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAMxD,OAAO,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,SAGlC,GAAG,OAAO,GAAG,QAAQ,GAAG,kBA4B5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,WAAW,CAK7C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG;IACrC,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CASA;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,QAM5C"}
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.clearAuthCache = exports.requireAuth = exports.getAuth = exports.authMiddleware = void 0;
|
|
9
|
-
const
|
|
9
|
+
const auth_service_1 = require("./shared/auth-service");
|
|
10
|
+
const token_extractor_1 = require("./shared/token-extractor");
|
|
11
|
+
const user_cache_1 = require("./shared/user-cache");
|
|
10
12
|
// Import Express type augmentation
|
|
11
13
|
require("./express.types");
|
|
12
|
-
const userCache = new Map();
|
|
13
14
|
/**
|
|
14
|
-
* Create Express
|
|
15
|
+
* Create Express middleware
|
|
15
16
|
*
|
|
16
17
|
* @example
|
|
17
18
|
* ```typescript
|
|
@@ -31,103 +32,29 @@ const userCache = new Map();
|
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
34
|
function authMiddleware(config) {
|
|
34
|
-
const
|
|
35
|
-
baseURL: config.baseURL,
|
|
36
|
-
apiKey: config.apiKey,
|
|
37
|
-
apiKeyHeader: config.apiKeyHeader,
|
|
38
|
-
});
|
|
39
|
-
const cacheTimeout = (config.cacheTimeout || 300) * 1000; // Convert to ms
|
|
40
|
-
const tokenStrategy = config.tokenStrategy || 'bearer';
|
|
41
|
-
const cookieName = config.cookieName || 'access_token';
|
|
42
|
-
const excludePaths = config.excludePaths || [];
|
|
35
|
+
const authService = new auth_service_1.AuthService(config);
|
|
43
36
|
return async (req, res, next) => {
|
|
44
37
|
// No type assertion needed - req already has user/token from Express.Request augmentation
|
|
45
38
|
// Check if path is excluded
|
|
46
|
-
|
|
47
|
-
if (typeof pattern === 'string') {
|
|
48
|
-
return req.path === pattern;
|
|
49
|
-
}
|
|
50
|
-
return pattern.test(req.path);
|
|
51
|
-
});
|
|
52
|
-
if (shouldSkip) {
|
|
39
|
+
if ((0, token_extractor_1.shouldExcludePath)(req.path, config.excludePaths)) {
|
|
53
40
|
req.user = null;
|
|
54
41
|
req.token = null;
|
|
55
42
|
return next();
|
|
56
43
|
}
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (authHeader && authHeader.startsWith('Bearer ')) {
|
|
65
|
-
token = authHeader.substring(7);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
else if (tokenStrategy === 'cookie') {
|
|
69
|
-
token = req.cookies?.[cookieName] || null;
|
|
70
|
-
}
|
|
71
|
-
// No token found
|
|
72
|
-
if (!token) {
|
|
73
|
-
if (config.optional) {
|
|
74
|
-
req.user = null;
|
|
75
|
-
req.token = null;
|
|
76
|
-
return next();
|
|
77
|
-
}
|
|
78
|
-
return res.status(401).json({
|
|
79
|
-
statusCode: 401,
|
|
80
|
-
message: 'Authentication required',
|
|
81
|
-
error: 'Unauthorized',
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
// Check cache first
|
|
86
|
-
const cached = userCache.get(token);
|
|
87
|
-
if (cached && Date.now() - cached.timestamp < cacheTimeout) {
|
|
88
|
-
req.user = cached.user;
|
|
89
|
-
req.token = token;
|
|
90
|
-
return next();
|
|
91
|
-
}
|
|
92
|
-
// Fetch user profile from API
|
|
93
|
-
client.setToken(token);
|
|
94
|
-
const user = await client.auth.profile();
|
|
95
|
-
// Update cache
|
|
96
|
-
userCache.set(token, {
|
|
97
|
-
user,
|
|
98
|
-
timestamp: Date.now(),
|
|
99
|
-
});
|
|
100
|
-
// Clean up old cache entries (simple cleanup)
|
|
101
|
-
if (userCache.size > 1000) {
|
|
102
|
-
const now = Date.now();
|
|
103
|
-
const entries = Array.from(userCache.entries());
|
|
104
|
-
for (const [key, entry] of entries) {
|
|
105
|
-
if (now - entry.timestamp > cacheTimeout) {
|
|
106
|
-
userCache.delete(key);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// Attach user to request
|
|
111
|
-
req.user = user;
|
|
112
|
-
req.token = token;
|
|
113
|
-
next();
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
// Clear cache on error
|
|
117
|
-
userCache.delete(token);
|
|
118
|
-
if (config.optional) {
|
|
119
|
-
req.user = null;
|
|
120
|
-
req.token = null;
|
|
121
|
-
return next();
|
|
122
|
-
}
|
|
123
|
-
const status = error.response?.status || 401;
|
|
124
|
-
const message = error.response?.data?.message || 'Authentication failed';
|
|
125
|
-
return res.status(status).json({
|
|
126
|
-
statusCode: status,
|
|
127
|
-
message,
|
|
44
|
+
// Authenticate request
|
|
45
|
+
const result = await authService.authenticate(req);
|
|
46
|
+
// Handle error
|
|
47
|
+
if (result.error) {
|
|
48
|
+
return res.status(result.error.status).json({
|
|
49
|
+
statusCode: result.error.status,
|
|
50
|
+
message: result.error.message,
|
|
128
51
|
error: 'Unauthorized',
|
|
129
52
|
});
|
|
130
53
|
}
|
|
54
|
+
// Attach user and token to request
|
|
55
|
+
req.user = result.user;
|
|
56
|
+
req.token = result.token;
|
|
57
|
+
next();
|
|
131
58
|
};
|
|
132
59
|
}
|
|
133
60
|
exports.authMiddleware = authMiddleware;
|
|
@@ -176,10 +103,10 @@ exports.requireAuth = requireAuth;
|
|
|
176
103
|
*/
|
|
177
104
|
function clearAuthCache(token) {
|
|
178
105
|
if (token) {
|
|
179
|
-
userCache.delete(token);
|
|
106
|
+
user_cache_1.userCache.delete(token);
|
|
180
107
|
}
|
|
181
108
|
else {
|
|
182
|
-
userCache.clear();
|
|
109
|
+
user_cache_1.userCache.clear();
|
|
183
110
|
}
|
|
184
111
|
}
|
|
185
112
|
exports.clearAuthCache = clearAuthCache;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nestjs.guard.d.ts","sourceRoot":"","sources":["../../src/middleware/nestjs.guard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"nestjs.guard.d.ts","sourceRoot":"","sources":["../../src/middleware/nestjs.guard.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC;;6BAO3C,GAAG,GAAG,QAAQ,OAAO,CAAC;;EAoBpD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC;;6BAOnD,GAAG,GAAG,QAAQ,OAAO,CAAC;;EAepD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,QAMhD"}
|