@insforge/sdk 1.4.0 → 1.4.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 +139 -10
- package/SDK-REFERENCE.md +34 -20
- package/dist/{client-CqfpCc8Z.d.mts → client-BR9o-WUm.d.ts} +53 -112
- package/dist/{client-CqfpCc8Z.d.ts → client-C-qBRoea.d.mts} +53 -112
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +124 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -16
- package/dist/index.mjs.map +1 -1
- package/dist/middleware-K59XjpUX.d.mts +67 -0
- package/dist/middleware-Tu_RlUAt.d.ts +67 -0
- package/dist/ssr/middleware.d.mts +3 -0
- package/dist/ssr/middleware.d.ts +3 -0
- package/dist/ssr/middleware.js +461 -0
- package/dist/ssr/middleware.js.map +1 -0
- package/dist/ssr/middleware.mjs +428 -0
- package/dist/ssr/middleware.mjs.map +1 -0
- package/dist/ssr.d.mts +45 -66
- package/dist/ssr.d.ts +45 -66
- package/dist/ssr.js +234 -15
- package/dist/ssr.js.map +1 -1
- package/dist/ssr.mjs +233 -15
- package/dist/ssr.mjs.map +1 -1
- package/dist/types-Dk-44JJf.d.mts +130 -0
- package/dist/types-Dk-44JJf.d.ts +130 -0
- package/package.json +6 -1
package/dist/ssr.d.ts
CHANGED
|
@@ -1,72 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { I as InsForgeClient } from './client-BR9o-WUm.js';
|
|
2
|
+
import { I as InsForgeConfig, e as AuthRefreshResponse, d as InsForgeError } from './types-Dk-44JJf.js';
|
|
3
|
+
import { A as AuthCookieSettings, C as CookieStore, a as CookieWriter } from './middleware-Tu_RlUAt.js';
|
|
4
|
+
export { h as AuthCookieNames, i as AuthCookieOptions, j as CookieOptions, k as CookieReader, D as DEFAULT_ACCESS_TOKEN_COOKIE, c as DEFAULT_REFRESH_TOKEN_COOKIE, U as UpdateSessionOptions, b as UpdateSessionResult, d as accessTokenCookieOptions, e as clearAuthCookies, g as getAccessTokenCookieName, f as getRefreshTokenCookieName, r as refreshTokenCookieOptions, s as setAuthCookies, u as updateSession } from './middleware-Tu_RlUAt.js';
|
|
2
5
|
import '@insforge/shared-schemas';
|
|
3
6
|
import '@supabase/postgrest-js';
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
interface CookieOptions {
|
|
12
|
-
domain?: string;
|
|
13
|
-
path?: string;
|
|
14
|
-
expires?: Date;
|
|
15
|
-
maxAge?: number;
|
|
16
|
-
httpOnly?: boolean;
|
|
17
|
-
secure?: boolean;
|
|
18
|
-
sameSite?: 'lax' | 'strict' | 'none';
|
|
19
|
-
}
|
|
20
|
-
interface AuthCookieOptions {
|
|
21
|
-
accessToken?: CookieOptions;
|
|
22
|
-
refreshToken?: CookieOptions;
|
|
23
|
-
}
|
|
24
|
-
type CookieStoreValue = string | {
|
|
25
|
-
value?: string | null;
|
|
26
|
-
} | undefined | null;
|
|
27
|
-
interface CookieReader {
|
|
28
|
-
get(name: string): CookieStoreValue;
|
|
29
|
-
}
|
|
30
|
-
interface CookieWriter {
|
|
31
|
-
set?(name: string, value: string, options?: CookieOptions): unknown;
|
|
32
|
-
set?(options: {
|
|
33
|
-
name: string;
|
|
34
|
-
value: string;
|
|
35
|
-
} & CookieOptions): unknown;
|
|
36
|
-
delete?(name: string): unknown;
|
|
37
|
-
delete?(options: {
|
|
38
|
-
name: string;
|
|
39
|
-
} & CookieOptions): unknown;
|
|
40
|
-
}
|
|
41
|
-
interface CookieStore extends CookieReader, CookieWriter {
|
|
42
|
-
}
|
|
43
|
-
interface AuthCookieSettings {
|
|
44
|
-
names?: AuthCookieNames;
|
|
45
|
-
options?: AuthCookieOptions;
|
|
46
|
-
}
|
|
47
|
-
declare function getAccessTokenCookieName(names?: AuthCookieNames): string;
|
|
48
|
-
declare function getRefreshTokenCookieName(names?: AuthCookieNames): string;
|
|
49
|
-
declare function accessTokenCookieOptions(token: string, overrides?: CookieOptions): CookieOptions;
|
|
50
|
-
declare function refreshTokenCookieOptions(token: string, overrides?: CookieOptions): CookieOptions;
|
|
51
|
-
declare function setAuthCookies(cookies: CookieWriter | undefined, tokens: {
|
|
52
|
-
accessToken: string;
|
|
53
|
-
refreshToken?: string | null;
|
|
54
|
-
}, settings?: AuthCookieSettings): void;
|
|
55
|
-
declare function clearAuthCookies(cookies: CookieWriter | undefined, settings?: AuthCookieSettings): void;
|
|
56
|
-
|
|
57
|
-
interface CreateBrowserClientOptions extends Omit<InsForgeConfig, 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
8
|
+
type BrowserAuth = Pick<InsForgeClient['auth'], 'getCurrentUser' | 'getProfile' | 'getPublicAuthConfig'>;
|
|
9
|
+
type BrowserInsForgeClient = Omit<InsForgeClient, 'auth'> & {
|
|
10
|
+
readonly auth: BrowserAuth;
|
|
11
|
+
};
|
|
12
|
+
interface CreateBrowserClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
58
13
|
refreshUrl?: string;
|
|
59
14
|
refreshLeewaySeconds?: number;
|
|
60
15
|
}
|
|
61
|
-
declare function createBrowserClient(options?: CreateBrowserClientOptions):
|
|
16
|
+
declare function createBrowserClient(options?: CreateBrowserClientOptions): BrowserInsForgeClient;
|
|
62
17
|
|
|
63
|
-
interface CreateServerClientOptions extends Omit<InsForgeConfig, 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
18
|
+
interface CreateServerClientOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
64
19
|
cookies?: Pick<CookieStore, 'get'>;
|
|
65
20
|
accessToken?: string;
|
|
66
21
|
}
|
|
67
22
|
declare function createServerClient(options?: CreateServerClientOptions): InsForgeClient;
|
|
68
23
|
|
|
69
|
-
interface RefreshAuthOptions extends Omit<InsForgeConfig, 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
24
|
+
interface RefreshAuthOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
70
25
|
request?: Request;
|
|
71
26
|
cookies?: Pick<CookieStore, 'get'>;
|
|
72
27
|
refreshToken?: string;
|
|
@@ -84,16 +39,40 @@ declare function createRefreshAuthRouter(options?: Omit<RefreshAuthOptions, 'req
|
|
|
84
39
|
POST: RefreshAuthRouteHandler;
|
|
85
40
|
};
|
|
86
41
|
|
|
87
|
-
interface
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
42
|
+
interface CreateAuthActionsOptions extends Omit<InsForgeConfig, 'accessToken' | 'edgeFunctionToken' | 'isServerMode' | 'auth'>, AuthCookieSettings {
|
|
43
|
+
/**
|
|
44
|
+
* Read/write cookie store. Use this in Next.js Server Actions:
|
|
45
|
+
* `createAuthActions({ cookies: await cookies() })`.
|
|
46
|
+
*/
|
|
47
|
+
cookies?: CookieStore;
|
|
48
|
+
/**
|
|
49
|
+
* Request cookie reader. Use with `responseCookies` in Route Handlers where
|
|
50
|
+
* request and response cookies are separate objects.
|
|
51
|
+
*/
|
|
52
|
+
requestCookies?: Pick<CookieStore, 'get'>;
|
|
53
|
+
/**
|
|
54
|
+
* Response cookie writer. Use with `requestCookies` in Route Handlers.
|
|
55
|
+
*/
|
|
56
|
+
responseCookies?: CookieWriter;
|
|
91
57
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
58
|
+
type AuthTokenKeys = 'accessToken' | 'refreshToken' | 'csrfToken';
|
|
59
|
+
type SafeAuthData<T> = Omit<NonNullable<T>, AuthTokenKeys>;
|
|
60
|
+
type AuthResultData<TMethod extends (...args: any[]) => Promise<any>> = Awaited<ReturnType<TMethod>> extends {
|
|
61
|
+
data: infer TData;
|
|
62
|
+
} ? TData : never;
|
|
63
|
+
type SafeAuthAction<TMethod extends (...args: any[]) => Promise<any>> = (...args: Parameters<TMethod>) => Promise<{
|
|
64
|
+
data: SafeAuthData<AuthResultData<TMethod>> | null;
|
|
95
65
|
error: InsForgeError | null;
|
|
66
|
+
}>;
|
|
67
|
+
interface AuthActions {
|
|
68
|
+
signUp: SafeAuthAction<InsForgeClient['auth']['signUp']>;
|
|
69
|
+
signInWithPassword: SafeAuthAction<InsForgeClient['auth']['signInWithPassword']>;
|
|
70
|
+
signInWithOAuth: InsForgeClient['auth']['signInWithOAuth'];
|
|
71
|
+
signInWithIdToken: SafeAuthAction<InsForgeClient['auth']['signInWithIdToken']>;
|
|
72
|
+
exchangeOAuthCode: SafeAuthAction<InsForgeClient['auth']['exchangeOAuthCode']>;
|
|
73
|
+
verifyEmail: SafeAuthAction<InsForgeClient['auth']['verifyEmail']>;
|
|
74
|
+
signOut: InsForgeClient['auth']['signOut'];
|
|
96
75
|
}
|
|
97
|
-
declare function
|
|
76
|
+
declare function createAuthActions(options?: CreateAuthActionsOptions): AuthActions;
|
|
98
77
|
|
|
99
|
-
export { type
|
|
78
|
+
export { type AuthActions, AuthCookieSettings, CookieStore, CookieWriter, type CreateAuthActionsOptions, type CreateBrowserClientOptions, type CreateServerClientOptions, type RefreshAuthOptions, type RefreshAuthResult, type RefreshAuthRouteHandler, createAuthActions, createBrowserClient, createRefreshAuthRouter, createServerClient, refreshAuth };
|
package/dist/ssr.js
CHANGED
|
@@ -34,6 +34,7 @@ __export(ssr_exports, {
|
|
|
34
34
|
DEFAULT_REFRESH_TOKEN_COOKIE: () => DEFAULT_REFRESH_TOKEN_COOKIE,
|
|
35
35
|
accessTokenCookieOptions: () => accessTokenCookieOptions,
|
|
36
36
|
clearAuthCookies: () => clearAuthCookies,
|
|
37
|
+
createAuthActions: () => createAuthActions,
|
|
37
38
|
createBrowserClient: () => createBrowserClient,
|
|
38
39
|
createRefreshAuthRouter: () => createRefreshAuthRouter,
|
|
39
40
|
createServerClient: () => createServerClient,
|
|
@@ -445,7 +446,7 @@ var HttpClient = class {
|
|
|
445
446
|
return Math.round(jitter);
|
|
446
447
|
}
|
|
447
448
|
shouldRefreshAccessToken(statusCode, errorCode, authToken, options = {}) {
|
|
448
|
-
return statusCode === 401 && REFRESHABLE_AUTH_ERROR_CODES.has(errorCode ?? "") && !this.config.isServerMode && !this.config.edgeFunctionToken && !options.skipAuthRefresh && authToken !== null;
|
|
449
|
+
return statusCode === 401 && REFRESHABLE_AUTH_ERROR_CODES.has(errorCode ?? "") && !this.config.isServerMode && !this.config.accessToken && !this.config.edgeFunctionToken && !options.skipAuthRefresh && authToken !== null;
|
|
449
450
|
}
|
|
450
451
|
async fetchWithRetry(args) {
|
|
451
452
|
const {
|
|
@@ -881,19 +882,32 @@ var HttpClient = class {
|
|
|
881
882
|
|
|
882
883
|
// src/modules/auth/helpers.ts
|
|
883
884
|
var PKCE_VERIFIER_KEY = "insforge_pkce_verifier";
|
|
885
|
+
async function getWebCrypto() {
|
|
886
|
+
const webCrypto = globalThis.crypto;
|
|
887
|
+
if (typeof webCrypto?.getRandomValues === "function" && webCrypto.subtle) {
|
|
888
|
+
return webCrypto;
|
|
889
|
+
}
|
|
890
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
891
|
+
const { webcrypto } = await import("crypto");
|
|
892
|
+
return webcrypto;
|
|
893
|
+
}
|
|
894
|
+
throw new Error("Web Crypto API is not available in this environment");
|
|
895
|
+
}
|
|
884
896
|
function base64UrlEncode(buffer) {
|
|
885
897
|
const base64 = btoa(String.fromCharCode(...buffer));
|
|
886
898
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
887
899
|
}
|
|
888
|
-
function generateCodeVerifier() {
|
|
900
|
+
async function generateCodeVerifier() {
|
|
901
|
+
const webCrypto = await getWebCrypto();
|
|
889
902
|
const array = new Uint8Array(32);
|
|
890
|
-
|
|
903
|
+
webCrypto.getRandomValues(array);
|
|
891
904
|
return base64UrlEncode(array);
|
|
892
905
|
}
|
|
893
906
|
async function generateCodeChallenge(verifier) {
|
|
907
|
+
const webCrypto = await getWebCrypto();
|
|
894
908
|
const encoder = new TextEncoder();
|
|
895
909
|
const data = encoder.encode(verifier);
|
|
896
|
-
const hash = await
|
|
910
|
+
const hash = await webCrypto.subtle.digest("SHA-256", data);
|
|
897
911
|
return base64UrlEncode(new Uint8Array(hash));
|
|
898
912
|
}
|
|
899
913
|
function storePkceVerifier(verifier) {
|
|
@@ -940,7 +954,7 @@ var Auth = class {
|
|
|
940
954
|
this.http = http;
|
|
941
955
|
this.tokenManager = tokenManager;
|
|
942
956
|
this.options = options;
|
|
943
|
-
this.authCallbackHandled = this.detectAuthCallback();
|
|
957
|
+
this.authCallbackHandled = options.detectOAuthCallback === false ? Promise.resolve() : this.detectAuthCallback();
|
|
944
958
|
}
|
|
945
959
|
isServerMode() {
|
|
946
960
|
return !!this.options.isServerMode;
|
|
@@ -1086,7 +1100,7 @@ var Auth = class {
|
|
|
1086
1100
|
}
|
|
1087
1101
|
const { provider } = signInOptions;
|
|
1088
1102
|
const providerKey = encodeURIComponent(provider.toLowerCase());
|
|
1089
|
-
const codeVerifier = generateCodeVerifier();
|
|
1103
|
+
const codeVerifier = await generateCodeVerifier();
|
|
1090
1104
|
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
1091
1105
|
storePkceVerifier(codeVerifier);
|
|
1092
1106
|
const params = {
|
|
@@ -1657,7 +1671,7 @@ var StorageBucket = class {
|
|
|
1657
1671
|
size: file.size,
|
|
1658
1672
|
mimeType: file.type || "application/octet-stream",
|
|
1659
1673
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1660
|
-
url: this.getPublicUrl(strategy.key)
|
|
1674
|
+
url: this.getPublicUrl(strategy.key).data.publicUrl
|
|
1661
1675
|
},
|
|
1662
1676
|
error: null
|
|
1663
1677
|
};
|
|
@@ -1729,11 +1743,101 @@ var StorageBucket = class {
|
|
|
1729
1743
|
}
|
|
1730
1744
|
}
|
|
1731
1745
|
/**
|
|
1732
|
-
* Get public URL for a
|
|
1746
|
+
* Get the public URL for an object in a public bucket.
|
|
1747
|
+
*
|
|
1748
|
+
* Pure string construction — no network call, no auth. The URL only resolves
|
|
1749
|
+
* if the bucket is public; for private objects use {@link createSignedUrl}.
|
|
1750
|
+
*
|
|
1733
1751
|
* @param path - The object key/path
|
|
1752
|
+
* @returns `{ data: { publicUrl }, error }` — matches the external SDK pattern,
|
|
1753
|
+
* so `const { data } = getPublicUrl(path)` then `data.publicUrl`.
|
|
1734
1754
|
*/
|
|
1735
1755
|
getPublicUrl(path) {
|
|
1736
|
-
|
|
1756
|
+
const publicUrl = `${this.http.baseUrl}/api/storage/buckets/${this.bucketName}/objects/${encodeURIComponent(path)}`;
|
|
1757
|
+
return { data: { publicUrl }, error: null };
|
|
1758
|
+
}
|
|
1759
|
+
/**
|
|
1760
|
+
* Resolve a download strategy (signed or direct URL) for an object with a
|
|
1761
|
+
* caller-supplied TTL. Prefers the canonical GET route and falls back to the
|
|
1762
|
+
* legacy POST alias so signed-URL creation still works against older backends
|
|
1763
|
+
* that predate the GET route (they return 404/405 for it). A genuine
|
|
1764
|
+
* "object not found" (STORAGE_NOT_FOUND) is not retried.
|
|
1765
|
+
*/
|
|
1766
|
+
async requestDownloadStrategy(path, expiresIn) {
|
|
1767
|
+
const encoded = encodeURIComponent(path);
|
|
1768
|
+
try {
|
|
1769
|
+
return await this.http.get(
|
|
1770
|
+
`/api/storage/buckets/${this.bucketName}/download-strategy/objects/${encoded}`,
|
|
1771
|
+
{ params: { expiresIn: expiresIn.toString() } }
|
|
1772
|
+
);
|
|
1773
|
+
} catch (error) {
|
|
1774
|
+
const status = error instanceof InsForgeError ? error.statusCode : void 0;
|
|
1775
|
+
const isMissingRoute = (status === 404 || status === 405) && !(error instanceof InsForgeError && error.error === "STORAGE_NOT_FOUND");
|
|
1776
|
+
if (!isMissingRoute) throw error;
|
|
1777
|
+
return await this.http.post(
|
|
1778
|
+
`/api/storage/buckets/${this.bucketName}/objects/${encoded}/download-strategy`,
|
|
1779
|
+
{ expiresIn }
|
|
1780
|
+
);
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Create a signed URL for an object.
|
|
1785
|
+
*
|
|
1786
|
+
* Returns a time-limited, credential-free URL that can be handed directly to
|
|
1787
|
+
* a browser (`<img src>`), an email, or a third party — no SDK or session is
|
|
1788
|
+
* needed to fetch it. Authorization is enforced when the URL is minted (the
|
|
1789
|
+
* caller must be allowed to read the object), so the resulting link is a
|
|
1790
|
+
* pre-authorized capability scoped to this one object until it expires.
|
|
1791
|
+
*
|
|
1792
|
+
* @param path - The object key/path
|
|
1793
|
+
* @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d).
|
|
1794
|
+
* Honored for private buckets; public buckets return their long-lived URL.
|
|
1795
|
+
*/
|
|
1796
|
+
async createSignedUrl(path, expiresIn = 3600) {
|
|
1797
|
+
try {
|
|
1798
|
+
const strategy = await this.requestDownloadStrategy(path, expiresIn);
|
|
1799
|
+
return {
|
|
1800
|
+
data: {
|
|
1801
|
+
signedUrl: strategy.url,
|
|
1802
|
+
expiresAt: strategy.expiresAt ? new Date(strategy.expiresAt).toISOString() : null
|
|
1803
|
+
},
|
|
1804
|
+
error: null
|
|
1805
|
+
};
|
|
1806
|
+
} catch (error) {
|
|
1807
|
+
return {
|
|
1808
|
+
data: null,
|
|
1809
|
+
error: error instanceof InsForgeError ? error : new InsForgeError("Failed to create signed URL", 500, "STORAGE_ERROR")
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* Create signed URLs for multiple objects in a single call.
|
|
1815
|
+
*
|
|
1816
|
+
* Each entry resolves independently: a failure on one key (not found / not
|
|
1817
|
+
* permitted) is reported on that entry's `error` without failing the rest.
|
|
1818
|
+
*
|
|
1819
|
+
* @param paths - The object keys/paths
|
|
1820
|
+
* @param expiresIn - Lifetime in seconds (default 3600 = 1h, max 604800 = 7d)
|
|
1821
|
+
*/
|
|
1822
|
+
async createSignedUrls(paths, expiresIn = 3600) {
|
|
1823
|
+
try {
|
|
1824
|
+
const data = await Promise.all(
|
|
1825
|
+
paths.map(async (path) => {
|
|
1826
|
+
const { data: signed, error } = await this.createSignedUrl(path, expiresIn);
|
|
1827
|
+
return {
|
|
1828
|
+
path,
|
|
1829
|
+
signedUrl: signed?.signedUrl ?? null,
|
|
1830
|
+
error: error ? error.message : null
|
|
1831
|
+
};
|
|
1832
|
+
})
|
|
1833
|
+
);
|
|
1834
|
+
return { data, error: null };
|
|
1835
|
+
} catch (error) {
|
|
1836
|
+
return {
|
|
1837
|
+
data: null,
|
|
1838
|
+
error: error instanceof InsForgeError ? error : new InsForgeError("Failed to create signed URLs", 500, "STORAGE_ERROR")
|
|
1839
|
+
};
|
|
1840
|
+
}
|
|
1737
1841
|
}
|
|
1738
1842
|
/**
|
|
1739
1843
|
* List objects in the bucket
|
|
@@ -2712,12 +2816,14 @@ var InsForgeClient = class {
|
|
|
2712
2816
|
const logger = new Logger(config.debug);
|
|
2713
2817
|
this.tokenManager = new TokenManager();
|
|
2714
2818
|
this.http = new HttpClient(config, this.tokenManager, logger);
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
this.
|
|
2819
|
+
const accessToken = config.accessToken ?? config.edgeFunctionToken;
|
|
2820
|
+
if (accessToken) {
|
|
2821
|
+
this.http.setAuthToken(accessToken);
|
|
2822
|
+
this.tokenManager.setAccessToken(accessToken);
|
|
2718
2823
|
}
|
|
2719
2824
|
this.auth = new Auth(this.http, this.tokenManager, {
|
|
2720
|
-
isServerMode: config.isServerMode ?? !!
|
|
2825
|
+
isServerMode: config.isServerMode ?? !!accessToken,
|
|
2826
|
+
detectOAuthCallback: config.auth?.detectOAuthCallback
|
|
2721
2827
|
});
|
|
2722
2828
|
this.database = new Database(this.http);
|
|
2723
2829
|
this.storage = new Storage(this.http);
|
|
@@ -3123,7 +3229,13 @@ function createBrowserClient(options = {}) {
|
|
|
3123
3229
|
...options,
|
|
3124
3230
|
baseUrl,
|
|
3125
3231
|
anonKey,
|
|
3126
|
-
fetch: ssrFetch
|
|
3232
|
+
fetch: ssrFetch,
|
|
3233
|
+
// Browser clients manage tokens via the refresh route, not a static
|
|
3234
|
+
// config token; shadow any untyped accessToken in the options spread.
|
|
3235
|
+
accessToken: void 0,
|
|
3236
|
+
auth: {
|
|
3237
|
+
detectOAuthCallback: false
|
|
3238
|
+
}
|
|
3127
3239
|
});
|
|
3128
3240
|
const setAccessToken = client.setAccessToken.bind(client);
|
|
3129
3241
|
client.setAccessToken = (token) => {
|
|
@@ -3161,7 +3273,10 @@ function createServerClient(options = {}) {
|
|
|
3161
3273
|
baseUrl,
|
|
3162
3274
|
anonKey,
|
|
3163
3275
|
isServerMode: true,
|
|
3164
|
-
|
|
3276
|
+
accessToken: accessToken ?? void 0,
|
|
3277
|
+
// The cookie/option token is the only credential source here; shadow any
|
|
3278
|
+
// untyped edgeFunctionToken smuggled through the options spread.
|
|
3279
|
+
edgeFunctionToken: void 0
|
|
3165
3280
|
});
|
|
3166
3281
|
}
|
|
3167
3282
|
|
|
@@ -3325,6 +3440,109 @@ function createRefreshAuthRouter(options = {}) {
|
|
|
3325
3440
|
};
|
|
3326
3441
|
}
|
|
3327
3442
|
|
|
3443
|
+
// src/ssr/auth-actions.ts
|
|
3444
|
+
function persistSessionCookies(cookies, data, settings) {
|
|
3445
|
+
if (!data?.accessToken) return;
|
|
3446
|
+
setAuthCookies(
|
|
3447
|
+
cookies,
|
|
3448
|
+
{
|
|
3449
|
+
accessToken: data.accessToken,
|
|
3450
|
+
refreshToken: data.refreshToken
|
|
3451
|
+
},
|
|
3452
|
+
settings
|
|
3453
|
+
);
|
|
3454
|
+
}
|
|
3455
|
+
function sanitizeAuthData(data) {
|
|
3456
|
+
if (!data) return null;
|
|
3457
|
+
const {
|
|
3458
|
+
accessToken: _accessToken,
|
|
3459
|
+
refreshToken: _refreshToken,
|
|
3460
|
+
csrfToken: _csrfToken,
|
|
3461
|
+
...safeData
|
|
3462
|
+
} = data;
|
|
3463
|
+
return safeData;
|
|
3464
|
+
}
|
|
3465
|
+
function toSafeAuthResult(result) {
|
|
3466
|
+
return {
|
|
3467
|
+
data: sanitizeAuthData(result.data),
|
|
3468
|
+
error: result.error
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
function createAuthActions(options = {}) {
|
|
3472
|
+
const {
|
|
3473
|
+
cookies,
|
|
3474
|
+
requestCookies,
|
|
3475
|
+
responseCookies,
|
|
3476
|
+
names,
|
|
3477
|
+
options: cookieOptions,
|
|
3478
|
+
...clientOptions
|
|
3479
|
+
} = options;
|
|
3480
|
+
const readCookies = requestCookies ?? cookies;
|
|
3481
|
+
const writeCookies = responseCookies ?? cookies;
|
|
3482
|
+
if (!writeCookies?.set) {
|
|
3483
|
+
throw new Error(
|
|
3484
|
+
"createAuthActions() requires a writable cookie store. Pass cookies in Server Actions or responseCookies in Route Handlers."
|
|
3485
|
+
);
|
|
3486
|
+
}
|
|
3487
|
+
const cookieSettings = {
|
|
3488
|
+
names,
|
|
3489
|
+
options: cookieOptions
|
|
3490
|
+
};
|
|
3491
|
+
const createClient = () => createServerClient({
|
|
3492
|
+
...clientOptions,
|
|
3493
|
+
names,
|
|
3494
|
+
options: cookieOptions,
|
|
3495
|
+
cookies: readCookies
|
|
3496
|
+
});
|
|
3497
|
+
return {
|
|
3498
|
+
signUp: async (request) => {
|
|
3499
|
+
const result = await createClient().auth.signUp(request);
|
|
3500
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3501
|
+
return toSafeAuthResult(result);
|
|
3502
|
+
},
|
|
3503
|
+
signInWithPassword: async (request) => {
|
|
3504
|
+
const result = await createClient().auth.signInWithPassword(request);
|
|
3505
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3506
|
+
return toSafeAuthResult(
|
|
3507
|
+
result
|
|
3508
|
+
);
|
|
3509
|
+
},
|
|
3510
|
+
signInWithOAuth: async (providerOrOptions, signInOptions) => {
|
|
3511
|
+
return createClient().auth.signInWithOAuth(
|
|
3512
|
+
providerOrOptions,
|
|
3513
|
+
signInOptions
|
|
3514
|
+
);
|
|
3515
|
+
},
|
|
3516
|
+
signInWithIdToken: async (credentials) => {
|
|
3517
|
+
const result = await createClient().auth.signInWithIdToken(credentials);
|
|
3518
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3519
|
+
return toSafeAuthResult(
|
|
3520
|
+
result
|
|
3521
|
+
);
|
|
3522
|
+
},
|
|
3523
|
+
exchangeOAuthCode: async (code, codeVerifier) => {
|
|
3524
|
+
const result = await createClient().auth.exchangeOAuthCode(
|
|
3525
|
+
code,
|
|
3526
|
+
codeVerifier
|
|
3527
|
+
);
|
|
3528
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3529
|
+
return toSafeAuthResult(
|
|
3530
|
+
result
|
|
3531
|
+
);
|
|
3532
|
+
},
|
|
3533
|
+
verifyEmail: async (request) => {
|
|
3534
|
+
const result = await createClient().auth.verifyEmail(request);
|
|
3535
|
+
persistSessionCookies(writeCookies, result.data, cookieSettings);
|
|
3536
|
+
return toSafeAuthResult(result);
|
|
3537
|
+
},
|
|
3538
|
+
signOut: async () => {
|
|
3539
|
+
const result = await createClient().auth.signOut();
|
|
3540
|
+
clearAuthCookies(writeCookies, cookieSettings);
|
|
3541
|
+
return result;
|
|
3542
|
+
}
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3328
3546
|
// src/ssr/update-session.ts
|
|
3329
3547
|
async function updateSession(options) {
|
|
3330
3548
|
const accessCookieName = getAccessTokenCookieName(options.names);
|
|
@@ -3386,6 +3604,7 @@ async function updateSession(options) {
|
|
|
3386
3604
|
DEFAULT_REFRESH_TOKEN_COOKIE,
|
|
3387
3605
|
accessTokenCookieOptions,
|
|
3388
3606
|
clearAuthCookies,
|
|
3607
|
+
createAuthActions,
|
|
3389
3608
|
createBrowserClient,
|
|
3390
3609
|
createRefreshAuthRouter,
|
|
3391
3610
|
createServerClient,
|