@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
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://ttf-auth-docs.netlify.app/](https://ttf-auth-docs.netlify.app/)
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
@@ -24,6 +24,7 @@ interface AuthConfig {
24
24
  localStorageKey?: string;
25
25
  token?: string;
26
26
  csrfEnabled?: boolean;
27
+ enableSocket?: boolean;
27
28
  upfilesConfig?: UpfilesConfig;
28
29
  }
29
30
  interface UpfilesConfig {
@@ -24,6 +24,7 @@ interface AuthConfig {
24
24
  localStorageKey?: string;
25
25
  token?: string;
26
26
  csrfEnabled?: boolean;
27
+ enableSocket?: boolean;
27
28
  upfilesConfig?: UpfilesConfig;
28
29
  }
29
30
  interface UpfilesConfig {
@@ -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("ttf-auth-modal-styles")) {
4344
+ if (document.getElementById("ktw-auth-modal-styles")) {
4144
4345
  return;
4145
4346
  }
4146
4347
  const styleElement = document.createElement("style");
4147
- styleElement.id = "ttf-auth-modal-styles";
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 */
@@ -4199,34 +4400,6 @@ var injectModalStyles = () => {
4199
4400
  `;
4200
4401
  document.head.appendChild(styleElement);
4201
4402
  };
4202
-
4203
- // src/react/components/utils/getAnonymousUserId.ts
4204
- var ANONYMOUS_USER_ID_KEY = "ttf_auth_anonymous_user_id";
4205
- function generateUUID() {
4206
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
4207
- return crypto.randomUUID();
4208
- }
4209
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
4210
- const r = Math.random() * 16 | 0;
4211
- const v = c === "x" ? r : r & 3 | 8;
4212
- return v.toString(16);
4213
- });
4214
- }
4215
- function getAnonymousUserId() {
4216
- if (typeof window === "undefined" || typeof localStorage === "undefined") {
4217
- return null;
4218
- }
4219
- try {
4220
- let anonymousId = localStorage.getItem(ANONYMOUS_USER_ID_KEY);
4221
- if (!anonymousId) {
4222
- anonymousId = generateUUID();
4223
- localStorage.setItem(ANONYMOUS_USER_ID_KEY, anonymousId);
4224
- }
4225
- return anonymousId;
4226
- } catch {
4227
- return generateUUID();
4228
- }
4229
- }
4230
4403
  var AvatarUploader = ({
4231
4404
  onUploadComplete,
4232
4405
  onError,
@@ -4247,10 +4420,6 @@ var AvatarUploader = ({
4247
4420
  if (user?.id) {
4248
4421
  return `users/${user.id}/`;
4249
4422
  }
4250
- const anonymousId = getAnonymousUserId();
4251
- if (anonymousId) {
4252
- return `anonymous/${anonymousId}/`;
4253
- }
4254
4423
  return upfilesConfig.folderPath || "/";
4255
4424
  }, [user?.id, upfilesConfig.folderPath]);
4256
4425
  const handleSelect = async (image) => {
@@ -4630,10 +4799,6 @@ var AvatarManager = ({
4630
4799
  if (user?.id) {
4631
4800
  return `users/${user.id}/`;
4632
4801
  }
4633
- const anonymousId = getAnonymousUserId();
4634
- if (anonymousId) {
4635
- return `anonymous/${anonymousId}/`;
4636
- }
4637
4802
  return upfilesConfig.folderPath || "/";
4638
4803
  }, [user?.id, upfilesConfig.folderPath]);
4639
4804
  const handleSelect = async (image) => {