@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.
- 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 -39
- package/dist/index.components.js.map +1 -1
- package/dist/index.components.mjs +204 -39
- 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 -58
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -60
- 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 -54
- package/dist/index.next.js.map +1 -1
- package/dist/index.next.mjs +261 -54
- 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
|
@@ -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
|