win-portal-auth-sdk 1.3.0 → 1.3.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/README.md CHANGED
@@ -305,9 +305,27 @@ const client = new AuthClient({
305
305
  baseURL?: string; // Optional: Base URL for requests
306
306
  apiKeyHeader?: string; // Optional: Custom header name (default: 'X-API-Key')
307
307
  timeout?: number; // Optional: Request timeout (default: 30000ms)
308
+ advanced?: { // Optional: Advanced configuration
309
+ activityThrottleMs?: number; // Activity handler throttle (default: 1000ms)
310
+ refreshTimeoutMs?: number; // Refresh token timeout (default: 5000ms)
311
+ }
308
312
  })
309
313
  ```
310
314
 
315
+ **Advanced Configuration:**
316
+
317
+ ```typescript
318
+ // ปรับแต่ง performance และ timeout settings
319
+ const client = new AuthClient({
320
+ apiKey: 'your-api-key',
321
+ baseURL: 'https://api.example.com',
322
+ advanced: {
323
+ activityThrottleMs: 500, // ลด throttle time สำหรับ responsive มากขึ้น (แต่ใช้ CPU มากขึ้น)
324
+ refreshTimeoutMs: 10000, // เพิ่ม timeout สำหรับ slow network
325
+ }
326
+ });
327
+ ```
328
+
311
329
  #### HTTP Methods
312
330
 
313
331
  - `get<T>(url, config?)` - GET request
@@ -369,6 +387,62 @@ const client = new AuthClient({
369
387
  - `getApiKeyMasked()` - Get masked API key for display
370
388
  - `getAxiosInstance()` - Get underlying axios instance
371
389
 
390
+ #### Session Management
391
+
392
+ **Inactivity Detection:**
393
+
394
+ - `enableInactivityDetection(options)` - Enable inactivity detection ที่จับ user activity (mouse/keyboard/touch/scroll)
395
+ - จับ user activity และ trigger callback เมื่อ inactivity timeout
396
+ - ใช้ timeout และ warning time จาก session management config เป็น default
397
+ - Support SSR (Next.js) โดยไม่ error
398
+
399
+ ```typescript
400
+ // Enable inactivity detection
401
+ await authClient.enableInactivityDetection({
402
+ callbacks: {
403
+ onInactivityWarning: (remainingSeconds) => {
404
+ console.log(`Inactivity warning: ${remainingSeconds} seconds remaining`);
405
+ // แสดง notification หรือ dialog
406
+ alert(`Session will expire in ${remainingSeconds} seconds due to inactivity`);
407
+ },
408
+ onInactivityTimeout: () => {
409
+ console.log('Inactivity timeout');
410
+ // Redirect to login หรือ logout
411
+ authClient.clearToken();
412
+ window.location.href = '/login';
413
+ }
414
+ },
415
+ timeoutSeconds: 1800, // 30 minutes (optional, default: จาก session management config)
416
+ warningSeconds: 300, // 5 minutes warning (optional, default: จาก session management config)
417
+ events: ['mousemove', 'keydown', 'touchstart', 'scroll'] // (optional, default: ทั้งหมด)
418
+ });
419
+
420
+ // Disable inactivity detection
421
+ authClient.disableInactivityDetection();
422
+ ```
423
+
424
+ **Session Expiration Monitoring:**
425
+
426
+ - `enableSessionExpirationMonitoring(options)` - Enable session expiration monitoring
427
+ - ตรวจสอบ session expiration ตาม config จาก settings/sessions
428
+ - เรียก callback เมื่อใกล้หมดอายุ
429
+
430
+ ```typescript
431
+ await authClient.enableSessionExpirationMonitoring({
432
+ callbacks: {
433
+ onSessionExpiring: (remainingMinutes, expirationType) => {
434
+ console.log(`Session will expire in ${remainingMinutes} minutes (${expirationType})`);
435
+ // แสดง notification หรือ dialog
436
+ },
437
+ onSessionExpired: () => {
438
+ console.log('Session expired');
439
+ // Redirect to login
440
+ }
441
+ },
442
+ checkIntervalSeconds: 30 // ตรวจสอบทุก 30 วินาที
443
+ });
444
+ ```
445
+
372
446
  ## Authentication Types
373
447
 
374
448
  The SDK supports three authentication types through the `X-Auth-Type` header:
@@ -65,6 +65,35 @@ export interface AutomaticRefreshOptions {
65
65
  */
66
66
  onRefreshFailure?: () => void | Promise<void>;
67
67
  }
68
+ export interface InactivityCallbacks {
69
+ /**
70
+ * Callback เมื่อ inactivity ใกล้หมดเวลา (ตาม warningSeconds)
71
+ * @param remainingSeconds - จำนวนวินาทีที่เหลือก่อน inactivity timeout
72
+ */
73
+ onInactivityWarning?: (remainingSeconds: number) => void | Promise<void>;
74
+ /**
75
+ * Callback เมื่อ inactivity timeout แล้ว
76
+ */
77
+ onInactivityTimeout?: () => void | Promise<void>;
78
+ }
79
+ export interface InactivityDetectionOptions {
80
+ /**
81
+ * Callbacks สำหรับ inactivity events
82
+ */
83
+ callbacks: InactivityCallbacks;
84
+ /**
85
+ * Optional: ระยะเวลา inactivity timeout เป็นวินาที (default: ใช้จาก session management config)
86
+ */
87
+ timeoutSeconds?: number;
88
+ /**
89
+ * Optional: ระยะเวลา warning ก่อน timeout เป็นวินาที (default: ใช้จาก session management config)
90
+ */
91
+ warningSeconds?: number;
92
+ /**
93
+ * Optional: Events ที่ต้องการจับ (default: ทั้งหมด ['mousemove', 'keydown', 'touchstart', 'scroll'])
94
+ */
95
+ events?: ('mousemove' | 'keydown' | 'touchstart' | 'scroll')[];
96
+ }
68
97
  export declare class AuthClient {
69
98
  private client;
70
99
  private apiKey;
@@ -77,14 +106,24 @@ export declare class AuthClient {
77
106
  private automaticRefreshEnabled;
78
107
  private lastRefreshAttempt;
79
108
  private refreshPromise;
80
- private readonly REFRESH_COOLDOWN_MS;
81
109
  private sessionExpirationCallbacks;
82
110
  private sessionManagementConfig;
83
111
  private sessionManagementConfigPromise;
84
112
  private sessionExpirationCheckInterval;
85
113
  private sessionExpirationCheckIntervalSeconds;
86
114
  private lastWarningTime;
87
- private readonly WARNING_COOLDOWN_MS;
115
+ private inactivityCallbacks;
116
+ private inactivityTimeout;
117
+ private inactivityWarningTimeout;
118
+ private lastActivityTime;
119
+ private inactivityDetectionEnabled;
120
+ private inactivityTimeoutSeconds;
121
+ private inactivityWarningSeconds;
122
+ private activityEvents;
123
+ private activityHandler;
124
+ private activityThrottleTimeout;
125
+ private activityThrottleMs;
126
+ private refreshTimeoutMs;
88
127
  readonly auth: AuthAPI;
89
128
  readonly health: HealthAPI;
90
129
  readonly systemConfig: SystemConfigAPI;
@@ -286,5 +325,61 @@ export declare class AuthClient {
286
325
  * Reload session management config (for when config changes)
287
326
  */
288
327
  reloadSessionManagementConfig(): Promise<void>;
328
+ /**
329
+ * Enable inactivity detection
330
+ * จับ user activity (mouse/keyboard/touch/scroll) และ trigger callback เมื่อ inactivity timeout
331
+ *
332
+ * @param options - Options for inactivity detection
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * await authClient.enableInactivityDetection({
337
+ * callbacks: {
338
+ * onInactivityWarning: (remainingSeconds) => {
339
+ * console.log(`Inactivity warning: ${remainingSeconds} seconds remaining`);
340
+ * // แสดง notification หรือ dialog
341
+ * },
342
+ * onInactivityTimeout: () => {
343
+ * console.log('Inactivity timeout');
344
+ * // Redirect to login หรือ logout
345
+ * authClient.clearToken();
346
+ * window.location.href = '/login';
347
+ * }
348
+ * },
349
+ * timeoutSeconds: 1800, // 30 minutes (optional, default: จาก session management config)
350
+ * warningSeconds: 300, // 5 minutes warning (optional, default: จาก session management config)
351
+ * events: ['mousemove', 'keydown', 'touchstart', 'scroll'] // (optional, default: ทั้งหมด)
352
+ * });
353
+ * ```
354
+ */
355
+ enableInactivityDetection(options: InactivityDetectionOptions): Promise<void>;
356
+ /**
357
+ * Disable inactivity detection
358
+ */
359
+ disableInactivityDetection(): void;
360
+ /**
361
+ * Handle user activity - reset inactivity timer with throttle
362
+ */
363
+ private handleUserActivity;
364
+ /**
365
+ * Setup activity event listeners
366
+ */
367
+ private setupActivityListeners;
368
+ /**
369
+ * Remove activity event listeners
370
+ */
371
+ private removeActivityListeners;
372
+ /**
373
+ * Clear inactivity timeouts (helper method)
374
+ */
375
+ private clearInactivityTimeouts;
376
+ /**
377
+ * Reset inactivity timer
378
+ */
379
+ private resetInactivityTimer;
380
+ /**
381
+ * Check inactivity timeout and trigger callbacks if needed
382
+ */
383
+ private checkInactivityTimeout;
289
384
  }
290
385
  //# sourceMappingURL=auth-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/client/auth-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-client.d.ts","sourceRoot":"","sources":["../../src/client/auth-client.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,17 @@ exports.AuthClient = void 0;
14
14
  const axios_1 = __importDefault(require("axios"));
15
15
  const api_1 = require("./api");
16
16
  const token_utils_1 = require("../utils/token-utils");
17
+ const logger_1 = require("../utils/logger");
18
+ // Constants - Default values
19
+ const DEFAULT_INACTIVITY_TIMEOUT_SECONDS = 30 * 60; // 30 minutes
20
+ const DEFAULT_WARNING_SECONDS = 5 * 60; // 5 minutes
21
+ const DEFAULT_SESSION_CHECK_INTERVAL_SECONDS = 30; // 30 seconds
22
+ // Internal constants - Rate limiting (ไม่ควรให้ customize)
23
+ const REFRESH_COOLDOWN_MS = 30 * 1000; // 30 seconds - rate limiting for refresh
24
+ const WARNING_COOLDOWN_MS = 60 * 1000; // 1 minute - rate limiting for warnings
25
+ // Internal constants - Performance tuning (สามารถ customize ได้ผ่าน advanced config)
26
+ const DEFAULT_ACTIVITY_THROTTLE_MS = 1000; // 1 second - throttle activity handler
27
+ const DEFAULT_REFRESH_TIMEOUT_MS = 5000; // 5 seconds - refresh timeout
17
28
  class AuthClient {
18
29
  constructor(config) {
19
30
  this.token = null;
@@ -25,21 +36,38 @@ class AuthClient {
25
36
  this.automaticRefreshEnabled = null;
26
37
  this.lastRefreshAttempt = 0;
27
38
  this.refreshPromise = null;
28
- this.REFRESH_COOLDOWN_MS = 30 * 1000; // 30 seconds cooldown
29
39
  // Session expiration monitoring
30
40
  this.sessionExpirationCallbacks = null;
31
41
  this.sessionManagementConfig = null;
32
42
  this.sessionManagementConfigPromise = null;
33
43
  this.sessionExpirationCheckInterval = null;
34
- this.sessionExpirationCheckIntervalSeconds = 30;
44
+ this.sessionExpirationCheckIntervalSeconds = DEFAULT_SESSION_CHECK_INTERVAL_SECONDS;
35
45
  this.lastWarningTime = 0;
36
- this.WARNING_COOLDOWN_MS = 60 * 1000; // 1 minute cooldown between warnings
46
+ // Inactivity detection
47
+ this.inactivityCallbacks = null;
48
+ this.inactivityTimeout = null;
49
+ this.inactivityWarningTimeout = null;
50
+ this.lastActivityTime = 0;
51
+ this.inactivityDetectionEnabled = false;
52
+ this.inactivityTimeoutSeconds = 0;
53
+ this.inactivityWarningSeconds = 0;
54
+ this.activityEvents = [];
55
+ this.activityHandler = null;
56
+ this.activityThrottleTimeout = null;
57
+ this.activityThrottleMs = DEFAULT_ACTIVITY_THROTTLE_MS;
58
+ this.refreshTimeoutMs = DEFAULT_REFRESH_TIMEOUT_MS;
37
59
  this.apiKey = config.apiKey;
38
60
  this.apiKeyHeader = config.apiKeyHeader || 'X-API-Key';
39
- console.log('[AuthClient] Initializing with config:', {
61
+ // Apply advanced config if provided
62
+ if (config.advanced) {
63
+ this.activityThrottleMs = config.advanced.activityThrottleMs ?? DEFAULT_ACTIVITY_THROTTLE_MS;
64
+ this.refreshTimeoutMs = config.advanced.refreshTimeoutMs ?? DEFAULT_REFRESH_TIMEOUT_MS;
65
+ }
66
+ logger_1.logger.debug('Initializing with config:', {
40
67
  baseURL: config.baseURL,
41
68
  timeout: config.timeout,
42
69
  apiKeyHeader: this.apiKeyHeader,
70
+ advanced: config.advanced,
43
71
  });
44
72
  this.client = axios_1.default.create({
45
73
  baseURL: config.baseURL,
@@ -67,29 +95,28 @@ class AuthClient {
67
95
  const isCritical = remainingMinutes !== null && remainingMinutes <= 1;
68
96
  const now = Date.now();
69
97
  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...`);
98
+ if (timeSinceLastRefresh >= REFRESH_COOLDOWN_MS && !this.refreshPromise) {
99
+ logger_1.logger.debug(`Token near expiration (${remainingMinutes} min remaining), refreshing...`);
73
100
  this.lastRefreshAttempt = now;
74
101
  if (isCritical) {
75
102
  // Critical: await refresh
76
103
  try {
77
104
  const newToken = await Promise.race([
78
105
  this.performRefresh(),
79
- new Promise((_, reject) => setTimeout(() => reject(new Error('Refresh timeout')), 5000)),
106
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Refresh timeout')), this.refreshTimeoutMs)),
80
107
  ]);
81
108
  this.token = newToken;
82
109
  requestConfig.headers['Authorization'] = `Bearer ${newToken}`;
83
- console.log('[AuthClient] Token refreshed successfully (critical)');
110
+ logger_1.logger.info('Token refreshed successfully (critical)');
84
111
  }
85
112
  catch (error) {
86
- console.error('[AuthClient] Critical token refresh failed:', error);
113
+ logger_1.logger.error('Critical token refresh failed:', error);
87
114
  }
88
115
  }
89
116
  else {
90
117
  // Background refresh
91
118
  this.performRefresh().catch((error) => {
92
- console.error('[AuthClient] Background token refresh failed:', error);
119
+ logger_1.logger.error('Background token refresh failed:', error);
93
120
  });
94
121
  }
95
122
  }
@@ -107,7 +134,7 @@ class AuthClient {
107
134
  // Handle 401 errors - try refresh token before failing
108
135
  if (error.response?.status === 401 && originalRequest && this.refreshTokenCallbacks) {
109
136
  if (originalRequest._retry) {
110
- console.warn('[AuthClient] 401 Unauthorized after retry - refresh failed');
137
+ logger_1.logger.warn('401 Unauthorized after retry - refresh failed');
111
138
  if (this.refreshTokenCallbacks.onRefreshFailure) {
112
139
  await this.refreshTokenCallbacks.onRefreshFailure();
113
140
  }
@@ -115,7 +142,7 @@ class AuthClient {
115
142
  }
116
143
  // Skip refresh for refresh endpoint itself
117
144
  if (originalRequest.url?.includes('/auth/refresh') || originalRequest.url?.includes('/auth/refresh-token')) {
118
- console.error('[AuthClient] Refresh endpoint failed - session expired');
145
+ logger_1.logger.error('Refresh endpoint failed - session expired');
119
146
  if (this.refreshTokenCallbacks.onRefreshFailure) {
120
147
  await this.refreshTokenCallbacks.onRefreshFailure();
121
148
  }
@@ -124,15 +151,15 @@ class AuthClient {
124
151
  // Try to refresh token
125
152
  try {
126
153
  originalRequest._retry = true;
127
- console.log('[AuthClient] 401 detected, attempting token refresh...');
154
+ logger_1.logger.debug('401 detected, attempting token refresh...');
128
155
  const newToken = await this.performRefresh();
129
156
  originalRequest.headers = originalRequest.headers || {};
130
157
  originalRequest.headers.Authorization = `Bearer ${newToken}`;
131
- console.log('[AuthClient] Token refreshed, retrying original request...');
158
+ logger_1.logger.debug('Token refreshed, retrying original request...');
132
159
  return this.client(originalRequest);
133
160
  }
134
161
  catch (refreshError) {
135
- console.error('[AuthClient] Token refresh failed:', refreshError);
162
+ logger_1.logger.error('Token refresh failed:', refreshError);
136
163
  if (this.refreshTokenCallbacks.onRefreshFailure) {
137
164
  await this.refreshTokenCallbacks.onRefreshFailure();
138
165
  }
@@ -141,10 +168,10 @@ class AuthClient {
141
168
  }
142
169
  // Handle other errors
143
170
  if (error.response?.status === 401) {
144
- console.error('[AuthClient] API Key authentication failed');
171
+ logger_1.logger.error('API Key authentication failed');
145
172
  }
146
173
  else if (error.response?.status === 429) {
147
- console.error('[AuthClient] Rate limit exceeded');
174
+ logger_1.logger.error('Rate limit exceeded');
148
175
  }
149
176
  return Promise.reject(error);
150
177
  });
@@ -170,7 +197,7 @@ class AuthClient {
170
197
  * ```
171
198
  */
172
199
  initializeOAuth(config) {
173
- console.log('[AuthClient] Initializing OAuth with:', {
200
+ logger_1.logger.debug('Initializing OAuth with:', {
174
201
  clientId: config.clientId,
175
202
  redirectUri: config.redirectUri,
176
203
  scope: config.scope,
@@ -244,7 +271,7 @@ class AuthClient {
244
271
  setToken(token, type = 'jwt') {
245
272
  this.token = token;
246
273
  this.authType = type;
247
- console.log(`[AuthClient] Token set with type: ${type}`);
274
+ logger_1.logger.debug(`Token set with type: ${type}`);
248
275
  // Reset warning time when token changes
249
276
  this.lastWarningTime = 0;
250
277
  // If session expiration monitoring is enabled, check immediately
@@ -265,7 +292,7 @@ class AuthClient {
265
292
  */
266
293
  setAuthType(type) {
267
294
  this.authType = type;
268
- console.log(`[AuthClient] Auth type changed to: ${type}`);
295
+ logger_1.logger.debug(`Auth type changed to: ${type}`);
269
296
  }
270
297
  /**
271
298
  * Get current token (masked)
@@ -379,10 +406,10 @@ class AuthClient {
379
406
  const config = await this.systemConfig.getSecurityJwtConfig();
380
407
  this.refreshThresholdMinutes = config.refresh_threshold_minutes;
381
408
  this.automaticRefreshEnabled = config.automatic_refresh ?? true;
382
- console.log(`[AuthClient] JWT config loaded: refresh_threshold_minutes=${this.refreshThresholdMinutes} minutes, automatic_refresh=${this.automaticRefreshEnabled}`);
409
+ logger_1.logger.debug(`JWT config loaded: refresh_threshold_minutes=${this.refreshThresholdMinutes} minutes, automatic_refresh=${this.automaticRefreshEnabled}`);
383
410
  }
384
411
  catch (error) {
385
- console.error('[AuthClient] Failed to load JWT config:', error);
412
+ logger_1.logger.error('Failed to load JWT config:', error);
386
413
  // Reset to allow retry
387
414
  this.jwtConfigPromise = null;
388
415
  throw error;
@@ -429,7 +456,7 @@ class AuthClient {
429
456
  if (session.refresh_token) {
430
457
  await this.refreshTokenCallbacks.setRefreshToken(session.refresh_token);
431
458
  }
432
- console.log('[AuthClient] Token refreshed successfully');
459
+ logger_1.logger.debug('Token refreshed successfully');
433
460
  return newAccessToken;
434
461
  }
435
462
  catch (error) {
@@ -442,11 +469,11 @@ class AuthClient {
442
469
  if (tokens.refresh_token) {
443
470
  await this.refreshTokenCallbacks.setRefreshToken(tokens.refresh_token);
444
471
  }
445
- console.log('[AuthClient] Token refreshed successfully (fallback)');
472
+ logger_1.logger.debug('Token refreshed successfully (fallback)');
446
473
  return newAccessToken;
447
474
  }
448
475
  catch (fallbackError) {
449
- console.error('[AuthClient] Fallback refresh also failed:', fallbackError);
476
+ logger_1.logger.error('Fallback refresh also failed:', fallbackError);
450
477
  throw fallbackError;
451
478
  }
452
479
  }
@@ -487,7 +514,7 @@ class AuthClient {
487
514
  */
488
515
  async enableSessionExpirationMonitoring(options) {
489
516
  this.sessionExpirationCallbacks = options.callbacks;
490
- this.sessionExpirationCheckIntervalSeconds = options.checkIntervalSeconds ?? 30;
517
+ this.sessionExpirationCheckIntervalSeconds = options.checkIntervalSeconds ?? DEFAULT_SESSION_CHECK_INTERVAL_SECONDS;
491
518
  // Load session management config
492
519
  await this.loadSessionManagementConfig();
493
520
  // Start monitoring
@@ -519,7 +546,7 @@ class AuthClient {
519
546
  try {
520
547
  const config = await this.systemConfig.getSessionManagement();
521
548
  this.sessionManagementConfig = config;
522
- console.log('[AuthClient] Session management config loaded:', {
549
+ logger_1.logger.debug('Session management config loaded:', {
523
550
  inactivityEnabled: config.inactivity.enabled,
524
551
  inactivityTimeout: `${config.inactivity.timeout_duration} ${config.inactivity.timeout_unit}`,
525
552
  inactivityWarningMinutes: config.inactivity.warning_minutes,
@@ -528,7 +555,7 @@ class AuthClient {
528
555
  });
529
556
  }
530
557
  catch (error) {
531
- console.error('[AuthClient] Failed to load session management config:', error);
558
+ logger_1.logger.error('Failed to load session management config:', error);
532
559
  // Reset to allow retry
533
560
  this.sessionManagementConfigPromise = null;
534
561
  throw error;
@@ -628,7 +655,7 @@ class AuthClient {
628
655
  // Check cooldown to avoid spam
629
656
  const now = Date.now();
630
657
  const timeSinceLastWarning = now - this.lastWarningTime;
631
- if (timeSinceLastWarning >= this.WARNING_COOLDOWN_MS) {
658
+ if (timeSinceLastWarning >= WARNING_COOLDOWN_MS) {
632
659
  this.lastWarningTime = now;
633
660
  this.sessionExpirationCallbacks.onSessionExpiring(remainingMinutes, expirationType);
634
661
  }
@@ -641,5 +668,224 @@ class AuthClient {
641
668
  this.sessionManagementConfig = null;
642
669
  await this.loadSessionManagementConfig();
643
670
  }
671
+ /**
672
+ * Enable inactivity detection
673
+ * จับ user activity (mouse/keyboard/touch/scroll) และ trigger callback เมื่อ inactivity timeout
674
+ *
675
+ * @param options - Options for inactivity detection
676
+ *
677
+ * @example
678
+ * ```typescript
679
+ * await authClient.enableInactivityDetection({
680
+ * callbacks: {
681
+ * onInactivityWarning: (remainingSeconds) => {
682
+ * console.log(`Inactivity warning: ${remainingSeconds} seconds remaining`);
683
+ * // แสดง notification หรือ dialog
684
+ * },
685
+ * onInactivityTimeout: () => {
686
+ * console.log('Inactivity timeout');
687
+ * // Redirect to login หรือ logout
688
+ * authClient.clearToken();
689
+ * window.location.href = '/login';
690
+ * }
691
+ * },
692
+ * timeoutSeconds: 1800, // 30 minutes (optional, default: จาก session management config)
693
+ * warningSeconds: 300, // 5 minutes warning (optional, default: จาก session management config)
694
+ * events: ['mousemove', 'keydown', 'touchstart', 'scroll'] // (optional, default: ทั้งหมด)
695
+ * });
696
+ * ```
697
+ */
698
+ async enableInactivityDetection(options) {
699
+ // Disable existing detection if any
700
+ this.disableInactivityDetection();
701
+ this.inactivityCallbacks = options.callbacks;
702
+ // Load session management config if not loaded
703
+ if (!this.sessionManagementConfig) {
704
+ await this.loadSessionManagementConfig();
705
+ }
706
+ // Determine timeout and warning seconds
707
+ if (options.timeoutSeconds !== undefined) {
708
+ this.inactivityTimeoutSeconds = options.timeoutSeconds;
709
+ }
710
+ else if (this.sessionManagementConfig?.inactivity.enabled) {
711
+ // Use session management config
712
+ this.inactivityTimeoutSeconds =
713
+ (0, token_utils_1.convertDurationToMinutes)(this.sessionManagementConfig.inactivity.timeout_duration, this.sessionManagementConfig.inactivity.timeout_unit) * 60; // Convert to seconds
714
+ }
715
+ else {
716
+ // Default: 30 minutes
717
+ this.inactivityTimeoutSeconds = DEFAULT_INACTIVITY_TIMEOUT_SECONDS;
718
+ }
719
+ if (options.warningSeconds !== undefined) {
720
+ this.inactivityWarningSeconds = options.warningSeconds;
721
+ }
722
+ else if (this.sessionManagementConfig?.inactivity.warning_minutes) {
723
+ // Use session management config (convert minutes to seconds)
724
+ this.inactivityWarningSeconds = this.sessionManagementConfig.inactivity.warning_minutes * 60;
725
+ }
726
+ else {
727
+ // Default: 5 minutes
728
+ this.inactivityWarningSeconds = DEFAULT_WARNING_SECONDS;
729
+ }
730
+ // Determine events to listen
731
+ this.activityEvents = options.events || ['mousemove', 'keydown', 'touchstart', 'scroll'];
732
+ // Initialize last activity time
733
+ this.lastActivityTime = Date.now();
734
+ // Enable detection
735
+ this.inactivityDetectionEnabled = true;
736
+ // Setup event listeners
737
+ this.setupActivityListeners();
738
+ // Start timer
739
+ this.resetInactivityTimer();
740
+ logger_1.logger.debug('Inactivity detection enabled:', {
741
+ timeoutSeconds: this.inactivityTimeoutSeconds,
742
+ warningSeconds: this.inactivityWarningSeconds,
743
+ events: this.activityEvents,
744
+ });
745
+ }
746
+ /**
747
+ * Disable inactivity detection
748
+ */
749
+ disableInactivityDetection() {
750
+ this.inactivityDetectionEnabled = false;
751
+ // Clear throttle timeout
752
+ if (this.activityThrottleTimeout) {
753
+ clearTimeout(this.activityThrottleTimeout);
754
+ this.activityThrottleTimeout = null;
755
+ }
756
+ // Clear timeouts
757
+ this.clearInactivityTimeouts();
758
+ // Remove event listeners
759
+ this.removeActivityListeners();
760
+ // Reset state
761
+ this.inactivityCallbacks = null;
762
+ this.lastActivityTime = 0;
763
+ this.inactivityTimeoutSeconds = 0;
764
+ this.inactivityWarningSeconds = 0;
765
+ this.activityEvents = [];
766
+ logger_1.logger.debug('Inactivity detection disabled');
767
+ }
768
+ /**
769
+ * Handle user activity - reset inactivity timer with throttle
770
+ */
771
+ handleUserActivity() {
772
+ if (!this.inactivityDetectionEnabled) {
773
+ return;
774
+ }
775
+ // Throttle: reset timer สูงสุดทุก 1 วินาที เพื่อลด CPU usage
776
+ if (this.activityThrottleTimeout) {
777
+ return;
778
+ }
779
+ this.lastActivityTime = Date.now();
780
+ this.resetInactivityTimer();
781
+ this.activityThrottleTimeout = setTimeout(() => {
782
+ this.activityThrottleTimeout = null;
783
+ }, this.activityThrottleMs);
784
+ }
785
+ /**
786
+ * Setup activity event listeners
787
+ */
788
+ setupActivityListeners() {
789
+ if (typeof window === 'undefined') {
790
+ logger_1.logger.warn('Cannot setup activity listeners: window is undefined (SSR)');
791
+ return;
792
+ }
793
+ // Remove existing listeners if any
794
+ this.removeActivityListeners();
795
+ // Create handler
796
+ const handler = () => {
797
+ this.handleUserActivity();
798
+ };
799
+ this.activityHandler = handler;
800
+ // Setup listeners for each event type
801
+ this.activityEvents.forEach((eventType) => {
802
+ window.addEventListener(eventType, handler, { passive: true });
803
+ });
804
+ logger_1.logger.debug('Activity listeners setup:', this.activityEvents);
805
+ }
806
+ /**
807
+ * Remove activity event listeners
808
+ */
809
+ removeActivityListeners() {
810
+ if (typeof window === 'undefined' || !this.activityHandler) {
811
+ return;
812
+ }
813
+ const handler = this.activityHandler;
814
+ this.activityEvents.forEach((eventType) => {
815
+ window.removeEventListener(eventType, handler);
816
+ });
817
+ this.activityHandler = null;
818
+ logger_1.logger.debug('Activity listeners removed');
819
+ }
820
+ /**
821
+ * Clear inactivity timeouts (helper method)
822
+ */
823
+ clearInactivityTimeouts() {
824
+ if (this.inactivityWarningTimeout) {
825
+ clearTimeout(this.inactivityWarningTimeout);
826
+ this.inactivityWarningTimeout = null;
827
+ }
828
+ if (this.inactivityTimeout) {
829
+ clearTimeout(this.inactivityTimeout);
830
+ this.inactivityTimeout = null;
831
+ }
832
+ }
833
+ /**
834
+ * Reset inactivity timer
835
+ */
836
+ resetInactivityTimer() {
837
+ // Clear existing timeouts
838
+ this.clearInactivityTimeouts();
839
+ if (!this.inactivityDetectionEnabled || !this.inactivityCallbacks) {
840
+ return;
841
+ }
842
+ const now = Date.now();
843
+ this.lastActivityTime = now;
844
+ // Setup warning timeout
845
+ if (this.inactivityWarningSeconds > 0 && this.inactivityCallbacks.onInactivityWarning) {
846
+ const warningTime = this.inactivityTimeoutSeconds - this.inactivityWarningSeconds;
847
+ if (warningTime > 0) {
848
+ const timerStartTime = now; // Capture start time for this timer
849
+ this.inactivityWarningTimeout = setTimeout(() => {
850
+ // Calculate remaining seconds based on when timer was set
851
+ const elapsedSeconds = (Date.now() - timerStartTime) / 1000;
852
+ const remainingSeconds = this.inactivityTimeoutSeconds - elapsedSeconds;
853
+ if (this.inactivityCallbacks?.onInactivityWarning && remainingSeconds > 0) {
854
+ this.inactivityCallbacks.onInactivityWarning(Math.floor(remainingSeconds));
855
+ }
856
+ }, warningTime * 1000);
857
+ }
858
+ }
859
+ // Setup timeout
860
+ this.inactivityTimeout = setTimeout(() => {
861
+ if (this.inactivityCallbacks?.onInactivityTimeout) {
862
+ this.inactivityCallbacks.onInactivityTimeout();
863
+ }
864
+ }, this.inactivityTimeoutSeconds * 1000);
865
+ }
866
+ /**
867
+ * Check inactivity timeout and trigger callbacks if needed
868
+ */
869
+ checkInactivityTimeout() {
870
+ if (!this.inactivityDetectionEnabled || !this.inactivityCallbacks) {
871
+ return;
872
+ }
873
+ const now = Date.now();
874
+ const inactiveSeconds = (now - this.lastActivityTime) / 1000;
875
+ // Check if timeout reached
876
+ if (inactiveSeconds >= this.inactivityTimeoutSeconds) {
877
+ if (this.inactivityCallbacks.onInactivityTimeout) {
878
+ this.inactivityCallbacks.onInactivityTimeout();
879
+ }
880
+ return;
881
+ }
882
+ // Check if warning should be triggered
883
+ const remainingSeconds = this.inactivityTimeoutSeconds - inactiveSeconds;
884
+ if (remainingSeconds <= this.inactivityWarningSeconds &&
885
+ remainingSeconds > 0 &&
886
+ this.inactivityCallbacks.onInactivityWarning) {
887
+ this.inactivityCallbacks.onInactivityWarning(Math.floor(remainingSeconds));
888
+ }
889
+ }
644
890
  }
645
891
  exports.AuthClient = AuthClient;
@@ -2,6 +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';
5
+ export type { RefreshTokenCallbacks, AutomaticRefreshOptions, SessionExpirationCallbacks, SessionExpirationOptions, InactivityCallbacks, InactivityDetectionOptions, } from './auth-client';
6
6
  export * from './api';
7
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;AAC3C,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,cAAc,OAAO,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,EACxB,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,cAAc,OAAO,CAAC"}
package/dist/index.d.ts CHANGED
@@ -8,4 +8,5 @@ export * from './types';
8
8
  export * from './client';
9
9
  export * from './middleware';
10
10
  export * from './utils/token-utils';
11
+ export { logger } from './utils/logger';
11
12
  //# 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;AAG7B,cAAc,qBAAqB,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;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
20
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.logger = void 0;
23
24
  // Types
24
25
  __exportStar(require("./types"), exports);
25
26
  // Client (Frontend & Backend)
@@ -28,3 +29,5 @@ __exportStar(require("./client"), exports);
28
29
  __exportStar(require("./middleware"), exports);
29
30
  // Utils
30
31
  __exportStar(require("./utils/token-utils"), exports);
32
+ var logger_1 = require("./utils/logger");
33
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
@@ -67,6 +67,24 @@ export interface AuthSdkConfig {
67
67
  baseURL?: string;
68
68
  apiKeyHeader?: string;
69
69
  timeout?: number;
70
+ /**
71
+ * Advanced configuration options
72
+ * สำหรับปรับแต่ง internal behavior ของ SDK
73
+ */
74
+ advanced?: {
75
+ /**
76
+ * Activity throttle time (milliseconds)
77
+ * ระยะเวลาที่ throttle activity handler เพื่อลด CPU usage
78
+ * Default: 1000ms (1 second)
79
+ */
80
+ activityThrottleMs?: number;
81
+ /**
82
+ * Refresh token timeout (milliseconds)
83
+ * ระยะเวลาที่รอ refresh token request ก่อน timeout
84
+ * Default: 5000ms (5 seconds)
85
+ */
86
+ refreshTimeoutMs?: number;
87
+ };
70
88
  }
71
89
  /**
72
90
  * NestJS Module Configuration
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,YAAY,EAAE,mBAAmB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IAGf,iBAAiB,EAAE,OAAO,CAAC;IAG3B,qBAAqB,EAAE,MAAM,CAAC;IAG9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAGxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;IAGtD,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,IAAI,CAAC;IAGlB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAGD,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,cAAc,CAAC;AAG7B,cAAc,cAAc,CAAC;AAG7B,cAAc,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE;QACL,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,kBAAkB,CAAC;IAChC,YAAY,EAAE,mBAAmB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IAGf,iBAAiB,EAAE,OAAO,CAAC;IAG3B,qBAAqB,EAAE,MAAM,CAAC;IAG9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAGxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;IAGtD,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,IAAI,CAAC;IAGlB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IAGpB,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,QAAQ,CAAC,EAAE;QACT;;;;WAIG;QACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B;;;;WAIG;QACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAGD,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,cAAc,CAAC;AAG7B,cAAc,cAAc,CAAC;AAG7B,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Logger Utility
3
+ *
4
+ * @description Centralized logging utility for Auth SDK
5
+ * Supports different log levels and environment-based filtering
6
+ */
7
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
8
+ interface LoggerConfig {
9
+ enabled: boolean;
10
+ logLevel: LogLevel;
11
+ }
12
+ declare class Logger {
13
+ private config;
14
+ private shouldLog;
15
+ debug(...args: any[]): void;
16
+ info(...args: any[]): void;
17
+ warn(...args: any[]): void;
18
+ error(...args: any[]): void;
19
+ setConfig(config: Partial<LoggerConfig>): void;
20
+ }
21
+ export declare const logger: Logger;
22
+ export {};
23
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,UAAU,YAAY;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAGZ;IAEF,OAAO,CAAC,SAAS;IAUjB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM3B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM1B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM1B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM3B,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;CAG/C;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * Logger Utility
4
+ *
5
+ * @description Centralized logging utility for Auth SDK
6
+ * Supports different log levels and environment-based filtering
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.logger = void 0;
10
+ class Logger {
11
+ constructor() {
12
+ this.config = {
13
+ enabled: true,
14
+ logLevel: process.env.NODE_ENV === 'production' ? 'warn' : 'debug',
15
+ };
16
+ }
17
+ shouldLog(level) {
18
+ if (!this.config.enabled)
19
+ return false;
20
+ const levels = ['debug', 'info', 'warn', 'error'];
21
+ const currentLevelIndex = levels.indexOf(this.config.logLevel);
22
+ const messageLevelIndex = levels.indexOf(level);
23
+ return messageLevelIndex >= currentLevelIndex;
24
+ }
25
+ debug(...args) {
26
+ if (this.shouldLog('debug')) {
27
+ console.log('[AuthClient]', ...args);
28
+ }
29
+ }
30
+ info(...args) {
31
+ if (this.shouldLog('info')) {
32
+ console.log('[AuthClient]', ...args);
33
+ }
34
+ }
35
+ warn(...args) {
36
+ if (this.shouldLog('warn')) {
37
+ console.warn('[AuthClient]', ...args);
38
+ }
39
+ }
40
+ error(...args) {
41
+ if (this.shouldLog('error')) {
42
+ console.error('[AuthClient]', ...args);
43
+ }
44
+ }
45
+ setConfig(config) {
46
+ this.config = { ...this.config, ...config };
47
+ }
48
+ }
49
+ exports.logger = new Logger();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "win-portal-auth-sdk",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Shared authentication SDK for Win Portal applications with JWT and OAuth support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",