@insforge/sdk 1.1.6 → 1.2.0-dev.1

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
@@ -175,8 +175,6 @@ var HttpClient = class {
175
175
  };
176
176
 
177
177
  // src/lib/token-manager.ts
178
- var TOKEN_KEY = "insforge-auth-token";
179
- var USER_KEY = "insforge-auth-user";
180
178
  var CSRF_TOKEN_COOKIE = "insforge_csrf_token";
181
179
  function getCsrfToken() {
182
180
  if (typeof document === "undefined") return null;
@@ -196,81 +194,20 @@ function clearCsrfToken() {
196
194
  document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;
197
195
  }
198
196
  var TokenManager = class {
199
- constructor(storage) {
197
+ constructor() {
200
198
  // In-memory storage
201
199
  this.accessToken = null;
202
200
  this.user = null;
203
- // Mode: 'memory' (new backend) or 'storage' (legacy backend, default)
204
- this._mode = "storage";
205
201
  // Callback for token changes (used by realtime to reconnect with new token)
206
202
  this.onTokenChange = null;
207
- if (storage) {
208
- this.storage = storage;
209
- } else if (typeof window !== "undefined" && window.localStorage) {
210
- this.storage = window.localStorage;
211
- } else {
212
- const store = /* @__PURE__ */ new Map();
213
- this.storage = {
214
- getItem: (key) => store.get(key) || null,
215
- setItem: (key, value) => {
216
- store.set(key, value);
217
- },
218
- removeItem: (key) => {
219
- store.delete(key);
220
- }
221
- };
222
- }
223
203
  }
224
204
  /**
225
- * Get current mode
226
- */
227
- get mode() {
228
- return this._mode;
229
- }
230
- /**
231
- * Set mode to memory (new backend with cookies + memory)
232
- */
233
- setMemoryMode() {
234
- if (this._mode === "storage") {
235
- this.storage.removeItem(TOKEN_KEY);
236
- this.storage.removeItem(USER_KEY);
237
- }
238
- this._mode = "memory";
239
- }
240
- /**
241
- * Set mode to storage (legacy backend with localStorage)
242
- * Also loads existing session from localStorage
243
- */
244
- setStorageMode() {
245
- this._mode = "storage";
246
- this.loadFromStorage();
247
- }
248
- /**
249
- * Load session from localStorage
250
- */
251
- loadFromStorage() {
252
- const token = this.storage.getItem(TOKEN_KEY);
253
- const userStr = this.storage.getItem(USER_KEY);
254
- if (token && userStr) {
255
- try {
256
- this.accessToken = token;
257
- this.user = JSON.parse(userStr);
258
- } catch {
259
- this.clearSession();
260
- }
261
- }
262
- }
263
- /**
264
- * Save session (memory always, localStorage only in storage mode)
205
+ * Save session in memory
265
206
  */
266
207
  saveSession(session) {
267
208
  const tokenChanged = session.accessToken !== this.accessToken;
268
209
  this.accessToken = session.accessToken;
269
210
  this.user = session.user;
270
- if (this._mode === "storage") {
271
- this.storage.setItem(TOKEN_KEY, session.accessToken);
272
- this.storage.setItem(USER_KEY, JSON.stringify(session.user));
273
- }
274
211
  if (tokenChanged && this.onTokenChange) {
275
212
  this.onTokenChange();
276
213
  }
@@ -279,7 +216,6 @@ var TokenManager = class {
279
216
  * Get current session
280
217
  */
281
218
  getSession() {
282
- this.loadFromStorage();
283
219
  if (!this.accessToken || !this.user) return null;
284
220
  return {
285
221
  accessToken: this.accessToken,
@@ -290,7 +226,6 @@ var TokenManager = class {
290
226
  * Get access token
291
227
  */
292
228
  getAccessToken() {
293
- this.loadFromStorage();
294
229
  return this.accessToken;
295
230
  }
296
231
  /**
@@ -299,9 +234,6 @@ var TokenManager = class {
299
234
  setAccessToken(token) {
300
235
  const tokenChanged = token !== this.accessToken;
301
236
  this.accessToken = token;
302
- if (this._mode === "storage") {
303
- this.storage.setItem(TOKEN_KEY, token);
304
- }
305
237
  if (tokenChanged && this.onTokenChange) {
306
238
  this.onTokenChange();
307
239
  }
@@ -317,30 +249,18 @@ var TokenManager = class {
317
249
  */
318
250
  setUser(user) {
319
251
  this.user = user;
320
- if (this._mode === "storage") {
321
- this.storage.setItem(USER_KEY, JSON.stringify(user));
322
- }
323
252
  }
324
253
  /**
325
- * Clear session (both memory and localStorage)
254
+ * Clear in-memory session
326
255
  */
327
256
  clearSession() {
328
257
  const hadToken = this.accessToken !== null;
329
258
  this.accessToken = null;
330
259
  this.user = null;
331
- this.storage.removeItem(TOKEN_KEY);
332
- this.storage.removeItem(USER_KEY);
333
260
  if (hadToken && this.onTokenChange) {
334
261
  this.onTokenChange();
335
262
  }
336
263
  }
337
- /**
338
- * Check if there's a session in localStorage (for legacy detection)
339
- */
340
- hasStoredSession() {
341
- const token = this.storage.getItem(TOKEN_KEY);
342
- return !!token;
343
- }
344
264
  };
345
265
 
346
266
  // src/modules/auth/helpers.ts
@@ -375,19 +295,6 @@ function retrievePkceVerifier() {
375
295
  }
376
296
  return verifier;
377
297
  }
378
- function isHostedAuthEnvironment() {
379
- if (typeof window === "undefined") {
380
- return false;
381
- }
382
- const { hostname, port, protocol } = window.location;
383
- if (hostname === "localhost" && port === "7130") {
384
- return true;
385
- }
386
- if (protocol === "https:" && hostname.endsWith(".insforge.app")) {
387
- return true;
388
- }
389
- return false;
390
- }
391
298
  function wrapError(error, fallbackMessage) {
392
299
  if (error instanceof InsForgeError) {
393
300
  return { data: null, error };
@@ -412,14 +319,18 @@ function cleanUrlParams(...params) {
412
319
 
413
320
  // src/modules/auth/auth.ts
414
321
  var Auth = class {
415
- constructor(http, tokenManager) {
322
+ constructor(http, tokenManager, options = {}) {
416
323
  this.http = http;
417
324
  this.tokenManager = tokenManager;
325
+ this.options = options;
418
326
  this.authCallbackHandled = this.detectAuthCallback();
419
327
  }
328
+ isServerMode() {
329
+ return !!this.options.isServerMode;
330
+ }
420
331
  /**
421
332
  * Save session from API response
422
- * Handles token storage, CSRF token, and HTTP client auth header
333
+ * Handles token storage, CSRF token, and HTTP auth header
423
334
  */
424
335
  saveSessionFromResponse(response) {
425
336
  if (!response.accessToken || !response.user) {
@@ -429,11 +340,12 @@ var Auth = class {
429
340
  accessToken: response.accessToken,
430
341
  user: response.user
431
342
  };
432
- if (response.csrfToken) {
433
- this.tokenManager.setMemoryMode();
343
+ if (!this.isServerMode() && response.csrfToken) {
434
344
  setCsrfToken(response.csrfToken);
435
345
  }
436
- this.tokenManager.saveSession(session);
346
+ if (!this.isServerMode()) {
347
+ this.tokenManager.saveSession(session);
348
+ }
437
349
  this.http.setAuthToken(response.accessToken);
438
350
  return true;
439
351
  }
@@ -445,7 +357,7 @@ var Auth = class {
445
357
  * Supports PKCE flow (insforge_code) and legacy flow (access_token in URL)
446
358
  */
447
359
  async detectAuthCallback() {
448
- if (typeof window === "undefined") return;
360
+ if (this.isServerMode() || typeof window === "undefined") return;
449
361
  try {
450
362
  const params = new URLSearchParams(window.location.search);
451
363
  const error = params.get("error");
@@ -470,7 +382,6 @@ var Auth = class {
470
382
  const csrfToken = params.get("csrf_token");
471
383
  const name = params.get("name");
472
384
  if (csrfToken) {
473
- this.tokenManager.setMemoryMode();
474
385
  setCsrfToken(csrfToken);
475
386
  }
476
387
  const session = {
@@ -499,7 +410,7 @@ var Auth = class {
499
410
  async signUp(request) {
500
411
  try {
501
412
  const response = await this.http.post(
502
- "/api/auth/users",
413
+ this.isServerMode() ? "/api/auth/users?client_type=mobile" : "/api/auth/users",
503
414
  request,
504
415
  { credentials: "include" }
505
416
  );
@@ -514,7 +425,7 @@ var Auth = class {
514
425
  async signInWithPassword(request) {
515
426
  try {
516
427
  const response = await this.http.post(
517
- "/api/auth/sessions",
428
+ this.isServerMode() ? "/api/auth/sessions?client_type=mobile" : "/api/auth/sessions",
518
429
  request,
519
430
  { credentials: "include" }
520
431
  );
@@ -527,12 +438,18 @@ var Auth = class {
527
438
  async signOut() {
528
439
  try {
529
440
  try {
530
- await this.http.post("/api/auth/logout", void 0, { credentials: "include" });
441
+ await this.http.post(
442
+ this.isServerMode() ? "/api/auth/logout?client_type=mobile" : "/api/auth/logout",
443
+ void 0,
444
+ { credentials: "include" }
445
+ );
531
446
  } catch {
532
447
  }
533
448
  this.tokenManager.clearSession();
534
449
  this.http.setAuthToken(null);
535
- clearCsrfToken();
450
+ if (!this.isServerMode()) {
451
+ clearCsrfToken();
452
+ }
536
453
  return { error: null };
537
454
  } catch {
538
455
  return { error: new InsForgeError("Failed to sign out", 500, "SIGNOUT_ERROR") };
@@ -552,11 +469,8 @@ var Auth = class {
552
469
  storePkceVerifier(codeVerifier);
553
470
  const params = { code_challenge: codeChallenge };
554
471
  if (redirectTo) params.redirect_uri = redirectTo;
555
- const response = await this.http.get(
556
- `/api/auth/oauth/${provider}`,
557
- { params }
558
- );
559
- if (typeof window !== "undefined" && !skipBrowserRedirect) {
472
+ const response = await this.http.get(`/api/auth/oauth/${provider}`, { params });
473
+ if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
560
474
  window.location.href = response.authUrl;
561
475
  return { data: {}, error: null };
562
476
  }
@@ -596,11 +510,16 @@ var Auth = class {
596
510
  };
597
511
  }
598
512
  const request = { code, code_verifier: verifier };
599
- const response = await this.http.post("/api/auth/oauth/exchange", request, { credentials: "include" });
513
+ const response = await this.http.post(
514
+ this.isServerMode() ? "/api/auth/oauth/exchange?client_type=mobile" : "/api/auth/oauth/exchange",
515
+ request,
516
+ { credentials: "include" }
517
+ );
600
518
  this.saveSessionFromResponse(response);
601
519
  return {
602
520
  data: {
603
521
  accessToken: response.accessToken,
522
+ refreshToken: response.refreshToken,
604
523
  user: response.user,
605
524
  redirectTo: response.redirectTo
606
525
  },
@@ -620,7 +539,11 @@ var Auth = class {
620
539
  async signInWithIdToken(credentials) {
621
540
  try {
622
541
  const { provider, token } = credentials;
623
- const response = await this.http.post("/api/auth/id-token?client_type=mobile", { provider, token }, { credentials: "include" });
542
+ const response = await this.http.post(
543
+ "/api/auth/id-token?client_type=mobile",
544
+ { provider, token },
545
+ { credentials: "include" }
546
+ );
624
547
  this.saveSessionFromResponse(response);
625
548
  return {
626
549
  data: {
@@ -638,102 +561,69 @@ var Auth = class {
638
561
  // Session Management
639
562
  // ============================================================================
640
563
  /**
641
- * Get current session, automatically waits for pending OAuth callback
642
- * @deprecated Use `getCurrentUser` instead
564
+ * Refresh the current auth session.
565
+ *
566
+ * Browser mode:
567
+ * - Uses httpOnly refresh cookie and optional CSRF header.
568
+ *
569
+ * Server mode (`isServerMode: true`):
570
+ * - Uses mobile auth flow and requires `refreshToken` in request body.
643
571
  */
644
- async getCurrentSession() {
645
- await this.authCallbackHandled;
572
+ async refreshSession(options) {
646
573
  try {
647
- const session = this.tokenManager.getSession();
648
- if (session) {
649
- this.http.setAuthToken(session.accessToken);
650
- return { data: { session }, error: null };
574
+ if (this.isServerMode() && !options?.refreshToken) {
575
+ return {
576
+ data: null,
577
+ error: new InsForgeError(
578
+ "refreshToken is required when refreshing session in server mode",
579
+ 400,
580
+ "REFRESH_TOKEN_REQUIRED"
581
+ )
582
+ };
651
583
  }
652
- if (typeof window !== "undefined") {
653
- try {
654
- const csrfToken = getCsrfToken();
655
- const response = await this.http.post("/api/auth/refresh", void 0, {
656
- headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
657
- credentials: "include"
658
- });
659
- if (response.accessToken) {
660
- this.tokenManager.setMemoryMode();
661
- this.tokenManager.setAccessToken(response.accessToken);
662
- this.http.setAuthToken(response.accessToken);
663
- if (response.user) this.tokenManager.setUser(response.user);
664
- if (response.csrfToken) setCsrfToken(response.csrfToken);
665
- return { data: { session: this.tokenManager.getSession() }, error: null };
666
- }
667
- } catch (error) {
668
- if (error instanceof InsForgeError) {
669
- if (error.statusCode === 404) {
670
- this.tokenManager.setStorageMode();
671
- const session2 = this.tokenManager.getSession();
672
- if (session2?.accessToken) {
673
- +this.http.setAuthToken(session2.accessToken);
674
- }
675
- return { data: { session: session2 }, error: null };
676
- }
677
- return { data: { session: null }, error };
678
- }
584
+ const csrfToken = !this.isServerMode() ? getCsrfToken() : null;
585
+ const response = await this.http.post(
586
+ this.isServerMode() ? "/api/auth/refresh?client_type=mobile" : "/api/auth/refresh",
587
+ this.isServerMode() ? { refreshToken: options?.refreshToken } : void 0,
588
+ {
589
+ headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
590
+ credentials: "include"
679
591
  }
592
+ );
593
+ if (response.accessToken) {
594
+ this.saveSessionFromResponse(response);
680
595
  }
681
- return { data: { session: null }, error: null };
596
+ return { data: response, error: null };
682
597
  } catch (error) {
683
- if (error instanceof InsForgeError) {
684
- return { data: { session: null }, error };
685
- }
686
- return {
687
- data: { session: null },
688
- error: new InsForgeError(
689
- "An unexpected error occurred while getting session",
690
- 500,
691
- "UNEXPECTED_ERROR"
692
- )
693
- };
598
+ return wrapError(error, "An unexpected error occurred during session refresh");
694
599
  }
695
600
  }
696
601
  /**
697
- * Get current user, automatically waits for pending OAuth callback
698
- */
602
+ * Get current user, automatically waits for pending OAuth callback
603
+ */
699
604
  async getCurrentUser() {
700
605
  await this.authCallbackHandled;
701
- if (isHostedAuthEnvironment()) {
702
- return { data: { user: null }, error: null };
703
- }
704
606
  try {
607
+ if (this.isServerMode()) {
608
+ const accessToken = this.tokenManager.getAccessToken();
609
+ if (!accessToken) return { data: { user: null }, error: null };
610
+ this.http.setAuthToken(accessToken);
611
+ const response = await this.http.get("/api/auth/sessions/current");
612
+ const user = response.user ?? null;
613
+ return { data: { user }, error: null };
614
+ }
705
615
  const session = this.tokenManager.getSession();
706
616
  if (session) {
707
617
  this.http.setAuthToken(session.accessToken);
708
618
  return { data: { user: session.user }, error: null };
709
619
  }
710
620
  if (typeof window !== "undefined") {
711
- try {
712
- const csrfToken = getCsrfToken();
713
- const response = await this.http.post("/api/auth/refresh", void 0, {
714
- headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
715
- credentials: "include"
716
- });
717
- if (response.accessToken) {
718
- this.tokenManager.setMemoryMode();
719
- this.tokenManager.setAccessToken(response.accessToken);
720
- this.http.setAuthToken(response.accessToken);
721
- if (response.user) this.tokenManager.setUser(response.user);
722
- if (response.csrfToken) setCsrfToken(response.csrfToken);
723
- return { data: { user: response.user ?? null }, error: null };
724
- }
725
- } catch (error) {
726
- if (error instanceof InsForgeError) {
727
- if (error.statusCode === 404) {
728
- this.tokenManager.setStorageMode();
729
- const session2 = this.tokenManager.getSession();
730
- if (session2?.accessToken) {
731
- +this.http.setAuthToken(session2.accessToken);
732
- }
733
- return { data: { user: session2?.user ?? null }, error: null };
734
- }
735
- return { data: { user: null }, error };
736
- }
621
+ const { data: refreshed, error: refreshError } = await this.refreshSession();
622
+ if (refreshError) {
623
+ return { data: { user: null }, error: refreshError };
624
+ }
625
+ if (refreshed?.accessToken) {
626
+ return { data: { user: refreshed.user ?? null }, error: null };
737
627
  }
738
628
  }
739
629
  return { data: { user: null }, error: null };
@@ -764,12 +654,11 @@ var Auth = class {
764
654
  }
765
655
  async setProfile(profile) {
766
656
  try {
767
- const response = await this.http.patch(
768
- "/api/auth/profiles/current",
769
- { profile }
770
- );
657
+ const response = await this.http.patch("/api/auth/profiles/current", {
658
+ profile
659
+ });
771
660
  const currentUser = this.tokenManager.getUser();
772
- if (currentUser && response.profile !== void 0) {
661
+ if (!this.isServerMode() && currentUser && response.profile !== void 0) {
773
662
  this.tokenManager.setUser({ ...currentUser, profile: response.profile });
774
663
  }
775
664
  return { data: response, error: null };
@@ -798,7 +687,7 @@ var Auth = class {
798
687
  async verifyEmail(request) {
799
688
  try {
800
689
  const response = await this.http.post(
801
- "/api/auth/email/verify",
690
+ this.isServerMode() ? "/api/auth/email/verify?client_type=mobile" : "/api/auth/email/verify",
802
691
  request,
803
692
  { credentials: "include" }
804
693
  );
@@ -1651,8 +1540,7 @@ var Realtime = class {
1651
1540
  return this.connectPromise;
1652
1541
  }
1653
1542
  this.connectPromise = new Promise((resolve, reject) => {
1654
- const session = this.tokenManager.getSession();
1655
- const token = session?.accessToken ?? this.anonKey;
1543
+ const token = this.tokenManager.getAccessToken() ?? this.anonKey;
1656
1544
  this.socket = (0, import_socket.io)(this.baseUrl, {
1657
1545
  transports: ["websocket"],
1658
1546
  auth: token ? { token } : void 0
@@ -1891,19 +1779,14 @@ var Emails = class {
1891
1779
  var InsForgeClient = class {
1892
1780
  constructor(config = {}) {
1893
1781
  this.http = new HttpClient(config);
1894
- this.tokenManager = new TokenManager(config.storage);
1782
+ this.tokenManager = new TokenManager();
1895
1783
  if (config.edgeFunctionToken) {
1896
1784
  this.http.setAuthToken(config.edgeFunctionToken);
1897
- this.tokenManager.saveSession({
1898
- accessToken: config.edgeFunctionToken,
1899
- user: {}
1900
- });
1901
- }
1902
- const existingSession = this.tokenManager.getSession();
1903
- if (existingSession?.accessToken) {
1904
- this.http.setAuthToken(existingSession.accessToken);
1785
+ this.tokenManager.setAccessToken(config.edgeFunctionToken);
1905
1786
  }
1906
- this.auth = new Auth(this.http, this.tokenManager);
1787
+ this.auth = new Auth(this.http, this.tokenManager, {
1788
+ isServerMode: config.isServerMode ?? false
1789
+ });
1907
1790
  this.database = new Database(this.http, this.tokenManager);
1908
1791
  this.storage = new Storage(this.http);
1909
1792
  this.ai = new AI(this.http);