@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.js CHANGED
@@ -27,8 +27,6 @@ __export(index_exports, {
27
27
  HttpClient: () => HttpClient,
28
28
  InsForgeClient: () => InsForgeClient,
29
29
  InsForgeError: () => InsForgeError,
30
- LocalSessionStorage: () => LocalSessionStorage,
31
- SecureSessionStorage: () => SecureSessionStorage,
32
30
  Storage: () => Storage,
33
31
  StorageBucket: () => StorageBucket,
34
32
  TokenManager: () => TokenManager,
@@ -60,8 +58,6 @@ var InsForgeError = class _InsForgeError extends Error {
60
58
  var HttpClient = class {
61
59
  constructor(config) {
62
60
  this.userToken = null;
63
- this.isRefreshing = false;
64
- this.refreshQueue = [];
65
61
  this.baseUrl = config.baseUrl || "http://localhost:7130";
66
62
  this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
67
63
  this.anonKey = config.anonKey;
@@ -74,12 +70,6 @@ var HttpClient = class {
74
70
  );
75
71
  }
76
72
  }
77
- /**
78
- * Set the refresh callback for automatic token refresh on 401
79
- */
80
- setRefreshCallback(callback) {
81
- this.refreshCallback = callback;
82
- }
83
73
  buildUrl(path, params) {
84
74
  const url = new URL(path, this.baseUrl);
85
75
  if (params) {
@@ -96,9 +86,6 @@ var HttpClient = class {
96
86
  return url.toString();
97
87
  }
98
88
  async request(method, path, options = {}) {
99
- return this.performRequest(method, path, options, false);
100
- }
101
- async performRequest(method, path, options = {}, isRetry = false) {
102
89
  const { params, headers = {}, body, ...fetchOptions } = options;
103
90
  const url = this.buildUrl(path, params);
104
91
  const requestHeaders = {
@@ -124,17 +111,9 @@ var HttpClient = class {
124
111
  method,
125
112
  headers: requestHeaders,
126
113
  body: processedBody,
127
- ...fetchOptions,
128
- credentials: "include"
114
+ credentials: "include",
115
+ ...fetchOptions
129
116
  });
130
- const isRefreshEndpoint = path.includes("/api/auth/refresh") || path.includes("/api/auth/logout");
131
- if (response.status === 401 && !isRetry && !isRefreshEndpoint && this.refreshCallback) {
132
- const newToken = await this.handleTokenRefresh();
133
- if (newToken) {
134
- this.setAuthToken(newToken);
135
- return this.performRequest(method, path, options, true);
136
- }
137
- }
138
117
  if (response.status === 204) {
139
118
  return void 0;
140
119
  }
@@ -166,38 +145,6 @@ var HttpClient = class {
166
145
  }
167
146
  return data;
168
147
  }
169
- /**
170
- * Handle token refresh with queue to prevent duplicate refreshes
171
- * Multiple concurrent 401s will wait for a single refresh to complete
172
- */
173
- async handleTokenRefresh() {
174
- if (this.isRefreshing) {
175
- return new Promise((resolve, reject) => {
176
- this.refreshQueue.push({ resolve, reject });
177
- });
178
- }
179
- this.isRefreshing = true;
180
- try {
181
- const newToken = await this.refreshCallback?.();
182
- this.refreshQueue.forEach(({ resolve, reject }) => {
183
- if (newToken) {
184
- resolve(newToken);
185
- } else {
186
- reject(new Error("Token refresh failed"));
187
- }
188
- });
189
- this.refreshQueue = [];
190
- return newToken || null;
191
- } catch (error) {
192
- this.refreshQueue.forEach(({ reject }) => {
193
- reject(error instanceof Error ? error : new Error("Token refresh failed"));
194
- });
195
- this.refreshQueue = [];
196
- return null;
197
- } finally {
198
- this.isRefreshing = false;
199
- }
200
- }
201
148
  get(path, options) {
202
149
  return this.request("GET", path, options);
203
150
  }
@@ -226,58 +173,32 @@ var HttpClient = class {
226
173
  }
227
174
  };
228
175
 
229
- // src/lib/session-storage.ts
176
+ // src/lib/token-manager.ts
230
177
  var TOKEN_KEY = "insforge-auth-token";
231
178
  var USER_KEY = "insforge-auth-user";
232
179
  var AUTH_FLAG_COOKIE = "isAuthenticated";
233
- var SecureSessionStorage = class {
234
- constructor() {
235
- this.strategyId = "secure";
236
- this.accessToken = null;
237
- this.user = null;
238
- }
239
- saveSession(session) {
240
- this.accessToken = session.accessToken;
241
- this.user = session.user;
242
- }
243
- getSession() {
244
- if (!this.accessToken || !this.user) return null;
245
- return {
246
- accessToken: this.accessToken,
247
- user: this.user
248
- };
249
- }
250
- getAccessToken() {
251
- return this.accessToken;
252
- }
253
- setAccessToken(token) {
254
- this.accessToken = token;
255
- }
256
- getUser() {
257
- return this.user;
258
- }
259
- setUser(user) {
260
- this.user = user;
261
- }
262
- clearSession() {
180
+ function hasAuthCookie() {
181
+ if (typeof document === "undefined") return false;
182
+ return document.cookie.split(";").some(
183
+ (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
184
+ );
185
+ }
186
+ function setAuthCookie() {
187
+ if (typeof document === "undefined") return;
188
+ const maxAge = 7 * 24 * 60 * 60;
189
+ document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
190
+ }
191
+ function clearAuthCookie() {
192
+ if (typeof document === "undefined") return;
193
+ document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
194
+ }
195
+ var TokenManager = class {
196
+ constructor(storage) {
197
+ // In-memory storage
263
198
  this.accessToken = null;
264
199
  this.user = null;
265
- }
266
- shouldAttemptRefresh() {
267
- if (this.accessToken) return false;
268
- return this.hasAuthFlag();
269
- }
270
- // --- Private: Auth Flag Cookie Detection (SDK-managed on frontend domain) ---
271
- hasAuthFlag() {
272
- if (typeof document === "undefined") return false;
273
- return document.cookie.split(";").some(
274
- (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
275
- );
276
- }
277
- };
278
- var LocalSessionStorage = class {
279
- constructor(storage) {
280
- this.strategyId = "local";
200
+ // Mode: 'memory' (new backend) or 'storage' (legacy backend, default)
201
+ this._mode = "storage";
281
202
  if (storage) {
282
203
  this.storage = storage;
283
204
  } else if (typeof window !== "undefined" && window.localStorage) {
@@ -295,126 +216,111 @@ var LocalSessionStorage = class {
295
216
  };
296
217
  }
297
218
  }
298
- saveSession(session) {
299
- this.storage.setItem(TOKEN_KEY, session.accessToken);
300
- this.storage.setItem(USER_KEY, JSON.stringify(session.user));
301
- }
302
- getSession() {
303
- const token = this.storage.getItem(TOKEN_KEY);
304
- const userStr = this.storage.getItem(USER_KEY);
305
- if (!token || !userStr) return null;
306
- try {
307
- const user = JSON.parse(userStr);
308
- return { accessToken: token, user };
309
- } catch {
310
- this.clearSession();
311
- return null;
312
- }
313
- }
314
- getAccessToken() {
315
- const token = this.storage.getItem(TOKEN_KEY);
316
- return typeof token === "string" ? token : null;
317
- }
318
- setAccessToken(token) {
319
- this.storage.setItem(TOKEN_KEY, token);
320
- }
321
- getUser() {
322
- const userStr = this.storage.getItem(USER_KEY);
323
- if (!userStr) return null;
324
- try {
325
- return JSON.parse(userStr);
326
- } catch {
327
- return null;
328
- }
329
- }
330
- setUser(user) {
331
- this.storage.setItem(USER_KEY, JSON.stringify(user));
332
- }
333
- clearSession() {
334
- this.storage.removeItem(TOKEN_KEY);
335
- this.storage.removeItem(USER_KEY);
336
- }
337
- shouldAttemptRefresh() {
338
- return false;
339
- }
340
- };
341
-
342
- // src/lib/token-manager.ts
343
- var TokenManager = class {
344
219
  /**
345
- * Create a new TokenManager
346
- * @param storage - Optional custom storage adapter (used for initial LocalSessionStorage)
220
+ * Get current mode
347
221
  */
348
- constructor(storage) {
349
- this.strategy = new LocalSessionStorage(storage);
222
+ get mode() {
223
+ return this._mode;
350
224
  }
351
225
  /**
352
- * Set the storage strategy
353
- * Called after capability discovery to switch to the appropriate strategy
226
+ * Set mode to memory (new backend with cookies + memory)
354
227
  */
355
- setStrategy(strategy) {
356
- const existingSession = this.strategy.getSession();
357
- const previousId = this.strategy.strategyId;
358
- this.strategy = strategy;
359
- if (existingSession && previousId !== strategy.strategyId) {
360
- strategy.saveSession(existingSession);
228
+ setMemoryMode() {
229
+ if (this._mode === "storage") {
230
+ this.storage.removeItem(TOKEN_KEY);
231
+ this.storage.removeItem(USER_KEY);
361
232
  }
233
+ this._mode = "memory";
234
+ }
235
+ /**
236
+ * Set mode to storage (legacy backend with localStorage)
237
+ * Also loads existing session from localStorage
238
+ */
239
+ setStorageMode() {
240
+ this._mode = "storage";
241
+ this.loadFromStorage();
362
242
  }
363
243
  /**
364
- * Get the current strategy identifier
244
+ * Load session from localStorage
365
245
  */
366
- getStrategyId() {
367
- return this.strategy.strategyId;
246
+ loadFromStorage() {
247
+ const token = this.storage.getItem(TOKEN_KEY);
248
+ const userStr = this.storage.getItem(USER_KEY);
249
+ if (token && userStr) {
250
+ try {
251
+ this.accessToken = token;
252
+ this.user = JSON.parse(userStr);
253
+ } catch {
254
+ this.clearSession();
255
+ }
256
+ }
368
257
  }
369
- // --- Delegated Methods ---
370
258
  /**
371
- * Save session data
259
+ * Save session (memory always, localStorage only in storage mode)
372
260
  */
373
261
  saveSession(session) {
374
- this.strategy.saveSession(session);
262
+ this.accessToken = session.accessToken;
263
+ this.user = session.user;
264
+ if (this._mode === "storage") {
265
+ this.storage.setItem(TOKEN_KEY, session.accessToken);
266
+ this.storage.setItem(USER_KEY, JSON.stringify(session.user));
267
+ }
375
268
  }
376
269
  /**
377
270
  * Get current session
378
271
  */
379
272
  getSession() {
380
- return this.strategy.getSession();
273
+ if (!this.accessToken || !this.user) return null;
274
+ return {
275
+ accessToken: this.accessToken,
276
+ user: this.user
277
+ };
381
278
  }
382
279
  /**
383
280
  * Get access token
384
281
  */
385
282
  getAccessToken() {
386
- return this.strategy.getAccessToken();
283
+ return this.accessToken;
387
284
  }
388
285
  /**
389
- * Update access token (e.g., after refresh)
286
+ * Set access token
390
287
  */
391
288
  setAccessToken(token) {
392
- this.strategy.setAccessToken(token);
289
+ this.accessToken = token;
290
+ if (this._mode === "storage") {
291
+ this.storage.setItem(TOKEN_KEY, token);
292
+ }
393
293
  }
394
294
  /**
395
- * Get user data
295
+ * Get user
396
296
  */
397
297
  getUser() {
398
- return this.strategy.getUser();
298
+ return this.user;
399
299
  }
400
300
  /**
401
- * Update user data
301
+ * Set user
402
302
  */
403
303
  setUser(user) {
404
- this.strategy.setUser(user);
304
+ this.user = user;
305
+ if (this._mode === "storage") {
306
+ this.storage.setItem(USER_KEY, JSON.stringify(user));
307
+ }
405
308
  }
406
309
  /**
407
- * Clear all session data
310
+ * Clear session (both memory and localStorage)
408
311
  */
409
312
  clearSession() {
410
- this.strategy.clearSession();
313
+ this.accessToken = null;
314
+ this.user = null;
315
+ this.storage.removeItem(TOKEN_KEY);
316
+ this.storage.removeItem(USER_KEY);
411
317
  }
412
318
  /**
413
- * Check if token refresh should be attempted
414
- * (e.g., on page reload in secure mode)
319
+ * Check if there's a session in localStorage (for legacy detection)
415
320
  */
416
- shouldAttemptRefresh() {
417
- return this.strategy.shouldAttemptRefresh();
321
+ hasStoredSession() {
322
+ const token = this.storage.getItem(TOKEN_KEY);
323
+ return !!token;
418
324
  }
419
325
  };
420
326
 
@@ -531,77 +437,75 @@ var Auth = class {
531
437
  this.detectAuthCallback();
532
438
  }
533
439
  /**
534
- * Set the isAuthenticated cookie flag on the frontend domain
535
- * This is managed by SDK, not backend, to work in cross-origin scenarios
536
- */
537
- setAuthenticatedCookie() {
538
- if (typeof document === "undefined") return;
539
- const maxAge = 7 * 24 * 60 * 60;
540
- document.cookie = `${AUTH_FLAG_COOKIE}=true; path=/; max-age=${maxAge}; SameSite=Lax`;
541
- }
542
- /**
543
- * Clear the isAuthenticated cookie flag from the frontend domain
544
- */
545
- clearAuthenticatedCookie() {
546
- if (typeof document === "undefined") return;
547
- document.cookie = `${AUTH_FLAG_COOKIE}=; path=/; max-age=0; SameSite=Lax`;
548
- }
549
- /**
550
- * Switch to SecureSessionStorage (cookie-based auth)
551
- * Called when backend returns sessionMode: 'secure'
552
- * @internal
553
- */
554
- _switchToSecureStorage() {
555
- console.log("[InsForge:Auth] _switchToSecureStorage() called, current strategy:", this.tokenManager.getStrategyId());
556
- if (this.tokenManager.getStrategyId() === "secure") {
557
- console.log("[InsForge:Auth] _switchToSecureStorage() - already in secure mode, skipping");
558
- return;
440
+ * Restore session on app initialization
441
+ *
442
+ * @returns Object with isLoggedIn status
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * const client = new InsForgeClient({ baseUrl: '...' });
447
+ * const { isLoggedIn } = await client.auth.restoreSession();
448
+ *
449
+ * if (isLoggedIn) {
450
+ * const { data } = await client.auth.getCurrentUser();
451
+ * }
452
+ * ```
453
+ */
454
+ async restoreSession() {
455
+ if (typeof window === "undefined") {
456
+ return { isLoggedIn: false };
559
457
  }
560
- const currentSession = this.tokenManager.getSession();
561
- this.tokenManager.setStrategy(new SecureSessionStorage());
562
- if (typeof localStorage !== "undefined") {
563
- console.log("[InsForge:Auth] _switchToSecureStorage() - clearing localStorage");
564
- localStorage.removeItem(TOKEN_KEY);
565
- localStorage.removeItem(USER_KEY);
458
+ if (this.tokenManager.getAccessToken()) {
459
+ return { isLoggedIn: true };
566
460
  }
567
- console.log("[InsForge:Auth] _switchToSecureStorage() - setting isAuthenticated cookie");
568
- this.setAuthenticatedCookie();
569
- if (currentSession) {
570
- this.tokenManager.saveSession(currentSession);
461
+ if (hasAuthCookie()) {
462
+ try {
463
+ const response = await this.http.post(
464
+ "/api/auth/refresh"
465
+ );
466
+ if (response.accessToken) {
467
+ this.tokenManager.setMemoryMode();
468
+ this.tokenManager.setAccessToken(response.accessToken);
469
+ this.http.setAuthToken(response.accessToken);
470
+ if (response.user) {
471
+ this.tokenManager.setUser(response.user);
472
+ }
473
+ return { isLoggedIn: true };
474
+ }
475
+ } catch (error) {
476
+ if (error instanceof InsForgeError) {
477
+ if (error.statusCode === 404) {
478
+ this.tokenManager.setStorageMode();
479
+ const token = this.tokenManager.getAccessToken();
480
+ if (token) {
481
+ this.http.setAuthToken(token);
482
+ return { isLoggedIn: true };
483
+ }
484
+ return { isLoggedIn: false };
485
+ }
486
+ if (error.statusCode === 401 || error.statusCode === 403) {
487
+ clearAuthCookie();
488
+ return { isLoggedIn: false };
489
+ }
490
+ }
491
+ return { isLoggedIn: false };
492
+ }
571
493
  }
572
- }
573
- /**
574
- * Switch to LocalSessionStorage (localStorage-based auth)
575
- * Called when cookie-based auth fails (fallback)
576
- * @internal
577
- */
578
- _switchToLocalStorage() {
579
- if (this.tokenManager.getStrategyId() === "local") return;
580
- const currentSession = this.tokenManager.getSession();
581
- this.tokenManager.setStrategy(new LocalSessionStorage());
582
- this.clearAuthenticatedCookie();
583
- if (currentSession) {
584
- this.tokenManager.saveSession(currentSession);
494
+ if (this.tokenManager.hasStoredSession()) {
495
+ this.tokenManager.setStorageMode();
496
+ const token = this.tokenManager.getAccessToken();
497
+ if (token) {
498
+ this.http.setAuthToken(token);
499
+ return { isLoggedIn: true };
500
+ }
585
501
  }
502
+ return { isLoggedIn: false };
586
503
  }
587
504
  /**
588
- * Detect storage strategy based on backend response
589
- * @param sessionMode - The sessionMode returned by backend ('secure' or undefined)
590
- * @internal
505
+ * Automatically detect and handle OAuth callback parameters in the URL
506
+ * This runs on initialization to seamlessly complete the OAuth flow
507
+ * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
591
508
  */
592
- _detectStorageFromResponse(sessionMode) {
593
- console.log("[InsForge:Auth] _detectStorageFromResponse() - sessionMode:", sessionMode);
594
- if (sessionMode === "secure") {
595
- this._switchToSecureStorage();
596
- } else {
597
- this._switchToLocalStorage();
598
- }
599
- }
600
- /**
601
- * Automatically detect and handle OAuth callback parameters in the URL
602
- * This runs on initialization to seamlessly complete the OAuth flow
603
- * Matches the backend's OAuth callback response (backend/src/api/routes/auth.ts:540-544)
604
- */
605
509
  detectAuthCallback() {
606
510
  if (typeof window === "undefined") return;
607
511
  try {
@@ -610,9 +514,7 @@ var Auth = class {
610
514
  const userId = params.get("user_id");
611
515
  const email = params.get("email");
612
516
  const name = params.get("name");
613
- const sessionMode = params.get("session_mode");
614
517
  if (accessToken && userId && email) {
615
- this._detectStorageFromResponse(sessionMode || void 0);
616
518
  const session = {
617
519
  accessToken,
618
520
  user: {
@@ -626,14 +528,14 @@ var Auth = class {
626
528
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
627
529
  }
628
530
  };
629
- this.tokenManager.saveSession(session);
630
531
  this.http.setAuthToken(accessToken);
532
+ this.tokenManager.saveSession(session);
533
+ setAuthCookie();
631
534
  const url = new URL(window.location.href);
632
535
  url.searchParams.delete("access_token");
633
536
  url.searchParams.delete("user_id");
634
537
  url.searchParams.delete("email");
635
538
  url.searchParams.delete("name");
636
- url.searchParams.delete("session_mode");
637
539
  if (params.has("error")) {
638
540
  url.searchParams.delete("error");
639
541
  }
@@ -649,16 +551,13 @@ var Auth = class {
649
551
  async signUp(request) {
650
552
  try {
651
553
  const response = await this.http.post("/api/auth/users", request);
652
- const sessionMode = response.sessionMode;
653
- this._detectStorageFromResponse(sessionMode);
654
- if (response.accessToken && response.user) {
554
+ if (response.accessToken && response.user && !isHostedAuthEnvironment()) {
655
555
  const session = {
656
556
  accessToken: response.accessToken,
657
557
  user: response.user
658
558
  };
659
- if (!isHostedAuthEnvironment()) {
660
- this.tokenManager.saveSession(session);
661
- }
559
+ this.tokenManager.saveSession(session);
560
+ setAuthCookie();
662
561
  this.http.setAuthToken(response.accessToken);
663
562
  }
664
563
  return {
@@ -685,23 +584,15 @@ var Auth = class {
685
584
  async signInWithPassword(request) {
686
585
  try {
687
586
  const response = await this.http.post("/api/auth/sessions", request);
688
- const sessionMode = response.sessionMode;
689
- this._detectStorageFromResponse(sessionMode);
690
- const session = {
691
- accessToken: response.accessToken || "",
692
- user: response.user || {
693
- id: "",
694
- email: "",
695
- name: "",
696
- emailVerified: false,
697
- createdAt: "",
698
- updatedAt: ""
699
- }
700
- };
701
- if (!isHostedAuthEnvironment()) {
587
+ if (response.accessToken && response.user && !isHostedAuthEnvironment()) {
588
+ const session = {
589
+ accessToken: response.accessToken,
590
+ user: response.user
591
+ };
702
592
  this.tokenManager.saveSession(session);
593
+ setAuthCookie();
594
+ this.http.setAuthToken(response.accessToken);
703
595
  }
704
- this.http.setAuthToken(response.accessToken || "");
705
596
  return {
706
597
  data: response,
707
598
  error: null
@@ -756,28 +647,18 @@ var Auth = class {
756
647
  }
757
648
  /**
758
649
  * Sign out the current user
759
- * In modern mode, also calls backend to clear the refresh token cookie
760
650
  */
761
651
  async signOut() {
762
- console.log("[InsForge:Auth] signOut() called");
763
- console.log("[InsForge:Auth] signOut() stack trace:", new Error().stack);
764
652
  try {
765
- if (this.tokenManager.getStrategyId() === "secure") {
766
- console.log("[InsForge:Auth] signOut() - calling backend /api/auth/logout");
767
- try {
768
- await this.http.post("/api/auth/logout");
769
- console.log("[InsForge:Auth] signOut() - backend logout successful");
770
- } catch (e) {
771
- console.log("[InsForge:Auth] signOut() - backend logout failed (ignored):", e);
772
- }
653
+ try {
654
+ await this.http.post("/api/auth/logout");
655
+ } catch {
773
656
  }
774
657
  this.tokenManager.clearSession();
775
658
  this.http.setAuthToken(null);
776
- this.clearAuthenticatedCookie();
777
- console.log("[InsForge:Auth] signOut() - completed");
659
+ clearAuthCookie();
778
660
  return { error: null };
779
661
  } catch (error) {
780
- console.error("[InsForge:Auth] signOut() - error:", error);
781
662
  return {
782
663
  error: new InsForgeError(
783
664
  "Failed to sign out",
@@ -787,58 +668,6 @@ var Auth = class {
787
668
  };
788
669
  }
789
670
  }
790
- /**
791
- * Refresh the access token using the httpOnly refresh token cookie
792
- * Only works when backend supports secure session storage (httpOnly cookies)
793
- *
794
- * @returns New access token or throws an error
795
- */
796
- async refreshToken() {
797
- console.log("[InsForge:Auth] refreshToken() called");
798
- try {
799
- const response = await this.http.post(
800
- "/api/auth/refresh"
801
- );
802
- console.log("[InsForge:Auth] refreshToken() - response received, hasAccessToken:", !!response.accessToken);
803
- if (response.accessToken) {
804
- this._detectStorageFromResponse(response.sessionMode);
805
- this.tokenManager.setAccessToken(response.accessToken);
806
- this.http.setAuthToken(response.accessToken);
807
- if (response.user) {
808
- this.tokenManager.setUser(response.user);
809
- }
810
- console.log("[InsForge:Auth] refreshToken() - success");
811
- return response.accessToken;
812
- }
813
- throw new InsForgeError(
814
- "No access token in refresh response",
815
- 500,
816
- "REFRESH_FAILED"
817
- );
818
- } catch (error) {
819
- console.error("[InsForge:Auth] refreshToken() - error:", error);
820
- if (error instanceof InsForgeError) {
821
- if (error.statusCode === 404) {
822
- console.log("[InsForge:Auth] refreshToken() - 404 detected, backend does not support refresh endpoint");
823
- console.log("[InsForge:Auth] refreshToken() - switching to LocalSessionStorage for backward compatibility");
824
- this._switchToLocalStorage();
825
- this.clearAuthenticatedCookie();
826
- }
827
- if (error.statusCode === 401 || error.statusCode === 403) {
828
- console.log("[InsForge:Auth] refreshToken() - clearing session due to 401/403");
829
- this.tokenManager.clearSession();
830
- this.http.setAuthToken(null);
831
- this.clearAuthenticatedCookie();
832
- }
833
- throw error;
834
- }
835
- throw new InsForgeError(
836
- "Token refresh failed",
837
- 500,
838
- "REFRESH_FAILED"
839
- );
840
- }
841
- }
842
671
  /**
843
672
  * Get all public authentication configuration (OAuth + Email)
844
673
  * Returns both OAuth providers and email authentication settings in one request
@@ -879,40 +708,19 @@ var Auth = class {
879
708
  /**
880
709
  * Get the current user with full profile information
881
710
  * Returns both auth info (id, email, role) and profile data (dynamic fields from users table)
882
- *
883
- * In secure session mode (httpOnly cookie), this method will automatically attempt
884
- * to refresh the session if no access token is available (e.g., after page reload).
885
711
  */
886
712
  async getCurrentUser() {
887
- console.log("[InsForge:Auth] getCurrentUser() called");
888
713
  try {
889
- let accessToken = this.tokenManager.getAccessToken();
890
- const shouldRefresh = this.tokenManager.shouldAttemptRefresh();
891
- console.log("[InsForge:Auth] getCurrentUser() - hasAccessToken:", !!accessToken, "shouldAttemptRefresh:", shouldRefresh);
892
- if (!accessToken && shouldRefresh) {
893
- console.log("[InsForge:Auth] getCurrentUser() - attempting refresh");
894
- try {
895
- accessToken = await this.refreshToken();
896
- } catch (error) {
897
- console.log("[InsForge:Auth] getCurrentUser() - refresh failed:", error);
898
- if (error instanceof InsForgeError && (error.statusCode === 401 || error.statusCode === 403)) {
899
- return { data: null, error };
900
- }
901
- return { data: null, error: error instanceof InsForgeError ? error : new InsForgeError("Token refresh failed", 500, "REFRESH_FAILED") };
902
- }
903
- }
904
- if (!accessToken) {
905
- console.log("[InsForge:Auth] getCurrentUser() - no access token, returning null");
714
+ const session = this.tokenManager.getSession();
715
+ if (!session?.accessToken) {
906
716
  return { data: null, error: null };
907
717
  }
908
- this.http.setAuthToken(accessToken);
909
- console.log("[InsForge:Auth] getCurrentUser() - fetching user from API");
718
+ this.http.setAuthToken(session.accessToken);
910
719
  const authResponse = await this.http.get("/api/auth/sessions/current");
911
720
  const { data: profile, error: profileError } = await this.database.from("users").select("*").eq("id", authResponse.user.id).single();
912
721
  if (profileError && profileError.code !== "PGRST116") {
913
722
  return { data: null, error: profileError };
914
723
  }
915
- console.log("[InsForge:Auth] getCurrentUser() - success");
916
724
  return {
917
725
  data: {
918
726
  user: authResponse.user,
@@ -921,12 +729,8 @@ var Auth = class {
921
729
  error: null
922
730
  };
923
731
  } catch (error) {
924
- console.error("[InsForge:Auth] getCurrentUser() - catch error:", error);
925
732
  if (error instanceof InsForgeError && error.statusCode === 401) {
926
- console.log("[InsForge:Auth] getCurrentUser() - 401 error, clearing local session only (NOT calling signOut)");
927
- this.tokenManager.clearSession();
928
- this.http.setAuthToken(null);
929
- this.clearAuthenticatedCookie();
733
+ await this.signOut();
930
734
  return { data: null, error: null };
931
735
  }
932
736
  if (error instanceof InsForgeError) {
@@ -1174,15 +978,14 @@ var Auth = class {
1174
978
  "/api/auth/email/verify",
1175
979
  request
1176
980
  );
1177
- const sessionMode = response.sessionMode;
1178
- this._detectStorageFromResponse(sessionMode);
1179
- if (response.accessToken) {
981
+ if (response.accessToken && !isHostedAuthEnvironment()) {
1180
982
  const session = {
1181
983
  accessToken: response.accessToken,
1182
984
  user: response.user || {}
1183
985
  };
1184
986
  this.tokenManager.saveSession(session);
1185
987
  this.http.setAuthToken(response.accessToken);
988
+ setAuthCookie();
1186
989
  }
1187
990
  return {
1188
991
  data: response,
@@ -1726,24 +1529,10 @@ var Functions = class {
1726
1529
  };
1727
1530
 
1728
1531
  // src/client.ts
1729
- function hasAuthenticatedCookie() {
1730
- if (typeof document === "undefined") return false;
1731
- return document.cookie.split(";").some(
1732
- (c) => c.trim().startsWith(`${AUTH_FLAG_COOKIE}=`)
1733
- );
1734
- }
1735
1532
  var InsForgeClient = class {
1736
1533
  constructor(config = {}) {
1737
- console.log("[InsForge:Client] Initializing SDK");
1738
1534
  this.http = new HttpClient(config);
1739
1535
  this.tokenManager = new TokenManager(config.storage);
1740
- const hasAuthCookie = hasAuthenticatedCookie();
1741
- console.log("[InsForge:Client] hasAuthenticatedCookie:", hasAuthCookie);
1742
- console.log("[InsForge:Client] document.cookie:", typeof document !== "undefined" ? document.cookie : "N/A (SSR)");
1743
- if (hasAuthCookie) {
1744
- console.log("[InsForge:Client] Switching to SecureSessionStorage");
1745
- this.tokenManager.setStrategy(new SecureSessionStorage());
1746
- }
1747
1536
  if (config.edgeFunctionToken) {
1748
1537
  this.http.setAuthToken(config.edgeFunctionToken);
1749
1538
  this.tokenManager.saveSession({
@@ -1752,32 +1541,15 @@ var InsForgeClient = class {
1752
1541
  // Will be populated by getCurrentUser()
1753
1542
  });
1754
1543
  }
1755
- this.http.setRefreshCallback(async () => {
1756
- console.log("[InsForge:Client] HTTP 401 refresh callback triggered");
1757
- try {
1758
- return await this.auth.refreshToken();
1759
- } catch (e) {
1760
- console.log("[InsForge:Client] Refresh callback failed:", e);
1761
- if (this.tokenManager.getStrategyId() === "secure") {
1762
- console.log("[InsForge:Client] Falling back to LocalSessionStorage");
1763
- this.auth._switchToLocalStorage();
1764
- }
1765
- return null;
1766
- }
1767
- });
1768
1544
  const existingSession = this.tokenManager.getSession();
1769
- console.log("[InsForge:Client] existingSession:", !!existingSession, "strategyId:", this.tokenManager.getStrategyId());
1770
1545
  if (existingSession?.accessToken) {
1771
1546
  this.http.setAuthToken(existingSession.accessToken);
1772
- } else if (this.tokenManager.getStrategyId() === "secure") {
1773
- console.log("[InsForge:Client] Secure mode, no session in memory - will refresh on first API call");
1774
1547
  }
1775
1548
  this.auth = new Auth(this.http, this.tokenManager);
1776
1549
  this.database = new Database(this.http, this.tokenManager);
1777
1550
  this.storage = new Storage(this.http);
1778
1551
  this.ai = new AI(this.http);
1779
1552
  this.functions = new Functions(this.http);
1780
- console.log("[InsForge:Client] SDK initialized");
1781
1553
  }
1782
1554
  /**
1783
1555
  * Get the underlying HTTP client for custom requests
@@ -1791,12 +1563,6 @@ var InsForgeClient = class {
1791
1563
  getHttpClient() {
1792
1564
  return this.http;
1793
1565
  }
1794
- /**
1795
- * Get the current storage strategy identifier
1796
- */
1797
- getStorageStrategy() {
1798
- return this.tokenManager.getStrategyId();
1799
- }
1800
1566
  /**
1801
1567
  * Future modules will be added here:
1802
1568
  * - database: Database operations
@@ -1821,8 +1587,6 @@ var index_default = InsForgeClient;
1821
1587
  HttpClient,
1822
1588
  InsForgeClient,
1823
1589
  InsForgeError,
1824
- LocalSessionStorage,
1825
- SecureSessionStorage,
1826
1590
  Storage,
1827
1591
  StorageBucket,
1828
1592
  TokenManager,