@thetechfossil/auth2 1.2.19 → 1.2.20
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 +1 -1
- package/dist/index.components.d.mts +1 -0
- package/dist/index.components.d.ts +1 -0
- package/dist/index.components.js +204 -3
- package/dist/index.components.js.map +1 -1
- package/dist/index.components.mjs +204 -3
- package/dist/index.components.mjs.map +1 -1
- package/dist/index.d.mts +110 -3
- package/dist/index.d.ts +110 -3
- package/dist/index.js +399 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -24
- package/dist/index.mjs.map +1 -1
- package/dist/index.next.d.mts +53 -1
- package/dist/index.next.d.ts +53 -1
- package/dist/index.next.js +261 -18
- package/dist/index.next.js.map +1 -1
- package/dist/index.next.mjs +261 -18
- package/dist/index.next.mjs.map +1 -1
- package/dist/index.next.server.d.mts +80 -2
- package/dist/index.next.server.d.ts +80 -2
- package/dist/index.next.server.js +335 -1
- package/dist/index.next.server.js.map +1 -1
- package/dist/index.next.server.mjs +332 -2
- package/dist/index.next.server.mjs.map +1 -1
- package/dist/index.node.d.mts +80 -2
- package/dist/index.node.d.ts +80 -2
- package/dist/index.node.js +335 -1
- package/dist/index.node.js.map +1 -1
- package/dist/index.node.mjs +332 -2
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.react-native.d.mts +227 -0
- package/dist/index.react-native.d.ts +227 -0
- package/dist/index.react-native.js +1684 -0
- package/dist/index.react-native.js.map +1 -0
- package/dist/index.react-native.mjs +1648 -0
- package/dist/index.react-native.mjs.map +1 -0
- package/package.json +119 -102
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var axios = require('axios');
|
|
5
|
+
var socket_ioClient = require('socket.io-client');
|
|
5
6
|
var upfiles = require('@thetechfossil/upfiles');
|
|
6
7
|
var React = require('react');
|
|
7
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -133,16 +134,134 @@ var HttpClient = class {
|
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
};
|
|
137
|
+
var SocketService = class {
|
|
138
|
+
constructor(config) {
|
|
139
|
+
this.socket = null;
|
|
140
|
+
this.token = null;
|
|
141
|
+
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
142
|
+
this.isConnecting = false;
|
|
143
|
+
this.config = {
|
|
144
|
+
autoConnect: false,
|
|
145
|
+
reconnection: true,
|
|
146
|
+
reconnectionAttempts: 5,
|
|
147
|
+
reconnectionDelay: 1e3,
|
|
148
|
+
...config
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
connect(token) {
|
|
152
|
+
if (this.socket?.connected || this.isConnecting) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.token = token;
|
|
156
|
+
this.isConnecting = true;
|
|
157
|
+
this.socket = socket_ioClient.io(this.config.baseUrl, {
|
|
158
|
+
auth: { token },
|
|
159
|
+
autoConnect: true,
|
|
160
|
+
reconnection: this.config.reconnection,
|
|
161
|
+
reconnectionAttempts: this.config.reconnectionAttempts,
|
|
162
|
+
reconnectionDelay: this.config.reconnectionDelay,
|
|
163
|
+
transports: ["websocket", "polling"]
|
|
164
|
+
});
|
|
165
|
+
this.setupEventListeners();
|
|
166
|
+
}
|
|
167
|
+
setupEventListeners() {
|
|
168
|
+
if (!this.socket) return;
|
|
169
|
+
this.socket.on("connect", () => {
|
|
170
|
+
this.isConnecting = false;
|
|
171
|
+
console.log("[Auth SDK] Socket connected");
|
|
172
|
+
this.emit("connected", {});
|
|
173
|
+
});
|
|
174
|
+
this.socket.on("disconnect", (reason) => {
|
|
175
|
+
console.log("[Auth SDK] Socket disconnected:", reason);
|
|
176
|
+
this.emit("disconnected", { reason });
|
|
177
|
+
});
|
|
178
|
+
this.socket.on("connect_error", (error) => {
|
|
179
|
+
this.isConnecting = false;
|
|
180
|
+
console.error("[Auth SDK] Socket connection error:", error.message);
|
|
181
|
+
this.emit("error", { error: error.message });
|
|
182
|
+
});
|
|
183
|
+
this.socket.on("user:updated", (data) => {
|
|
184
|
+
this.emit("user:updated", data);
|
|
185
|
+
});
|
|
186
|
+
this.socket.on("session:revoked", (data) => {
|
|
187
|
+
this.emit("session:revoked", data);
|
|
188
|
+
});
|
|
189
|
+
this.socket.on("session:all-revoked", () => {
|
|
190
|
+
this.emit("session:all-revoked", {});
|
|
191
|
+
});
|
|
192
|
+
this.socket.on("auth:password-changed", () => {
|
|
193
|
+
this.emit("auth:password-changed", {});
|
|
194
|
+
});
|
|
195
|
+
this.socket.on("auth:2fa-changed", (data) => {
|
|
196
|
+
this.emit("auth:2fa-changed", data);
|
|
197
|
+
});
|
|
198
|
+
this.socket.on("user:refresh", () => {
|
|
199
|
+
this.emit("user:refresh", {});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
disconnect() {
|
|
203
|
+
if (this.socket) {
|
|
204
|
+
this.socket.disconnect();
|
|
205
|
+
this.socket = null;
|
|
206
|
+
this.token = null;
|
|
207
|
+
this.isConnecting = false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
isConnected() {
|
|
211
|
+
return this.socket?.connected ?? false;
|
|
212
|
+
}
|
|
213
|
+
// Event subscription
|
|
214
|
+
on(event, handler) {
|
|
215
|
+
if (!this.eventHandlers.has(event)) {
|
|
216
|
+
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
217
|
+
}
|
|
218
|
+
this.eventHandlers.get(event).add(handler);
|
|
219
|
+
return () => {
|
|
220
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
off(event, handler) {
|
|
224
|
+
if (handler) {
|
|
225
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
226
|
+
} else {
|
|
227
|
+
this.eventHandlers.delete(event);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
emit(event, data) {
|
|
231
|
+
const handlers = this.eventHandlers.get(event);
|
|
232
|
+
if (handlers) {
|
|
233
|
+
handlers.forEach((handler) => {
|
|
234
|
+
try {
|
|
235
|
+
handler(data);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error(`[Auth SDK] Error in event handler for ${event}:`, error);
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Request fresh user data from server
|
|
243
|
+
requestUserRefresh() {
|
|
244
|
+
if (this.socket?.connected) {
|
|
245
|
+
this.socket.emit("request:user");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
};
|
|
136
249
|
var AuthService = class {
|
|
250
|
+
// 5 minutes cache
|
|
137
251
|
constructor(config) {
|
|
138
252
|
this.token = null;
|
|
139
253
|
this.upfilesClient = null;
|
|
254
|
+
this.cachedUser = null;
|
|
255
|
+
this.userCacheTimestamp = 0;
|
|
256
|
+
this.USER_CACHE_TTL = 5 * 60 * 1e3;
|
|
140
257
|
this.config = {
|
|
141
258
|
localStorageKey: "auth_token",
|
|
142
259
|
csrfEnabled: true,
|
|
260
|
+
enableSocket: true,
|
|
143
261
|
...config
|
|
144
262
|
};
|
|
145
263
|
this.httpClient = new HttpClient(this.config.baseUrl);
|
|
264
|
+
this.socketService = new SocketService({ baseUrl: this.config.baseUrl });
|
|
146
265
|
this.loadTokenFromStorage();
|
|
147
266
|
if (this.config.upfilesConfig) {
|
|
148
267
|
this.upfilesClient = new upfiles.UpfilesClient({
|
|
@@ -159,6 +278,9 @@ var AuthService = class {
|
|
|
159
278
|
this.httpClient.setFrontendBaseUrl(frontendBaseUrl);
|
|
160
279
|
}
|
|
161
280
|
}
|
|
281
|
+
if (this.token && this.config.enableSocket !== false) {
|
|
282
|
+
this.connectSocket();
|
|
283
|
+
}
|
|
162
284
|
}
|
|
163
285
|
loadTokenFromStorage() {
|
|
164
286
|
if (typeof window !== "undefined" && this.config.localStorageKey) {
|
|
@@ -191,6 +313,57 @@ var AuthService = class {
|
|
|
191
313
|
}
|
|
192
314
|
}
|
|
193
315
|
}
|
|
316
|
+
// Socket connection management
|
|
317
|
+
connectSocket() {
|
|
318
|
+
if (this.token && this.config.enableSocket !== false && typeof window !== "undefined") {
|
|
319
|
+
this.socketService.connect(this.token);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
disconnectSocket() {
|
|
323
|
+
this.socketService.disconnect();
|
|
324
|
+
}
|
|
325
|
+
// Socket event subscription
|
|
326
|
+
onUserUpdated(handler) {
|
|
327
|
+
return this.socketService.on("user:updated", (data) => {
|
|
328
|
+
if (data.user) {
|
|
329
|
+
this.cachedUser = data.user;
|
|
330
|
+
this.userCacheTimestamp = Date.now();
|
|
331
|
+
}
|
|
332
|
+
handler(data);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
onSessionRevoked(handler) {
|
|
336
|
+
return this.socketService.on("session:revoked", handler);
|
|
337
|
+
}
|
|
338
|
+
onAllSessionsRevoked(handler) {
|
|
339
|
+
return this.socketService.on("session:all-revoked", handler);
|
|
340
|
+
}
|
|
341
|
+
onPasswordChanged(handler) {
|
|
342
|
+
return this.socketService.on("auth:password-changed", handler);
|
|
343
|
+
}
|
|
344
|
+
on2FAChanged(handler) {
|
|
345
|
+
return this.socketService.on("auth:2fa-changed", handler);
|
|
346
|
+
}
|
|
347
|
+
onSocketConnected(handler) {
|
|
348
|
+
return this.socketService.on("connected", handler);
|
|
349
|
+
}
|
|
350
|
+
onSocketDisconnected(handler) {
|
|
351
|
+
return this.socketService.on("disconnected", handler);
|
|
352
|
+
}
|
|
353
|
+
onSocketError(handler) {
|
|
354
|
+
return this.socketService.on("error", handler);
|
|
355
|
+
}
|
|
356
|
+
isSocketConnected() {
|
|
357
|
+
return this.socketService.isConnected();
|
|
358
|
+
}
|
|
359
|
+
// Cache management
|
|
360
|
+
clearUserCache() {
|
|
361
|
+
this.cachedUser = null;
|
|
362
|
+
this.userCacheTimestamp = 0;
|
|
363
|
+
}
|
|
364
|
+
isCacheValid() {
|
|
365
|
+
return this.cachedUser !== null && Date.now() - this.userCacheTimestamp < this.USER_CACHE_TTL;
|
|
366
|
+
}
|
|
194
367
|
isAuthenticated() {
|
|
195
368
|
return !!this.token;
|
|
196
369
|
}
|
|
@@ -256,6 +429,11 @@ var AuthService = class {
|
|
|
256
429
|
this.token = response.token;
|
|
257
430
|
this.httpClient.setAuthToken(response.token);
|
|
258
431
|
this.saveTokenToStorage(response.token);
|
|
432
|
+
if (response.user) {
|
|
433
|
+
this.cachedUser = response.user;
|
|
434
|
+
this.userCacheTimestamp = Date.now();
|
|
435
|
+
}
|
|
436
|
+
this.connectSocket();
|
|
259
437
|
return response;
|
|
260
438
|
}
|
|
261
439
|
if (response.success && (response.message === "OTP sent to your email." || response.message === "OTP sent to your phone number.")) {
|
|
@@ -265,6 +443,11 @@ var AuthService = class {
|
|
|
265
443
|
this.token = response.token;
|
|
266
444
|
this.httpClient.setAuthToken(response.token);
|
|
267
445
|
this.saveTokenToStorage(response.token);
|
|
446
|
+
if (response.user) {
|
|
447
|
+
this.cachedUser = response.user;
|
|
448
|
+
this.userCacheTimestamp = Date.now();
|
|
449
|
+
}
|
|
450
|
+
this.connectSocket();
|
|
268
451
|
return response;
|
|
269
452
|
}
|
|
270
453
|
throw new Error(response.message || "Login failed");
|
|
@@ -308,21 +491,29 @@ var AuthService = class {
|
|
|
308
491
|
}
|
|
309
492
|
}
|
|
310
493
|
async logout() {
|
|
494
|
+
this.disconnectSocket();
|
|
311
495
|
try {
|
|
312
496
|
await this.httpClient.post("/api/v1/auth/logout", {});
|
|
313
497
|
} catch (error) {
|
|
314
498
|
console.warn("Failed to call logout endpoint:", error);
|
|
315
499
|
}
|
|
316
500
|
this.token = null;
|
|
501
|
+
this.cachedUser = null;
|
|
502
|
+
this.userCacheTimestamp = 0;
|
|
317
503
|
this.httpClient.removeAuthToken();
|
|
318
504
|
this.httpClient.removeCsrfToken();
|
|
319
505
|
this.removeTokenFromStorage();
|
|
320
506
|
}
|
|
321
|
-
async getProfile() {
|
|
507
|
+
async getProfile(forceRefresh = false) {
|
|
322
508
|
if (!this.token) {
|
|
323
509
|
throw new Error("Not authenticated");
|
|
324
510
|
}
|
|
511
|
+
if (!forceRefresh && this.isCacheValid() && this.cachedUser) {
|
|
512
|
+
return this.cachedUser;
|
|
513
|
+
}
|
|
325
514
|
const response = await this.httpClient.get("/api/v1/user/me");
|
|
515
|
+
this.cachedUser = response.user;
|
|
516
|
+
this.userCacheTimestamp = Date.now();
|
|
326
517
|
return response.user;
|
|
327
518
|
}
|
|
328
519
|
async updateProfile(data) {
|
|
@@ -486,6 +677,16 @@ var AuthService = class {
|
|
|
486
677
|
);
|
|
487
678
|
return response;
|
|
488
679
|
}
|
|
680
|
+
async adminCreateUser(data) {
|
|
681
|
+
if (!this.token) {
|
|
682
|
+
throw new Error("Not authenticated");
|
|
683
|
+
}
|
|
684
|
+
const response = await this.httpClient.post(
|
|
685
|
+
"/api/v1/admin/create-user",
|
|
686
|
+
data
|
|
687
|
+
);
|
|
688
|
+
return response;
|
|
689
|
+
}
|
|
489
690
|
async adminVerifyUser(userId) {
|
|
490
691
|
if (!this.token) {
|
|
491
692
|
throw new Error("Not authenticated");
|
|
@@ -578,21 +779,49 @@ var AuthProvider = ({ children, config }) => {
|
|
|
578
779
|
const [user, setUser] = React.useState(null);
|
|
579
780
|
const [isLoaded, setIsLoaded] = React.useState(false);
|
|
580
781
|
const [loading, setLoading] = React.useState(false);
|
|
581
|
-
const
|
|
782
|
+
const [isSocketConnected, setIsSocketConnected] = React.useState(false);
|
|
783
|
+
React.useEffect(() => {
|
|
784
|
+
const unsubUserUpdated = authService.onUserUpdated(({ user: updatedUser }) => {
|
|
785
|
+
if (updatedUser) {
|
|
786
|
+
setUser(updatedUser);
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
const unsubSessionRevoked = authService.onSessionRevoked(() => {
|
|
790
|
+
authService.logout().then(() => {
|
|
791
|
+
setUser(null);
|
|
792
|
+
});
|
|
793
|
+
});
|
|
794
|
+
const unsubAllSessionsRevoked = authService.onAllSessionsRevoked(() => {
|
|
795
|
+
authService.logout().then(() => {
|
|
796
|
+
setUser(null);
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
const unsubPasswordChanged = authService.onPasswordChanged(() => {
|
|
800
|
+
authService.logout().then(() => {
|
|
801
|
+
setUser(null);
|
|
802
|
+
});
|
|
803
|
+
});
|
|
804
|
+
const unsubConnected = authService.onSocketConnected(() => {
|
|
805
|
+
setIsSocketConnected(true);
|
|
806
|
+
});
|
|
807
|
+
const unsubDisconnected = authService.onSocketDisconnected(() => {
|
|
808
|
+
setIsSocketConnected(false);
|
|
809
|
+
});
|
|
810
|
+
return () => {
|
|
811
|
+
unsubUserUpdated();
|
|
812
|
+
unsubSessionRevoked();
|
|
813
|
+
unsubAllSessionsRevoked();
|
|
814
|
+
unsubPasswordChanged();
|
|
815
|
+
unsubConnected();
|
|
816
|
+
unsubDisconnected();
|
|
817
|
+
};
|
|
818
|
+
}, [authService]);
|
|
819
|
+
React.useEffect(() => {
|
|
582
820
|
const authenticated = authService.isAuthenticated();
|
|
583
821
|
if (authenticated) {
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
setUser(
|
|
587
|
-
} catch (error) {
|
|
588
|
-
console.error("Failed to fetch fresh user profile, falling back to token:", error);
|
|
589
|
-
try {
|
|
590
|
-
const currentUser = authService.getCurrentUser();
|
|
591
|
-
setUser(currentUser);
|
|
592
|
-
} catch (fallbackError) {
|
|
593
|
-
console.error("Failed to get current user from token:", fallbackError);
|
|
594
|
-
setUser(null);
|
|
595
|
-
}
|
|
822
|
+
const currentUser = authService.getCurrentUser();
|
|
823
|
+
if (currentUser) {
|
|
824
|
+
setUser(currentUser);
|
|
596
825
|
}
|
|
597
826
|
} else {
|
|
598
827
|
setUser(null);
|
|
@@ -600,8 +829,21 @@ var AuthProvider = ({ children, config }) => {
|
|
|
600
829
|
setIsLoaded(true);
|
|
601
830
|
}, [authService]);
|
|
602
831
|
React.useEffect(() => {
|
|
603
|
-
|
|
604
|
-
|
|
832
|
+
if (!isLoaded) return;
|
|
833
|
+
const authenticated = authService.isAuthenticated();
|
|
834
|
+
if (!authenticated) return;
|
|
835
|
+
const fetchFreshUser = async () => {
|
|
836
|
+
try {
|
|
837
|
+
const freshUser = await authService.getProfile();
|
|
838
|
+
setUser(freshUser);
|
|
839
|
+
} catch (error) {
|
|
840
|
+
console.warn("[Auth SDK] Failed to fetch fresh user profile:", error);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
if (isSocketConnected) {
|
|
844
|
+
fetchFreshUser();
|
|
845
|
+
}
|
|
846
|
+
}, [authService, isLoaded, isSocketConnected]);
|
|
605
847
|
const signIn = React.useCallback(async (data) => {
|
|
606
848
|
setLoading(true);
|
|
607
849
|
try {
|
|
@@ -823,6 +1065,7 @@ var AuthProvider = ({ children, config }) => {
|
|
|
823
1065
|
isLoaded,
|
|
824
1066
|
isSignedIn: !!user,
|
|
825
1067
|
loading,
|
|
1068
|
+
isSocketConnected,
|
|
826
1069
|
signIn,
|
|
827
1070
|
signUp,
|
|
828
1071
|
signOut,
|
|
@@ -3707,15 +3950,15 @@ var VerifyEmail = ({ token, onSuccess, onError }) => {
|
|
|
3707
3950
|
const [message, setMessage] = React.useState("");
|
|
3708
3951
|
React.useEffect(() => {
|
|
3709
3952
|
const verify = async () => {
|
|
3710
|
-
const
|
|
3711
|
-
if (!
|
|
3953
|
+
const verifyToken2 = token || (typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("token") : null);
|
|
3954
|
+
if (!verifyToken2) {
|
|
3712
3955
|
setStatus("error");
|
|
3713
3956
|
setMessage("No verification token provided");
|
|
3714
3957
|
onError?.("No verification token provided");
|
|
3715
3958
|
return;
|
|
3716
3959
|
}
|
|
3717
3960
|
try {
|
|
3718
|
-
const response = await verifyEmailToken(
|
|
3961
|
+
const response = await verifyEmailToken(verifyToken2);
|
|
3719
3962
|
if (response.success) {
|
|
3720
3963
|
setStatus("success");
|
|
3721
3964
|
setMessage("Email verified successfully! Redirecting...");
|
|
@@ -4474,11 +4717,11 @@ var ChangePassword = ({ onSuccess, appearance }) => {
|
|
|
4474
4717
|
|
|
4475
4718
|
// src/react/components/utils/injectModalStyles.ts
|
|
4476
4719
|
var injectModalStyles = () => {
|
|
4477
|
-
if (document.getElementById("
|
|
4720
|
+
if (document.getElementById("ktw-auth-modal-styles")) {
|
|
4478
4721
|
return;
|
|
4479
4722
|
}
|
|
4480
4723
|
const styleElement = document.createElement("style");
|
|
4481
|
-
styleElement.id = "
|
|
4724
|
+
styleElement.id = "ktw-auth-modal-styles";
|
|
4482
4725
|
styleElement.textContent = `
|
|
4483
4726
|
/* ImageManager Modal Styles - Critical for proper modal display */
|
|
4484
4727
|
/* Radix UI Dialog styles - Force visibility */
|
|
@@ -5016,7 +5259,11 @@ __export(react_exports, {
|
|
|
5016
5259
|
// src/node/index.ts
|
|
5017
5260
|
var node_exports = {};
|
|
5018
5261
|
__export(node_exports, {
|
|
5019
|
-
AuthClient: () => AuthClient
|
|
5262
|
+
AuthClient: () => AuthClient,
|
|
5263
|
+
TokenVerifier: () => TokenVerifier,
|
|
5264
|
+
createTokenVerifier: () => createTokenVerifier,
|
|
5265
|
+
getTokenVerifier: () => getTokenVerifier,
|
|
5266
|
+
verifyToken: () => verifyToken
|
|
5020
5267
|
});
|
|
5021
5268
|
|
|
5022
5269
|
// src/node/auth-client.ts
|
|
@@ -5097,6 +5344,135 @@ var AuthClient = class extends AuthService {
|
|
|
5097
5344
|
}
|
|
5098
5345
|
};
|
|
5099
5346
|
|
|
5347
|
+
// src/node/token-verifier.ts
|
|
5348
|
+
var TokenVerifier = class {
|
|
5349
|
+
constructor(config) {
|
|
5350
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
5351
|
+
this.cleanupInterval = null;
|
|
5352
|
+
this.config = {
|
|
5353
|
+
cacheTTL: 6e4,
|
|
5354
|
+
// 1 minute default
|
|
5355
|
+
cacheEnabled: true,
|
|
5356
|
+
...config
|
|
5357
|
+
};
|
|
5358
|
+
if (this.config.cacheEnabled) {
|
|
5359
|
+
this.startCleanup();
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
/**
|
|
5363
|
+
* Verify a JWT token and get user data
|
|
5364
|
+
* Returns cached user if available and valid
|
|
5365
|
+
*/
|
|
5366
|
+
async verifyToken(token) {
|
|
5367
|
+
if (!token) {
|
|
5368
|
+
return null;
|
|
5369
|
+
}
|
|
5370
|
+
if (this.config.cacheEnabled) {
|
|
5371
|
+
const cached = this.getFromCache(token);
|
|
5372
|
+
if (cached) {
|
|
5373
|
+
return cached;
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
try {
|
|
5377
|
+
const response = await fetch(`${this.config.authServiceUrl}/api/v1/user/me`, {
|
|
5378
|
+
headers: {
|
|
5379
|
+
"Authorization": `Bearer ${token}`,
|
|
5380
|
+
"Content-Type": "application/json"
|
|
5381
|
+
}
|
|
5382
|
+
});
|
|
5383
|
+
if (!response.ok) {
|
|
5384
|
+
this.cache.delete(token);
|
|
5385
|
+
return null;
|
|
5386
|
+
}
|
|
5387
|
+
const data = await response.json();
|
|
5388
|
+
const user = data.user || null;
|
|
5389
|
+
if (user && this.config.cacheEnabled) {
|
|
5390
|
+
this.setCache(token, user);
|
|
5391
|
+
}
|
|
5392
|
+
return user;
|
|
5393
|
+
} catch (error) {
|
|
5394
|
+
console.error("[TokenVerifier] Auth service verification failed:", error);
|
|
5395
|
+
return null;
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
/**
|
|
5399
|
+
* Invalidate cache for a specific token
|
|
5400
|
+
*/
|
|
5401
|
+
invalidateToken(token) {
|
|
5402
|
+
this.cache.delete(token);
|
|
5403
|
+
}
|
|
5404
|
+
/**
|
|
5405
|
+
* Clear all cached tokens
|
|
5406
|
+
*/
|
|
5407
|
+
clearCache() {
|
|
5408
|
+
this.cache.clear();
|
|
5409
|
+
}
|
|
5410
|
+
/**
|
|
5411
|
+
* Get cache statistics
|
|
5412
|
+
*/
|
|
5413
|
+
getCacheStats() {
|
|
5414
|
+
return {
|
|
5415
|
+
size: this.cache.size,
|
|
5416
|
+
enabled: this.config.cacheEnabled,
|
|
5417
|
+
ttl: this.config.cacheTTL
|
|
5418
|
+
};
|
|
5419
|
+
}
|
|
5420
|
+
/**
|
|
5421
|
+
* Stop the cleanup interval (call when shutting down)
|
|
5422
|
+
*/
|
|
5423
|
+
destroy() {
|
|
5424
|
+
if (this.cleanupInterval) {
|
|
5425
|
+
clearInterval(this.cleanupInterval);
|
|
5426
|
+
this.cleanupInterval = null;
|
|
5427
|
+
}
|
|
5428
|
+
this.cache.clear();
|
|
5429
|
+
}
|
|
5430
|
+
getFromCache(token) {
|
|
5431
|
+
const entry = this.cache.get(token);
|
|
5432
|
+
if (!entry) {
|
|
5433
|
+
return null;
|
|
5434
|
+
}
|
|
5435
|
+
if (Date.now() > entry.expiresAt) {
|
|
5436
|
+
this.cache.delete(token);
|
|
5437
|
+
return null;
|
|
5438
|
+
}
|
|
5439
|
+
return entry.user;
|
|
5440
|
+
}
|
|
5441
|
+
setCache(token, user) {
|
|
5442
|
+
this.cache.set(token, {
|
|
5443
|
+
user,
|
|
5444
|
+
expiresAt: Date.now() + this.config.cacheTTL
|
|
5445
|
+
});
|
|
5446
|
+
}
|
|
5447
|
+
startCleanup() {
|
|
5448
|
+
this.cleanupInterval = setInterval(() => {
|
|
5449
|
+
const now = Date.now();
|
|
5450
|
+
for (const [token, entry] of this.cache.entries()) {
|
|
5451
|
+
if (now > entry.expiresAt) {
|
|
5452
|
+
this.cache.delete(token);
|
|
5453
|
+
}
|
|
5454
|
+
}
|
|
5455
|
+
}, 6e4);
|
|
5456
|
+
if (this.cleanupInterval && this.cleanupInterval.unref) {
|
|
5457
|
+
this.cleanupInterval.unref();
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
};
|
|
5461
|
+
var defaultVerifier = null;
|
|
5462
|
+
function createTokenVerifier(config) {
|
|
5463
|
+
defaultVerifier = new TokenVerifier(config);
|
|
5464
|
+
return defaultVerifier;
|
|
5465
|
+
}
|
|
5466
|
+
function getTokenVerifier() {
|
|
5467
|
+
if (!defaultVerifier) {
|
|
5468
|
+
throw new Error("TokenVerifier not initialized. Call createTokenVerifier() first.");
|
|
5469
|
+
}
|
|
5470
|
+
return defaultVerifier;
|
|
5471
|
+
}
|
|
5472
|
+
async function verifyToken(token) {
|
|
5473
|
+
return getTokenVerifier().verifyToken(token);
|
|
5474
|
+
}
|
|
5475
|
+
|
|
5100
5476
|
Object.defineProperty(exports, "ConnectProjectDialog", {
|
|
5101
5477
|
enumerable: true,
|
|
5102
5478
|
get: function () { return upfiles.ConnectProjectDialog; }
|
|
@@ -5135,6 +5511,7 @@ exports.ResetPassword = ResetPassword;
|
|
|
5135
5511
|
exports.SignIn = SignIn;
|
|
5136
5512
|
exports.SignOut = SignOut;
|
|
5137
5513
|
exports.SignUp = SignUp;
|
|
5514
|
+
exports.SocketService = SocketService;
|
|
5138
5515
|
exports.UserButton = UserButton;
|
|
5139
5516
|
exports.UserProfile = UserProfile;
|
|
5140
5517
|
exports.VerifyEmail = VerifyEmail;
|