@thetechfossil/auth2 1.2.18 → 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.
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 +204 -39
  5. package/dist/index.components.js.map +1 -1
  6. package/dist/index.components.mjs +204 -39
  7. package/dist/index.components.mjs.map +1 -1
  8. package/dist/index.d.mts +110 -3
  9. package/dist/index.d.ts +110 -3
  10. package/dist/index.js +399 -58
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +400 -60
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/index.next.d.mts +53 -1
  15. package/dist/index.next.d.ts +53 -1
  16. package/dist/index.next.js +261 -54
  17. package/dist/index.next.js.map +1 -1
  18. package/dist/index.next.mjs +261 -54
  19. package/dist/index.next.mjs.map +1 -1
  20. package/dist/index.next.server.d.mts +80 -2
  21. package/dist/index.next.server.d.ts +80 -2
  22. package/dist/index.next.server.js +335 -1
  23. package/dist/index.next.server.js.map +1 -1
  24. package/dist/index.next.server.mjs +332 -2
  25. package/dist/index.next.server.mjs.map +1 -1
  26. package/dist/index.node.d.mts +80 -2
  27. package/dist/index.node.d.ts +80 -2
  28. package/dist/index.node.js +335 -1
  29. package/dist/index.node.js.map +1 -1
  30. package/dist/index.node.mjs +332 -2
  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
@@ -1,4 +1,5 @@
1
1
  import axios from 'axios';
2
+ import { io } from 'socket.io-client';
2
3
  import { UpfilesClient } from '@thetechfossil/upfiles';
3
4
  import { cookies } from 'next/headers';
4
5
  import { redirect } from 'next/navigation';
@@ -120,16 +121,134 @@ var HttpClient = class {
120
121
  }
121
122
  }
122
123
  };
124
+ var SocketService = class {
125
+ constructor(config) {
126
+ this.socket = null;
127
+ this.token = null;
128
+ this.eventHandlers = /* @__PURE__ */ new Map();
129
+ this.isConnecting = false;
130
+ this.config = {
131
+ autoConnect: false,
132
+ reconnection: true,
133
+ reconnectionAttempts: 5,
134
+ reconnectionDelay: 1e3,
135
+ ...config
136
+ };
137
+ }
138
+ connect(token) {
139
+ if (this.socket?.connected || this.isConnecting) {
140
+ return;
141
+ }
142
+ this.token = token;
143
+ this.isConnecting = true;
144
+ this.socket = io(this.config.baseUrl, {
145
+ auth: { token },
146
+ autoConnect: true,
147
+ reconnection: this.config.reconnection,
148
+ reconnectionAttempts: this.config.reconnectionAttempts,
149
+ reconnectionDelay: this.config.reconnectionDelay,
150
+ transports: ["websocket", "polling"]
151
+ });
152
+ this.setupEventListeners();
153
+ }
154
+ setupEventListeners() {
155
+ if (!this.socket) return;
156
+ this.socket.on("connect", () => {
157
+ this.isConnecting = false;
158
+ console.log("[Auth SDK] Socket connected");
159
+ this.emit("connected", {});
160
+ });
161
+ this.socket.on("disconnect", (reason) => {
162
+ console.log("[Auth SDK] Socket disconnected:", reason);
163
+ this.emit("disconnected", { reason });
164
+ });
165
+ this.socket.on("connect_error", (error) => {
166
+ this.isConnecting = false;
167
+ console.error("[Auth SDK] Socket connection error:", error.message);
168
+ this.emit("error", { error: error.message });
169
+ });
170
+ this.socket.on("user:updated", (data) => {
171
+ this.emit("user:updated", data);
172
+ });
173
+ this.socket.on("session:revoked", (data) => {
174
+ this.emit("session:revoked", data);
175
+ });
176
+ this.socket.on("session:all-revoked", () => {
177
+ this.emit("session:all-revoked", {});
178
+ });
179
+ this.socket.on("auth:password-changed", () => {
180
+ this.emit("auth:password-changed", {});
181
+ });
182
+ this.socket.on("auth:2fa-changed", (data) => {
183
+ this.emit("auth:2fa-changed", data);
184
+ });
185
+ this.socket.on("user:refresh", () => {
186
+ this.emit("user:refresh", {});
187
+ });
188
+ }
189
+ disconnect() {
190
+ if (this.socket) {
191
+ this.socket.disconnect();
192
+ this.socket = null;
193
+ this.token = null;
194
+ this.isConnecting = false;
195
+ }
196
+ }
197
+ isConnected() {
198
+ return this.socket?.connected ?? false;
199
+ }
200
+ // Event subscription
201
+ on(event, handler) {
202
+ if (!this.eventHandlers.has(event)) {
203
+ this.eventHandlers.set(event, /* @__PURE__ */ new Set());
204
+ }
205
+ this.eventHandlers.get(event).add(handler);
206
+ return () => {
207
+ this.eventHandlers.get(event)?.delete(handler);
208
+ };
209
+ }
210
+ off(event, handler) {
211
+ if (handler) {
212
+ this.eventHandlers.get(event)?.delete(handler);
213
+ } else {
214
+ this.eventHandlers.delete(event);
215
+ }
216
+ }
217
+ emit(event, data) {
218
+ const handlers = this.eventHandlers.get(event);
219
+ if (handlers) {
220
+ handlers.forEach((handler) => {
221
+ try {
222
+ handler(data);
223
+ } catch (error) {
224
+ console.error(`[Auth SDK] Error in event handler for ${event}:`, error);
225
+ }
226
+ });
227
+ }
228
+ }
229
+ // Request fresh user data from server
230
+ requestUserRefresh() {
231
+ if (this.socket?.connected) {
232
+ this.socket.emit("request:user");
233
+ }
234
+ }
235
+ };
123
236
  var AuthService = class {
237
+ // 5 minutes cache
124
238
  constructor(config) {
125
239
  this.token = null;
126
240
  this.upfilesClient = null;
241
+ this.cachedUser = null;
242
+ this.userCacheTimestamp = 0;
243
+ this.USER_CACHE_TTL = 5 * 60 * 1e3;
127
244
  this.config = {
128
245
  localStorageKey: "auth_token",
129
246
  csrfEnabled: true,
247
+ enableSocket: true,
130
248
  ...config
131
249
  };
132
250
  this.httpClient = new HttpClient(this.config.baseUrl);
251
+ this.socketService = new SocketService({ baseUrl: this.config.baseUrl });
133
252
  this.loadTokenFromStorage();
134
253
  if (this.config.upfilesConfig) {
135
254
  this.upfilesClient = new UpfilesClient({
@@ -146,6 +265,9 @@ var AuthService = class {
146
265
  this.httpClient.setFrontendBaseUrl(frontendBaseUrl);
147
266
  }
148
267
  }
268
+ if (this.token && this.config.enableSocket !== false) {
269
+ this.connectSocket();
270
+ }
149
271
  }
150
272
  loadTokenFromStorage() {
151
273
  if (typeof window !== "undefined" && this.config.localStorageKey) {
@@ -178,6 +300,57 @@ var AuthService = class {
178
300
  }
179
301
  }
180
302
  }
303
+ // Socket connection management
304
+ connectSocket() {
305
+ if (this.token && this.config.enableSocket !== false && typeof window !== "undefined") {
306
+ this.socketService.connect(this.token);
307
+ }
308
+ }
309
+ disconnectSocket() {
310
+ this.socketService.disconnect();
311
+ }
312
+ // Socket event subscription
313
+ onUserUpdated(handler) {
314
+ return this.socketService.on("user:updated", (data) => {
315
+ if (data.user) {
316
+ this.cachedUser = data.user;
317
+ this.userCacheTimestamp = Date.now();
318
+ }
319
+ handler(data);
320
+ });
321
+ }
322
+ onSessionRevoked(handler) {
323
+ return this.socketService.on("session:revoked", handler);
324
+ }
325
+ onAllSessionsRevoked(handler) {
326
+ return this.socketService.on("session:all-revoked", handler);
327
+ }
328
+ onPasswordChanged(handler) {
329
+ return this.socketService.on("auth:password-changed", handler);
330
+ }
331
+ on2FAChanged(handler) {
332
+ return this.socketService.on("auth:2fa-changed", handler);
333
+ }
334
+ onSocketConnected(handler) {
335
+ return this.socketService.on("connected", handler);
336
+ }
337
+ onSocketDisconnected(handler) {
338
+ return this.socketService.on("disconnected", handler);
339
+ }
340
+ onSocketError(handler) {
341
+ return this.socketService.on("error", handler);
342
+ }
343
+ isSocketConnected() {
344
+ return this.socketService.isConnected();
345
+ }
346
+ // Cache management
347
+ clearUserCache() {
348
+ this.cachedUser = null;
349
+ this.userCacheTimestamp = 0;
350
+ }
351
+ isCacheValid() {
352
+ return this.cachedUser !== null && Date.now() - this.userCacheTimestamp < this.USER_CACHE_TTL;
353
+ }
181
354
  isAuthenticated() {
182
355
  return !!this.token;
183
356
  }
@@ -243,6 +416,11 @@ var AuthService = class {
243
416
  this.token = response.token;
244
417
  this.httpClient.setAuthToken(response.token);
245
418
  this.saveTokenToStorage(response.token);
419
+ if (response.user) {
420
+ this.cachedUser = response.user;
421
+ this.userCacheTimestamp = Date.now();
422
+ }
423
+ this.connectSocket();
246
424
  return response;
247
425
  }
248
426
  if (response.success && (response.message === "OTP sent to your email." || response.message === "OTP sent to your phone number.")) {
@@ -252,6 +430,11 @@ var AuthService = class {
252
430
  this.token = response.token;
253
431
  this.httpClient.setAuthToken(response.token);
254
432
  this.saveTokenToStorage(response.token);
433
+ if (response.user) {
434
+ this.cachedUser = response.user;
435
+ this.userCacheTimestamp = Date.now();
436
+ }
437
+ this.connectSocket();
255
438
  return response;
256
439
  }
257
440
  throw new Error(response.message || "Login failed");
@@ -295,21 +478,29 @@ var AuthService = class {
295
478
  }
296
479
  }
297
480
  async logout() {
481
+ this.disconnectSocket();
298
482
  try {
299
483
  await this.httpClient.post("/api/v1/auth/logout", {});
300
484
  } catch (error) {
301
485
  console.warn("Failed to call logout endpoint:", error);
302
486
  }
303
487
  this.token = null;
488
+ this.cachedUser = null;
489
+ this.userCacheTimestamp = 0;
304
490
  this.httpClient.removeAuthToken();
305
491
  this.httpClient.removeCsrfToken();
306
492
  this.removeTokenFromStorage();
307
493
  }
308
- async getProfile() {
494
+ async getProfile(forceRefresh = false) {
309
495
  if (!this.token) {
310
496
  throw new Error("Not authenticated");
311
497
  }
498
+ if (!forceRefresh && this.isCacheValid() && this.cachedUser) {
499
+ return this.cachedUser;
500
+ }
312
501
  const response = await this.httpClient.get("/api/v1/user/me");
502
+ this.cachedUser = response.user;
503
+ this.userCacheTimestamp = Date.now();
313
504
  return response.user;
314
505
  }
315
506
  async updateProfile(data) {
@@ -473,6 +664,16 @@ var AuthService = class {
473
664
  );
474
665
  return response;
475
666
  }
667
+ async adminCreateUser(data) {
668
+ if (!this.token) {
669
+ throw new Error("Not authenticated");
670
+ }
671
+ const response = await this.httpClient.post(
672
+ "/api/v1/admin/create-user",
673
+ data
674
+ );
675
+ return response;
676
+ }
476
677
  async adminVerifyUser(userId) {
477
678
  if (!this.token) {
478
679
  throw new Error("Not authenticated");
@@ -581,6 +782,135 @@ var AuthClient = class extends AuthService {
581
782
  }
582
783
  };
583
784
 
785
+ // src/node/token-verifier.ts
786
+ var TokenVerifier = class {
787
+ constructor(config) {
788
+ this.cache = /* @__PURE__ */ new Map();
789
+ this.cleanupInterval = null;
790
+ this.config = {
791
+ cacheTTL: 6e4,
792
+ // 1 minute default
793
+ cacheEnabled: true,
794
+ ...config
795
+ };
796
+ if (this.config.cacheEnabled) {
797
+ this.startCleanup();
798
+ }
799
+ }
800
+ /**
801
+ * Verify a JWT token and get user data
802
+ * Returns cached user if available and valid
803
+ */
804
+ async verifyToken(token) {
805
+ if (!token) {
806
+ return null;
807
+ }
808
+ if (this.config.cacheEnabled) {
809
+ const cached = this.getFromCache(token);
810
+ if (cached) {
811
+ return cached;
812
+ }
813
+ }
814
+ try {
815
+ const response = await fetch(`${this.config.authServiceUrl}/api/v1/user/me`, {
816
+ headers: {
817
+ "Authorization": `Bearer ${token}`,
818
+ "Content-Type": "application/json"
819
+ }
820
+ });
821
+ if (!response.ok) {
822
+ this.cache.delete(token);
823
+ return null;
824
+ }
825
+ const data = await response.json();
826
+ const user = data.user || null;
827
+ if (user && this.config.cacheEnabled) {
828
+ this.setCache(token, user);
829
+ }
830
+ return user;
831
+ } catch (error) {
832
+ console.error("[TokenVerifier] Auth service verification failed:", error);
833
+ return null;
834
+ }
835
+ }
836
+ /**
837
+ * Invalidate cache for a specific token
838
+ */
839
+ invalidateToken(token) {
840
+ this.cache.delete(token);
841
+ }
842
+ /**
843
+ * Clear all cached tokens
844
+ */
845
+ clearCache() {
846
+ this.cache.clear();
847
+ }
848
+ /**
849
+ * Get cache statistics
850
+ */
851
+ getCacheStats() {
852
+ return {
853
+ size: this.cache.size,
854
+ enabled: this.config.cacheEnabled,
855
+ ttl: this.config.cacheTTL
856
+ };
857
+ }
858
+ /**
859
+ * Stop the cleanup interval (call when shutting down)
860
+ */
861
+ destroy() {
862
+ if (this.cleanupInterval) {
863
+ clearInterval(this.cleanupInterval);
864
+ this.cleanupInterval = null;
865
+ }
866
+ this.cache.clear();
867
+ }
868
+ getFromCache(token) {
869
+ const entry = this.cache.get(token);
870
+ if (!entry) {
871
+ return null;
872
+ }
873
+ if (Date.now() > entry.expiresAt) {
874
+ this.cache.delete(token);
875
+ return null;
876
+ }
877
+ return entry.user;
878
+ }
879
+ setCache(token, user) {
880
+ this.cache.set(token, {
881
+ user,
882
+ expiresAt: Date.now() + this.config.cacheTTL
883
+ });
884
+ }
885
+ startCleanup() {
886
+ this.cleanupInterval = setInterval(() => {
887
+ const now = Date.now();
888
+ for (const [token, entry] of this.cache.entries()) {
889
+ if (now > entry.expiresAt) {
890
+ this.cache.delete(token);
891
+ }
892
+ }
893
+ }, 6e4);
894
+ if (this.cleanupInterval && this.cleanupInterval.unref) {
895
+ this.cleanupInterval.unref();
896
+ }
897
+ }
898
+ };
899
+ var defaultVerifier = null;
900
+ function createTokenVerifier(config) {
901
+ defaultVerifier = new TokenVerifier(config);
902
+ return defaultVerifier;
903
+ }
904
+ function getTokenVerifier() {
905
+ if (!defaultVerifier) {
906
+ throw new Error("TokenVerifier not initialized. Call createTokenVerifier() first.");
907
+ }
908
+ return defaultVerifier;
909
+ }
910
+ async function verifyToken(token) {
911
+ return getTokenVerifier().verifyToken(token);
912
+ }
913
+
584
914
  // src/nextjs/server-auth.ts
585
915
  var NextServerAuth = class _NextServerAuth extends AuthClient {
586
916
  constructor(config) {
@@ -779,6 +1109,6 @@ function createAuthMiddleware(config) {
779
1109
  return authMiddleware(config);
780
1110
  }
781
1111
 
782
- export { AuthClient, AuthServer, AuthService, HttpClient, NextServerAuth, auth, authMiddleware, createAuthMiddleware, currentUser, getAuthServer, redirectIfAuthenticated, requireAuth };
1112
+ export { AuthClient, AuthServer, AuthService, HttpClient, NextServerAuth, TokenVerifier, auth, authMiddleware, createAuthMiddleware, createTokenVerifier, currentUser, getAuthServer, getTokenVerifier, redirectIfAuthenticated, requireAuth, verifyToken };
783
1113
  //# sourceMappingURL=index.next.server.mjs.map
784
1114
  //# sourceMappingURL=index.next.server.mjs.map