@insforge/sdk 1.2.1-dev.0 → 1.2.1-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -3
- package/dist/index.d.mts +74 -74
- package/dist/index.d.ts +74 -74
- package/dist/index.js +315 -176
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +315 -176
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -232,6 +232,95 @@ var Logger = class {
|
|
|
232
232
|
}
|
|
233
233
|
};
|
|
234
234
|
|
|
235
|
+
// src/lib/token-manager.ts
|
|
236
|
+
var CSRF_TOKEN_COOKIE = "insforge_csrf_token";
|
|
237
|
+
function getCsrfToken() {
|
|
238
|
+
if (typeof document === "undefined") return null;
|
|
239
|
+
const match = document.cookie.split(";").find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));
|
|
240
|
+
if (!match) return null;
|
|
241
|
+
return match.split("=")[1] || null;
|
|
242
|
+
}
|
|
243
|
+
function setCsrfToken(token) {
|
|
244
|
+
if (typeof document === "undefined") return;
|
|
245
|
+
const maxAge = 7 * 24 * 60 * 60;
|
|
246
|
+
const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
|
|
247
|
+
document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;
|
|
248
|
+
}
|
|
249
|
+
function clearCsrfToken() {
|
|
250
|
+
if (typeof document === "undefined") return;
|
|
251
|
+
const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
|
|
252
|
+
document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;
|
|
253
|
+
}
|
|
254
|
+
var TokenManager = class {
|
|
255
|
+
constructor() {
|
|
256
|
+
// In-memory storage
|
|
257
|
+
this.accessToken = null;
|
|
258
|
+
this.user = null;
|
|
259
|
+
// Callback for token changes (used by realtime to reconnect with new token)
|
|
260
|
+
this.onTokenChange = null;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Save session in memory
|
|
264
|
+
*/
|
|
265
|
+
saveSession(session) {
|
|
266
|
+
const tokenChanged = session.accessToken !== this.accessToken;
|
|
267
|
+
this.accessToken = session.accessToken;
|
|
268
|
+
this.user = session.user;
|
|
269
|
+
if (tokenChanged && this.onTokenChange) {
|
|
270
|
+
this.onTokenChange();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get current session
|
|
275
|
+
*/
|
|
276
|
+
getSession() {
|
|
277
|
+
if (!this.accessToken || !this.user) return null;
|
|
278
|
+
return {
|
|
279
|
+
accessToken: this.accessToken,
|
|
280
|
+
user: this.user
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get access token
|
|
285
|
+
*/
|
|
286
|
+
getAccessToken() {
|
|
287
|
+
return this.accessToken;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Set access token
|
|
291
|
+
*/
|
|
292
|
+
setAccessToken(token) {
|
|
293
|
+
const tokenChanged = token !== this.accessToken;
|
|
294
|
+
this.accessToken = token;
|
|
295
|
+
if (tokenChanged && this.onTokenChange) {
|
|
296
|
+
this.onTokenChange();
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Get user
|
|
301
|
+
*/
|
|
302
|
+
getUser() {
|
|
303
|
+
return this.user;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Set user
|
|
307
|
+
*/
|
|
308
|
+
setUser(user) {
|
|
309
|
+
this.user = user;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Clear in-memory session
|
|
313
|
+
*/
|
|
314
|
+
clearSession() {
|
|
315
|
+
const hadToken = this.accessToken !== null;
|
|
316
|
+
this.accessToken = null;
|
|
317
|
+
this.user = null;
|
|
318
|
+
if (hadToken && this.onTokenChange) {
|
|
319
|
+
this.onTokenChange();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
235
324
|
// src/lib/http-client.ts
|
|
236
325
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
237
326
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
@@ -239,16 +328,23 @@ var HttpClient = class {
|
|
|
239
328
|
/**
|
|
240
329
|
* Creates a new HttpClient instance.
|
|
241
330
|
* @param config - SDK configuration including baseUrl, timeout, retry settings, and fetch implementation.
|
|
331
|
+
* @param tokenManager - Token manager for session persistence.
|
|
242
332
|
* @param logger - Optional logger instance for request/response debugging.
|
|
243
333
|
*/
|
|
244
|
-
constructor(config, logger) {
|
|
334
|
+
constructor(config, tokenManager, logger) {
|
|
245
335
|
this.userToken = null;
|
|
336
|
+
this.autoRefreshToken = true;
|
|
337
|
+
this.isRefreshing = false;
|
|
338
|
+
this.refreshPromise = null;
|
|
339
|
+
this.refreshToken = null;
|
|
246
340
|
this.baseUrl = config.baseUrl || "http://localhost:7130";
|
|
341
|
+
this.autoRefreshToken = config.autoRefreshToken ?? true;
|
|
247
342
|
this.fetch = config.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
248
343
|
this.anonKey = config.anonKey;
|
|
249
344
|
this.defaultHeaders = {
|
|
250
345
|
...config.headers
|
|
251
346
|
};
|
|
347
|
+
this.tokenManager = tokenManager ?? new TokenManager();
|
|
252
348
|
this.logger = logger || new Logger(false);
|
|
253
349
|
this.timeout = config.timeout ?? 3e4;
|
|
254
350
|
this.retryCount = config.retryCount ?? 3;
|
|
@@ -302,8 +398,14 @@ var HttpClient = class {
|
|
|
302
398
|
* @returns Parsed response data.
|
|
303
399
|
* @throws {InsForgeError} On timeout, network failure, or HTTP error responses.
|
|
304
400
|
*/
|
|
305
|
-
async
|
|
306
|
-
const {
|
|
401
|
+
async handleRequest(method, path, options = {}) {
|
|
402
|
+
const {
|
|
403
|
+
params,
|
|
404
|
+
headers = {},
|
|
405
|
+
body,
|
|
406
|
+
signal: callerSignal,
|
|
407
|
+
...fetchOptions
|
|
408
|
+
} = options;
|
|
307
409
|
const url = this.buildUrl(path, params);
|
|
308
410
|
const startTime = Date.now();
|
|
309
411
|
const canRetry = IDEMPOTENT_METHODS.has(method.toUpperCase()) || options.idempotent === true;
|
|
@@ -342,7 +444,9 @@ var HttpClient = class {
|
|
|
342
444
|
for (let attempt = 0; attempt <= maxAttempts; attempt++) {
|
|
343
445
|
if (attempt > 0) {
|
|
344
446
|
const delay = this.computeRetryDelay(attempt);
|
|
345
|
-
this.logger.warn(
|
|
447
|
+
this.logger.warn(
|
|
448
|
+
`Retry ${attempt}/${maxAttempts} for ${method} ${url} in ${delay}ms`
|
|
449
|
+
);
|
|
346
450
|
if (callerSignal?.aborted) throw callerSignal.reason;
|
|
347
451
|
await new Promise((resolve, reject) => {
|
|
348
452
|
const onAbort = () => {
|
|
@@ -350,7 +454,8 @@ var HttpClient = class {
|
|
|
350
454
|
reject(callerSignal.reason);
|
|
351
455
|
};
|
|
352
456
|
const timer2 = setTimeout(() => {
|
|
353
|
-
if (callerSignal)
|
|
457
|
+
if (callerSignal)
|
|
458
|
+
callerSignal.removeEventListener("abort", onAbort);
|
|
354
459
|
resolve();
|
|
355
460
|
}, delay);
|
|
356
461
|
if (callerSignal) {
|
|
@@ -370,10 +475,16 @@ var HttpClient = class {
|
|
|
370
475
|
controller.abort(callerSignal.reason);
|
|
371
476
|
} else {
|
|
372
477
|
const onCallerAbort = () => controller.abort(callerSignal.reason);
|
|
373
|
-
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
478
|
+
callerSignal.addEventListener("abort", onCallerAbort, {
|
|
479
|
+
once: true
|
|
480
|
+
});
|
|
481
|
+
controller.signal.addEventListener(
|
|
482
|
+
"abort",
|
|
483
|
+
() => {
|
|
484
|
+
callerSignal.removeEventListener("abort", onCallerAbort);
|
|
485
|
+
},
|
|
486
|
+
{ once: true }
|
|
487
|
+
);
|
|
377
488
|
}
|
|
378
489
|
}
|
|
379
490
|
}
|
|
@@ -417,7 +528,13 @@ var HttpClient = class {
|
|
|
417
528
|
}
|
|
418
529
|
if (timer !== void 0) clearTimeout(timer);
|
|
419
530
|
if (!response.ok) {
|
|
420
|
-
this.logger.logResponse(
|
|
531
|
+
this.logger.logResponse(
|
|
532
|
+
method,
|
|
533
|
+
url,
|
|
534
|
+
response.status,
|
|
535
|
+
Date.now() - startTime,
|
|
536
|
+
data
|
|
537
|
+
);
|
|
421
538
|
if (data && typeof data === "object" && "error" in data) {
|
|
422
539
|
if (!data.statusCode && !data.status) {
|
|
423
540
|
data.statusCode = response.status;
|
|
@@ -436,7 +553,13 @@ var HttpClient = class {
|
|
|
436
553
|
"REQUEST_FAILED"
|
|
437
554
|
);
|
|
438
555
|
}
|
|
439
|
-
this.logger.logResponse(
|
|
556
|
+
this.logger.logResponse(
|
|
557
|
+
method,
|
|
558
|
+
url,
|
|
559
|
+
response.status,
|
|
560
|
+
Date.now() - startTime,
|
|
561
|
+
data
|
|
562
|
+
);
|
|
440
563
|
return data;
|
|
441
564
|
} catch (err) {
|
|
442
565
|
if (timer !== void 0) clearTimeout(timer);
|
|
@@ -470,6 +593,33 @@ var HttpClient = class {
|
|
|
470
593
|
"NETWORK_ERROR"
|
|
471
594
|
);
|
|
472
595
|
}
|
|
596
|
+
async request(method, path, options = {}) {
|
|
597
|
+
try {
|
|
598
|
+
return await this.handleRequest(method, path, { ...options });
|
|
599
|
+
} catch (error) {
|
|
600
|
+
if (error instanceof InsForgeError && error.statusCode === 401 && error.error === "INVALID_TOKEN" && this.autoRefreshToken) {
|
|
601
|
+
try {
|
|
602
|
+
const newTokenData = await this.handleTokenRefresh();
|
|
603
|
+
this.setAuthToken(newTokenData.accessToken);
|
|
604
|
+
this.tokenManager.saveSession(newTokenData);
|
|
605
|
+
if (newTokenData.csrfToken) {
|
|
606
|
+
setCsrfToken(newTokenData.csrfToken);
|
|
607
|
+
}
|
|
608
|
+
if (newTokenData.refreshToken) {
|
|
609
|
+
this.setRefreshToken(newTokenData.refreshToken);
|
|
610
|
+
}
|
|
611
|
+
return await this.handleRequest(method, path, { ...options });
|
|
612
|
+
} catch (error2) {
|
|
613
|
+
this.tokenManager.clearSession();
|
|
614
|
+
this.userToken = null;
|
|
615
|
+
this.refreshToken = null;
|
|
616
|
+
clearCsrfToken();
|
|
617
|
+
throw error2;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
throw error;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
473
623
|
/** Performs a GET request. */
|
|
474
624
|
get(path, options) {
|
|
475
625
|
return this.request("GET", path, options);
|
|
@@ -494,6 +644,9 @@ var HttpClient = class {
|
|
|
494
644
|
setAuthToken(token) {
|
|
495
645
|
this.userToken = token;
|
|
496
646
|
}
|
|
647
|
+
setRefreshToken(token) {
|
|
648
|
+
this.refreshToken = token;
|
|
649
|
+
}
|
|
497
650
|
/** Returns the current default headers including the authorization header if set. */
|
|
498
651
|
getHeaders() {
|
|
499
652
|
const headers = { ...this.defaultHeaders };
|
|
@@ -503,94 +656,31 @@ var HttpClient = class {
|
|
|
503
656
|
}
|
|
504
657
|
return headers;
|
|
505
658
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
var CSRF_TOKEN_COOKIE = "insforge_csrf_token";
|
|
510
|
-
function getCsrfToken() {
|
|
511
|
-
if (typeof document === "undefined") return null;
|
|
512
|
-
const match = document.cookie.split(";").find((c) => c.trim().startsWith(`${CSRF_TOKEN_COOKIE}=`));
|
|
513
|
-
if (!match) return null;
|
|
514
|
-
return match.split("=")[1] || null;
|
|
515
|
-
}
|
|
516
|
-
function setCsrfToken(token) {
|
|
517
|
-
if (typeof document === "undefined") return;
|
|
518
|
-
const maxAge = 7 * 24 * 60 * 60;
|
|
519
|
-
const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
|
|
520
|
-
document.cookie = `${CSRF_TOKEN_COOKIE}=${encodeURIComponent(token)}; path=/; max-age=${maxAge}; SameSite=Lax${secure}`;
|
|
521
|
-
}
|
|
522
|
-
function clearCsrfToken() {
|
|
523
|
-
if (typeof document === "undefined") return;
|
|
524
|
-
const secure = typeof window !== "undefined" && window.location.protocol === "https:" ? "; Secure" : "";
|
|
525
|
-
document.cookie = `${CSRF_TOKEN_COOKIE}=; path=/; max-age=0; SameSite=Lax${secure}`;
|
|
526
|
-
}
|
|
527
|
-
var TokenManager = class {
|
|
528
|
-
constructor() {
|
|
529
|
-
// In-memory storage
|
|
530
|
-
this.accessToken = null;
|
|
531
|
-
this.user = null;
|
|
532
|
-
// Callback for token changes (used by realtime to reconnect with new token)
|
|
533
|
-
this.onTokenChange = null;
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Save session in memory
|
|
537
|
-
*/
|
|
538
|
-
saveSession(session) {
|
|
539
|
-
const tokenChanged = session.accessToken !== this.accessToken;
|
|
540
|
-
this.accessToken = session.accessToken;
|
|
541
|
-
this.user = session.user;
|
|
542
|
-
if (tokenChanged && this.onTokenChange) {
|
|
543
|
-
this.onTokenChange();
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Get current session
|
|
548
|
-
*/
|
|
549
|
-
getSession() {
|
|
550
|
-
if (!this.accessToken || !this.user) return null;
|
|
551
|
-
return {
|
|
552
|
-
accessToken: this.accessToken,
|
|
553
|
-
user: this.user
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Get access token
|
|
558
|
-
*/
|
|
559
|
-
getAccessToken() {
|
|
560
|
-
return this.accessToken;
|
|
561
|
-
}
|
|
562
|
-
/**
|
|
563
|
-
* Set access token
|
|
564
|
-
*/
|
|
565
|
-
setAccessToken(token) {
|
|
566
|
-
const tokenChanged = token !== this.accessToken;
|
|
567
|
-
this.accessToken = token;
|
|
568
|
-
if (tokenChanged && this.onTokenChange) {
|
|
569
|
-
this.onTokenChange();
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Get user
|
|
574
|
-
*/
|
|
575
|
-
getUser() {
|
|
576
|
-
return this.user;
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Set user
|
|
580
|
-
*/
|
|
581
|
-
setUser(user) {
|
|
582
|
-
this.user = user;
|
|
583
|
-
}
|
|
584
|
-
/**
|
|
585
|
-
* Clear in-memory session
|
|
586
|
-
*/
|
|
587
|
-
clearSession() {
|
|
588
|
-
const hadToken = this.accessToken !== null;
|
|
589
|
-
this.accessToken = null;
|
|
590
|
-
this.user = null;
|
|
591
|
-
if (hadToken && this.onTokenChange) {
|
|
592
|
-
this.onTokenChange();
|
|
659
|
+
async handleTokenRefresh() {
|
|
660
|
+
if (this.isRefreshing) {
|
|
661
|
+
return this.refreshPromise;
|
|
593
662
|
}
|
|
663
|
+
this.isRefreshing = true;
|
|
664
|
+
this.refreshPromise = (async () => {
|
|
665
|
+
try {
|
|
666
|
+
const csrfToken = getCsrfToken();
|
|
667
|
+
const body = this.refreshToken ? { refreshToken: this.refreshToken } : void 0;
|
|
668
|
+
const response = await this.handleRequest(
|
|
669
|
+
"POST",
|
|
670
|
+
"/api/auth/sessions/current",
|
|
671
|
+
{
|
|
672
|
+
body,
|
|
673
|
+
headers: csrfToken ? { "X-CSRF-Token": csrfToken } : {},
|
|
674
|
+
credentials: "include"
|
|
675
|
+
}
|
|
676
|
+
);
|
|
677
|
+
return response;
|
|
678
|
+
} finally {
|
|
679
|
+
this.isRefreshing = false;
|
|
680
|
+
this.refreshPromise = null;
|
|
681
|
+
}
|
|
682
|
+
})();
|
|
683
|
+
return this.refreshPromise;
|
|
594
684
|
}
|
|
595
685
|
};
|
|
596
686
|
|
|
@@ -679,6 +769,7 @@ var Auth = class {
|
|
|
679
769
|
this.tokenManager.saveSession(session);
|
|
680
770
|
}
|
|
681
771
|
this.http.setAuthToken(response.accessToken);
|
|
772
|
+
this.http.setRefreshToken(response.refreshToken ?? null);
|
|
682
773
|
return true;
|
|
683
774
|
}
|
|
684
775
|
// ============================================================================
|
|
@@ -686,7 +777,7 @@ var Auth = class {
|
|
|
686
777
|
// ============================================================================
|
|
687
778
|
/**
|
|
688
779
|
* Detect and handle OAuth callback parameters in URL
|
|
689
|
-
* Supports PKCE flow (insforge_code)
|
|
780
|
+
* Supports PKCE flow (insforge_code)
|
|
690
781
|
*/
|
|
691
782
|
async detectAuthCallback() {
|
|
692
783
|
if (this.isServerMode() || typeof window === "undefined") return;
|
|
@@ -707,31 +798,6 @@ var Auth = class {
|
|
|
707
798
|
}
|
|
708
799
|
return;
|
|
709
800
|
}
|
|
710
|
-
const accessToken = params.get("access_token");
|
|
711
|
-
const userId = params.get("user_id");
|
|
712
|
-
const email = params.get("email");
|
|
713
|
-
if (accessToken && userId && email) {
|
|
714
|
-
const csrfToken = params.get("csrf_token");
|
|
715
|
-
const name = params.get("name");
|
|
716
|
-
if (csrfToken) {
|
|
717
|
-
setCsrfToken(csrfToken);
|
|
718
|
-
}
|
|
719
|
-
const session = {
|
|
720
|
-
accessToken,
|
|
721
|
-
user: {
|
|
722
|
-
id: userId,
|
|
723
|
-
email,
|
|
724
|
-
profile: { name: name || "" },
|
|
725
|
-
metadata: null,
|
|
726
|
-
emailVerified: false,
|
|
727
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
728
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
729
|
-
}
|
|
730
|
-
};
|
|
731
|
-
this.tokenManager.saveSession(session);
|
|
732
|
-
this.http.setAuthToken(accessToken);
|
|
733
|
-
cleanUrlParams("access_token", "user_id", "email", "name", "csrf_token");
|
|
734
|
-
}
|
|
735
801
|
} catch (error) {
|
|
736
802
|
console.debug("OAuth callback detection skipped:", error);
|
|
737
803
|
}
|
|
@@ -749,6 +815,9 @@ var Auth = class {
|
|
|
749
815
|
if (response.accessToken && response.user) {
|
|
750
816
|
this.saveSessionFromResponse(response);
|
|
751
817
|
}
|
|
818
|
+
if (response.refreshToken) {
|
|
819
|
+
this.http.setRefreshToken(response.refreshToken);
|
|
820
|
+
}
|
|
752
821
|
return { data: response, error: null };
|
|
753
822
|
} catch (error) {
|
|
754
823
|
return wrapError(error, "An unexpected error occurred during sign up");
|
|
@@ -762,6 +831,9 @@ var Auth = class {
|
|
|
762
831
|
{ credentials: "include" }
|
|
763
832
|
);
|
|
764
833
|
this.saveSessionFromResponse(response);
|
|
834
|
+
if (response.refreshToken) {
|
|
835
|
+
this.http.setRefreshToken(response.refreshToken);
|
|
836
|
+
}
|
|
765
837
|
return { data: response, error: null };
|
|
766
838
|
} catch (error) {
|
|
767
839
|
return wrapError(error, "An unexpected error occurred during sign in");
|
|
@@ -779,12 +851,15 @@ var Auth = class {
|
|
|
779
851
|
}
|
|
780
852
|
this.tokenManager.clearSession();
|
|
781
853
|
this.http.setAuthToken(null);
|
|
854
|
+
this.http.setRefreshToken(null);
|
|
782
855
|
if (!this.isServerMode()) {
|
|
783
856
|
clearCsrfToken();
|
|
784
857
|
}
|
|
785
858
|
return { error: null };
|
|
786
859
|
} catch {
|
|
787
|
-
return {
|
|
860
|
+
return {
|
|
861
|
+
error: new InsForgeError("Failed to sign out", 500, "SIGNOUT_ERROR")
|
|
862
|
+
};
|
|
788
863
|
}
|
|
789
864
|
}
|
|
790
865
|
// ============================================================================
|
|
@@ -806,7 +881,9 @@ var Auth = class {
|
|
|
806
881
|
providerKey
|
|
807
882
|
);
|
|
808
883
|
const oauthPath = isBuiltInProvider ? `/api/auth/oauth/${providerKey}` : `/api/auth/oauth/custom/${providerKey}`;
|
|
809
|
-
const response = await this.http.get(oauthPath, {
|
|
884
|
+
const response = await this.http.get(oauthPath, {
|
|
885
|
+
params
|
|
886
|
+
});
|
|
810
887
|
if (!this.isServerMode() && typeof window !== "undefined" && !skipBrowserRedirect) {
|
|
811
888
|
window.location.href = response.authUrl;
|
|
812
889
|
return { data: {}, error: null };
|
|
@@ -846,7 +923,10 @@ var Auth = class {
|
|
|
846
923
|
)
|
|
847
924
|
};
|
|
848
925
|
}
|
|
849
|
-
const request = {
|
|
926
|
+
const request = {
|
|
927
|
+
code,
|
|
928
|
+
code_verifier: verifier
|
|
929
|
+
};
|
|
850
930
|
const response = await this.http.post(
|
|
851
931
|
this.isServerMode() ? "/api/auth/oauth/exchange?client_type=mobile" : "/api/auth/oauth/exchange",
|
|
852
932
|
request,
|
|
@@ -854,16 +934,14 @@ var Auth = class {
|
|
|
854
934
|
);
|
|
855
935
|
this.saveSessionFromResponse(response);
|
|
856
936
|
return {
|
|
857
|
-
data:
|
|
858
|
-
accessToken: response.accessToken,
|
|
859
|
-
refreshToken: response.refreshToken,
|
|
860
|
-
user: response.user,
|
|
861
|
-
redirectTo: response.redirectTo
|
|
862
|
-
},
|
|
937
|
+
data: response,
|
|
863
938
|
error: null
|
|
864
939
|
};
|
|
865
940
|
} catch (error) {
|
|
866
|
-
return wrapError(
|
|
941
|
+
return wrapError(
|
|
942
|
+
error,
|
|
943
|
+
"An unexpected error occurred during OAuth code exchange"
|
|
944
|
+
);
|
|
867
945
|
}
|
|
868
946
|
}
|
|
869
947
|
/**
|
|
@@ -882,16 +960,18 @@ var Auth = class {
|
|
|
882
960
|
{ credentials: "include" }
|
|
883
961
|
);
|
|
884
962
|
this.saveSessionFromResponse(response);
|
|
963
|
+
if (response.refreshToken) {
|
|
964
|
+
this.http.setRefreshToken(response.refreshToken);
|
|
965
|
+
}
|
|
885
966
|
return {
|
|
886
|
-
data:
|
|
887
|
-
accessToken: response.accessToken,
|
|
888
|
-
refreshToken: response.refreshToken,
|
|
889
|
-
user: response.user
|
|
890
|
-
},
|
|
967
|
+
data: response,
|
|
891
968
|
error: null
|
|
892
969
|
};
|
|
893
970
|
} catch (error) {
|
|
894
|
-
return wrapError(
|
|
971
|
+
return wrapError(
|
|
972
|
+
error,
|
|
973
|
+
"An unexpected error occurred during ID token sign in"
|
|
974
|
+
);
|
|
895
975
|
}
|
|
896
976
|
}
|
|
897
977
|
// ============================================================================
|
|
@@ -932,7 +1012,10 @@ var Auth = class {
|
|
|
932
1012
|
}
|
|
933
1013
|
return { data: response, error: null };
|
|
934
1014
|
} catch (error) {
|
|
935
|
-
return wrapError(
|
|
1015
|
+
return wrapError(
|
|
1016
|
+
error,
|
|
1017
|
+
"An unexpected error occurred during session refresh"
|
|
1018
|
+
);
|
|
936
1019
|
}
|
|
937
1020
|
}
|
|
938
1021
|
/**
|
|
@@ -945,7 +1028,9 @@ var Auth = class {
|
|
|
945
1028
|
const accessToken = this.tokenManager.getAccessToken();
|
|
946
1029
|
if (!accessToken) return { data: { user: null }, error: null };
|
|
947
1030
|
this.http.setAuthToken(accessToken);
|
|
948
|
-
const response = await this.http.get(
|
|
1031
|
+
const response = await this.http.get(
|
|
1032
|
+
"/api/auth/sessions/current"
|
|
1033
|
+
);
|
|
949
1034
|
const user = response.user ?? null;
|
|
950
1035
|
return { data: { user }, error: null };
|
|
951
1036
|
}
|
|
@@ -983,24 +1068,38 @@ var Auth = class {
|
|
|
983
1068
|
// ============================================================================
|
|
984
1069
|
async getProfile(userId) {
|
|
985
1070
|
try {
|
|
986
|
-
const response = await this.http.get(
|
|
1071
|
+
const response = await this.http.get(
|
|
1072
|
+
`/api/auth/profiles/${userId}`
|
|
1073
|
+
);
|
|
987
1074
|
return { data: response, error: null };
|
|
988
1075
|
} catch (error) {
|
|
989
|
-
return wrapError(
|
|
1076
|
+
return wrapError(
|
|
1077
|
+
error,
|
|
1078
|
+
"An unexpected error occurred while fetching user profile"
|
|
1079
|
+
);
|
|
990
1080
|
}
|
|
991
1081
|
}
|
|
992
1082
|
async setProfile(profile) {
|
|
993
1083
|
try {
|
|
994
|
-
const response = await this.http.patch(
|
|
995
|
-
|
|
996
|
-
|
|
1084
|
+
const response = await this.http.patch(
|
|
1085
|
+
"/api/auth/profiles/current",
|
|
1086
|
+
{
|
|
1087
|
+
profile
|
|
1088
|
+
}
|
|
1089
|
+
);
|
|
997
1090
|
const currentUser = this.tokenManager.getUser();
|
|
998
1091
|
if (!this.isServerMode() && currentUser && response.profile !== void 0) {
|
|
999
|
-
this.tokenManager.setUser({
|
|
1092
|
+
this.tokenManager.setUser({
|
|
1093
|
+
...currentUser,
|
|
1094
|
+
profile: response.profile
|
|
1095
|
+
});
|
|
1000
1096
|
}
|
|
1001
1097
|
return { data: response, error: null };
|
|
1002
1098
|
} catch (error) {
|
|
1003
|
-
return wrapError(
|
|
1099
|
+
return wrapError(
|
|
1100
|
+
error,
|
|
1101
|
+
"An unexpected error occurred while updating user profile"
|
|
1102
|
+
);
|
|
1004
1103
|
}
|
|
1005
1104
|
}
|
|
1006
1105
|
// ============================================================================
|
|
@@ -1008,19 +1107,15 @@ var Auth = class {
|
|
|
1008
1107
|
// ============================================================================
|
|
1009
1108
|
async resendVerificationEmail(request) {
|
|
1010
1109
|
try {
|
|
1011
|
-
const response = await this.http.post(
|
|
1012
|
-
"/api/auth/email/send-verification",
|
|
1013
|
-
request
|
|
1014
|
-
);
|
|
1110
|
+
const response = await this.http.post("/api/auth/email/send-verification", request);
|
|
1015
1111
|
return { data: response, error: null };
|
|
1016
1112
|
} catch (error) {
|
|
1017
|
-
return wrapError(
|
|
1113
|
+
return wrapError(
|
|
1114
|
+
error,
|
|
1115
|
+
"An unexpected error occurred while sending verification email"
|
|
1116
|
+
);
|
|
1018
1117
|
}
|
|
1019
1118
|
}
|
|
1020
|
-
/** @deprecated Use `resendVerificationEmail` instead */
|
|
1021
|
-
async sendVerificationEmail(request) {
|
|
1022
|
-
return this.resendVerificationEmail(request);
|
|
1023
|
-
}
|
|
1024
1119
|
async verifyEmail(request) {
|
|
1025
1120
|
try {
|
|
1026
1121
|
const response = await this.http.post(
|
|
@@ -1029,9 +1124,15 @@ var Auth = class {
|
|
|
1029
1124
|
{ credentials: "include" }
|
|
1030
1125
|
);
|
|
1031
1126
|
this.saveSessionFromResponse(response);
|
|
1127
|
+
if (response.refreshToken) {
|
|
1128
|
+
this.http.setRefreshToken(response.refreshToken);
|
|
1129
|
+
}
|
|
1032
1130
|
return { data: response, error: null };
|
|
1033
1131
|
} catch (error) {
|
|
1034
|
-
return wrapError(
|
|
1132
|
+
return wrapError(
|
|
1133
|
+
error,
|
|
1134
|
+
"An unexpected error occurred while verifying email"
|
|
1135
|
+
);
|
|
1035
1136
|
}
|
|
1036
1137
|
}
|
|
1037
1138
|
// ============================================================================
|
|
@@ -1039,13 +1140,13 @@ var Auth = class {
|
|
|
1039
1140
|
// ============================================================================
|
|
1040
1141
|
async sendResetPasswordEmail(request) {
|
|
1041
1142
|
try {
|
|
1042
|
-
const response = await this.http.post(
|
|
1043
|
-
"/api/auth/email/send-reset-password",
|
|
1044
|
-
request
|
|
1045
|
-
);
|
|
1143
|
+
const response = await this.http.post("/api/auth/email/send-reset-password", request);
|
|
1046
1144
|
return { data: response, error: null };
|
|
1047
1145
|
} catch (error) {
|
|
1048
|
-
return wrapError(
|
|
1146
|
+
return wrapError(
|
|
1147
|
+
error,
|
|
1148
|
+
"An unexpected error occurred while sending password reset email"
|
|
1149
|
+
);
|
|
1049
1150
|
}
|
|
1050
1151
|
}
|
|
1051
1152
|
async exchangeResetPasswordToken(request) {
|
|
@@ -1056,7 +1157,10 @@ var Auth = class {
|
|
|
1056
1157
|
);
|
|
1057
1158
|
return { data: response, error: null };
|
|
1058
1159
|
} catch (error) {
|
|
1059
|
-
return wrapError(
|
|
1160
|
+
return wrapError(
|
|
1161
|
+
error,
|
|
1162
|
+
"An unexpected error occurred while verifying reset code"
|
|
1163
|
+
);
|
|
1060
1164
|
}
|
|
1061
1165
|
}
|
|
1062
1166
|
async resetPassword(request) {
|
|
@@ -1067,7 +1171,10 @@ var Auth = class {
|
|
|
1067
1171
|
);
|
|
1068
1172
|
return { data: response, error: null };
|
|
1069
1173
|
} catch (error) {
|
|
1070
|
-
return wrapError(
|
|
1174
|
+
return wrapError(
|
|
1175
|
+
error,
|
|
1176
|
+
"An unexpected error occurred while resetting password"
|
|
1177
|
+
);
|
|
1071
1178
|
}
|
|
1072
1179
|
}
|
|
1073
1180
|
// ============================================================================
|
|
@@ -1075,10 +1182,15 @@ var Auth = class {
|
|
|
1075
1182
|
// ============================================================================
|
|
1076
1183
|
async getPublicAuthConfig() {
|
|
1077
1184
|
try {
|
|
1078
|
-
const response = await this.http.get(
|
|
1185
|
+
const response = await this.http.get(
|
|
1186
|
+
"/api/auth/public-config"
|
|
1187
|
+
);
|
|
1079
1188
|
return { data: response, error: null };
|
|
1080
1189
|
} catch (error) {
|
|
1081
|
-
return wrapError(
|
|
1190
|
+
return wrapError(
|
|
1191
|
+
error,
|
|
1192
|
+
"An unexpected error occurred while fetching auth configuration"
|
|
1193
|
+
);
|
|
1082
1194
|
}
|
|
1083
1195
|
}
|
|
1084
1196
|
};
|
|
@@ -1824,9 +1936,17 @@ var Functions = class _Functions {
|
|
|
1824
1936
|
});
|
|
1825
1937
|
return { data, error: null };
|
|
1826
1938
|
} catch (error) {
|
|
1827
|
-
if (error
|
|
1939
|
+
if (error instanceof Error && error.name === "AbortError") throw error;
|
|
1940
|
+
if (error instanceof InsForgeError && error.statusCode === 404) {
|
|
1828
1941
|
} else {
|
|
1829
|
-
return {
|
|
1942
|
+
return {
|
|
1943
|
+
data: null,
|
|
1944
|
+
error: error instanceof InsForgeError ? error : new InsForgeError(
|
|
1945
|
+
error instanceof Error ? error.message : "Function invocation failed",
|
|
1946
|
+
500,
|
|
1947
|
+
"FUNCTION_ERROR"
|
|
1948
|
+
)
|
|
1949
|
+
};
|
|
1830
1950
|
}
|
|
1831
1951
|
}
|
|
1832
1952
|
}
|
|
@@ -1835,7 +1955,15 @@ var Functions = class _Functions {
|
|
|
1835
1955
|
const data = await this.http.request(method, path, { body, headers });
|
|
1836
1956
|
return { data, error: null };
|
|
1837
1957
|
} catch (error) {
|
|
1838
|
-
|
|
1958
|
+
if (error instanceof Error && error.name === "AbortError") throw error;
|
|
1959
|
+
return {
|
|
1960
|
+
data: null,
|
|
1961
|
+
error: error instanceof InsForgeError ? error : new InsForgeError(
|
|
1962
|
+
error instanceof Error ? error.message : "Function invocation failed",
|
|
1963
|
+
500,
|
|
1964
|
+
"FUNCTION_ERROR"
|
|
1965
|
+
)
|
|
1966
|
+
};
|
|
1839
1967
|
}
|
|
1840
1968
|
}
|
|
1841
1969
|
};
|
|
@@ -2106,8 +2234,15 @@ var Emails = class {
|
|
|
2106
2234
|
);
|
|
2107
2235
|
return { data, error: null };
|
|
2108
2236
|
} catch (error) {
|
|
2109
|
-
|
|
2110
|
-
return {
|
|
2237
|
+
if (error instanceof Error && error.name === "AbortError") throw error;
|
|
2238
|
+
return {
|
|
2239
|
+
data: null,
|
|
2240
|
+
error: error instanceof InsForgeError ? error : new InsForgeError(
|
|
2241
|
+
error instanceof Error ? error.message : "Email send failed",
|
|
2242
|
+
500,
|
|
2243
|
+
"EMAIL_ERROR"
|
|
2244
|
+
)
|
|
2245
|
+
};
|
|
2111
2246
|
}
|
|
2112
2247
|
}
|
|
2113
2248
|
};
|
|
@@ -2116,8 +2251,8 @@ var Emails = class {
|
|
|
2116
2251
|
var InsForgeClient = class {
|
|
2117
2252
|
constructor(config = {}) {
|
|
2118
2253
|
const logger = new Logger(config.debug);
|
|
2119
|
-
this.http = new HttpClient(config, logger);
|
|
2120
2254
|
this.tokenManager = new TokenManager();
|
|
2255
|
+
this.http = new HttpClient(config, this.tokenManager, logger);
|
|
2121
2256
|
if (config.edgeFunctionToken) {
|
|
2122
2257
|
this.http.setAuthToken(config.edgeFunctionToken);
|
|
2123
2258
|
this.tokenManager.setAccessToken(config.edgeFunctionToken);
|
|
@@ -2129,12 +2264,16 @@ var InsForgeClient = class {
|
|
|
2129
2264
|
this.storage = new Storage(this.http);
|
|
2130
2265
|
this.ai = new AI(this.http);
|
|
2131
2266
|
this.functions = new Functions(this.http, config.functionsUrl);
|
|
2132
|
-
this.realtime = new Realtime(
|
|
2267
|
+
this.realtime = new Realtime(
|
|
2268
|
+
this.http.baseUrl,
|
|
2269
|
+
this.tokenManager,
|
|
2270
|
+
config.anonKey
|
|
2271
|
+
);
|
|
2133
2272
|
this.emails = new Emails(this.http);
|
|
2134
2273
|
}
|
|
2135
2274
|
/**
|
|
2136
2275
|
* Get the underlying HTTP client for custom requests
|
|
2137
|
-
*
|
|
2276
|
+
*
|
|
2138
2277
|
* @example
|
|
2139
2278
|
* ```typescript
|
|
2140
2279
|
* const httpClient = client.getHttpClient();
|