win-portal-auth-sdk 1.1.2 → 1.3.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.
@@ -13,10 +13,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.AuthClient = void 0;
14
14
  const axios_1 = __importDefault(require("axios"));
15
15
  const api_1 = require("./api");
16
+ const token_utils_1 = require("../utils/token-utils");
16
17
  class AuthClient {
17
18
  constructor(config) {
18
19
  this.token = null;
19
20
  this.authType = 'hybrid'; // Default to hybrid
21
+ // Automatic refresh configuration
22
+ this.refreshTokenCallbacks = null;
23
+ this.jwtConfigPromise = null;
24
+ this.refreshThresholdMinutes = null;
25
+ this.automaticRefreshEnabled = null;
26
+ this.lastRefreshAttempt = 0;
27
+ this.refreshPromise = null;
28
+ this.REFRESH_COOLDOWN_MS = 30 * 1000; // 30 seconds cooldown
29
+ // Session expiration monitoring
30
+ this.sessionExpirationCallbacks = null;
31
+ this.sessionManagementConfig = null;
32
+ this.sessionManagementConfigPromise = null;
33
+ this.sessionExpirationCheckInterval = null;
34
+ this.sessionExpirationCheckIntervalSeconds = 30;
35
+ this.lastWarningTime = 0;
36
+ this.WARNING_COOLDOWN_MS = 60 * 1000; // 1 minute cooldown between warnings
20
37
  this.apiKey = config.apiKey;
21
38
  this.apiKeyHeader = config.apiKeyHeader || 'X-API-Key';
22
39
  console.log('[AuthClient] Initializing with config:', {
@@ -31,8 +48,8 @@ class AuthClient {
31
48
  'Content-Type': 'application/json',
32
49
  },
33
50
  });
34
- // Add request interceptor to inject API key
35
- this.client.interceptors.request.use((requestConfig) => {
51
+ // Add request interceptor to inject API key and handle automatic refresh
52
+ this.client.interceptors.request.use(async (requestConfig) => {
36
53
  if (requestConfig.headers) {
37
54
  requestConfig.headers[this.apiKeyHeader] = this.apiKey;
38
55
  // Inject JWT token if available
@@ -40,14 +57,89 @@ class AuthClient {
40
57
  requestConfig.headers['Authorization'] = `Bearer ${this.token}`;
41
58
  // ✅ Inject X-Auth-Type header for better performance
42
59
  requestConfig.headers['X-Auth-Type'] = this.authType;
60
+ // ✅ Automatic token refresh: ตรวจสอบและ refresh token ก่อนหมดอายุ
61
+ if (this.refreshTokenCallbacks &&
62
+ (0, token_utils_1.isTokenValid)(this.token) &&
63
+ this.refreshThresholdMinutes !== null &&
64
+ this.automaticRefreshEnabled === true) {
65
+ if ((0, token_utils_1.isTokenNearExpiration)(this.token, this.refreshThresholdMinutes)) {
66
+ const remainingMinutes = (0, token_utils_1.getTokenExpirationMinutes)(this.token);
67
+ const isCritical = remainingMinutes !== null && remainingMinutes <= 1;
68
+ const now = Date.now();
69
+ const timeSinceLastRefresh = now - this.lastRefreshAttempt;
70
+ if (timeSinceLastRefresh >= this.REFRESH_COOLDOWN_MS &&
71
+ !this.refreshPromise) {
72
+ console.log(`[AuthClient] Token near expiration (${remainingMinutes} min remaining), refreshing...`);
73
+ this.lastRefreshAttempt = now;
74
+ if (isCritical) {
75
+ // Critical: await refresh
76
+ try {
77
+ const newToken = await Promise.race([
78
+ this.performRefresh(),
79
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Refresh timeout')), 5000)),
80
+ ]);
81
+ this.token = newToken;
82
+ requestConfig.headers['Authorization'] = `Bearer ${newToken}`;
83
+ console.log('[AuthClient] Token refreshed successfully (critical)');
84
+ }
85
+ catch (error) {
86
+ console.error('[AuthClient] Critical token refresh failed:', error);
87
+ }
88
+ }
89
+ else {
90
+ // Background refresh
91
+ this.performRefresh().catch((error) => {
92
+ console.error('[AuthClient] Background token refresh failed:', error);
93
+ });
94
+ }
95
+ }
96
+ }
97
+ }
43
98
  }
44
99
  }
45
100
  return requestConfig;
46
101
  }, (error) => {
47
102
  return Promise.reject(error);
48
103
  });
49
- // Add response interceptor for error handling
50
- this.client.interceptors.response.use((response) => response, (error) => {
104
+ // Add response interceptor for error handling and token refresh on 401
105
+ this.client.interceptors.response.use((response) => response, async (error) => {
106
+ const originalRequest = error.config;
107
+ // Handle 401 errors - try refresh token before failing
108
+ if (error.response?.status === 401 && originalRequest && this.refreshTokenCallbacks) {
109
+ if (originalRequest._retry) {
110
+ console.warn('[AuthClient] 401 Unauthorized after retry - refresh failed');
111
+ if (this.refreshTokenCallbacks.onRefreshFailure) {
112
+ await this.refreshTokenCallbacks.onRefreshFailure();
113
+ }
114
+ return Promise.reject(error);
115
+ }
116
+ // Skip refresh for refresh endpoint itself
117
+ if (originalRequest.url?.includes('/auth/refresh') || originalRequest.url?.includes('/auth/refresh-token')) {
118
+ console.error('[AuthClient] Refresh endpoint failed - session expired');
119
+ if (this.refreshTokenCallbacks.onRefreshFailure) {
120
+ await this.refreshTokenCallbacks.onRefreshFailure();
121
+ }
122
+ return Promise.reject(error);
123
+ }
124
+ // Try to refresh token
125
+ try {
126
+ originalRequest._retry = true;
127
+ console.log('[AuthClient] 401 detected, attempting token refresh...');
128
+ const newToken = await this.performRefresh();
129
+ originalRequest.headers = originalRequest.headers || {};
130
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
131
+ console.log('[AuthClient] Token refreshed, retrying original request...');
132
+ return this.client(originalRequest);
133
+ }
134
+ catch (refreshError) {
135
+ console.error('[AuthClient] Token refresh failed:', refreshError);
136
+ if (this.refreshTokenCallbacks.onRefreshFailure) {
137
+ await this.refreshTokenCallbacks.onRefreshFailure();
138
+ }
139
+ return Promise.reject(refreshError);
140
+ }
141
+ }
142
+ // Handle other errors
51
143
  if (error.response?.status === 401) {
52
144
  console.error('[AuthClient] API Key authentication failed');
53
145
  }
@@ -62,6 +154,7 @@ class AuthClient {
62
154
  this.systemConfig = new api_1.SystemConfigAPI(this);
63
155
  this.files = new api_1.FilesAPI(this);
64
156
  this.eventLog = new api_1.EventLogApi(this);
157
+ this.license = new api_1.LicenseAPI(this);
65
158
  this.line = new api_1.LineAPI(this);
66
159
  }
67
160
  /**
@@ -152,6 +245,12 @@ class AuthClient {
152
245
  this.token = token;
153
246
  this.authType = type;
154
247
  console.log(`[AuthClient] Token set with type: ${type}`);
248
+ // Reset warning time when token changes
249
+ this.lastWarningTime = 0;
250
+ // If session expiration monitoring is enabled, check immediately
251
+ if (this.sessionExpirationCallbacks) {
252
+ this.checkSessionExpiration();
253
+ }
155
254
  }
156
255
  /**
157
256
  * Get current token type
@@ -185,6 +284,7 @@ class AuthClient {
185
284
  clearToken() {
186
285
  this.token = null;
187
286
  this.authType = 'hybrid';
287
+ this.lastWarningTime = 0;
188
288
  }
189
289
  /**
190
290
  * Get axios instance for advanced usage
@@ -192,5 +292,354 @@ class AuthClient {
192
292
  getAxiosInstance() {
193
293
  return this.client;
194
294
  }
295
+ /**
296
+ * Enable automatic token refresh
297
+ * Call this after user is authenticated to enable automatic refresh
298
+ *
299
+ * @param options - Options for automatic refresh
300
+ *
301
+ * @example
302
+ * ```typescript
303
+ * // Simple: SDK manages localStorage automatically
304
+ * await authClient.enableAutomaticRefresh({
305
+ * refreshTokenKey: 'refresh_token',
306
+ * onRefreshFailure: () => window.location.href = '/login'
307
+ * });
308
+ *
309
+ * // Advanced: Custom callbacks
310
+ * await authClient.enableAutomaticRefresh({
311
+ * callbacks: {
312
+ * getRefreshToken: () => customStorage.get('refresh_token'),
313
+ * setRefreshToken: (token) => customStorage.set('refresh_token', token),
314
+ * clearRefreshToken: () => customStorage.remove('refresh_token'),
315
+ * onRefreshFailure: () => window.location.href = '/login'
316
+ * }
317
+ * });
318
+ * ```
319
+ */
320
+ async enableAutomaticRefresh(options) {
321
+ if (options.refreshTokenKey) {
322
+ // Use localStorage with provided key
323
+ const key = options.refreshTokenKey;
324
+ this.refreshTokenCallbacks = {
325
+ getRefreshToken: () => {
326
+ if (typeof window === 'undefined')
327
+ return null;
328
+ return localStorage.getItem(key);
329
+ },
330
+ setRefreshToken: (token) => {
331
+ if (typeof window === 'undefined')
332
+ return;
333
+ localStorage.setItem(key, token);
334
+ },
335
+ clearRefreshToken: () => {
336
+ if (typeof window === 'undefined')
337
+ return;
338
+ localStorage.removeItem(key);
339
+ },
340
+ onRefreshFailure: options.onRefreshFailure,
341
+ };
342
+ }
343
+ else if (options.callbacks) {
344
+ // Use custom callbacks
345
+ this.refreshTokenCallbacks = {
346
+ ...options.callbacks,
347
+ onRefreshFailure: options.onRefreshFailure || options.callbacks.onRefreshFailure,
348
+ };
349
+ }
350
+ else {
351
+ throw new Error('Either refreshTokenKey or callbacks must be provided');
352
+ }
353
+ await this.loadJwtConfig();
354
+ }
355
+ /**
356
+ * Disable automatic token refresh
357
+ */
358
+ disableAutomaticRefresh() {
359
+ this.refreshTokenCallbacks = null;
360
+ this.refreshThresholdMinutes = null;
361
+ this.automaticRefreshEnabled = null;
362
+ this.jwtConfigPromise = null;
363
+ }
364
+ /**
365
+ * Load JWT config from API
366
+ */
367
+ async loadJwtConfig() {
368
+ if (this.jwtConfigPromise) {
369
+ return this.jwtConfigPromise;
370
+ }
371
+ this.jwtConfigPromise = this.performJwtConfigLoad();
372
+ return this.jwtConfigPromise;
373
+ }
374
+ /**
375
+ * Perform JWT config load
376
+ */
377
+ async performJwtConfigLoad() {
378
+ try {
379
+ const config = await this.systemConfig.getSecurityJwtConfig();
380
+ this.refreshThresholdMinutes = config.refresh_threshold_minutes;
381
+ this.automaticRefreshEnabled = config.automatic_refresh ?? true;
382
+ console.log(`[AuthClient] JWT config loaded: refresh_threshold_minutes=${this.refreshThresholdMinutes} minutes, automatic_refresh=${this.automaticRefreshEnabled}`);
383
+ }
384
+ catch (error) {
385
+ console.error('[AuthClient] Failed to load JWT config:', error);
386
+ // Reset to allow retry
387
+ this.jwtConfigPromise = null;
388
+ throw error;
389
+ }
390
+ }
391
+ /**
392
+ * Perform token refresh
393
+ */
394
+ async performRefresh() {
395
+ // If refresh is already in progress, wait for it
396
+ if (this.refreshPromise) {
397
+ return this.refreshPromise;
398
+ }
399
+ if (!this.refreshTokenCallbacks) {
400
+ throw new Error('Refresh token callbacks not configured');
401
+ }
402
+ this.refreshPromise = this.doRefresh();
403
+ try {
404
+ const newToken = await this.refreshPromise;
405
+ return newToken;
406
+ }
407
+ finally {
408
+ this.refreshPromise = null;
409
+ }
410
+ }
411
+ /**
412
+ * Execute refresh token request
413
+ */
414
+ async doRefresh() {
415
+ if (!this.refreshTokenCallbacks) {
416
+ throw new Error('Refresh token callbacks not configured');
417
+ }
418
+ const refreshToken = await this.refreshTokenCallbacks.getRefreshToken();
419
+ if (!refreshToken) {
420
+ throw new Error('No refresh token available');
421
+ }
422
+ try {
423
+ // Try refreshWithToken first (for mobile apps with refresh token)
424
+ const session = await this.auth.refreshWithToken(refreshToken);
425
+ const newAccessToken = session.access_token;
426
+ // Update token in client
427
+ this.token = newAccessToken;
428
+ // Save new refresh token if rotated
429
+ if (session.refresh_token) {
430
+ await this.refreshTokenCallbacks.setRefreshToken(session.refresh_token);
431
+ }
432
+ console.log('[AuthClient] Token refreshed successfully');
433
+ return newAccessToken;
434
+ }
435
+ catch (error) {
436
+ // If refreshWithToken fails, try regular refresh endpoint
437
+ if (error.response?.status === 404 || error.response?.status === 400) {
438
+ try {
439
+ const tokens = await this.auth.refresh(refreshToken);
440
+ const newAccessToken = tokens.access_token;
441
+ this.token = newAccessToken;
442
+ if (tokens.refresh_token) {
443
+ await this.refreshTokenCallbacks.setRefreshToken(tokens.refresh_token);
444
+ }
445
+ console.log('[AuthClient] Token refreshed successfully (fallback)');
446
+ return newAccessToken;
447
+ }
448
+ catch (fallbackError) {
449
+ console.error('[AuthClient] Fallback refresh also failed:', fallbackError);
450
+ throw fallbackError;
451
+ }
452
+ }
453
+ throw error;
454
+ }
455
+ }
456
+ /**
457
+ * Reload JWT config (for when config changes)
458
+ */
459
+ async reloadJwtConfig() {
460
+ this.jwtConfigPromise = null;
461
+ this.refreshThresholdMinutes = null;
462
+ this.automaticRefreshEnabled = null;
463
+ await this.loadJwtConfig();
464
+ }
465
+ /**
466
+ * Enable session expiration monitoring
467
+ * จะตรวจสอบ session expiration ตาม config จาก settings/sessions และเรียก callback เมื่อใกล้หมดอายุ
468
+ *
469
+ * @param options - Options for session expiration monitoring
470
+ *
471
+ * @example
472
+ * ```typescript
473
+ * await authClient.enableSessionExpirationMonitoring({
474
+ * callbacks: {
475
+ * onSessionExpiring: (remainingMinutes, expirationType) => {
476
+ * console.log(`Session will expire in ${remainingMinutes} minutes (${expirationType})`);
477
+ * // แสดง notification หรือ dialog
478
+ * },
479
+ * onSessionExpired: () => {
480
+ * console.log('Session expired');
481
+ * // Redirect to login
482
+ * }
483
+ * },
484
+ * checkIntervalSeconds: 30 // ตรวจสอบทุก 30 วินาที
485
+ * });
486
+ * ```
487
+ */
488
+ async enableSessionExpirationMonitoring(options) {
489
+ this.sessionExpirationCallbacks = options.callbacks;
490
+ this.sessionExpirationCheckIntervalSeconds = options.checkIntervalSeconds ?? 30;
491
+ // Load session management config
492
+ await this.loadSessionManagementConfig();
493
+ // Start monitoring
494
+ this.startSessionExpirationMonitoring();
495
+ }
496
+ /**
497
+ * Disable session expiration monitoring
498
+ */
499
+ disableSessionExpirationMonitoring() {
500
+ this.stopSessionExpirationMonitoring();
501
+ this.sessionExpirationCallbacks = null;
502
+ this.sessionManagementConfig = null;
503
+ this.sessionManagementConfigPromise = null;
504
+ }
505
+ /**
506
+ * Load session management config from API
507
+ */
508
+ async loadSessionManagementConfig() {
509
+ if (this.sessionManagementConfigPromise) {
510
+ return this.sessionManagementConfigPromise;
511
+ }
512
+ this.sessionManagementConfigPromise = this.performSessionManagementConfigLoad();
513
+ return this.sessionManagementConfigPromise;
514
+ }
515
+ /**
516
+ * Perform session management config load
517
+ */
518
+ async performSessionManagementConfigLoad() {
519
+ try {
520
+ const config = await this.systemConfig.getSessionManagement();
521
+ this.sessionManagementConfig = config;
522
+ console.log('[AuthClient] Session management config loaded:', {
523
+ inactivityEnabled: config.inactivity.enabled,
524
+ inactivityTimeout: `${config.inactivity.timeout_duration} ${config.inactivity.timeout_unit}`,
525
+ inactivityWarningMinutes: config.inactivity.warning_minutes,
526
+ lifetimeEnabled: config.lifetime.enabled,
527
+ lifetimeMax: config.lifetime.enabled ? `${config.lifetime.max_duration} ${config.lifetime.max_unit}` : 'N/A',
528
+ });
529
+ }
530
+ catch (error) {
531
+ console.error('[AuthClient] Failed to load session management config:', error);
532
+ // Reset to allow retry
533
+ this.sessionManagementConfigPromise = null;
534
+ throw error;
535
+ }
536
+ }
537
+ /**
538
+ * Start session expiration monitoring interval
539
+ */
540
+ startSessionExpirationMonitoring() {
541
+ // Clear existing interval if any
542
+ this.stopSessionExpirationMonitoring();
543
+ // Check immediately
544
+ this.checkSessionExpiration();
545
+ // Set up interval
546
+ this.sessionExpirationCheckInterval = setInterval(() => {
547
+ this.checkSessionExpiration();
548
+ }, this.sessionExpirationCheckIntervalSeconds * 1000);
549
+ }
550
+ /**
551
+ * Stop session expiration monitoring interval
552
+ */
553
+ stopSessionExpirationMonitoring() {
554
+ if (this.sessionExpirationCheckInterval) {
555
+ clearInterval(this.sessionExpirationCheckInterval);
556
+ this.sessionExpirationCheckInterval = null;
557
+ }
558
+ }
559
+ /**
560
+ * Check session expiration and trigger callbacks if needed
561
+ *
562
+ * Note: ใช้ token expiration time เป็นตัวประมาณ session expiration
563
+ * เพราะเราไม่มี session creation time หรือ last activity time ใน SDK
564
+ * Token expiration จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน (extend_on_activity)
565
+ */
566
+ checkSessionExpiration() {
567
+ if (!this.token || !this.sessionExpirationCallbacks || !this.sessionManagementConfig) {
568
+ return;
569
+ }
570
+ // Check if token is expired
571
+ if ((0, token_utils_1.isTokenExpired)(this.token)) {
572
+ if (this.sessionExpirationCallbacks.onSessionExpired) {
573
+ this.sessionExpirationCallbacks.onSessionExpired();
574
+ }
575
+ return;
576
+ }
577
+ const tokenExpirationMinutes = (0, token_utils_1.getTokenExpirationMinutes)(this.token);
578
+ if (tokenExpirationMinutes === null) {
579
+ return;
580
+ }
581
+ // ใช้ token expiration time เป็นตัวประมาณ session expiration
582
+ // เพราะ token จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน (extend_on_activity)
583
+ // ดังนั้น token expiration time จะสะท้อน session expiration time ได้ดีพอสมควร
584
+ // ตรวจสอบว่า session expiration monitoring เปิดใช้งานหรือไม่
585
+ const inactivityEnabled = this.sessionManagementConfig.inactivity.enabled;
586
+ const lifetimeEnabled = this.sessionManagementConfig.lifetime.enabled;
587
+ // ถ้าไม่มี expiration config เปิดใช้งาน ให้ใช้ token expiration
588
+ if (!inactivityEnabled && !lifetimeEnabled) {
589
+ // ใช้ token expiration time เป็นตัวประมาณ
590
+ const warningMinutes = this.sessionManagementConfig.inactivity.warning_minutes;
591
+ if (tokenExpirationMinutes <= warningMinutes && tokenExpirationMinutes > 0) {
592
+ this.triggerExpiringWarning(tokenExpirationMinutes, 'inactivity');
593
+ }
594
+ return;
595
+ }
596
+ // คำนวณ session expiration times จาก config
597
+ const inactivityTimeoutMinutes = inactivityEnabled
598
+ ? (0, token_utils_1.convertDurationToMinutes)(this.sessionManagementConfig.inactivity.timeout_duration, this.sessionManagementConfig.inactivity.timeout_unit)
599
+ : null;
600
+ const lifetimeMaxMinutes = lifetimeEnabled
601
+ ? (0, token_utils_1.convertDurationToMinutes)(this.sessionManagementConfig.lifetime.max_duration, this.sessionManagementConfig.lifetime.max_unit)
602
+ : null;
603
+ // ใช้ token expiration time เป็นตัวประมาณ session expiration
604
+ // เพราะ token จะถูก refresh อัตโนมัติเมื่อมีการใช้งาน
605
+ // ดังนั้น token expiration time จะสะท้อน session expiration time ได้ดีพอสมควร
606
+ const warningMinutes = this.sessionManagementConfig.inactivity.warning_minutes;
607
+ // ตรวจสอบว่า token expiration time ใกล้หมดอายุตาม warning_minutes หรือไม่
608
+ if (tokenExpirationMinutes <= warningMinutes && tokenExpirationMinutes > 0) {
609
+ // กำหนด expiration type จาก config
610
+ let expirationType = 'inactivity';
611
+ if (inactivityTimeoutMinutes !== null && lifetimeMaxMinutes !== null) {
612
+ // ใช้ type ที่สั้นกว่า
613
+ expirationType = inactivityTimeoutMinutes <= lifetimeMaxMinutes ? 'inactivity' : 'lifetime';
614
+ }
615
+ else if (lifetimeMaxMinutes !== null) {
616
+ expirationType = 'lifetime';
617
+ }
618
+ this.triggerExpiringWarning(tokenExpirationMinutes, expirationType);
619
+ }
620
+ }
621
+ /**
622
+ * Trigger expiring warning callback with cooldown
623
+ */
624
+ triggerExpiringWarning(remainingMinutes, expirationType) {
625
+ if (!this.sessionExpirationCallbacks?.onSessionExpiring) {
626
+ return;
627
+ }
628
+ // Check cooldown to avoid spam
629
+ const now = Date.now();
630
+ const timeSinceLastWarning = now - this.lastWarningTime;
631
+ if (timeSinceLastWarning >= this.WARNING_COOLDOWN_MS) {
632
+ this.lastWarningTime = now;
633
+ this.sessionExpirationCallbacks.onSessionExpiring(remainingMinutes, expirationType);
634
+ }
635
+ }
636
+ /**
637
+ * Reload session management config (for when config changes)
638
+ */
639
+ async reloadSessionManagementConfig() {
640
+ this.sessionManagementConfigPromise = null;
641
+ this.sessionManagementConfig = null;
642
+ await this.loadSessionManagementConfig();
643
+ }
195
644
  }
196
645
  exports.AuthClient = AuthClient;
@@ -2,4 +2,6 @@
2
2
  * Client exports for frontend applications
3
3
  */
4
4
  export { AuthClient } from './auth-client';
5
+ export type { RefreshTokenCallbacks, AutomaticRefreshOptions, SessionExpirationCallbacks, SessionExpirationOptions, } from './auth-client';
6
+ export * from './api';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,cAAc,OAAO,CAAC"}
@@ -2,7 +2,22 @@
2
2
  /**
3
3
  * Client exports for frontend applications
4
4
  */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
5
19
  Object.defineProperty(exports, "__esModule", { value: true });
6
20
  exports.AuthClient = void 0;
7
21
  var auth_client_1 = require("./auth-client");
8
22
  Object.defineProperty(exports, "AuthClient", { enumerable: true, get: function () { return auth_client_1.AuthClient; } });
23
+ __exportStar(require("./api"), exports);
package/dist/index.d.ts CHANGED
@@ -7,4 +7,5 @@
7
7
  export * from './types';
8
8
  export * from './client';
9
9
  export * from './middleware';
10
+ export * from './utils/token-utils';
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,cAAc,cAAc,CAAC;AAG7B,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -26,3 +26,5 @@ __exportStar(require("./types"), exports);
26
26
  __exportStar(require("./client"), exports);
27
27
  // Middleware (Backend only - Express & NestJS)
28
28
  __exportStar(require("./middleware"), exports);
29
+ // Utils
30
+ __exportStar(require("./utils/token-utils"), exports);
@@ -66,6 +66,15 @@ export interface User {
66
66
  export interface RefreshTokenRequest {
67
67
  refresh_token: string;
68
68
  }
69
+ /**
70
+ * Refresh Token Request with optional metadata
71
+ */
72
+ export interface RefreshTokenRequestWithMetadata {
73
+ refresh_token: string;
74
+ ip_address?: string;
75
+ user_agent?: string;
76
+ device_id?: string;
77
+ }
69
78
  /**
70
79
  * Authentication Tokens
71
80
  * Result of token refresh
@@ -1 +1 @@
1
- {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../src/types/auth.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,gBAAgB,CAAC,EAAE;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"auth.types.d.ts","sourceRoot":"","sources":["../../src/types/auth.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,SAAS,CAAC,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,gBAAgB,CAAC,EAAE;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -29,4 +29,41 @@ export interface SystemConfig {
29
29
  * Returns an object with key-value pairs for a category
30
30
  */
31
31
  export type SystemConfigByCategory = Record<string, any>;
32
+ /**
33
+ * Security JWT Configuration
34
+ * Configuration for JWT token settings
35
+ */
36
+ export interface SecurityJwtConfig {
37
+ jwt_secret: string;
38
+ access_token_expiry_minutes: number;
39
+ refresh_token_expiry_days: number;
40
+ automatic_refresh: boolean;
41
+ refresh_threshold_minutes: number;
42
+ rotate_refresh_token: boolean;
43
+ revoke_on_logout: boolean;
44
+ max_refresh_attempts: number;
45
+ }
46
+ /**
47
+ * Session Management Configuration
48
+ * Configuration for session timeout and expiration settings
49
+ */
50
+ export interface SessionManagementConfig {
51
+ inactivity: {
52
+ enabled: boolean;
53
+ timeout_duration: number;
54
+ timeout_unit: 'minutes' | 'hours' | 'days';
55
+ warning_minutes: number;
56
+ extend_on_activity: boolean;
57
+ };
58
+ lifetime: {
59
+ enabled: boolean;
60
+ max_duration: number;
61
+ max_unit: 'minutes' | 'hours' | 'days';
62
+ };
63
+ concurrent: {
64
+ max_sessions: number;
65
+ logout_inactive: boolean;
66
+ show_badge: boolean;
67
+ };
68
+ }
32
69
  //# sourceMappingURL=system-config.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"system-config.types.d.ts","sourceRoot":"","sources":["../../src/types/system-config.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"system-config.types.d.ts","sourceRoot":"","sources":["../../src/types/system-config.types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IAC9D,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B,EAAE,MAAM,CAAC;IACpC,yBAAyB,EAAE,MAAM,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE;QACV,OAAO,EAAE,OAAO,CAAC;QACjB,gBAAgB,EAAE,MAAM,CAAC;QACzB,YAAY,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;QAC3C,eAAe,EAAE,MAAM,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;KACxC,CAAC;IACF,UAAU,EAAE;QACV,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,OAAO,CAAC;QACzB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;CACH"}