@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
package/dist/index.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
  import axios from 'axios';
3
+ import { io } from 'socket.io-client';
3
4
  import { UpfilesClient, ImageManager } from '@thetechfossil/upfiles';
4
5
  export { ConnectProjectDialog, ImageManager, ProjectFilesWidget, UpfilesClient, Uploader } from '@thetechfossil/upfiles';
5
- import React, { createContext, forwardRef, useContext, useState, useCallback, useEffect, useRef, useMemo } from 'react';
6
+ import React, { createContext, forwardRef, useContext, useState, useEffect, useCallback, useRef, useMemo } from 'react';
6
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
8
 
8
9
  var __defProp = Object.defineProperty;
@@ -16,6 +17,16 @@ var __export = (target, all) => {
16
17
  for (var name in all)
17
18
  __defProp(target, name, { get: all[name], enumerable: true });
18
19
  };
20
+ var ERROR_MESSAGES = {
21
+ NETWORK_ERROR: "Unable to connect to the server. Please check your internet connection and try again.",
22
+ TIMEOUT: "The request took too long. Please try again.",
23
+ SERVER_ERROR: "Something went wrong on our end. Please try again later.",
24
+ UNAUTHORIZED: "Your session has expired. Please log in again.",
25
+ FORBIDDEN: "You do not have permission to perform this action.",
26
+ NOT_FOUND: "The requested resource was not found.",
27
+ RATE_LIMITED: "Too many requests. Please wait a moment and try again.",
28
+ UNKNOWN: "An unexpected error occurred. Please try again."
29
+ };
19
30
  var HttpClient = class {
20
31
  constructor(baseUrl, defaultHeaders = {}) {
21
32
  this.csrfToken = null;
@@ -50,7 +61,7 @@ var HttpClient = class {
50
61
  }
51
62
  return config;
52
63
  },
53
- (error) => Promise.reject(error)
64
+ (error) => Promise.reject(this.createUserFriendlyError(error))
54
65
  );
55
66
  this.axiosInstance.interceptors.response.use(
56
67
  (response) => response,
@@ -65,18 +76,71 @@ var HttpClient = class {
65
76
  }
66
77
  return this.axiosInstance(originalRequest);
67
78
  } catch (refreshError) {
68
- return Promise.reject(refreshError);
79
+ return Promise.reject(this.createUserFriendlyError(refreshError));
69
80
  }
70
81
  }
71
- if (error.response && error.response.data && error.response.data.message) {
72
- const customError = new Error(error.response.data.message);
73
- customError.response = error.response;
74
- return Promise.reject(customError);
75
- }
76
- return Promise.reject(error);
82
+ return Promise.reject(this.createUserFriendlyError(error));
77
83
  }
78
84
  );
79
85
  }
86
+ /**
87
+ * Creates a user-friendly error message from an Axios error
88
+ */
89
+ createUserFriendlyError(error) {
90
+ if (error instanceof Error && !error.isAxiosError) {
91
+ return error;
92
+ }
93
+ let message;
94
+ let statusCode;
95
+ if (axios.isAxiosError(error)) {
96
+ statusCode = error.response?.status;
97
+ const responseData = error.response?.data;
98
+ if (responseData?.message) {
99
+ message = responseData.message;
100
+ } else if (!error.response) {
101
+ if (error.code === "ECONNABORTED" || error.message.includes("timeout")) {
102
+ message = ERROR_MESSAGES.TIMEOUT;
103
+ } else if (error.code === "ERR_NETWORK" || error.message === "Network Error") {
104
+ message = ERROR_MESSAGES.NETWORK_ERROR;
105
+ } else {
106
+ message = ERROR_MESSAGES.NETWORK_ERROR;
107
+ }
108
+ } else {
109
+ switch (statusCode) {
110
+ case 400:
111
+ message = responseData?.message || "Invalid request. Please check your input.";
112
+ break;
113
+ case 401:
114
+ message = responseData?.message || ERROR_MESSAGES.UNAUTHORIZED;
115
+ break;
116
+ case 403:
117
+ message = responseData?.message || ERROR_MESSAGES.FORBIDDEN;
118
+ break;
119
+ case 404:
120
+ message = responseData?.message || ERROR_MESSAGES.NOT_FOUND;
121
+ break;
122
+ case 429:
123
+ message = ERROR_MESSAGES.RATE_LIMITED;
124
+ break;
125
+ case 500:
126
+ case 502:
127
+ case 503:
128
+ case 504:
129
+ message = ERROR_MESSAGES.SERVER_ERROR;
130
+ break;
131
+ default:
132
+ message = responseData?.message || ERROR_MESSAGES.UNKNOWN;
133
+ }
134
+ }
135
+ } else {
136
+ message = error?.message || ERROR_MESSAGES.UNKNOWN;
137
+ }
138
+ const customError = new Error(message);
139
+ customError.response = error?.response;
140
+ customError.statusCode = statusCode;
141
+ customError.originalError = error;
142
+ return customError;
143
+ }
80
144
  async get(endpoint, headers) {
81
145
  const response = await this.axiosInstance.get(endpoint, { headers });
82
146
  return response.data;
@@ -127,16 +191,134 @@ var HttpClient = class {
127
191
  }
128
192
  }
129
193
  };
194
+ var SocketService = class {
195
+ constructor(config) {
196
+ this.socket = null;
197
+ this.token = null;
198
+ this.eventHandlers = /* @__PURE__ */ new Map();
199
+ this.isConnecting = false;
200
+ this.config = {
201
+ autoConnect: false,
202
+ reconnection: true,
203
+ reconnectionAttempts: 5,
204
+ reconnectionDelay: 1e3,
205
+ ...config
206
+ };
207
+ }
208
+ connect(token) {
209
+ if (this.socket?.connected || this.isConnecting) {
210
+ return;
211
+ }
212
+ this.token = token;
213
+ this.isConnecting = true;
214
+ this.socket = io(this.config.baseUrl, {
215
+ auth: { token },
216
+ autoConnect: true,
217
+ reconnection: this.config.reconnection,
218
+ reconnectionAttempts: this.config.reconnectionAttempts,
219
+ reconnectionDelay: this.config.reconnectionDelay,
220
+ transports: ["websocket", "polling"]
221
+ });
222
+ this.setupEventListeners();
223
+ }
224
+ setupEventListeners() {
225
+ if (!this.socket) return;
226
+ this.socket.on("connect", () => {
227
+ this.isConnecting = false;
228
+ console.log("[Auth SDK] Socket connected");
229
+ this.emit("connected", {});
230
+ });
231
+ this.socket.on("disconnect", (reason) => {
232
+ console.log("[Auth SDK] Socket disconnected:", reason);
233
+ this.emit("disconnected", { reason });
234
+ });
235
+ this.socket.on("connect_error", (error) => {
236
+ this.isConnecting = false;
237
+ console.error("[Auth SDK] Socket connection error:", error.message);
238
+ this.emit("error", { error: error.message });
239
+ });
240
+ this.socket.on("user:updated", (data) => {
241
+ this.emit("user:updated", data);
242
+ });
243
+ this.socket.on("session:revoked", (data) => {
244
+ this.emit("session:revoked", data);
245
+ });
246
+ this.socket.on("session:all-revoked", () => {
247
+ this.emit("session:all-revoked", {});
248
+ });
249
+ this.socket.on("auth:password-changed", () => {
250
+ this.emit("auth:password-changed", {});
251
+ });
252
+ this.socket.on("auth:2fa-changed", (data) => {
253
+ this.emit("auth:2fa-changed", data);
254
+ });
255
+ this.socket.on("user:refresh", () => {
256
+ this.emit("user:refresh", {});
257
+ });
258
+ }
259
+ disconnect() {
260
+ if (this.socket) {
261
+ this.socket.disconnect();
262
+ this.socket = null;
263
+ this.token = null;
264
+ this.isConnecting = false;
265
+ }
266
+ }
267
+ isConnected() {
268
+ return this.socket?.connected ?? false;
269
+ }
270
+ // Event subscription
271
+ on(event, handler) {
272
+ if (!this.eventHandlers.has(event)) {
273
+ this.eventHandlers.set(event, /* @__PURE__ */ new Set());
274
+ }
275
+ this.eventHandlers.get(event).add(handler);
276
+ return () => {
277
+ this.eventHandlers.get(event)?.delete(handler);
278
+ };
279
+ }
280
+ off(event, handler) {
281
+ if (handler) {
282
+ this.eventHandlers.get(event)?.delete(handler);
283
+ } else {
284
+ this.eventHandlers.delete(event);
285
+ }
286
+ }
287
+ emit(event, data) {
288
+ const handlers = this.eventHandlers.get(event);
289
+ if (handlers) {
290
+ handlers.forEach((handler) => {
291
+ try {
292
+ handler(data);
293
+ } catch (error) {
294
+ console.error(`[Auth SDK] Error in event handler for ${event}:`, error);
295
+ }
296
+ });
297
+ }
298
+ }
299
+ // Request fresh user data from server
300
+ requestUserRefresh() {
301
+ if (this.socket?.connected) {
302
+ this.socket.emit("request:user");
303
+ }
304
+ }
305
+ };
130
306
  var AuthService = class {
307
+ // 5 minutes cache
131
308
  constructor(config) {
132
309
  this.token = null;
133
310
  this.upfilesClient = null;
311
+ this.cachedUser = null;
312
+ this.userCacheTimestamp = 0;
313
+ this.USER_CACHE_TTL = 5 * 60 * 1e3;
134
314
  this.config = {
135
315
  localStorageKey: "auth_token",
136
316
  csrfEnabled: true,
317
+ enableSocket: true,
137
318
  ...config
138
319
  };
139
320
  this.httpClient = new HttpClient(this.config.baseUrl);
321
+ this.socketService = new SocketService({ baseUrl: this.config.baseUrl });
140
322
  this.loadTokenFromStorage();
141
323
  if (this.config.upfilesConfig) {
142
324
  this.upfilesClient = new UpfilesClient({
@@ -153,6 +335,9 @@ var AuthService = class {
153
335
  this.httpClient.setFrontendBaseUrl(frontendBaseUrl);
154
336
  }
155
337
  }
338
+ if (this.token && this.config.enableSocket !== false) {
339
+ this.connectSocket();
340
+ }
156
341
  }
157
342
  loadTokenFromStorage() {
158
343
  if (typeof window !== "undefined" && this.config.localStorageKey) {
@@ -185,6 +370,57 @@ var AuthService = class {
185
370
  }
186
371
  }
187
372
  }
373
+ // Socket connection management
374
+ connectSocket() {
375
+ if (this.token && this.config.enableSocket !== false && typeof window !== "undefined") {
376
+ this.socketService.connect(this.token);
377
+ }
378
+ }
379
+ disconnectSocket() {
380
+ this.socketService.disconnect();
381
+ }
382
+ // Socket event subscription
383
+ onUserUpdated(handler) {
384
+ return this.socketService.on("user:updated", (data) => {
385
+ if (data.user) {
386
+ this.cachedUser = data.user;
387
+ this.userCacheTimestamp = Date.now();
388
+ }
389
+ handler(data);
390
+ });
391
+ }
392
+ onSessionRevoked(handler) {
393
+ return this.socketService.on("session:revoked", handler);
394
+ }
395
+ onAllSessionsRevoked(handler) {
396
+ return this.socketService.on("session:all-revoked", handler);
397
+ }
398
+ onPasswordChanged(handler) {
399
+ return this.socketService.on("auth:password-changed", handler);
400
+ }
401
+ on2FAChanged(handler) {
402
+ return this.socketService.on("auth:2fa-changed", handler);
403
+ }
404
+ onSocketConnected(handler) {
405
+ return this.socketService.on("connected", handler);
406
+ }
407
+ onSocketDisconnected(handler) {
408
+ return this.socketService.on("disconnected", handler);
409
+ }
410
+ onSocketError(handler) {
411
+ return this.socketService.on("error", handler);
412
+ }
413
+ isSocketConnected() {
414
+ return this.socketService.isConnected();
415
+ }
416
+ // Cache management
417
+ clearUserCache() {
418
+ this.cachedUser = null;
419
+ this.userCacheTimestamp = 0;
420
+ }
421
+ isCacheValid() {
422
+ return this.cachedUser !== null && Date.now() - this.userCacheTimestamp < this.USER_CACHE_TTL;
423
+ }
188
424
  isAuthenticated() {
189
425
  return !!this.token;
190
426
  }
@@ -250,6 +486,11 @@ var AuthService = class {
250
486
  this.token = response.token;
251
487
  this.httpClient.setAuthToken(response.token);
252
488
  this.saveTokenToStorage(response.token);
489
+ if (response.user) {
490
+ this.cachedUser = response.user;
491
+ this.userCacheTimestamp = Date.now();
492
+ }
493
+ this.connectSocket();
253
494
  return response;
254
495
  }
255
496
  if (response.success && (response.message === "OTP sent to your email." || response.message === "OTP sent to your phone number.")) {
@@ -259,6 +500,11 @@ var AuthService = class {
259
500
  this.token = response.token;
260
501
  this.httpClient.setAuthToken(response.token);
261
502
  this.saveTokenToStorage(response.token);
503
+ if (response.user) {
504
+ this.cachedUser = response.user;
505
+ this.userCacheTimestamp = Date.now();
506
+ }
507
+ this.connectSocket();
262
508
  return response;
263
509
  }
264
510
  throw new Error(response.message || "Login failed");
@@ -302,21 +548,29 @@ var AuthService = class {
302
548
  }
303
549
  }
304
550
  async logout() {
551
+ this.disconnectSocket();
305
552
  try {
306
553
  await this.httpClient.post("/api/v1/auth/logout", {});
307
554
  } catch (error) {
308
555
  console.warn("Failed to call logout endpoint:", error);
309
556
  }
310
557
  this.token = null;
558
+ this.cachedUser = null;
559
+ this.userCacheTimestamp = 0;
311
560
  this.httpClient.removeAuthToken();
312
561
  this.httpClient.removeCsrfToken();
313
562
  this.removeTokenFromStorage();
314
563
  }
315
- async getProfile() {
564
+ async getProfile(forceRefresh = false) {
316
565
  if (!this.token) {
317
566
  throw new Error("Not authenticated");
318
567
  }
568
+ if (!forceRefresh && this.isCacheValid() && this.cachedUser) {
569
+ return this.cachedUser;
570
+ }
319
571
  const response = await this.httpClient.get("/api/v1/user/me");
572
+ this.cachedUser = response.user;
573
+ this.userCacheTimestamp = Date.now();
320
574
  return response.user;
321
575
  }
322
576
  async updateProfile(data) {
@@ -480,6 +734,16 @@ var AuthService = class {
480
734
  );
481
735
  return response;
482
736
  }
737
+ async adminCreateUser(data) {
738
+ if (!this.token) {
739
+ throw new Error("Not authenticated");
740
+ }
741
+ const response = await this.httpClient.post(
742
+ "/api/v1/admin/create-user",
743
+ data
744
+ );
745
+ return response;
746
+ }
483
747
  async adminVerifyUser(userId) {
484
748
  if (!this.token) {
485
749
  throw new Error("Not authenticated");
@@ -572,21 +836,49 @@ var AuthProvider = ({ children, config }) => {
572
836
  const [user, setUser] = useState(null);
573
837
  const [isLoaded, setIsLoaded] = useState(false);
574
838
  const [loading, setLoading] = useState(false);
575
- const checkAuthStatus = useCallback(async () => {
839
+ const [isSocketConnected, setIsSocketConnected] = useState(false);
840
+ useEffect(() => {
841
+ const unsubUserUpdated = authService.onUserUpdated(({ user: updatedUser }) => {
842
+ if (updatedUser) {
843
+ setUser(updatedUser);
844
+ }
845
+ });
846
+ const unsubSessionRevoked = authService.onSessionRevoked(() => {
847
+ authService.logout().then(() => {
848
+ setUser(null);
849
+ });
850
+ });
851
+ const unsubAllSessionsRevoked = authService.onAllSessionsRevoked(() => {
852
+ authService.logout().then(() => {
853
+ setUser(null);
854
+ });
855
+ });
856
+ const unsubPasswordChanged = authService.onPasswordChanged(() => {
857
+ authService.logout().then(() => {
858
+ setUser(null);
859
+ });
860
+ });
861
+ const unsubConnected = authService.onSocketConnected(() => {
862
+ setIsSocketConnected(true);
863
+ });
864
+ const unsubDisconnected = authService.onSocketDisconnected(() => {
865
+ setIsSocketConnected(false);
866
+ });
867
+ return () => {
868
+ unsubUserUpdated();
869
+ unsubSessionRevoked();
870
+ unsubAllSessionsRevoked();
871
+ unsubPasswordChanged();
872
+ unsubConnected();
873
+ unsubDisconnected();
874
+ };
875
+ }, [authService]);
876
+ useEffect(() => {
576
877
  const authenticated = authService.isAuthenticated();
577
878
  if (authenticated) {
578
- try {
579
- const freshUser = await authService.getProfile();
580
- setUser(freshUser);
581
- } catch (error) {
582
- console.error("Failed to fetch fresh user profile, falling back to token:", error);
583
- try {
584
- const currentUser = authService.getCurrentUser();
585
- setUser(currentUser);
586
- } catch (fallbackError) {
587
- console.error("Failed to get current user from token:", fallbackError);
588
- setUser(null);
589
- }
879
+ const currentUser = authService.getCurrentUser();
880
+ if (currentUser) {
881
+ setUser(currentUser);
590
882
  }
591
883
  } else {
592
884
  setUser(null);
@@ -594,8 +886,21 @@ var AuthProvider = ({ children, config }) => {
594
886
  setIsLoaded(true);
595
887
  }, [authService]);
596
888
  useEffect(() => {
597
- checkAuthStatus();
598
- }, [checkAuthStatus]);
889
+ if (!isLoaded) return;
890
+ const authenticated = authService.isAuthenticated();
891
+ if (!authenticated) return;
892
+ const fetchFreshUser = async () => {
893
+ try {
894
+ const freshUser = await authService.getProfile();
895
+ setUser(freshUser);
896
+ } catch (error) {
897
+ console.warn("[Auth SDK] Failed to fetch fresh user profile:", error);
898
+ }
899
+ };
900
+ if (isSocketConnected) {
901
+ fetchFreshUser();
902
+ }
903
+ }, [authService, isLoaded, isSocketConnected]);
599
904
  const signIn = useCallback(async (data) => {
600
905
  setLoading(true);
601
906
  try {
@@ -817,6 +1122,7 @@ var AuthProvider = ({ children, config }) => {
817
1122
  isLoaded,
818
1123
  isSignedIn: !!user,
819
1124
  loading,
1125
+ isSocketConnected,
820
1126
  signIn,
821
1127
  signUp,
822
1128
  signOut,
@@ -3701,15 +4007,15 @@ var VerifyEmail = ({ token, onSuccess, onError }) => {
3701
4007
  const [message, setMessage] = useState("");
3702
4008
  useEffect(() => {
3703
4009
  const verify = async () => {
3704
- const verifyToken = token || (typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("token") : null);
3705
- if (!verifyToken) {
4010
+ const verifyToken2 = token || (typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("token") : null);
4011
+ if (!verifyToken2) {
3706
4012
  setStatus("error");
3707
4013
  setMessage("No verification token provided");
3708
4014
  onError?.("No verification token provided");
3709
4015
  return;
3710
4016
  }
3711
4017
  try {
3712
- const response = await verifyEmailToken(verifyToken);
4018
+ const response = await verifyEmailToken(verifyToken2);
3713
4019
  if (response.success) {
3714
4020
  setStatus("success");
3715
4021
  setMessage("Email verified successfully! Redirecting...");
@@ -4468,11 +4774,11 @@ var ChangePassword = ({ onSuccess, appearance }) => {
4468
4774
 
4469
4775
  // src/react/components/utils/injectModalStyles.ts
4470
4776
  var injectModalStyles = () => {
4471
- if (document.getElementById("ttf-auth-modal-styles")) {
4777
+ if (document.getElementById("ktw-auth-modal-styles")) {
4472
4778
  return;
4473
4779
  }
4474
4780
  const styleElement = document.createElement("style");
4475
- styleElement.id = "ttf-auth-modal-styles";
4781
+ styleElement.id = "ktw-auth-modal-styles";
4476
4782
  styleElement.textContent = `
4477
4783
  /* ImageManager Modal Styles - Critical for proper modal display */
4478
4784
  /* Radix UI Dialog styles - Force visibility */
@@ -5010,7 +5316,11 @@ __export(react_exports, {
5010
5316
  // src/node/index.ts
5011
5317
  var node_exports = {};
5012
5318
  __export(node_exports, {
5013
- AuthClient: () => AuthClient
5319
+ AuthClient: () => AuthClient,
5320
+ TokenVerifier: () => TokenVerifier,
5321
+ createTokenVerifier: () => createTokenVerifier,
5322
+ getTokenVerifier: () => getTokenVerifier,
5323
+ verifyToken: () => verifyToken
5014
5324
  });
5015
5325
 
5016
5326
  // src/node/auth-client.ts
@@ -5091,6 +5401,135 @@ var AuthClient = class extends AuthService {
5091
5401
  }
5092
5402
  };
5093
5403
 
5094
- export { AuthFlow, AuthProvider, AuthService, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, UserButton, UserProfile, VerifyEmail, node_exports as node, react_exports as react, useAuth };
5404
+ // src/node/token-verifier.ts
5405
+ var TokenVerifier = class {
5406
+ constructor(config) {
5407
+ this.cache = /* @__PURE__ */ new Map();
5408
+ this.cleanupInterval = null;
5409
+ this.config = {
5410
+ cacheTTL: 6e4,
5411
+ // 1 minute default
5412
+ cacheEnabled: true,
5413
+ ...config
5414
+ };
5415
+ if (this.config.cacheEnabled) {
5416
+ this.startCleanup();
5417
+ }
5418
+ }
5419
+ /**
5420
+ * Verify a JWT token and get user data
5421
+ * Returns cached user if available and valid
5422
+ */
5423
+ async verifyToken(token) {
5424
+ if (!token) {
5425
+ return null;
5426
+ }
5427
+ if (this.config.cacheEnabled) {
5428
+ const cached = this.getFromCache(token);
5429
+ if (cached) {
5430
+ return cached;
5431
+ }
5432
+ }
5433
+ try {
5434
+ const response = await fetch(`${this.config.authServiceUrl}/api/v1/user/me`, {
5435
+ headers: {
5436
+ "Authorization": `Bearer ${token}`,
5437
+ "Content-Type": "application/json"
5438
+ }
5439
+ });
5440
+ if (!response.ok) {
5441
+ this.cache.delete(token);
5442
+ return null;
5443
+ }
5444
+ const data = await response.json();
5445
+ const user = data.user || null;
5446
+ if (user && this.config.cacheEnabled) {
5447
+ this.setCache(token, user);
5448
+ }
5449
+ return user;
5450
+ } catch (error) {
5451
+ console.error("[TokenVerifier] Auth service verification failed:", error);
5452
+ return null;
5453
+ }
5454
+ }
5455
+ /**
5456
+ * Invalidate cache for a specific token
5457
+ */
5458
+ invalidateToken(token) {
5459
+ this.cache.delete(token);
5460
+ }
5461
+ /**
5462
+ * Clear all cached tokens
5463
+ */
5464
+ clearCache() {
5465
+ this.cache.clear();
5466
+ }
5467
+ /**
5468
+ * Get cache statistics
5469
+ */
5470
+ getCacheStats() {
5471
+ return {
5472
+ size: this.cache.size,
5473
+ enabled: this.config.cacheEnabled,
5474
+ ttl: this.config.cacheTTL
5475
+ };
5476
+ }
5477
+ /**
5478
+ * Stop the cleanup interval (call when shutting down)
5479
+ */
5480
+ destroy() {
5481
+ if (this.cleanupInterval) {
5482
+ clearInterval(this.cleanupInterval);
5483
+ this.cleanupInterval = null;
5484
+ }
5485
+ this.cache.clear();
5486
+ }
5487
+ getFromCache(token) {
5488
+ const entry = this.cache.get(token);
5489
+ if (!entry) {
5490
+ return null;
5491
+ }
5492
+ if (Date.now() > entry.expiresAt) {
5493
+ this.cache.delete(token);
5494
+ return null;
5495
+ }
5496
+ return entry.user;
5497
+ }
5498
+ setCache(token, user) {
5499
+ this.cache.set(token, {
5500
+ user,
5501
+ expiresAt: Date.now() + this.config.cacheTTL
5502
+ });
5503
+ }
5504
+ startCleanup() {
5505
+ this.cleanupInterval = setInterval(() => {
5506
+ const now = Date.now();
5507
+ for (const [token, entry] of this.cache.entries()) {
5508
+ if (now > entry.expiresAt) {
5509
+ this.cache.delete(token);
5510
+ }
5511
+ }
5512
+ }, 6e4);
5513
+ if (this.cleanupInterval && this.cleanupInterval.unref) {
5514
+ this.cleanupInterval.unref();
5515
+ }
5516
+ }
5517
+ };
5518
+ var defaultVerifier = null;
5519
+ function createTokenVerifier(config) {
5520
+ defaultVerifier = new TokenVerifier(config);
5521
+ return defaultVerifier;
5522
+ }
5523
+ function getTokenVerifier() {
5524
+ if (!defaultVerifier) {
5525
+ throw new Error("TokenVerifier not initialized. Call createTokenVerifier() first.");
5526
+ }
5527
+ return defaultVerifier;
5528
+ }
5529
+ async function verifyToken(token) {
5530
+ return getTokenVerifier().verifyToken(token);
5531
+ }
5532
+
5533
+ export { AuthFlow, AuthProvider, AuthService, AvatarManager, AvatarUploader, ChangePassword, EmailVerificationPage, ForgotPassword, HttpClient, LoginForm, OtpForm, ProtectedRoute, PublicRoute, RegisterForm, ResetPassword, SignIn, SignOut, SignUp, SocketService, UserButton, UserProfile, VerifyEmail, node_exports as node, react_exports as react, useAuth };
5095
5534
  //# sourceMappingURL=index.mjs.map
5096
5535
  //# sourceMappingURL=index.mjs.map