@insforge/sdk 1.0.1-refresh.7 → 1.0.1-refresh.8

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/dist/index.mjs CHANGED
@@ -21,8 +21,6 @@ var InsForgeError = class _InsForgeError extends Error {
21
21
  var HttpClient = class {
22
22
  constructor(config) {
23
23
  this.userToken = null;
24
- this.isRefreshing = false;
25
- this.refreshQueue = [];
26
24
  this.baseUrl = config.baseUrl || "http://localhost:7130";
27
25
  this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
28
26
  this.anonKey = config.anonKey;
@@ -35,12 +33,6 @@ var HttpClient = class {
35
33
  );
36
34
  }
37
35
  }
38
- /**
39
- * Set the refresh callback for automatic token refresh on 401
40
- */
41
- setRefreshCallback(callback) {
42
- this.refreshCallback = callback;
43
- }
44
36
  buildUrl(path, params) {
45
37
  const url = new URL(path, this.baseUrl);
46
38
  if (params) {
@@ -57,9 +49,6 @@ var HttpClient = class {
57
49
  return url.toString();
58
50
  }
59
51
  async request(method, path, options = {}) {
60
- return this.performRequest(method, path, options, false);
61
- }
62
- async performRequest(method, path, options = {}, isRetry = false) {
63
52
  const { params, headers = {}, body, ...fetchOptions } = options;
64
53
  const url = this.buildUrl(path, params);
65
54
  const requestHeaders = {
@@ -85,17 +74,9 @@ var HttpClient = class {
85
74
  method,
86
75
  headers: requestHeaders,
87
76
  body: processedBody,
88
- ...fetchOptions,
89
- credentials: "include"
77
+ credentials: "include",
78
+ ...fetchOptions
90
79
  });
91
- const isRefreshEndpoint = path.includes("/api/auth/refresh") || path.includes("/api/auth/logout");
92
- if (response.status === 401 && !isRetry && !isRefreshEndpoint && this.refreshCallback) {
93
- const newToken = await this.handleTokenRefresh();
94
- if (newToken) {
95
- this.setAuthToken(newToken);
96
- return this.performRequest(method, path, options, true);
97
- }
98
- }
99
80
  if (response.status === 204) {
100
81
  return void 0;
101
82
  }
@@ -127,38 +108,6 @@ var HttpClient = class {
127
108
  }
128
109
  return data;
129
110
  }
130
- /**
131
- * Handle token refresh with queue to prevent duplicate refreshes
132
- * Multiple concurrent 401s will wait for a single refresh to complete
133
- */
134
- async handleTokenRefresh() {
135
- if (this.isRefreshing) {
136
- return new Promise((resolve, reject) => {
137
- this.refreshQueue.push({ resolve, reject });
138
- });
139
- }
140
- this.isRefreshing = true;
141
- try {
142
- const newToken = await this.refreshCallback?.();
143
- this.refreshQueue.forEach(({ resolve, reject }) => {
144
- if (newToken) {
145
- resolve(newToken);
146
- } else {
147
- reject(new Error("Token refresh failed"));
148
- }
149
- });
150
- this.refreshQueue = [];
151
- return newToken || null;
152
- } catch (error) {
153
- this.refreshQueue.forEach(({ reject }) => {
154
- reject(error instanceof Error ? error : new Error("Token refresh failed"));
155
- });
156
- this.refreshQueue = [];
157
- return null;
158
- } finally {
159
- this.isRefreshing = false;
160
- }
161
- }
162
111
  get(path, options) {
163
112
  return this.request("GET", path, options);
164
113
  }
@@ -187,58 +136,32 @@ var HttpClient = class {
187
136
  }
188
137
  };
189
138
 
190
- // src/lib/session-storage.ts
139
+ // src/lib/token-manager.ts
191
140
  var TOKEN_KEY = "insforge-auth-token";
192
141
  var USER_KEY = "insforge-auth-user";
193
142
  var AUTH_FLAG_COOKIE = "isAuthenticated";
194
- var SecureSessionStorage = class {
195
- constructor() {
196
- this.strategyId = "secure";
197
- this.accessToken = null;
198
- this.user = null;
199
- }
200
- saveSession(session) {
201
- this.accessToken = session.accessToken;
202
- this.user = session.user;
203
- }
204
- getSession() {
205
- if (!this.accessToken || !this.user) return null;
206
- return {
207
- accessToken: this.accessToken,
208
- user: this.user
209
- };
210
- }
211
- getAccessToken() {
212
- return this.accessToken;
213
- }
214
- setAccessToken(token) {
215
- this.accessToken = token;
216
- }
217
- getUser() {
218
- return this.user;
219
- }
220
- setUser(user) {
221
- this.user = user;
222
- }
223
- clearSession() {
143
+ function hasAuthCookie() {
144
+ if (typeof document === "undefined") return false;
145
+ return document.cookie.split(";").some(
146
+ (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
147
+ );
148
+ }
149
+ function setAuthCookie() {
150
+ if (typeof document === "undefined") return;
151
+ const maxAge = 7 * 24 * 60 * 60;
152
+ document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
153
+ }
154
+ function clearAuthCookie() {
155
+ if (typeof document === "undefined") return;
156
+ document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
157
+ }
158
+ var TokenManager = class {
159
+ constructor(storage) {
160
+ // In-memory storage
224
161
  this.accessToken = null;
225
162
  this.user = null;
226
- }
227
- shouldAttemptRefresh() {
228
- if (this.accessToken) return false;
229
- return this.hasAuthFlag();
230
- }
231
- // --- Private: Auth Flag Cookie Detection (SDK-managed on frontend domain) ---
232
- hasAuthFlag() {
233
- if (typeof document === "undefined") return false;
234
- return document.cookie.split(";").some(
235
- (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
236
- );
237
- }
238
- };
239
- var LocalSessionStorage = class {
240
- constructor(storage) {
241
- this.strategyId = "local";
163
+ // Mode: 'memory' (new backend) or 'storage' (legacy backend, default)
164
+ this._mode = "storage";
242
165
  if (storage) {
243
166
  this.storage = storage;
244
167
  } else if (typeof window !== "undefined" && window.localStorage) {
@@ -256,126 +179,111 @@ var LocalSessionStorage = class {
256
179
  };
257
180
  }
258
181
  }
259
- saveSession(session) {
260
- this.storage.setItem(TOKEN_KEY, session.accessToken);
261
- this.storage.setItem(USER_KEY, JSON.stringify(session.user));
262
- }
263
- getSession() {
264
- const token = this.storage.getItem(TOKEN_KEY);
265
- const userStr = this.storage.getItem(USER_KEY);
266
- if (!token || !userStr) return null;
267
- try {
268
- const user = JSON.parse(userStr);
269
- return { accessToken: token, user };
270
- } catch {
271
- this.clearSession();
272
- return null;
273
- }
274
- }
275
- getAccessToken() {
276
- const token = this.storage.getItem(TOKEN_KEY);
277
- return typeof token === "string" ? token : null;
278
- }
279
- setAccessToken(token) {
280
- this.storage.setItem(TOKEN_KEY, token);
281
- }
282
- getUser() {
283
- const userStr = this.storage.getItem(USER_KEY);
284
- if (!userStr) return null;
285
- try {
286
- return JSON.parse(userStr);
287
- } catch {
288
- return null;
289
- }
290
- }
291
- setUser(user) {
292
- this.storage.setItem(USER_KEY, JSON.stringify(user));
293
- }
294
- clearSession() {
295
- this.storage.removeItem(TOKEN_KEY);
296
- this.storage.removeItem(USER_KEY);
297
- }
298
- shouldAttemptRefresh() {
299
- return false;
300
- }
301
- };
302
-
303
- // src/lib/token-manager.ts
304
- var TokenManager = class {
305
182
  /**
306
- * Create a new TokenManager
307
- * @param storage - Optional custom storage adapter (used for initial LocalSessionStorage)
183
+ * Get current mode
308
184
  */
309
- constructor(storage) {
310
- this.strategy = new LocalSessionStorage(storage);
185
+ get mode() {
186
+ return this._mode;
311
187
  }
312
188
  /**
313
- * Set the storage strategy
314
- * Called after capability discovery to switch to the appropriate strategy
189
+ * Set mode to memory (new backend with cookies + memory)
315
190
  */
316
- setStrategy(strategy) {
317
- const existingSession = this.strategy.getSession();
318
- const previousId = this.strategy.strategyId;
319
- this.strategy = strategy;
320
- if (existingSession && previousId !== strategy.strategyId) {
321
- strategy.saveSession(existingSession);
191
+ setMemoryMode() {
192
+ if (this._mode === "storage") {
193
+ this.storage.removeItem(TOKEN_KEY);
194
+ this.storage.removeItem(USER_KEY);
322
195
  }
196
+ this._mode = "memory";
197
+ }
198
+ /**
199
+ * Set mode to storage (legacy backend with localStorage)
200
+ * Also loads existing session from localStorage
201
+ */
202
+ setStorageMode() {
203
+ this._mode = "storage";
204
+ this.loadFromStorage();
323
205
  }
324
206
  /**
325
- * Get the current strategy identifier
207
+ * Load session from localStorage
326
208
  */
327
- getStrategyId() {
328
- return this.strategy.strategyId;
209
+ loadFromStorage() {
210
+ const token = this.storage.getItem(TOKEN_KEY);
211
+ const userStr = this.storage.getItem(USER_KEY);
212
+ if (token && userStr) {
213
+ try {
214
+ this.accessToken = token;
215
+ this.user = JSON.parse(userStr);
216
+ } catch {
217
+ this.clearSession();
218
+ }
219
+ }
329
220
  }
330
- // --- Delegated Methods ---
331
221
  /**
332
- * Save session data
222
+ * Save session (memory always, localStorage only in storage mode)
333
223
  */
334
224
  saveSession(session) {
335
- this.strategy.saveSession(session);
225
+ this.accessToken = session.accessToken;
226
+ this.user = session.user;
227
+ if (this._mode === "storage") {
228
+ this.storage.setItem(TOKEN_KEY, session.accessToken);
229
+ this.storage.setItem(USER_KEY, JSON.stringify(session.user));
230
+ }
336
231
  }
337
232
  /**
338
233
  * Get current session
339
234
  */
340
235
  getSession() {
341
- return this.strategy.getSession();
236
+ if (!this.accessToken || !this.user) return null;
237
+ return {
238
+ accessToken: this.accessToken,
239
+ user: this.user
240
+ };
342
241
  }
343
242
  /**
344
243
  * Get access token
345
244
  */
346
245
  getAccessToken() {
347
- return this.strategy.getAccessToken();
246
+ return this.accessToken;
348
247
  }
349
248
  /**
350
- * Update access token (e.g., after refresh)
249
+ * Set access token
351
250
  */
352
251
  setAccessToken(token) {
353
- this.strategy.setAccessToken(token);
252
+ this.accessToken = token;
253
+ if (this._mode === "storage") {
254
+ this.storage.setItem(TOKEN_KEY, token);
255
+ }
354
256
  }
355
257
  /**
356
- * Get user data
258
+ * Get user
357
259
  */
358
260
  getUser() {
359
- return this.strategy.getUser();
261
+ return this.user;
360
262
  }
361
263
  /**
362
- * Update user data
264
+ * Set user
363
265
  */
364
266
  setUser(user) {
365
- this.strategy.setUser(user);
267
+ this.user = user;
268
+ if (this._mode === "storage") {
269
+ this.storage.setItem(USER_KEY, JSON.stringify(user));
270
+ }
366
271
  }
367
272
  /**
368
- * Clear all session data
273
+ * Clear session (both memory and localStorage)
369
274
  */
370
275
  clearSession() {
371
- this.strategy.clearSession();
276
+ this.accessToken = null;
277
+ this.user = null;
278
+ this.storage.removeItem(TOKEN_KEY);
279
+ this.storage.removeItem(USER_KEY);
372
280
  }
373
281
  /**
374
- * Check if token refresh should be attempted
375
- * (e.g., on page reload in secure mode)
282
+ * Check if there's a session in localStorage (for legacy detection)
376
283
  */
377
- shouldAttemptRefresh() {
378
- return this.strategy.shouldAttemptRefresh();
284
+ hasStoredSession() {
285
+ const token = this.storage.getItem(TOKEN_KEY);
286
+ return !!token;
379
287
  }
380
288
  };
381
289
 
@@ -492,77 +400,75 @@ var Auth = class {
492
400
  this.detectAuthCallback();
493
401
  }
494
402
  /**
495
- * Set the isAuthenticated cookie flag on the frontend domain
496
- * This is managed by SDK, not backend, to work in cross-origin scenarios
497
- */
498
- setAuthenticatedCookie() {
499
- if (typeof document === "undefined") return;
500
- const maxAge = 7 * 24 * 60 * 60;
501
- document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
502
- }
503
- /**
504
- * Clear the isAuthenticated cookie flag from the frontend domain
505
- */
506
- clearAuthenticatedCookie() {
507
- if (typeof document === "undefined") return;
508
- document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
509
- }
510
- /**
511
- * Switch to SecureSessionStorage (cookie-based auth)
512
- * Called when backend returns sessionMode: 'secure'
513
- * @internal
514
- */
515
- _switchToSecureStorage() {
516
- console.log("[InsForge:Auth] _switchToSecureStorage() called, current strategy:", this.tokenManager.getStrategyId());
517
- if (this.tokenManager.getStrategyId() === "secure") {
518
- console.log("[InsForge:Auth] _switchToSecureStorage() - already in secure mode, skipping");
519
- return;
403
+ * Restore session on app initialization
404
+ *
405
+ * @returns Object with isLoggedIn status
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * const client = new InsForgeClient({ baseUrl: '...' });
410
+ * const { isLoggedIn } = await client.auth.restoreSession();
411
+ *
412
+ * if (isLoggedIn) {
413
+ * const { data } = await client.auth.getCurrentUser();
414
+ * }
415
+ * ```
416
+ */
417
+ async restoreSession() {
418
+ if (typeof window === "undefined") {
419
+ return { isLoggedIn: false };
520
420
  }
521
- const currentSession = this.tokenManager.getSession();
522
- this.tokenManager.setStrategy(new SecureSessionStorage());
523
- if (typeof localStorage !== "undefined") {
524
- console.log("[InsForge:Auth] _switchToSecureStorage() - clearing localStorage");
525
- localStorage.removeItem(TOKEN_KEY);
526
- localStorage.removeItem(USER_KEY);
421
+ if (this.tokenManager.getAccessToken()) {
422
+ return { isLoggedIn: true };
527
423
  }
528
- console.log("[InsForge:Auth] _switchToSecureStorage() - setting isAuthenticated cookie");
529
- this.setAuthenticatedCookie();
530
- if (currentSession) {
531
- this.tokenManager.saveSession(currentSession);
424
+ if (hasAuthCookie()) {
425
+ try {
426
+ const response = await this.http.post(
427
+ "/api/auth/refresh"
428
+ );
429
+ if (response.accessToken) {
430
+ this.tokenManager.setMemoryMode();
431
+ this.tokenManager.setAccessToken(response.accessToken);
432
+ this.http.setAuthToken(response.accessToken);
433
+ if (response.user) {
434
+ this.tokenManager.setUser(response.user);
435
+ }
436
+ return { isLoggedIn: true };
437
+ }
438
+ } catch (error) {
439
+ if (error instanceof InsForgeError) {
440
+ if (error.statusCode === 404) {
441
+ this.tokenManager.setStorageMode();
442
+ const token = this.tokenManager.getAccessToken();
443
+ if (token) {
444
+ this.http.setAuthToken(token);
445
+ return { isLoggedIn: true };
446
+ }
447
+ return { isLoggedIn: false };
448
+ }
449
+ if (error.statusCode === 401 || error.statusCode === 403) {
450
+ clearAuthCookie();
451
+ return { isLoggedIn: false };
452
+ }
453
+ }
454
+ return { isLoggedIn: false };
455
+ }
532
456
  }
533
- }
534
- /**
535
- * Switch to LocalSessionStorage (localStorage-based auth)
536
- * Called when cookie-based auth fails (fallback)
537
- * @internal
538
- */
539
- _switchToLocalStorage() {
540
- if (this.tokenManager.getStrategyId() === "local") return;
541
- const currentSession = this.tokenManager.getSession();
542
- this.tokenManager.setStrategy(new LocalSessionStorage());
543
- this.clearAuthenticatedCookie();
544
- if (currentSession) {
545
- this.tokenManager.saveSession(currentSession);
457
+ if (this.tokenManager.hasStoredSession()) {
458
+ this.tokenManager.setStorageMode();
459
+ const token = this.tokenManager.getAccessToken();
460
+ if (token) {
461
+ this.http.setAuthToken(token);
462
+ return { isLoggedIn: true };
463
+ }
546
464
  }
465
+ return { isLoggedIn: false };
547
466
  }
548
467
  /**
549
- * Detect storage strategy based on backend response
550
- * @param sessionMode - The sessionMode returned by backend ('secure' or undefined)
551
- * @internal
468
+ * Automatically detect and handle OAuth callback parameters in the URL
469
+ * This runs on initialization to seamlessly complete the OAuth flow
470
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
552
471
  */
553
- _detectStorageFromResponse(sessionMode) {
554
- console.log("[InsForge:Auth] _detectStorageFromResponse() - sessionMode:", sessionMode);
555
- if (sessionMode === "secure") {
556
- this._switchToSecureStorage();
557
- } else {
558
- this._switchToLocalStorage();
559
- }
560
- }
561
- /**
562
- * Automatically detect and handle OAuth callback parameters in the URL
563
- * This runs on initialization to seamlessly complete the OAuth flow
564
- * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
565
- */
566
472
  detectAuthCallback() {
567
473
  if (typeof window === "undefined") return;
568
474
  try {
@@ -571,9 +477,7 @@ var Auth = class {
571
477
  const userId = params.get("user_id");
572
478
  const email = params.get("email");
573
479
  const name = params.get("name");
574
- const sessionMode = params.get("session_mode");
575
480
  if (accessToken && userId && email) {
576
- this._detectStorageFromResponse(sessionMode || void 0);
577
481
  const session = {
578
482
  accessToken,
579
483
  user: {
@@ -587,14 +491,14 @@ var Auth = class {
587
491
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
588
492
  }
589
493
  };
590
- this.tokenManager.saveSession(session);
591
494
  this.http.setAuthToken(accessToken);
495
+ this.tokenManager.saveSession(session);
496
+ setAuthCookie();
592
497
  const url = new URL(window.location.href);
593
498
  url.searchParams.delete("access_token");
594
499
  url.searchParams.delete("user_id");
595
500
  url.searchParams.delete("email");
596
501
  url.searchParams.delete("name");
597
- url.searchParams.delete("session_mode");
598
502
  if (params.has("error")) {
599
503
  url.searchParams.delete("error");
600
504
  }
@@ -610,16 +514,13 @@ var Auth = class {
610
514
  async signUp(request) {
611
515
  try {
612
516
  const response = await this.http.post("/api/auth/users", request);
613
- const sessionMode = response.sessionMode;
614
- this._detectStorageFromResponse(sessionMode);
615
- if (response.accessToken && response.user) {
517
+ if (response.accessToken && response.user && !isHostedAuthEnvironment()) {
616
518
  const session = {
617
519
  accessToken: response.accessToken,
618
520
  user: response.user
619
521
  };
620
- if (!isHostedAuthEnvironment()) {
621
- this.tokenManager.saveSession(session);
622
- }
522
+ this.tokenManager.saveSession(session);
523
+ setAuthCookie();
623
524
  this.http.setAuthToken(response.accessToken);
624
525
  }
625
526
  return {
@@ -646,23 +547,15 @@ var Auth = class {
646
547
  async signInWithPassword(request) {
647
548
  try {
648
549
  const response = await this.http.post("/api/auth/sessions", request);
649
- const sessionMode = response.sessionMode;
650
- this._detectStorageFromResponse(sessionMode);
651
- const session = {
652
- accessToken: response.accessToken || "",
653
- user: response.user || {
654
- id: "",
655
- email: "",
656
- name: "",
657
- emailVerified: false,
658
- createdAt: "",
659
- updatedAt: ""
660
- }
661
- };
662
- if (!isHostedAuthEnvironment()) {
550
+ if (response.accessToken && response.user && !isHostedAuthEnvironment()) {
551
+ const session = {
552
+ accessToken: response.accessToken,
553
+ user: response.user
554
+ };
663
555
  this.tokenManager.saveSession(session);
556
+ setAuthCookie();
557
+ this.http.setAuthToken(response.accessToken);
664
558
  }
665
- this.http.setAuthToken(response.accessToken || "");
666
559
  return {
667
560
  data: response,
668
561
  error: null
@@ -717,28 +610,18 @@ var Auth = class {
717
610
  }
718
611
  /**
719
612
  * Sign out the current user
720
- * In modern mode, also calls backend to clear the refresh token cookie
721
613
  */
722
614
  async signOut() {
723
- console.log("[InsForge:Auth] signOut() called");
724
- console.log("[InsForge:Auth] signOut() stack trace:", new Error().stack);
725
615
  try {
726
- if (this.tokenManager.getStrategyId() === "secure") {
727
- console.log("[InsForge:Auth] signOut() - calling backend /api/auth/logout");
728
- try {
729
- await this.http.post("/api/auth/logout");
730
- console.log("[InsForge:Auth] signOut() - backend logout successful");
731
- } catch (e) {
732
- console.log("[InsForge:Auth] signOut() - backend logout failed (ignored):", e);
733
- }
616
+ try {
617
+ await this.http.post("/api/auth/logout");
618
+ } catch {
734
619
  }
735
620
  this.tokenManager.clearSession();
736
621
  this.http.setAuthToken(null);
737
- this.clearAuthenticatedCookie();
738
- console.log("[InsForge:Auth] signOut() - completed");
622
+ clearAuthCookie();
739
623
  return { error: null };
740
624
  } catch (error) {
741
- console.error("[InsForge:Auth] signOut() - error:", error);
742
625
  return {
743
626
  error: new InsForgeError(
744
627
  "Failed to sign out",
@@ -748,58 +631,6 @@ var Auth = class {
748
631
  };
749
632
  }
750
633
  }
751
- /**
752
- * Refresh the access token using the httpOnly refresh token cookie
753
- * Only works when backend supports secure session storage (httpOnly cookies)
754
- *
755
- * @returns New access token or throws an error
756
- */
757
- async refreshToken() {
758
- console.log("[InsForge:Auth] refreshToken() called");
759
- try {
760
- const response = await this.http.post(
761
- "/api/auth/refresh"
762
- );
763
- console.log("[InsForge:Auth] refreshToken() - response received, hasAccessToken:", !!response.accessToken);
764
- if (response.accessToken) {
765
- this._detectStorageFromResponse(response.sessionMode);
766
- this.tokenManager.setAccessToken(response.accessToken);
767
- this.http.setAuthToken(response.accessToken);
768
- if (response.user) {
769
- this.tokenManager.setUser(response.user);
770
- }
771
- console.log("[InsForge:Auth] refreshToken() - success");
772
- return response.accessToken;
773
- }
774
- throw new InsForgeError(
775
- "No access token in refresh response",
776
- 500,
777
- "REFRESH_FAILED"
778
- );
779
- } catch (error) {
780
- console.error("[InsForge:Auth] refreshToken() - error:", error);
781
- if (error instanceof InsForgeError) {
782
- if (error.statusCode === 404) {
783
- console.log("[InsForge:Auth] refreshToken() - 404 detected, backend does not support refresh endpoint");
784
- console.log("[InsForge:Auth] refreshToken() - switching to LocalSessionStorage for backward compatibility");
785
- this._switchToLocalStorage();
786
- this.clearAuthenticatedCookie();
787
- }
788
- if (error.statusCode === 401 || error.statusCode === 403) {
789
- console.log("[InsForge:Auth] refreshToken() - clearing session due to 401/403");
790
- this.tokenManager.clearSession();
791
- this.http.setAuthToken(null);
792
- this.clearAuthenticatedCookie();
793
- }
794
- throw error;
795
- }
796
- throw new InsForgeError(
797
- "Token refresh failed",
798
- 500,
799
- "REFRESH_FAILED"
800
- );
801
- }
802
- }
803
634
  /**
804
635
  * Get all public authentication configuration (OAuth + Email)
805
636
  * Returns both OAuth providers and email authentication settings in one request
@@ -840,40 +671,19 @@ var Auth = class {
840
671
  /**
841
672
  * Get the current user with full profile information
842
673
  * Returns both auth info (id, email, role) and profile data (dynamic fields from users table)
843
- *
844
- * In secure session mode (httpOnly cookie), this method will automatically attempt
845
- * to refresh the session if no access token is available (e.g., after page reload).
846
674
  */
847
675
  async getCurrentUser() {
848
- console.log("[InsForge:Auth] getCurrentUser() called");
849
676
  try {
850
- let accessToken = this.tokenManager.getAccessToken();
851
- const shouldRefresh = this.tokenManager.shouldAttemptRefresh();
852
- console.log("[InsForge:Auth] getCurrentUser() - hasAccessToken:", !!accessToken, "shouldAttemptRefresh:", shouldRefresh);
853
- if (!accessToken && shouldRefresh) {
854
- console.log("[InsForge:Auth] getCurrentUser() - attempting refresh");
855
- try {
856
- accessToken = await this.refreshToken();
857
- } catch (error) {
858
- console.log("[InsForge:Auth] getCurrentUser() - refresh failed:", error);
859
- if (error instanceof InsForgeError && (error.statusCode === 401 || error.statusCode === 403)) {
860
- return { data: null, error };
861
- }
862
- return { data: null, error: error instanceof InsForgeError ? error : new InsForgeError("Token refresh failed", 500, "REFRESH_FAILED") };
863
- }
864
- }
865
- if (!accessToken) {
866
- console.log("[InsForge:Auth] getCurrentUser() - no access token, returning null");
677
+ const session = this.tokenManager.getSession();
678
+ if (!session?.accessToken) {
867
679
  return { data: null, error: null };
868
680
  }
869
- this.http.setAuthToken(accessToken);
870
- console.log("[InsForge:Auth] getCurrentUser() - fetching user from API");
681
+ this.http.setAuthToken(session.accessToken);
871
682
  const authResponse = await this.http.get("/api/auth/sessions/current");
872
683
  const { data: profile, error: profileError } = await this.database.from("users").select("*").eq("id", authResponse.user.id).single();
873
684
  if (profileError && profileError.code !== "PGRST116") {
874
685
  return { data: null, error: profileError };
875
686
  }
876
- console.log("[InsForge:Auth] getCurrentUser() - success");
877
687
  return {
878
688
  data: {
879
689
  user: authResponse.user,
@@ -882,12 +692,8 @@ var Auth = class {
882
692
  error: null
883
693
  };
884
694
  } catch (error) {
885
- console.error("[InsForge:Auth] getCurrentUser() - catch error:", error);
886
695
  if (error instanceof InsForgeError && error.statusCode === 401) {
887
- console.log("[InsForge:Auth] getCurrentUser() - 401 error, clearing local session only (NOT calling signOut)");
888
- this.tokenManager.clearSession();
889
- this.http.setAuthToken(null);
890
- this.clearAuthenticatedCookie();
696
+ await this.signOut();
891
697
  return { data: null, error: null };
892
698
  }
893
699
  if (error instanceof InsForgeError) {
@@ -1135,15 +941,14 @@ var Auth = class {
1135
941
  "/api/auth/email/verify",
1136
942
  request
1137
943
  );
1138
- const sessionMode = response.sessionMode;
1139
- this._detectStorageFromResponse(sessionMode);
1140
- if (response.accessToken) {
944
+ if (response.accessToken && !isHostedAuthEnvironment()) {
1141
945
  const session = {
1142
946
  accessToken: response.accessToken,
1143
947
  user: response.user || {}
1144
948
  };
1145
949
  this.tokenManager.saveSession(session);
1146
950
  this.http.setAuthToken(response.accessToken);
951
+ setAuthCookie();
1147
952
  }
1148
953
  return {
1149
954
  data: response,
@@ -1687,24 +1492,10 @@ var Functions = class {
1687
1492
  };
1688
1493
 
1689
1494
  // src/client.ts
1690
- function hasAuthenticatedCookie() {
1691
- if (typeof document === "undefined") return false;
1692
- return document.cookie.split(";").some(
1693
- (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
1694
- );
1695
- }
1696
1495
  var InsForgeClient = class {
1697
1496
  constructor(config = {}) {
1698
- console.log("[InsForge:Client] Initializing SDK");
1699
1497
  this.http = new HttpClient(config);
1700
1498
  this.tokenManager = new TokenManager(config.storage);
1701
- const hasAuthCookie = hasAuthenticatedCookie();
1702
- console.log("[InsForge:Client] hasAuthenticatedCookie:", hasAuthCookie);
1703
- console.log("[InsForge:Client] document.cookie:", typeof document !== "undefined" ? document.cookie : "N/A (SSR)");
1704
- if (hasAuthCookie) {
1705
- console.log("[InsForge:Client] Switching to SecureSessionStorage");
1706
- this.tokenManager.setStrategy(new SecureSessionStorage());
1707
- }
1708
1499
  if (config.edgeFunctionToken) {
1709
1500
  this.http.setAuthToken(config.edgeFunctionToken);
1710
1501
  this.tokenManager.saveSession({
@@ -1713,32 +1504,15 @@ var InsForgeClient = class {
1713
1504
  // Will be populated by getCurrentUser()
1714
1505
  });
1715
1506
  }
1716
- this.http.setRefreshCallback(async () => {
1717
- console.log("[InsForge:Client] HTTP 401 refresh callback triggered");
1718
- try {
1719
- return await this.auth.refreshToken();
1720
- } catch (e) {
1721
- console.log("[InsForge:Client] Refresh callback failed:", e);
1722
- if (this.tokenManager.getStrategyId() === "secure") {
1723
- console.log("[InsForge:Client] Falling back to LocalSessionStorage");
1724
- this.auth._switchToLocalStorage();
1725
- }
1726
- return null;
1727
- }
1728
- });
1729
1507
  const existingSession = this.tokenManager.getSession();
1730
- console.log("[InsForge:Client] existingSession:", !!existingSession, "strategyId:", this.tokenManager.getStrategyId());
1731
1508
  if (existingSession?.accessToken) {
1732
1509
  this.http.setAuthToken(existingSession.accessToken);
1733
- } else if (this.tokenManager.getStrategyId() === "secure") {
1734
- console.log("[InsForge:Client] Secure mode, no session in memory - will refresh on first API call");
1735
1510
  }
1736
1511
  this.auth = new Auth(this.http, this.tokenManager);
1737
1512
  this.database = new Database(this.http, this.tokenManager);
1738
1513
  this.storage = new Storage(this.http);
1739
1514
  this.ai = new AI(this.http);
1740
1515
  this.functions = new Functions(this.http);
1741
- console.log("[InsForge:Client] SDK initialized");
1742
1516
  }
1743
1517
  /**
1744
1518
  * Get the underlying HTTP client for custom requests
@@ -1752,12 +1526,6 @@ var InsForgeClient = class {
1752
1526
  getHttpClient() {
1753
1527
  return this.http;
1754
1528
  }
1755
- /**
1756
- * Get the current storage strategy identifier
1757
- */
1758
- getStorageStrategy() {
1759
- return this.tokenManager.getStrategyId();
1760
- }
1761
1529
  /**
1762
1530
  * Future modules will be added here:
1763
1531
  * - database: Database operations
@@ -1781,8 +1549,6 @@ export {
1781
1549
  HttpClient,
1782
1550
  InsForgeClient,
1783
1551
  InsForgeError,
1784
- LocalSessionStorage,
1785
- SecureSessionStorage,
1786
1552
  Storage,
1787
1553
  StorageBucket,
1788
1554
  TokenManager,