@thetechfossil/auth2 1.2.19 → 1.2.21

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.
Files changed (38) hide show
  1. package/README.md +1 -1
  2. package/dist/index.components.d.mts +1 -0
  3. package/dist/index.components.d.ts +1 -0
  4. package/dist/index.components.js +275 -11
  5. package/dist/index.components.js.map +1 -1
  6. package/dist/index.components.mjs +275 -11
  7. package/dist/index.components.mjs.map +1 -1
  8. package/dist/index.d.mts +111 -3
  9. package/dist/index.d.ts +111 -3
  10. package/dist/index.js +470 -30
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +471 -32
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/index.next.d.mts +54 -1
  15. package/dist/index.next.d.ts +54 -1
  16. package/dist/index.next.js +332 -26
  17. package/dist/index.next.js.map +1 -1
  18. package/dist/index.next.mjs +332 -26
  19. package/dist/index.next.mjs.map +1 -1
  20. package/dist/index.next.server.d.mts +81 -2
  21. package/dist/index.next.server.d.ts +81 -2
  22. package/dist/index.next.server.js +406 -9
  23. package/dist/index.next.server.js.map +1 -1
  24. package/dist/index.next.server.mjs +403 -10
  25. package/dist/index.next.server.mjs.map +1 -1
  26. package/dist/index.node.d.mts +81 -2
  27. package/dist/index.node.d.ts +81 -2
  28. package/dist/index.node.js +406 -9
  29. package/dist/index.node.js.map +1 -1
  30. package/dist/index.node.mjs +403 -10
  31. package/dist/index.node.mjs.map +1 -1
  32. package/dist/index.react-native.d.mts +227 -0
  33. package/dist/index.react-native.d.ts +227 -0
  34. package/dist/index.react-native.js +1684 -0
  35. package/dist/index.react-native.js.map +1 -0
  36. package/dist/index.react-native.mjs +1648 -0
  37. package/dist/index.react-native.mjs.map +1 -0
  38. package/package.json +119 -102
@@ -14,6 +14,8 @@ interface User {
14
14
  phoneNumber?: string;
15
15
  avatar?: string;
16
16
  role: string;
17
+ emailVerified?: boolean;
18
+ twoFactorEnabled?: boolean;
17
19
  linkedAccounts?: LinkedAccount[];
18
20
  createdAt: string;
19
21
  updatedAt: string;
@@ -63,6 +65,7 @@ interface AuthConfig {
63
65
  localStorageKey?: string;
64
66
  token?: string;
65
67
  csrfEnabled?: boolean;
68
+ enableSocket?: boolean;
66
69
  upfilesConfig?: UpfilesConfig;
67
70
  }
68
71
  interface UpfilesConfig {
@@ -130,17 +133,57 @@ interface UseAuthReturn {
130
133
  }>;
131
134
  revokeSession: (sessionId: string) => Promise<AuthResponse>;
132
135
  revokeAllSessions: () => Promise<AuthResponse>;
136
+ adminCreateUser: (data: {
137
+ email: string;
138
+ name: string;
139
+ phoneNumber?: string;
140
+ password?: string;
141
+ }) => Promise<AuthResponse & {
142
+ user?: User;
143
+ }>;
144
+ adminVerifyUser: (userId: string) => Promise<AuthResponse>;
145
+ adminSuspendUser: (userId: string) => Promise<AuthResponse>;
146
+ adminActivateUser: (userId: string) => Promise<AuthResponse>;
133
147
  }
134
148
 
149
+ type SocketEventHandler<T = any> = (data: T) => void;
150
+
135
151
  declare class AuthService {
136
152
  private httpClient;
153
+ private socketService;
137
154
  private config;
138
155
  private token;
139
156
  private upfilesClient;
157
+ private cachedUser;
158
+ private userCacheTimestamp;
159
+ private readonly USER_CACHE_TTL;
140
160
  constructor(config: AuthConfig);
141
161
  private loadTokenFromStorage;
142
162
  private saveTokenToStorage;
143
163
  private removeTokenFromStorage;
164
+ private connectSocket;
165
+ private disconnectSocket;
166
+ onUserUpdated(handler: SocketEventHandler<{
167
+ user: User;
168
+ }>): () => void;
169
+ onSessionRevoked(handler: SocketEventHandler<{
170
+ sessionId?: string;
171
+ }>): () => void;
172
+ onAllSessionsRevoked(handler: SocketEventHandler<{}>): () => void;
173
+ onPasswordChanged(handler: SocketEventHandler<{}>): () => void;
174
+ on2FAChanged(handler: SocketEventHandler<{
175
+ enabled: boolean;
176
+ }>): () => void;
177
+ onSocketConnected(handler: SocketEventHandler<{}>): () => void;
178
+ onSocketDisconnected(handler: SocketEventHandler<{
179
+ reason: string;
180
+ }>): () => void;
181
+ onSocketError(handler: SocketEventHandler<{
182
+ error: string;
183
+ }>): () => void;
184
+ isSocketConnected(): boolean;
185
+ clearUserCache(): void;
186
+ private isCacheValid;
144
187
  isAuthenticated(): boolean;
145
188
  getToken(): string | null;
146
189
  getCurrentUser(): User | null;
@@ -154,7 +197,7 @@ declare class AuthService {
154
197
  verify(data: VerifyData): Promise<AuthResponse>;
155
198
  verifyEmailToken(token: string): Promise<AuthResponse>;
156
199
  logout(): Promise<void>;
157
- getProfile(): Promise<User>;
200
+ getProfile(forceRefresh?: boolean): Promise<User>;
158
201
  updateProfile(data: UpdateUserData): Promise<AuthResponse>;
159
202
  getAllUsers(): Promise<User[]>;
160
203
  getUserById(id: string): Promise<User>;
@@ -185,6 +228,14 @@ declare class AuthService {
185
228
  success: boolean;
186
229
  logs: any[];
187
230
  }>;
231
+ adminCreateUser(data: {
232
+ email: string;
233
+ name: string;
234
+ phoneNumber?: string;
235
+ password?: string;
236
+ }): Promise<AuthResponse & {
237
+ user?: User;
238
+ }>;
188
239
  adminVerifyUser(userId: string): Promise<AuthResponse>;
189
240
  adminForcePasswordReset(userId: string): Promise<AuthResponse>;
190
241
  adminSuspendUser(userId: string): Promise<AuthResponse>;
@@ -197,6 +248,7 @@ declare class HttpClient {
197
248
  private frontendBaseUrl;
198
249
  private baseUrl;
199
250
  constructor(baseUrl: string, defaultHeaders?: Record<string, string>);
251
+ private createUserFriendlyError;
200
252
  get<T>(endpoint: string, headers?: Record<string, string>): Promise<T>;
201
253
  post<T>(endpoint: string, data?: any, headers?: Record<string, string>): Promise<T>;
202
254
  put<T>(endpoint: string, data?: any, headers?: Record<string, string>): Promise<T>;
@@ -224,4 +276,31 @@ declare class AuthClient extends AuthService {
224
276
  getAllUsers(): Promise<User[]>;
225
277
  }
226
278
 
227
- export { type AuditLog, AuthClient, type AuthConfig, type AuthResponse, AuthService, type CsrfTokenResponse, HttpClient, type LinkedAccount, type LoginData, type MFASetup, type OAuthConfig, type OAuthProvider, type RegisterData, type Session, type UpdateUserData, type UpfilesConfig, type UseAuthReturn, type User, type VerifyData };
279
+ interface TokenVerifierConfig {
280
+ authServiceUrl: string;
281
+ cacheTTL?: number;
282
+ cacheEnabled?: boolean;
283
+ }
284
+ declare class TokenVerifier {
285
+ private config;
286
+ private cache;
287
+ private cleanupInterval;
288
+ constructor(config: TokenVerifierConfig);
289
+ verifyToken(token: string): Promise<User | null>;
290
+ invalidateToken(token: string): void;
291
+ clearCache(): void;
292
+ getCacheStats(): {
293
+ size: number;
294
+ enabled: boolean;
295
+ ttl: number;
296
+ };
297
+ destroy(): void;
298
+ private getFromCache;
299
+ private setCache;
300
+ private startCleanup;
301
+ }
302
+ declare function createTokenVerifier(config: TokenVerifierConfig): TokenVerifier;
303
+ declare function getTokenVerifier(): TokenVerifier;
304
+ declare function verifyToken(token: string): Promise<User | null>;
305
+
306
+ export { type AuditLog, AuthClient, type AuthConfig, type AuthResponse, AuthService, type CsrfTokenResponse, HttpClient, type LinkedAccount, type LoginData, type MFASetup, type OAuthConfig, type OAuthProvider, type RegisterData, type Session, TokenVerifier, type UpdateUserData, type UpfilesConfig, type UseAuthReturn, type User, type VerifyData, createTokenVerifier, getTokenVerifier, verifyToken };
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var axios = require('axios');
4
+ var socket_ioClient = require('socket.io-client');
4
5
  var upfiles = require('@thetechfossil/upfiles');
5
6
 
6
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -8,6 +9,16 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
  var axios__default = /*#__PURE__*/_interopDefault(axios);
9
10
 
10
11
  // src/core/http-client.ts
12
+ var ERROR_MESSAGES = {
13
+ NETWORK_ERROR: "Unable to connect to the server. Please check your internet connection and try again.",
14
+ TIMEOUT: "The request took too long. Please try again.",
15
+ SERVER_ERROR: "Something went wrong on our end. Please try again later.",
16
+ UNAUTHORIZED: "Your session has expired. Please log in again.",
17
+ FORBIDDEN: "You do not have permission to perform this action.",
18
+ NOT_FOUND: "The requested resource was not found.",
19
+ RATE_LIMITED: "Too many requests. Please wait a moment and try again.",
20
+ UNKNOWN: "An unexpected error occurred. Please try again."
21
+ };
11
22
  var HttpClient = class {
12
23
  constructor(baseUrl, defaultHeaders = {}) {
13
24
  this.csrfToken = null;
@@ -42,7 +53,7 @@ var HttpClient = class {
42
53
  }
43
54
  return config;
44
55
  },
45
- (error) => Promise.reject(error)
56
+ (error) => Promise.reject(this.createUserFriendlyError(error))
46
57
  );
47
58
  this.axiosInstance.interceptors.response.use(
48
59
  (response) => response,
@@ -57,18 +68,71 @@ var HttpClient = class {
57
68
  }
58
69
  return this.axiosInstance(originalRequest);
59
70
  } catch (refreshError) {
60
- return Promise.reject(refreshError);
71
+ return Promise.reject(this.createUserFriendlyError(refreshError));
61
72
  }
62
73
  }
63
- if (error.response && error.response.data && error.response.data.message) {
64
- const customError = new Error(error.response.data.message);
65
- customError.response = error.response;
66
- return Promise.reject(customError);
67
- }
68
- return Promise.reject(error);
74
+ return Promise.reject(this.createUserFriendlyError(error));
69
75
  }
70
76
  );
71
77
  }
78
+ /**
79
+ * Creates a user-friendly error message from an Axios error
80
+ */
81
+ createUserFriendlyError(error) {
82
+ if (error instanceof Error && !error.isAxiosError) {
83
+ return error;
84
+ }
85
+ let message;
86
+ let statusCode;
87
+ if (axios__default.default.isAxiosError(error)) {
88
+ statusCode = error.response?.status;
89
+ const responseData = error.response?.data;
90
+ if (responseData?.message) {
91
+ message = responseData.message;
92
+ } else if (!error.response) {
93
+ if (error.code === "ECONNABORTED" || error.message.includes("timeout")) {
94
+ message = ERROR_MESSAGES.TIMEOUT;
95
+ } else if (error.code === "ERR_NETWORK" || error.message === "Network Error") {
96
+ message = ERROR_MESSAGES.NETWORK_ERROR;
97
+ } else {
98
+ message = ERROR_MESSAGES.NETWORK_ERROR;
99
+ }
100
+ } else {
101
+ switch (statusCode) {
102
+ case 400:
103
+ message = responseData?.message || "Invalid request. Please check your input.";
104
+ break;
105
+ case 401:
106
+ message = responseData?.message || ERROR_MESSAGES.UNAUTHORIZED;
107
+ break;
108
+ case 403:
109
+ message = responseData?.message || ERROR_MESSAGES.FORBIDDEN;
110
+ break;
111
+ case 404:
112
+ message = responseData?.message || ERROR_MESSAGES.NOT_FOUND;
113
+ break;
114
+ case 429:
115
+ message = ERROR_MESSAGES.RATE_LIMITED;
116
+ break;
117
+ case 500:
118
+ case 502:
119
+ case 503:
120
+ case 504:
121
+ message = ERROR_MESSAGES.SERVER_ERROR;
122
+ break;
123
+ default:
124
+ message = responseData?.message || ERROR_MESSAGES.UNKNOWN;
125
+ }
126
+ }
127
+ } else {
128
+ message = error?.message || ERROR_MESSAGES.UNKNOWN;
129
+ }
130
+ const customError = new Error(message);
131
+ customError.response = error?.response;
132
+ customError.statusCode = statusCode;
133
+ customError.originalError = error;
134
+ return customError;
135
+ }
72
136
  async get(endpoint, headers) {
73
137
  const response = await this.axiosInstance.get(endpoint, { headers });
74
138
  return response.data;
@@ -119,16 +183,134 @@ var HttpClient = class {
119
183
  }
120
184
  }
121
185
  };
186
+ var SocketService = class {
187
+ constructor(config) {
188
+ this.socket = null;
189
+ this.token = null;
190
+ this.eventHandlers = /* @__PURE__ */ new Map();
191
+ this.isConnecting = false;
192
+ this.config = {
193
+ autoConnect: false,
194
+ reconnection: true,
195
+ reconnectionAttempts: 5,
196
+ reconnectionDelay: 1e3,
197
+ ...config
198
+ };
199
+ }
200
+ connect(token) {
201
+ if (this.socket?.connected || this.isConnecting) {
202
+ return;
203
+ }
204
+ this.token = token;
205
+ this.isConnecting = true;
206
+ this.socket = socket_ioClient.io(this.config.baseUrl, {
207
+ auth: { token },
208
+ autoConnect: true,
209
+ reconnection: this.config.reconnection,
210
+ reconnectionAttempts: this.config.reconnectionAttempts,
211
+ reconnectionDelay: this.config.reconnectionDelay,
212
+ transports: ["websocket", "polling"]
213
+ });
214
+ this.setupEventListeners();
215
+ }
216
+ setupEventListeners() {
217
+ if (!this.socket) return;
218
+ this.socket.on("connect", () => {
219
+ this.isConnecting = false;
220
+ console.log("[Auth SDK] Socket connected");
221
+ this.emit("connected", {});
222
+ });
223
+ this.socket.on("disconnect", (reason) => {
224
+ console.log("[Auth SDK] Socket disconnected:", reason);
225
+ this.emit("disconnected", { reason });
226
+ });
227
+ this.socket.on("connect_error", (error) => {
228
+ this.isConnecting = false;
229
+ console.error("[Auth SDK] Socket connection error:", error.message);
230
+ this.emit("error", { error: error.message });
231
+ });
232
+ this.socket.on("user:updated", (data) => {
233
+ this.emit("user:updated", data);
234
+ });
235
+ this.socket.on("session:revoked", (data) => {
236
+ this.emit("session:revoked", data);
237
+ });
238
+ this.socket.on("session:all-revoked", () => {
239
+ this.emit("session:all-revoked", {});
240
+ });
241
+ this.socket.on("auth:password-changed", () => {
242
+ this.emit("auth:password-changed", {});
243
+ });
244
+ this.socket.on("auth:2fa-changed", (data) => {
245
+ this.emit("auth:2fa-changed", data);
246
+ });
247
+ this.socket.on("user:refresh", () => {
248
+ this.emit("user:refresh", {});
249
+ });
250
+ }
251
+ disconnect() {
252
+ if (this.socket) {
253
+ this.socket.disconnect();
254
+ this.socket = null;
255
+ this.token = null;
256
+ this.isConnecting = false;
257
+ }
258
+ }
259
+ isConnected() {
260
+ return this.socket?.connected ?? false;
261
+ }
262
+ // Event subscription
263
+ on(event, handler) {
264
+ if (!this.eventHandlers.has(event)) {
265
+ this.eventHandlers.set(event, /* @__PURE__ */ new Set());
266
+ }
267
+ this.eventHandlers.get(event).add(handler);
268
+ return () => {
269
+ this.eventHandlers.get(event)?.delete(handler);
270
+ };
271
+ }
272
+ off(event, handler) {
273
+ if (handler) {
274
+ this.eventHandlers.get(event)?.delete(handler);
275
+ } else {
276
+ this.eventHandlers.delete(event);
277
+ }
278
+ }
279
+ emit(event, data) {
280
+ const handlers = this.eventHandlers.get(event);
281
+ if (handlers) {
282
+ handlers.forEach((handler) => {
283
+ try {
284
+ handler(data);
285
+ } catch (error) {
286
+ console.error(`[Auth SDK] Error in event handler for ${event}:`, error);
287
+ }
288
+ });
289
+ }
290
+ }
291
+ // Request fresh user data from server
292
+ requestUserRefresh() {
293
+ if (this.socket?.connected) {
294
+ this.socket.emit("request:user");
295
+ }
296
+ }
297
+ };
122
298
  var AuthService = class {
299
+ // 5 minutes cache
123
300
  constructor(config) {
124
301
  this.token = null;
125
302
  this.upfilesClient = null;
303
+ this.cachedUser = null;
304
+ this.userCacheTimestamp = 0;
305
+ this.USER_CACHE_TTL = 5 * 60 * 1e3;
126
306
  this.config = {
127
307
  localStorageKey: "auth_token",
128
308
  csrfEnabled: true,
309
+ enableSocket: true,
129
310
  ...config
130
311
  };
131
312
  this.httpClient = new HttpClient(this.config.baseUrl);
313
+ this.socketService = new SocketService({ baseUrl: this.config.baseUrl });
132
314
  this.loadTokenFromStorage();
133
315
  if (this.config.upfilesConfig) {
134
316
  this.upfilesClient = new upfiles.UpfilesClient({
@@ -145,6 +327,9 @@ var AuthService = class {
145
327
  this.httpClient.setFrontendBaseUrl(frontendBaseUrl);
146
328
  }
147
329
  }
330
+ if (this.token && this.config.enableSocket !== false) {
331
+ this.connectSocket();
332
+ }
148
333
  }
149
334
  loadTokenFromStorage() {
150
335
  if (typeof window !== "undefined" && this.config.localStorageKey) {
@@ -177,6 +362,57 @@ var AuthService = class {
177
362
  }
178
363
  }
179
364
  }
365
+ // Socket connection management
366
+ connectSocket() {
367
+ if (this.token && this.config.enableSocket !== false && typeof window !== "undefined") {
368
+ this.socketService.connect(this.token);
369
+ }
370
+ }
371
+ disconnectSocket() {
372
+ this.socketService.disconnect();
373
+ }
374
+ // Socket event subscription
375
+ onUserUpdated(handler) {
376
+ return this.socketService.on("user:updated", (data) => {
377
+ if (data.user) {
378
+ this.cachedUser = data.user;
379
+ this.userCacheTimestamp = Date.now();
380
+ }
381
+ handler(data);
382
+ });
383
+ }
384
+ onSessionRevoked(handler) {
385
+ return this.socketService.on("session:revoked", handler);
386
+ }
387
+ onAllSessionsRevoked(handler) {
388
+ return this.socketService.on("session:all-revoked", handler);
389
+ }
390
+ onPasswordChanged(handler) {
391
+ return this.socketService.on("auth:password-changed", handler);
392
+ }
393
+ on2FAChanged(handler) {
394
+ return this.socketService.on("auth:2fa-changed", handler);
395
+ }
396
+ onSocketConnected(handler) {
397
+ return this.socketService.on("connected", handler);
398
+ }
399
+ onSocketDisconnected(handler) {
400
+ return this.socketService.on("disconnected", handler);
401
+ }
402
+ onSocketError(handler) {
403
+ return this.socketService.on("error", handler);
404
+ }
405
+ isSocketConnected() {
406
+ return this.socketService.isConnected();
407
+ }
408
+ // Cache management
409
+ clearUserCache() {
410
+ this.cachedUser = null;
411
+ this.userCacheTimestamp = 0;
412
+ }
413
+ isCacheValid() {
414
+ return this.cachedUser !== null && Date.now() - this.userCacheTimestamp < this.USER_CACHE_TTL;
415
+ }
180
416
  isAuthenticated() {
181
417
  return !!this.token;
182
418
  }
@@ -242,6 +478,11 @@ var AuthService = class {
242
478
  this.token = response.token;
243
479
  this.httpClient.setAuthToken(response.token);
244
480
  this.saveTokenToStorage(response.token);
481
+ if (response.user) {
482
+ this.cachedUser = response.user;
483
+ this.userCacheTimestamp = Date.now();
484
+ }
485
+ this.connectSocket();
245
486
  return response;
246
487
  }
247
488
  if (response.success && (response.message === "OTP sent to your email." || response.message === "OTP sent to your phone number.")) {
@@ -251,6 +492,11 @@ var AuthService = class {
251
492
  this.token = response.token;
252
493
  this.httpClient.setAuthToken(response.token);
253
494
  this.saveTokenToStorage(response.token);
495
+ if (response.user) {
496
+ this.cachedUser = response.user;
497
+ this.userCacheTimestamp = Date.now();
498
+ }
499
+ this.connectSocket();
254
500
  return response;
255
501
  }
256
502
  throw new Error(response.message || "Login failed");
@@ -294,21 +540,29 @@ var AuthService = class {
294
540
  }
295
541
  }
296
542
  async logout() {
543
+ this.disconnectSocket();
297
544
  try {
298
545
  await this.httpClient.post("/api/v1/auth/logout", {});
299
546
  } catch (error) {
300
547
  console.warn("Failed to call logout endpoint:", error);
301
548
  }
302
549
  this.token = null;
550
+ this.cachedUser = null;
551
+ this.userCacheTimestamp = 0;
303
552
  this.httpClient.removeAuthToken();
304
553
  this.httpClient.removeCsrfToken();
305
554
  this.removeTokenFromStorage();
306
555
  }
307
- async getProfile() {
556
+ async getProfile(forceRefresh = false) {
308
557
  if (!this.token) {
309
558
  throw new Error("Not authenticated");
310
559
  }
560
+ if (!forceRefresh && this.isCacheValid() && this.cachedUser) {
561
+ return this.cachedUser;
562
+ }
311
563
  const response = await this.httpClient.get("/api/v1/user/me");
564
+ this.cachedUser = response.user;
565
+ this.userCacheTimestamp = Date.now();
312
566
  return response.user;
313
567
  }
314
568
  async updateProfile(data) {
@@ -472,6 +726,16 @@ var AuthService = class {
472
726
  );
473
727
  return response;
474
728
  }
729
+ async adminCreateUser(data) {
730
+ if (!this.token) {
731
+ throw new Error("Not authenticated");
732
+ }
733
+ const response = await this.httpClient.post(
734
+ "/api/v1/admin/create-user",
735
+ data
736
+ );
737
+ return response;
738
+ }
475
739
  async adminVerifyUser(userId) {
476
740
  if (!this.token) {
477
741
  throw new Error("Not authenticated");
@@ -580,8 +844,141 @@ var AuthClient = class extends AuthService {
580
844
  }
581
845
  };
582
846
 
847
+ // src/node/token-verifier.ts
848
+ var TokenVerifier = class {
849
+ constructor(config) {
850
+ this.cache = /* @__PURE__ */ new Map();
851
+ this.cleanupInterval = null;
852
+ this.config = {
853
+ cacheTTL: 6e4,
854
+ // 1 minute default
855
+ cacheEnabled: true,
856
+ ...config
857
+ };
858
+ if (this.config.cacheEnabled) {
859
+ this.startCleanup();
860
+ }
861
+ }
862
+ /**
863
+ * Verify a JWT token and get user data
864
+ * Returns cached user if available and valid
865
+ */
866
+ async verifyToken(token) {
867
+ if (!token) {
868
+ return null;
869
+ }
870
+ if (this.config.cacheEnabled) {
871
+ const cached = this.getFromCache(token);
872
+ if (cached) {
873
+ return cached;
874
+ }
875
+ }
876
+ try {
877
+ const response = await fetch(`${this.config.authServiceUrl}/api/v1/user/me`, {
878
+ headers: {
879
+ "Authorization": `Bearer ${token}`,
880
+ "Content-Type": "application/json"
881
+ }
882
+ });
883
+ if (!response.ok) {
884
+ this.cache.delete(token);
885
+ return null;
886
+ }
887
+ const data = await response.json();
888
+ const user = data.user || null;
889
+ if (user && this.config.cacheEnabled) {
890
+ this.setCache(token, user);
891
+ }
892
+ return user;
893
+ } catch (error) {
894
+ console.error("[TokenVerifier] Auth service verification failed:", error);
895
+ return null;
896
+ }
897
+ }
898
+ /**
899
+ * Invalidate cache for a specific token
900
+ */
901
+ invalidateToken(token) {
902
+ this.cache.delete(token);
903
+ }
904
+ /**
905
+ * Clear all cached tokens
906
+ */
907
+ clearCache() {
908
+ this.cache.clear();
909
+ }
910
+ /**
911
+ * Get cache statistics
912
+ */
913
+ getCacheStats() {
914
+ return {
915
+ size: this.cache.size,
916
+ enabled: this.config.cacheEnabled,
917
+ ttl: this.config.cacheTTL
918
+ };
919
+ }
920
+ /**
921
+ * Stop the cleanup interval (call when shutting down)
922
+ */
923
+ destroy() {
924
+ if (this.cleanupInterval) {
925
+ clearInterval(this.cleanupInterval);
926
+ this.cleanupInterval = null;
927
+ }
928
+ this.cache.clear();
929
+ }
930
+ getFromCache(token) {
931
+ const entry = this.cache.get(token);
932
+ if (!entry) {
933
+ return null;
934
+ }
935
+ if (Date.now() > entry.expiresAt) {
936
+ this.cache.delete(token);
937
+ return null;
938
+ }
939
+ return entry.user;
940
+ }
941
+ setCache(token, user) {
942
+ this.cache.set(token, {
943
+ user,
944
+ expiresAt: Date.now() + this.config.cacheTTL
945
+ });
946
+ }
947
+ startCleanup() {
948
+ this.cleanupInterval = setInterval(() => {
949
+ const now = Date.now();
950
+ for (const [token, entry] of this.cache.entries()) {
951
+ if (now > entry.expiresAt) {
952
+ this.cache.delete(token);
953
+ }
954
+ }
955
+ }, 6e4);
956
+ if (this.cleanupInterval && this.cleanupInterval.unref) {
957
+ this.cleanupInterval.unref();
958
+ }
959
+ }
960
+ };
961
+ var defaultVerifier = null;
962
+ function createTokenVerifier(config) {
963
+ defaultVerifier = new TokenVerifier(config);
964
+ return defaultVerifier;
965
+ }
966
+ function getTokenVerifier() {
967
+ if (!defaultVerifier) {
968
+ throw new Error("TokenVerifier not initialized. Call createTokenVerifier() first.");
969
+ }
970
+ return defaultVerifier;
971
+ }
972
+ async function verifyToken(token) {
973
+ return getTokenVerifier().verifyToken(token);
974
+ }
975
+
583
976
  exports.AuthClient = AuthClient;
584
977
  exports.AuthService = AuthService;
585
978
  exports.HttpClient = HttpClient;
979
+ exports.TokenVerifier = TokenVerifier;
980
+ exports.createTokenVerifier = createTokenVerifier;
981
+ exports.getTokenVerifier = getTokenVerifier;
982
+ exports.verifyToken = verifyToken;
586
983
  //# sourceMappingURL=index.node.js.map
587
984
  //# sourceMappingURL=index.node.js.map