@stackframe/stack 2.8.54 → 2.8.56
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/CHANGELOG.md +20 -0
- package/dist/components/credential-sign-up.js.map +1 -1
- package/dist/components/user-button.js +4 -4
- package/dist/components/user-button.js.map +1 -1
- package/dist/components-page/stack-handler.js.map +1 -1
- package/dist/esm/components/credential-sign-up.js.map +1 -1
- package/dist/esm/components/user-button.js +4 -4
- package/dist/esm/components/user-button.js.map +1 -1
- package/dist/esm/components-page/stack-handler.js.map +1 -1
- package/dist/esm/generated/global-css.js +1 -1
- package/dist/esm/generated/global-css.js.map +1 -1
- package/dist/esm/lib/cookie.js +56 -20
- package/dist/esm/lib/cookie.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js +7 -6
- package/dist/esm/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/esm/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/dist/generated/global-css.js +1 -1
- package/dist/generated/global-css.js.map +1 -1
- package/dist/lib/cookie.js +56 -20
- package/dist/lib/cookie.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js +6 -5
- package/dist/lib/stack-app/apps/implementations/client-app-impl.js.map +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js +1 -1
- package/dist/lib/stack-app/apps/implementations/common.js.map +1 -1
- package/package.json +4 -4
package/dist/esm/lib/cookie.js
CHANGED
|
@@ -58,7 +58,7 @@ function createNextCookieHelper(rscCookiesAwaited, rscHeadersAwaited) {
|
|
|
58
58
|
},
|
|
59
59
|
getAll: () => {
|
|
60
60
|
try {
|
|
61
|
-
rscCookiesAwaited.set("stack-is-https", "true", { secure: true });
|
|
61
|
+
rscCookiesAwaited.set("stack-is-https", "true", { secure: true, expires: new Date(Date.now() + 1e3 * 60 * 60 * 24 * 365) });
|
|
62
62
|
} catch (e) {
|
|
63
63
|
if (typeof e === "object" && e !== null && "message" in e && typeof e.message === "string" && e.message.includes("Cookies can only be modified in a Server Action or Route Handler")) {
|
|
64
64
|
} else {
|
|
@@ -76,21 +76,22 @@ function createNextCookieHelper(rscCookiesAwaited, rscHeadersAwaited) {
|
|
|
76
76
|
try {
|
|
77
77
|
rscCookiesAwaited.set(name, value, {
|
|
78
78
|
secure: isSecureCookie,
|
|
79
|
-
maxAge: options.maxAge,
|
|
80
|
-
domain: options.domain
|
|
79
|
+
maxAge: options.maxAge === "session" ? void 0 : options.maxAge,
|
|
80
|
+
domain: options.domain,
|
|
81
|
+
sameSite: "lax"
|
|
81
82
|
});
|
|
82
83
|
} catch (e) {
|
|
83
84
|
handleCookieError(e, options);
|
|
84
85
|
}
|
|
85
86
|
},
|
|
86
|
-
setOrDelete(name, value, options
|
|
87
|
+
setOrDelete(name, value, options) {
|
|
87
88
|
if (value === null) {
|
|
88
89
|
this.delete(name, options);
|
|
89
90
|
} else {
|
|
90
91
|
this.set(name, value, options);
|
|
91
92
|
}
|
|
92
93
|
},
|
|
93
|
-
delete(name, options
|
|
94
|
+
delete(name, options) {
|
|
94
95
|
try {
|
|
95
96
|
if (options.domain !== void 0) {
|
|
96
97
|
rscCookiesAwaited.delete({ name, domain: options.domain });
|
|
@@ -110,7 +111,7 @@ function getCookieClient(name) {
|
|
|
110
111
|
}
|
|
111
112
|
function getAllCookiesClient() {
|
|
112
113
|
ensureClient();
|
|
113
|
-
Cookies.set("stack-is-https", "true", { secure: true });
|
|
114
|
+
Cookies.set("stack-is-https", "true", { secure: true, expires: new Date(Date.now() + 1e3 * 60 * 60 * 24 * 365) });
|
|
114
115
|
return Cookies.get();
|
|
115
116
|
}
|
|
116
117
|
async function getCookie(name) {
|
|
@@ -130,21 +131,56 @@ function determineSecureFromClientContext() {
|
|
|
130
131
|
function determineSecureFromServerContext(cookies, headers) {
|
|
131
132
|
return cookies.has("stack-is-https") || headers.get("x-forwarded-proto") === "https";
|
|
132
133
|
}
|
|
133
|
-
|
|
134
|
+
var _shouldSetPartitionedClientCache = void 0;
|
|
135
|
+
function shouldSetPartitionedClient() {
|
|
136
|
+
return _shouldSetPartitionedClientCache ??= _internalShouldSetPartitionedClient();
|
|
137
|
+
}
|
|
138
|
+
function _internalShouldSetPartitionedClient() {
|
|
139
|
+
ensureClient();
|
|
140
|
+
if (!determineSecureFromClientContext()) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const cookie1Name = "__Host-stack-temporary-chips-test-" + Math.random().toString(36).substring(2, 15);
|
|
144
|
+
document.cookie = `${cookie1Name}=value1; Secure; path=/`;
|
|
145
|
+
const cookies1 = document.cookie.split("; ");
|
|
146
|
+
document.cookie = `${cookie1Name}=delete1; Secure; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;
|
|
147
|
+
if (cookies1.some((c) => c.startsWith(cookie1Name + "="))) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const cookie2Name = "__Host-stack-temporary-chips-test-" + Math.random().toString(36).substring(2, 15);
|
|
151
|
+
document.cookie = `${cookie2Name}=delete1; Secure; SameSite=None; Partitioned; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
152
|
+
document.cookie = `${cookie2Name}=delete2; Secure; SameSite=None; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
153
|
+
document.cookie = `${cookie2Name}=set1; Secure; SameSite=None; Partitioned; path=/`;
|
|
154
|
+
document.cookie = `${cookie2Name}=set2; Secure; SameSite=None; path=/`;
|
|
155
|
+
const cookies2 = document.cookie.split("; ");
|
|
156
|
+
const numberOfCookiesWithThisName = cookies2.filter((c) => c.startsWith(cookie2Name + "=")).length;
|
|
157
|
+
document.cookie = `${cookie2Name}=delete3; Secure; SameSite=None; Partitioned; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
158
|
+
document.cookie = `${cookie2Name}=delete4; Secure; SameSite=None; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;
|
|
159
|
+
return numberOfCookiesWithThisName === 2;
|
|
160
|
+
}
|
|
161
|
+
function setCookieClientInternal(name, value, options) {
|
|
134
162
|
const secure = options.secure ?? determineSecureFromClientContext();
|
|
163
|
+
const partitioned = shouldSetPartitionedClient();
|
|
135
164
|
Cookies.set(name, value, {
|
|
136
|
-
expires: options.maxAge ===
|
|
165
|
+
expires: options.maxAge === "session" ? void 0 : new Date(Date.now() + options.maxAge * 1e3),
|
|
137
166
|
domain: options.domain,
|
|
138
|
-
secure
|
|
167
|
+
secure,
|
|
168
|
+
sameSite: "Lax",
|
|
169
|
+
...partitioned ? {
|
|
170
|
+
partitioned,
|
|
171
|
+
sameSite: "None"
|
|
172
|
+
} : {}
|
|
139
173
|
});
|
|
140
174
|
}
|
|
141
|
-
function deleteCookieClientInternal(name, options
|
|
142
|
-
|
|
143
|
-
|
|
175
|
+
function deleteCookieClientInternal(name, options) {
|
|
176
|
+
for (const partitioned of [true, false]) {
|
|
177
|
+
if (options.domain !== void 0) {
|
|
178
|
+
Cookies.remove(name, { domain: options.domain, secure: determineSecureFromClientContext(), partitioned });
|
|
179
|
+
}
|
|
180
|
+
Cookies.remove(name, { secure: determineSecureFromClientContext(), partitioned });
|
|
144
181
|
}
|
|
145
|
-
Cookies.remove(name, { secure: determineSecureFromClientContext() });
|
|
146
182
|
}
|
|
147
|
-
function setOrDeleteCookieClient(name, value, options
|
|
183
|
+
function setOrDeleteCookieClient(name, value, options) {
|
|
148
184
|
ensureClient();
|
|
149
185
|
if (value === null) {
|
|
150
186
|
deleteCookieClientInternal(name, options);
|
|
@@ -152,23 +188,23 @@ function setOrDeleteCookieClient(name, value, options = {}) {
|
|
|
152
188
|
setCookieClientInternal(name, value, options);
|
|
153
189
|
}
|
|
154
190
|
}
|
|
155
|
-
async function setOrDeleteCookie(name, value, options
|
|
191
|
+
async function setOrDeleteCookie(name, value, options) {
|
|
156
192
|
const cookieHelper = await createCookieHelper();
|
|
157
193
|
cookieHelper.setOrDelete(name, value, options);
|
|
158
194
|
}
|
|
159
|
-
function deleteCookieClient(name, options
|
|
195
|
+
function deleteCookieClient(name, options) {
|
|
160
196
|
ensureClient();
|
|
161
197
|
deleteCookieClientInternal(name, options);
|
|
162
198
|
}
|
|
163
|
-
async function deleteCookie(name, options
|
|
199
|
+
async function deleteCookie(name, options) {
|
|
164
200
|
const cookieHelper = await createCookieHelper();
|
|
165
201
|
cookieHelper.delete(name, options);
|
|
166
202
|
}
|
|
167
|
-
function setCookieClient(name, value, options
|
|
203
|
+
function setCookieClient(name, value, options) {
|
|
168
204
|
ensureClient();
|
|
169
205
|
setCookieClientInternal(name, value, options);
|
|
170
206
|
}
|
|
171
|
-
async function setCookie(name, value, options
|
|
207
|
+
async function setCookie(name, value, options) {
|
|
172
208
|
const cookieHelper = await createCookieHelper();
|
|
173
209
|
cookieHelper.set(name, value, options);
|
|
174
210
|
}
|
|
@@ -189,7 +225,7 @@ function consumeVerifierAndStateCookie(state) {
|
|
|
189
225
|
if (!codeVerifier) {
|
|
190
226
|
return null;
|
|
191
227
|
}
|
|
192
|
-
deleteCookieClient(cookieName);
|
|
228
|
+
deleteCookieClient(cookieName, {});
|
|
193
229
|
return {
|
|
194
230
|
codeVerifier
|
|
195
231
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/cookie.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { cookies as rscCookies, headers as rscHeaders } from '@stackframe/stack-sc/force-react-server'; // THIS_LINE_PLATFORM next\nimport { isBrowserLike } from '@stackframe/stack-shared/dist/utils/env';\nimport { StackAssertionError } from '@stackframe/stack-shared/dist/utils/errors';\nimport Cookies from \"js-cookie\";\nimport { calculatePKCECodeChallenge, generateRandomCodeVerifier, generateRandomState } from \"oauth4webapi\";\n\ntype SetCookieOptions = { maxAge?: number, noOpIfServerComponent?: boolean, domain?: string, secure?: boolean };\ntype DeleteCookieOptions = { noOpIfServerComponent?: boolean, domain?: string };\n\nfunction ensureClient() {\n if (!isBrowserLike()) {\n throw new Error(\"cookieClient functions can only be called in a browser environment, yet window is undefined\");\n }\n}\n\nexport type CookieHelper = {\n get: (name: string) => string | null,\n getAll: () => Record<string, string>,\n set: (name: string, value: string, options: SetCookieOptions) => void,\n setOrDelete: (name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions) => void,\n delete: (name: string, options: DeleteCookieOptions) => void,\n};\n\nconst placeholderCookieHelperIdentity = { \"placeholder cookie helper identity\": true };\nexport async function createPlaceholderCookieHelper(): Promise<CookieHelper> {\n function throwError(): never {\n throw new StackAssertionError(\"Throwing cookie helper is just a placeholder. This should never be called\");\n }\n return {\n get: throwError,\n getAll: throwError,\n set: throwError,\n setOrDelete: throwError,\n delete: throwError,\n };\n}\n\nexport async function createCookieHelper(): Promise<CookieHelper> {\n if (isBrowserLike()) {\n return createBrowserCookieHelper();\n } else {\n return createNextCookieHelper(\n await rscCookies(),\n await rscHeaders(),\n );\n }\n}\n\nexport function createBrowserCookieHelper(): CookieHelper {\n return {\n get: getCookieClient,\n getAll: getAllCookiesClient,\n set: setCookieClient,\n setOrDelete: setOrDeleteCookieClient,\n delete: deleteCookieClient,\n };\n}\n\nfunction handleCookieError(e: unknown, options: DeleteCookieOptions | SetCookieOptions) {\n if (e instanceof Error && e.message.includes(\"Cookies can only be modified in\")) {\n if (options.noOpIfServerComponent) {\n // ignore\n } else {\n throw new StackAssertionError(\"Attempted to set cookie in server component. Pass { noOpIfServerComponent: true } in the options of Stack's cookie functions if this is intentional and you want to ignore this error. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options\");\n }\n } else {\n throw e;\n }\n}\n\nfunction createNextCookieHelper(\n rscCookiesAwaited: Awaited<ReturnType<typeof rscCookies>>,\n rscHeadersAwaited: Awaited<ReturnType<typeof rscHeaders>>,\n): CookieHelper {\n const cookieHelper = {\n get: (name: string) => {\n const all = cookieHelper.getAll();\n return all[name] ?? null;\n },\n getAll: () => {\n // set a helper cookie, see comment in `NextCookieHelper.set` below\n try {\n rscCookiesAwaited.set(\"stack-is-https\", \"true\", { secure: true });\n } catch (e) {\n if (\n typeof e === 'object'\n && e !== null\n && 'message' in e\n && typeof e.message === 'string'\n && e.message.includes('Cookies can only be modified in a Server Action or Route Handler')\n ) {\n // ignore\n } else {\n throw e;\n }\n }\n const all = rscCookiesAwaited.getAll();\n return all.reduce((acc, entry) => {\n acc[entry.name] = entry.value;\n return acc;\n }, {} as Record<string, string>);\n },\n set: (name: string, value: string, options: SetCookieOptions) => {\n // Whenever the client is on HTTPS, we want to set the Secure flag on the cookie.\n //\n // This is not easy to find out on a Next.js server, so we use the following steps:\n //\n // 1. If we're on the client, we can check window.location.protocol which is the ground-truth\n // 2. Check whether the stack-is-https cookie exists. This cookie is set in various places on\n // the client if the protocol is known to be HTTPS\n // 3. Check the X-Forwarded-Proto header\n // 4. Otherwise, assume HTTP without the S\n //\n // Note that malicious clients could theoretically manipulate the `stack-is-https` cookie or\n // the `X-Forwarded-Proto` header; that wouldn't cause any trouble except for themselves,\n // though.\n const isSecureCookie = determineSecureFromServerContext(rscCookiesAwaited, rscHeadersAwaited);\n\n try {\n rscCookiesAwaited.set(name, value, {\n secure: isSecureCookie,\n maxAge: options.maxAge,\n domain: options.domain,\n });\n } catch (e) {\n handleCookieError(e, options);\n }\n },\n setOrDelete(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions = {}) {\n if (value === null) {\n this.delete(name, options);\n } else {\n this.set(name, value, options);\n }\n },\n delete(name: string, options: DeleteCookieOptions = {}) {\n try {\n if (options.domain !== undefined) {\n rscCookiesAwaited.delete({ name, domain: options.domain });\n } else {\n rscCookiesAwaited.delete(name);\n }\n } catch (e) {\n handleCookieError(e, options);\n }\n },\n };\n return cookieHelper;\n}\n\nexport function getCookieClient(name: string): string | null {\n const all = getAllCookiesClient();\n return all[name] ?? null;\n}\n\nexport function getAllCookiesClient(): Record<string, string> {\n ensureClient();\n // set a helper cookie, see comment in `NextCookieHelper.set` above\n Cookies.set(\"stack-is-https\", \"true\", { secure: true });\n return Cookies.get();\n}\n\nexport async function getCookie(name: string): Promise<string | null> {\n const cookieHelper = await createCookieHelper();\n return cookieHelper.get(name);\n}\n\nexport async function isSecure(): Promise<boolean> {\n if (isBrowserLike()) {\n return determineSecureFromClientContext();\n }\n return determineSecureFromServerContext(await rscCookies(), await rscHeaders());\n return false;\n}\n\nfunction determineSecureFromClientContext(): boolean {\n return typeof window !== \"undefined\" && window.location.protocol === \"https:\";\n}\nfunction determineSecureFromServerContext(\n cookies: Awaited<ReturnType<typeof rscCookies>>,\n headers: Awaited<ReturnType<typeof rscHeaders>>,\n): boolean {\n return cookies.has(\"stack-is-https\") || headers.get(\"x-forwarded-proto\") === \"https\";\n}\n\nfunction setCookieClientInternal(name: string, value: string, options: SetCookieOptions = {}) {\n const secure = options.secure ?? determineSecureFromClientContext();\n Cookies.set(name, value, {\n expires: options.maxAge === undefined ? undefined : new Date(Date.now() + (options.maxAge) * 1000),\n domain: options.domain,\n secure,\n });\n}\n\nfunction deleteCookieClientInternal(name: string, options: DeleteCookieOptions = {}) {\n if (options.domain !== undefined) {\n Cookies.remove(name, { domain: options.domain, secure: determineSecureFromClientContext() });\n }\n Cookies.remove(name, { secure: determineSecureFromClientContext() });\n}\n\nexport function setOrDeleteCookieClient(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions = {}) {\n ensureClient();\n if (value === null) {\n deleteCookieClientInternal(name, options);\n } else {\n setCookieClientInternal(name, value, options);\n }\n}\n\nexport async function setOrDeleteCookie(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions = {}) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.setOrDelete(name, value, options);\n}\n\nexport function deleteCookieClient(name: string, options: DeleteCookieOptions = {}) {\n ensureClient();\n deleteCookieClientInternal(name, options);\n}\n\nexport async function deleteCookie(name: string, options: DeleteCookieOptions = {}) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.delete(name, options);\n}\n\nexport function setCookieClient(name: string, value: string, options: SetCookieOptions = {}) {\n ensureClient();\n setCookieClientInternal(name, value, options);\n}\n\nexport async function setCookie(name: string, value: string, options: SetCookieOptions = {}) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.set(name, value, options);\n}\n\nexport async function saveVerifierAndState() {\n const codeVerifier = generateRandomCodeVerifier();\n const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);\n const state = generateRandomState();\n\n await setCookie(\"stack-oauth-outer-\" + state, codeVerifier, { maxAge: 60 * 60 });\n\n return {\n codeChallenge,\n state,\n };\n}\n\nexport function consumeVerifierAndStateCookie(state: string) {\n ensureClient();\n const cookieName = \"stack-oauth-outer-\" + state;\n const codeVerifier = getCookieClient(cookieName);\n if (!codeVerifier) {\n return null;\n }\n deleteCookieClient(cookieName);\n return {\n codeVerifier,\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/cookie.ts"],"sourcesContent":["\n//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\nimport { cookies as rscCookies, headers as rscHeaders } from '@stackframe/stack-sc/force-react-server'; // THIS_LINE_PLATFORM next\nimport { isBrowserLike } from '@stackframe/stack-shared/dist/utils/env';\nimport { StackAssertionError } from '@stackframe/stack-shared/dist/utils/errors';\nimport Cookies from \"js-cookie\";\nimport { calculatePKCECodeChallenge, generateRandomCodeVerifier, generateRandomState } from \"oauth4webapi\";\n\n\n// INFO: This file is used to manage cookies. It also sets some cookie flags automatically, see this description.\n//\n// It provides asynchronous setCookie, getCookie, deleteCookie, etc. functions that can be used in various environments\n// (browser + Next.js for now). Under the hood, they just get a CookieHelper object and then set the cookies there.\n//\n// The CookieHelper object is a simple object that lets you set, get and delete cookies synchronously. Acquiring one\n// is asynchronous (except for browser environments, where they can be acquired synchronously), but once you have it,\n// you can use it synchronously. This function is useful if you cannot await in the calling code, but otherwise you\n// should prefer to await the functions directly.\n//\n// Some cookie flags are set automatically by the CookieHelper (and hence also the <xyz>Cookie functions).\n// In particular:\n// - SameSite is set to `Lax` by default, which is already true in Chromium-based browsers, so this creates\n// compatibility with other browsers that use either Strict or None (particularly Safari and Firefox, and older\n// versions of Chrome). If Partitioned is automatically set (as described below), then this value is set to `None`\n// instead.\n// - Secure is set depending on whether we could successfully determine that the client is on HTTPS. For this, we use a\n// set of heuristics:\n// - In a browser environment, we check window.location.protocol which is always accurate\n// - In a Next.js server environment:\n// - First we check the `stack-is-https` cookie, which is set in various places on the\n// client with a Secure attribute. If that one is passed on to the server, we know that the client is on HTTPS\n// and we can set the Secure flag on the cookie. TODO: Should we also do this with a second cookie with a\n// __Host- prefix, so a malicious subdomain of the current domain cannot forcibly enable HTTPS mode and\n// therefore prevent new cookies from being set?\n// - Otherwise, we check the X-Forwarded-Proto header. If that one is `https`, we know that the client is\n// (pretending to be) on HTTPS and we can set the Secure flag on the cookie. Note that this header is\n// spoofable by malicious clients (so is the cookie actually), but since setting this value can only *increase*\n// security (and therefore prevent setting of a cookie), and requires a malicious client, this is still safe.\n// - If neither of the above is true, we don't set the Secure flag on the cookie.\n// - Partitioned is set depending on whether it is needed & supported. Unfortunately, the fact that Partitioned\n// cookies require SameSite=None, browsers that don't support it will still set them as normal third-party cookies,\n// which are fundamentally unsafe. Therefore, we need to take extra care that we only ever set Partitioned cookies\n// if we know for sure that the browser supports it.\n// - In a browser environment, we check:\n// - Whether `Secure` is set. If it's not, we don't set Partitioned.\n// - Whether we can set & retrieve cookies without Partitioned being set. If this is the case, we are likely in a\n// top-level context or a browser that partitions cookies by default (eg. Firefox). In this case, we don't need\n// Partitioned and can just proceed as normal.\n// - Whether CHIPS is supported. To prevent the case where CHIPS is not supported but third-party cookies are (in\n// which we would accidentally set SameSite=None without Partitioned as the latter requires the former), we\n// check this by running a simple test with document.cookie.\n// - Whether the browser supports Partitioned cookies. If yes, set Partitioned. Otherwise, don't set Partitioned.\n// Since there's no easy cross-compat way to do this (CookieStore and document.cookie do not return whether a\n// cookie is partitioned on some/all versions of Safari and Firefox), we use a heuristic; we run this test by\n// creating two cookies with the same name: One with Partitioned and one without. If there are two resulting\n// cookies, that means they were put into different jars, implying that the browser supports Partitioned cookies\n// (but doesn't partition cookies by default). If they result in just one cookie, that could mean that the\n// browser doesn't support Partitioned cookies, or that the browser doesn't put partitioned cookies into\n// different jars by default, in which case we still don't know. This heuristic works on Chrome, but may\n// incorrectly conclude that some other browsers don't support Partitioned. But from a security perspective,\n// that is better than accidentally setting SameSite=None without Partitioned. TODO: Find a better heuristic to\n// to determine whether the browser supports Partitioned cookies or not.\n// - In a Next.js server environment, right now we do nothing because of the complexity involved :( TODO: In the\n// future, we could improve this for example by setting hint cookies from the client, but we need to make sure that\n// no malicious actor (eg. on a malicious subdomain) can forcefully enable Partitioned cookies on a browser that\n// does not support it.\n\n\ntype SetCookieOptions = { maxAge: number | \"session\", noOpIfServerComponent?: boolean, domain?: string, secure?: boolean };\ntype DeleteCookieOptions = { noOpIfServerComponent?: boolean, domain?: string };\n\nfunction ensureClient() {\n if (!isBrowserLike()) {\n throw new Error(\"cookieClient functions can only be called in a browser environment, yet window is undefined\");\n }\n}\n\nexport type CookieHelper = {\n get: (name: string) => string | null,\n getAll: () => Record<string, string>,\n set: (name: string, value: string, options: SetCookieOptions) => void,\n setOrDelete: (name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions) => void,\n delete: (name: string, options: DeleteCookieOptions) => void,\n};\n\nconst placeholderCookieHelperIdentity = { \"placeholder cookie helper identity\": true };\nexport async function createPlaceholderCookieHelper(): Promise<CookieHelper> {\n function throwError(): never {\n throw new StackAssertionError(\"Throwing cookie helper is just a placeholder. This should never be called\");\n }\n return {\n get: throwError,\n getAll: throwError,\n set: throwError,\n setOrDelete: throwError,\n delete: throwError,\n };\n}\n\nexport async function createCookieHelper(): Promise<CookieHelper> {\n if (isBrowserLike()) {\n return createBrowserCookieHelper();\n } else {\n return createNextCookieHelper(\n await rscCookies(),\n await rscHeaders(),\n );\n }\n}\n\nexport function createBrowserCookieHelper(): CookieHelper {\n return {\n get: getCookieClient,\n getAll: getAllCookiesClient,\n set: setCookieClient,\n setOrDelete: setOrDeleteCookieClient,\n delete: deleteCookieClient,\n };\n}\n\nfunction handleCookieError(e: unknown, options: DeleteCookieOptions | SetCookieOptions) {\n if (e instanceof Error && e.message.includes(\"Cookies can only be modified in\")) {\n if (options.noOpIfServerComponent) {\n // ignore\n } else {\n throw new StackAssertionError(\"Attempted to set cookie in server component. Pass { noOpIfServerComponent: true } in the options of Stack's cookie functions if this is intentional and you want to ignore this error. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options\");\n }\n } else {\n throw e;\n }\n}\n\nfunction createNextCookieHelper(\n rscCookiesAwaited: Awaited<ReturnType<typeof rscCookies>>,\n rscHeadersAwaited: Awaited<ReturnType<typeof rscHeaders>>,\n): CookieHelper {\n const cookieHelper = {\n get: (name: string) => {\n const all = cookieHelper.getAll();\n return all[name] ?? null;\n },\n getAll: () => {\n // set a helper cookie, see comment in `NextCookieHelper.set` below\n try {\n rscCookiesAwaited.set(\"stack-is-https\", \"true\", { secure: true, expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365) });\n } catch (e) {\n if (\n typeof e === 'object'\n && e !== null\n && 'message' in e\n && typeof e.message === 'string'\n && e.message.includes('Cookies can only be modified in a Server Action or Route Handler')\n ) {\n // ignore\n } else {\n throw e;\n }\n }\n const all = rscCookiesAwaited.getAll();\n return all.reduce((acc, entry) => {\n acc[entry.name] = entry.value;\n return acc;\n }, {} as Record<string, string>);\n },\n set: (name: string, value: string, options: SetCookieOptions) => {\n // Whenever the client is on HTTPS, we want to set the Secure flag on the cookie.\n //\n // This is not easy to find out on a Next.js server, so see the algorithm at the top of this file.\n //\n // Note that malicious clients could theoretically manipulate the `stack-is-https` cookie or\n // the `X-Forwarded-Proto` header; that wouldn't cause any trouble except for themselves,\n // though.\n const isSecureCookie = determineSecureFromServerContext(rscCookiesAwaited, rscHeadersAwaited);\n\n try {\n rscCookiesAwaited.set(name, value, {\n secure: isSecureCookie,\n maxAge: options.maxAge === \"session\" ? undefined : options.maxAge,\n domain: options.domain,\n sameSite: \"lax\",\n });\n } catch (e) {\n handleCookieError(e, options);\n }\n },\n setOrDelete(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions) {\n if (value === null) {\n this.delete(name, options);\n } else {\n this.set(name, value, options);\n }\n },\n delete(name: string, options: DeleteCookieOptions) {\n try {\n if (options.domain !== undefined) {\n rscCookiesAwaited.delete({ name, domain: options.domain });\n } else {\n rscCookiesAwaited.delete(name);\n }\n } catch (e) {\n handleCookieError(e, options);\n }\n },\n };\n return cookieHelper;\n}\n\nexport function getCookieClient(name: string): string | null {\n const all = getAllCookiesClient();\n return all[name] ?? null;\n}\n\nexport function getAllCookiesClient(): Record<string, string> {\n ensureClient();\n // set a helper cookie, see comment in `NextCookieHelper.set` above\n Cookies.set(\"stack-is-https\", \"true\", { secure: true, expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365) });\n return Cookies.get();\n}\n\nexport async function getCookie(name: string): Promise<string | null> {\n const cookieHelper = await createCookieHelper();\n return cookieHelper.get(name);\n}\n\nexport async function isSecure(): Promise<boolean> {\n if (isBrowserLike()) {\n return determineSecureFromClientContext();\n }\n return determineSecureFromServerContext(await rscCookies(), await rscHeaders());\n return false;\n}\n\nfunction determineSecureFromClientContext(): boolean {\n return typeof window !== \"undefined\" && window.location.protocol === \"https:\";\n}\nfunction determineSecureFromServerContext(\n cookies: Awaited<ReturnType<typeof rscCookies>>,\n headers: Awaited<ReturnType<typeof rscHeaders>>,\n): boolean {\n // see the algorithm at the top of this file\n // TODO: We should probably also check that the stack-is-https cookie has a Secure attribute itself,\n // TODO: We should consider adding another cookie __Host-stack-is-https, see the comment in the algorithm at the top of this file\n return cookies.has(\"stack-is-https\") || headers.get(\"x-forwarded-proto\") === \"https\";\n}\n\n\nlet _shouldSetPartitionedClientCache: boolean | undefined = undefined;\nfunction shouldSetPartitionedClient() {\n return _shouldSetPartitionedClientCache ??= _internalShouldSetPartitionedClient();\n}\nfunction _internalShouldSetPartitionedClient() {\n ensureClient();\n\n if (!(determineSecureFromClientContext())) {\n return false;\n }\n\n // check whether we can set & retrieve normal cookies (either because we're on a top-level/same-origin context or the browser partitions cookies by default)\n const cookie1Name = \"__Host-stack-temporary-chips-test-\" + Math.random().toString(36).substring(2, 15);\n document.cookie = `${cookie1Name}=value1; Secure; path=/`;\n const cookies1 = document.cookie.split(\"; \");\n document.cookie = `${cookie1Name}=delete1; Secure; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;`;\n if (cookies1.some((c) => c.startsWith(cookie1Name + \"=\"))) {\n return false;\n }\n\n\n // check whether Partitioned cookies are supported by the browser\n // TODO: See comment at the top. Feels like we should find a better way to do this\n const cookie2Name = \"__Host-stack-temporary-chips-test-\" + Math.random().toString(36).substring(2, 15);\n\n // just to be safe, delete the cookie first to avoid weird RNG-prediction attacks\n // I don't know what they look like (since this is a host cookie) but better safe than sorry\n // (this function should be 100% bulletproof so we don't accidentally fall back to non-partitioned third party cookies on unsupported browsers)\n document.cookie = `${cookie2Name}=delete1; Secure; SameSite=None; Partitioned; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n document.cookie = `${cookie2Name}=delete2; Secure; SameSite=None; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n\n // set the cookie, once partitioned and once not partitioned\n document.cookie = `${cookie2Name}=set1; Secure; SameSite=None; Partitioned; path=/`;\n document.cookie = `${cookie2Name}=set2; Secure; SameSite=None; path=/`;\n\n // check if there are two cookies\n const cookies2 = document.cookie.split(\"; \");\n const numberOfCookiesWithThisName = cookies2.filter((c) => c.startsWith(cookie2Name + \"=\")).length;\n\n // clean up\n document.cookie = `${cookie2Name}=delete3; Secure; SameSite=None; Partitioned; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n document.cookie = `${cookie2Name}=delete4; Secure; SameSite=None; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/`;\n\n return numberOfCookiesWithThisName === 2;\n}\n\nfunction setCookieClientInternal(name: string, value: string, options: SetCookieOptions) {\n const secure = options.secure ?? determineSecureFromClientContext();\n const partitioned = shouldSetPartitionedClient();\n Cookies.set(name, value, {\n expires: options.maxAge === \"session\" ? undefined : new Date(Date.now() + (options.maxAge) * 1000),\n domain: options.domain,\n secure,\n sameSite: \"Lax\",\n ...(partitioned ? {\n partitioned,\n sameSite: \"None\",\n } : {}),\n });\n}\n\nfunction deleteCookieClientInternal(name: string, options: DeleteCookieOptions) {\n for (const partitioned of [true, false]) {\n if (options.domain !== undefined) {\n Cookies.remove(name, { domain: options.domain, secure: determineSecureFromClientContext(), partitioned });\n }\n Cookies.remove(name, { secure: determineSecureFromClientContext(), partitioned });\n }\n}\n\nexport function setOrDeleteCookieClient(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions) {\n ensureClient();\n if (value === null) {\n deleteCookieClientInternal(name, options);\n } else {\n setCookieClientInternal(name, value, options);\n }\n}\n\nexport async function setOrDeleteCookie(name: string, value: string | null, options: SetCookieOptions & DeleteCookieOptions) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.setOrDelete(name, value, options);\n}\n\nexport function deleteCookieClient(name: string, options: DeleteCookieOptions) {\n ensureClient();\n deleteCookieClientInternal(name, options);\n}\n\nexport async function deleteCookie(name: string, options: DeleteCookieOptions) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.delete(name, options);\n}\n\nexport function setCookieClient(name: string, value: string, options: SetCookieOptions) {\n ensureClient();\n setCookieClientInternal(name, value, options);\n}\n\nexport async function setCookie(name: string, value: string, options: SetCookieOptions) {\n const cookieHelper = await createCookieHelper();\n cookieHelper.set(name, value, options);\n}\n\nexport async function saveVerifierAndState() {\n const codeVerifier = generateRandomCodeVerifier();\n const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);\n const state = generateRandomState();\n\n await setCookie(\"stack-oauth-outer-\" + state, codeVerifier, { maxAge: 60 * 60 });\n\n return {\n codeChallenge,\n state,\n };\n}\n\nexport function consumeVerifierAndStateCookie(state: string) {\n ensureClient();\n const cookieName = \"stack-oauth-outer-\" + state;\n const codeVerifier = getCookieClient(cookieName);\n if (!codeVerifier) {\n return null;\n }\n deleteCookieClient(cookieName, {});\n return {\n codeVerifier,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -6,6 +6,7 @@ import { encodeBase32 } from "@stackframe/stack-shared/dist/utils/bytes";
|
|
|
6
6
|
import { scrambleDuringCompileTime } from "@stackframe/stack-shared/dist/utils/compile-time";
|
|
7
7
|
import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
|
|
8
8
|
import { StackAssertionError, captureError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
|
9
|
+
import { parseJson } from "@stackframe/stack-shared/dist/utils/json";
|
|
9
10
|
import { DependenciesMap } from "@stackframe/stack-shared/dist/utils/maps";
|
|
10
11
|
import { deepPlainEquals, omit } from "@stackframe/stack-shared/dist/utils/objects";
|
|
11
12
|
import { neverResolve, runAsynchronously, wait } from "@stackframe/stack-shared/dist/utils/promises";
|
|
@@ -20,7 +21,7 @@ import * as NextNavigationUnscrambled from "next/navigation";
|
|
|
20
21
|
import React, { useCallback, useMemo } from "react";
|
|
21
22
|
import { constructRedirectUrl } from "../../../../utils/url.js";
|
|
22
23
|
import { addNewOAuthProviderOrScope, callOAuthCallback, signInWithOAuth } from "../../../auth.js";
|
|
23
|
-
import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookieClient, isSecure as isSecureCookieContext, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie.js";
|
|
24
|
+
import { createBrowserCookieHelper, createCookieHelper, createPlaceholderCookieHelper, deleteCookie, deleteCookieClient, isSecure as isSecureCookieContext, setOrDeleteCookie, setOrDeleteCookieClient } from "../../../cookie.js";
|
|
24
25
|
import { apiKeyCreationOptionsToCrud } from "../../api-keys/index.js";
|
|
25
26
|
import { stackAppInternalsSymbol } from "../../common.js";
|
|
26
27
|
import { contactChannelCreateOptionsToCrud, contactChannelUpdateOptionsToCrud } from "../../contact-channels/index.js";
|
|
@@ -28,7 +29,6 @@ import { adminProjectCreateOptionsToCrud } from "../../projects/index.js";
|
|
|
28
29
|
import { teamCreateOptionsToCrud, teamUpdateOptionsToCrud } from "../../teams/index.js";
|
|
29
30
|
import { attachUserDestructureGuard, userUpdateOptionsToCrud } from "../../users/index.js";
|
|
30
31
|
import { clientVersion, createCache, createCacheBySession, createEmptyTokenStore, getBaseUrl, getDefaultExtraRequestHeaders, getDefaultProjectId, getDefaultPublishableClientKey, getUrls, resolveConstructorOptions } from "./common.js";
|
|
31
|
-
import { parseJson } from "@stackframe/stack-shared/dist/utils/json";
|
|
32
32
|
import { useAsyncCache } from "./common.js";
|
|
33
33
|
import * as sc from "@stackframe/stack-sc";
|
|
34
34
|
import { cookies } from "@stackframe/stack-sc";
|
|
@@ -469,9 +469,10 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
469
469
|
return;
|
|
470
470
|
}
|
|
471
471
|
const domain = await this._trustedParentDomainCache.getOrWait([hostname], "read-write");
|
|
472
|
+
const cookieOptions = { maxAge: 60 * 60 * 24 * 365, noOpIfServerComponent: true };
|
|
472
473
|
const setCookie = async (targetDomain, value2) => {
|
|
473
474
|
const name = this._getCustomRefreshCookieName(targetDomain);
|
|
474
|
-
const options = {
|
|
475
|
+
const options = { ...cookieOptions, domain: targetDomain };
|
|
475
476
|
if (context === "browser") {
|
|
476
477
|
setOrDeleteCookieClient(name, value2, options);
|
|
477
478
|
} else {
|
|
@@ -484,7 +485,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
484
485
|
const value = refreshToken && updatedAt ? this._formatRefreshCookieValue(refreshToken, updatedAt) : null;
|
|
485
486
|
await setCookie(domain.data, value);
|
|
486
487
|
const isSecure = await isSecureCookieContext();
|
|
487
|
-
await setOrDeleteCookie(this._getRefreshTokenDefaultCookieNameForSecure(isSecure), null);
|
|
488
|
+
await setOrDeleteCookie(this._getRefreshTokenDefaultCookieNameForSecure(isSecure), null, cookieOptions);
|
|
488
489
|
});
|
|
489
490
|
}
|
|
490
491
|
async _getTrustedParentDomain(currentDomain) {
|
|
@@ -536,7 +537,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
536
537
|
);
|
|
537
538
|
setOrDeleteCookieClient(defaultName, refreshCookieValue, { maxAge: 60 * 60 * 24 * 365, secure });
|
|
538
539
|
setOrDeleteCookieClient(this._accessTokenCookieName, accessTokenPayload, { maxAge: 60 * 60 * 24 });
|
|
539
|
-
cookieNamesToDelete.forEach((name) => deleteCookieClient(name));
|
|
540
|
+
cookieNamesToDelete.forEach((name) => deleteCookieClient(name, {}));
|
|
540
541
|
this._queueCustomRefreshCookieUpdate(refreshToken, updatedAt, "browser");
|
|
541
542
|
hasSucceededInWriting = true;
|
|
542
543
|
} catch (e) {
|
|
@@ -580,7 +581,7 @@ var __StackClientAppImplIncomplete = class __StackClientAppImplIncomplete {
|
|
|
580
581
|
if (cookieNamesToDelete.length > 0) {
|
|
581
582
|
await Promise.all(
|
|
582
583
|
cookieNamesToDelete.map(
|
|
583
|
-
(name) =>
|
|
584
|
+
(name) => deleteCookie(name, { noOpIfServerComponent: true })
|
|
584
585
|
)
|
|
585
586
|
);
|
|
586
587
|
}
|