@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/README.md
CHANGED
|
@@ -15,7 +15,7 @@ A lightweight, easy-to-use authentication SDK for integrating with the Auth back
|
|
|
15
15
|
|
|
16
16
|
## Documentation
|
|
17
17
|
|
|
18
|
-
📚 **Complete documentation is available at:** [https://
|
|
18
|
+
📚 **Complete documentation is available at:** [https://ktw-auth-docs.netlify.app/](https://ktw-auth-docs.netlify.app/)
|
|
19
19
|
|
|
20
20
|
The documentation includes:
|
|
21
21
|
- Getting started guides
|
package/dist/index.components.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var axios = require('axios');
|
|
6
|
+
var socket_ioClient = require('socket.io-client');
|
|
6
7
|
var upfiles = require('@thetechfossil/upfiles');
|
|
7
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
8
9
|
|
|
@@ -128,16 +129,134 @@ var HttpClient = class {
|
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
};
|
|
132
|
+
var SocketService = class {
|
|
133
|
+
constructor(config) {
|
|
134
|
+
this.socket = null;
|
|
135
|
+
this.token = null;
|
|
136
|
+
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
137
|
+
this.isConnecting = false;
|
|
138
|
+
this.config = {
|
|
139
|
+
autoConnect: false,
|
|
140
|
+
reconnection: true,
|
|
141
|
+
reconnectionAttempts: 5,
|
|
142
|
+
reconnectionDelay: 1e3,
|
|
143
|
+
...config
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
connect(token) {
|
|
147
|
+
if (this.socket?.connected || this.isConnecting) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.token = token;
|
|
151
|
+
this.isConnecting = true;
|
|
152
|
+
this.socket = socket_ioClient.io(this.config.baseUrl, {
|
|
153
|
+
auth: { token },
|
|
154
|
+
autoConnect: true,
|
|
155
|
+
reconnection: this.config.reconnection,
|
|
156
|
+
reconnectionAttempts: this.config.reconnectionAttempts,
|
|
157
|
+
reconnectionDelay: this.config.reconnectionDelay,
|
|
158
|
+
transports: ["websocket", "polling"]
|
|
159
|
+
});
|
|
160
|
+
this.setupEventListeners();
|
|
161
|
+
}
|
|
162
|
+
setupEventListeners() {
|
|
163
|
+
if (!this.socket) return;
|
|
164
|
+
this.socket.on("connect", () => {
|
|
165
|
+
this.isConnecting = false;
|
|
166
|
+
console.log("[Auth SDK] Socket connected");
|
|
167
|
+
this.emit("connected", {});
|
|
168
|
+
});
|
|
169
|
+
this.socket.on("disconnect", (reason) => {
|
|
170
|
+
console.log("[Auth SDK] Socket disconnected:", reason);
|
|
171
|
+
this.emit("disconnected", { reason });
|
|
172
|
+
});
|
|
173
|
+
this.socket.on("connect_error", (error) => {
|
|
174
|
+
this.isConnecting = false;
|
|
175
|
+
console.error("[Auth SDK] Socket connection error:", error.message);
|
|
176
|
+
this.emit("error", { error: error.message });
|
|
177
|
+
});
|
|
178
|
+
this.socket.on("user:updated", (data) => {
|
|
179
|
+
this.emit("user:updated", data);
|
|
180
|
+
});
|
|
181
|
+
this.socket.on("session:revoked", (data) => {
|
|
182
|
+
this.emit("session:revoked", data);
|
|
183
|
+
});
|
|
184
|
+
this.socket.on("session:all-revoked", () => {
|
|
185
|
+
this.emit("session:all-revoked", {});
|
|
186
|
+
});
|
|
187
|
+
this.socket.on("auth:password-changed", () => {
|
|
188
|
+
this.emit("auth:password-changed", {});
|
|
189
|
+
});
|
|
190
|
+
this.socket.on("auth:2fa-changed", (data) => {
|
|
191
|
+
this.emit("auth:2fa-changed", data);
|
|
192
|
+
});
|
|
193
|
+
this.socket.on("user:refresh", () => {
|
|
194
|
+
this.emit("user:refresh", {});
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
disconnect() {
|
|
198
|
+
if (this.socket) {
|
|
199
|
+
this.socket.disconnect();
|
|
200
|
+
this.socket = null;
|
|
201
|
+
this.token = null;
|
|
202
|
+
this.isConnecting = false;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
isConnected() {
|
|
206
|
+
return this.socket?.connected ?? false;
|
|
207
|
+
}
|
|
208
|
+
// Event subscription
|
|
209
|
+
on(event, handler) {
|
|
210
|
+
if (!this.eventHandlers.has(event)) {
|
|
211
|
+
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
212
|
+
}
|
|
213
|
+
this.eventHandlers.get(event).add(handler);
|
|
214
|
+
return () => {
|
|
215
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
off(event, handler) {
|
|
219
|
+
if (handler) {
|
|
220
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
221
|
+
} else {
|
|
222
|
+
this.eventHandlers.delete(event);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
emit(event, data) {
|
|
226
|
+
const handlers = this.eventHandlers.get(event);
|
|
227
|
+
if (handlers) {
|
|
228
|
+
handlers.forEach((handler) => {
|
|
229
|
+
try {
|
|
230
|
+
handler(data);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.error(`[Auth SDK] Error in event handler for ${event}:`, error);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Request fresh user data from server
|
|
238
|
+
requestUserRefresh() {
|
|
239
|
+
if (this.socket?.connected) {
|
|
240
|
+
this.socket.emit("request:user");
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
};
|
|
131
244
|
var AuthService = class {
|
|
245
|
+
// 5 minutes cache
|
|
132
246
|
constructor(config) {
|
|
133
247
|
this.token = null;
|
|
134
248
|
this.upfilesClient = null;
|
|
249
|
+
this.cachedUser = null;
|
|
250
|
+
this.userCacheTimestamp = 0;
|
|
251
|
+
this.USER_CACHE_TTL = 5 * 60 * 1e3;
|
|
135
252
|
this.config = {
|
|
136
253
|
localStorageKey: "auth_token",
|
|
137
254
|
csrfEnabled: true,
|
|
255
|
+
enableSocket: true,
|
|
138
256
|
...config
|
|
139
257
|
};
|
|
140
258
|
this.httpClient = new HttpClient(this.config.baseUrl);
|
|
259
|
+
this.socketService = new SocketService({ baseUrl: this.config.baseUrl });
|
|
141
260
|
this.loadTokenFromStorage();
|
|
142
261
|
if (this.config.upfilesConfig) {
|
|
143
262
|
this.upfilesClient = new upfiles.UpfilesClient({
|
|
@@ -154,6 +273,9 @@ var AuthService = class {
|
|
|
154
273
|
this.httpClient.setFrontendBaseUrl(frontendBaseUrl);
|
|
155
274
|
}
|
|
156
275
|
}
|
|
276
|
+
if (this.token && this.config.enableSocket !== false) {
|
|
277
|
+
this.connectSocket();
|
|
278
|
+
}
|
|
157
279
|
}
|
|
158
280
|
loadTokenFromStorage() {
|
|
159
281
|
if (typeof window !== "undefined" && this.config.localStorageKey) {
|
|
@@ -186,6 +308,57 @@ var AuthService = class {
|
|
|
186
308
|
}
|
|
187
309
|
}
|
|
188
310
|
}
|
|
311
|
+
// Socket connection management
|
|
312
|
+
connectSocket() {
|
|
313
|
+
if (this.token && this.config.enableSocket !== false && typeof window !== "undefined") {
|
|
314
|
+
this.socketService.connect(this.token);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
disconnectSocket() {
|
|
318
|
+
this.socketService.disconnect();
|
|
319
|
+
}
|
|
320
|
+
// Socket event subscription
|
|
321
|
+
onUserUpdated(handler) {
|
|
322
|
+
return this.socketService.on("user:updated", (data) => {
|
|
323
|
+
if (data.user) {
|
|
324
|
+
this.cachedUser = data.user;
|
|
325
|
+
this.userCacheTimestamp = Date.now();
|
|
326
|
+
}
|
|
327
|
+
handler(data);
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
onSessionRevoked(handler) {
|
|
331
|
+
return this.socketService.on("session:revoked", handler);
|
|
332
|
+
}
|
|
333
|
+
onAllSessionsRevoked(handler) {
|
|
334
|
+
return this.socketService.on("session:all-revoked", handler);
|
|
335
|
+
}
|
|
336
|
+
onPasswordChanged(handler) {
|
|
337
|
+
return this.socketService.on("auth:password-changed", handler);
|
|
338
|
+
}
|
|
339
|
+
on2FAChanged(handler) {
|
|
340
|
+
return this.socketService.on("auth:2fa-changed", handler);
|
|
341
|
+
}
|
|
342
|
+
onSocketConnected(handler) {
|
|
343
|
+
return this.socketService.on("connected", handler);
|
|
344
|
+
}
|
|
345
|
+
onSocketDisconnected(handler) {
|
|
346
|
+
return this.socketService.on("disconnected", handler);
|
|
347
|
+
}
|
|
348
|
+
onSocketError(handler) {
|
|
349
|
+
return this.socketService.on("error", handler);
|
|
350
|
+
}
|
|
351
|
+
isSocketConnected() {
|
|
352
|
+
return this.socketService.isConnected();
|
|
353
|
+
}
|
|
354
|
+
// Cache management
|
|
355
|
+
clearUserCache() {
|
|
356
|
+
this.cachedUser = null;
|
|
357
|
+
this.userCacheTimestamp = 0;
|
|
358
|
+
}
|
|
359
|
+
isCacheValid() {
|
|
360
|
+
return this.cachedUser !== null && Date.now() - this.userCacheTimestamp < this.USER_CACHE_TTL;
|
|
361
|
+
}
|
|
189
362
|
isAuthenticated() {
|
|
190
363
|
return !!this.token;
|
|
191
364
|
}
|
|
@@ -251,6 +424,11 @@ var AuthService = class {
|
|
|
251
424
|
this.token = response.token;
|
|
252
425
|
this.httpClient.setAuthToken(response.token);
|
|
253
426
|
this.saveTokenToStorage(response.token);
|
|
427
|
+
if (response.user) {
|
|
428
|
+
this.cachedUser = response.user;
|
|
429
|
+
this.userCacheTimestamp = Date.now();
|
|
430
|
+
}
|
|
431
|
+
this.connectSocket();
|
|
254
432
|
return response;
|
|
255
433
|
}
|
|
256
434
|
if (response.success && (response.message === "OTP sent to your email." || response.message === "OTP sent to your phone number.")) {
|
|
@@ -260,6 +438,11 @@ var AuthService = class {
|
|
|
260
438
|
this.token = response.token;
|
|
261
439
|
this.httpClient.setAuthToken(response.token);
|
|
262
440
|
this.saveTokenToStorage(response.token);
|
|
441
|
+
if (response.user) {
|
|
442
|
+
this.cachedUser = response.user;
|
|
443
|
+
this.userCacheTimestamp = Date.now();
|
|
444
|
+
}
|
|
445
|
+
this.connectSocket();
|
|
263
446
|
return response;
|
|
264
447
|
}
|
|
265
448
|
throw new Error(response.message || "Login failed");
|
|
@@ -303,21 +486,29 @@ var AuthService = class {
|
|
|
303
486
|
}
|
|
304
487
|
}
|
|
305
488
|
async logout() {
|
|
489
|
+
this.disconnectSocket();
|
|
306
490
|
try {
|
|
307
491
|
await this.httpClient.post("/api/v1/auth/logout", {});
|
|
308
492
|
} catch (error) {
|
|
309
493
|
console.warn("Failed to call logout endpoint:", error);
|
|
310
494
|
}
|
|
311
495
|
this.token = null;
|
|
496
|
+
this.cachedUser = null;
|
|
497
|
+
this.userCacheTimestamp = 0;
|
|
312
498
|
this.httpClient.removeAuthToken();
|
|
313
499
|
this.httpClient.removeCsrfToken();
|
|
314
500
|
this.removeTokenFromStorage();
|
|
315
501
|
}
|
|
316
|
-
async getProfile() {
|
|
502
|
+
async getProfile(forceRefresh = false) {
|
|
317
503
|
if (!this.token) {
|
|
318
504
|
throw new Error("Not authenticated");
|
|
319
505
|
}
|
|
506
|
+
if (!forceRefresh && this.isCacheValid() && this.cachedUser) {
|
|
507
|
+
return this.cachedUser;
|
|
508
|
+
}
|
|
320
509
|
const response = await this.httpClient.get("/api/v1/user/me");
|
|
510
|
+
this.cachedUser = response.user;
|
|
511
|
+
this.userCacheTimestamp = Date.now();
|
|
321
512
|
return response.user;
|
|
322
513
|
}
|
|
323
514
|
async updateProfile(data) {
|
|
@@ -481,6 +672,16 @@ var AuthService = class {
|
|
|
481
672
|
);
|
|
482
673
|
return response;
|
|
483
674
|
}
|
|
675
|
+
async adminCreateUser(data) {
|
|
676
|
+
if (!this.token) {
|
|
677
|
+
throw new Error("Not authenticated");
|
|
678
|
+
}
|
|
679
|
+
const response = await this.httpClient.post(
|
|
680
|
+
"/api/v1/admin/create-user",
|
|
681
|
+
data
|
|
682
|
+
);
|
|
683
|
+
return response;
|
|
684
|
+
}
|
|
484
685
|
async adminVerifyUser(userId) {
|
|
485
686
|
if (!this.token) {
|
|
486
687
|
throw new Error("Not authenticated");
|
|
@@ -4140,11 +4341,11 @@ var ChangePassword = ({ onSuccess, appearance }) => {
|
|
|
4140
4341
|
|
|
4141
4342
|
// src/react/components/utils/injectModalStyles.ts
|
|
4142
4343
|
var injectModalStyles = () => {
|
|
4143
|
-
if (document.getElementById("
|
|
4344
|
+
if (document.getElementById("ktw-auth-modal-styles")) {
|
|
4144
4345
|
return;
|
|
4145
4346
|
}
|
|
4146
4347
|
const styleElement = document.createElement("style");
|
|
4147
|
-
styleElement.id = "
|
|
4348
|
+
styleElement.id = "ktw-auth-modal-styles";
|
|
4148
4349
|
styleElement.textContent = `
|
|
4149
4350
|
/* ImageManager Modal Styles - Critical for proper modal display */
|
|
4150
4351
|
/* Radix UI Dialog styles - Force visibility */
|