@stackframe/js 2.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1348 -0
- package/LICENSE +7 -0
- package/README.md +26 -0
- package/dist/esm/generated/global-css.js +6 -0
- package/dist/esm/generated/global-css.js.map +1 -0
- package/dist/esm/generated/quetzal-translations.js +2397 -0
- package/dist/esm/generated/quetzal-translations.js.map +1 -0
- package/dist/esm/global.d.js +1 -0
- package/dist/esm/global.d.js.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/auth.js +98 -0
- package/dist/esm/lib/auth.js.map +1 -0
- package/dist/esm/lib/cookie.js +302 -0
- package/dist/esm/lib/cookie.js.map +1 -0
- package/dist/esm/lib/stack-app.js +2087 -0
- package/dist/esm/lib/stack-app.js.map +1 -0
- package/dist/esm/utils/url.js +30 -0
- package/dist/esm/utils/url.js.map +1 -0
- package/dist/generated/global-css.d.mts +3 -0
- package/dist/generated/global-css.d.ts +3 -0
- package/dist/generated/global-css.js +31 -0
- package/dist/generated/global-css.js.map +1 -0
- package/dist/generated/quetzal-translations.d.mts +4 -0
- package/dist/generated/quetzal-translations.d.ts +4 -0
- package/dist/generated/quetzal-translations.js +2423 -0
- package/dist/generated/quetzal-translations.js.map +1 -0
- package/dist/global.d.d.mts +2 -0
- package/dist/global.d.d.ts +2 -0
- package/dist/global.d.js +2 -0
- package/dist/global.d.js.map +1 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth.d.mts +33 -0
- package/dist/lib/auth.d.ts +33 -0
- package/dist/lib/auth.js +125 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/cookie.d.mts +33 -0
- package/dist/lib/cookie.d.ts +33 -0
- package/dist/lib/cookie.js +349 -0
- package/dist/lib/cookie.js.map +1 -0
- package/dist/lib/stack-app.d.mts +726 -0
- package/dist/lib/stack-app.d.ts +726 -0
- package/dist/lib/stack-app.js +2127 -0
- package/dist/lib/stack-app.js.map +1 -0
- package/dist/utils/url.d.mts +4 -0
- package/dist/utils/url.d.ts +4 -0
- package/dist/utils/url.js +56 -0
- package/dist/utils/url.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=global.d.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nexport * from './lib/stack-app';\n\n"],"mappings":";AAIA,cAAc;","names":[]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// src/lib/auth.ts
|
|
2
|
+
import { KnownError } from "@stackframe/stack-shared";
|
|
3
|
+
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
|
|
4
|
+
import { neverResolve } from "@stackframe/stack-shared/dist/utils/promises";
|
|
5
|
+
import { Result } from "@stackframe/stack-shared/dist/utils/results";
|
|
6
|
+
import { deindent } from "@stackframe/stack-shared/dist/utils/strings";
|
|
7
|
+
import { constructRedirectUrl } from "../utils/url";
|
|
8
|
+
import { consumeVerifierAndStateCookie, saveVerifierAndState } from "./cookie";
|
|
9
|
+
async function signInWithOAuth(iface, options) {
|
|
10
|
+
const { codeChallenge, state } = await saveVerifierAndState();
|
|
11
|
+
const location = await iface.getOAuthUrl({
|
|
12
|
+
provider: options.provider,
|
|
13
|
+
redirectUrl: constructRedirectUrl(options.redirectUrl),
|
|
14
|
+
errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),
|
|
15
|
+
codeChallenge,
|
|
16
|
+
state,
|
|
17
|
+
type: "authenticate",
|
|
18
|
+
providerScope: options.providerScope
|
|
19
|
+
});
|
|
20
|
+
window.location.assign(location);
|
|
21
|
+
await neverResolve();
|
|
22
|
+
}
|
|
23
|
+
async function addNewOAuthProviderOrScope(iface, options, session) {
|
|
24
|
+
const { codeChallenge, state } = await saveVerifierAndState();
|
|
25
|
+
const location = await iface.getOAuthUrl({
|
|
26
|
+
provider: options.provider,
|
|
27
|
+
redirectUrl: constructRedirectUrl(options.redirectUrl),
|
|
28
|
+
errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),
|
|
29
|
+
afterCallbackRedirectUrl: constructRedirectUrl(window.location.href),
|
|
30
|
+
codeChallenge,
|
|
31
|
+
state,
|
|
32
|
+
type: "link",
|
|
33
|
+
session,
|
|
34
|
+
providerScope: options.providerScope
|
|
35
|
+
});
|
|
36
|
+
window.location.assign(location);
|
|
37
|
+
await neverResolve();
|
|
38
|
+
}
|
|
39
|
+
function consumeOAuthCallbackQueryParams() {
|
|
40
|
+
const requiredParams = ["code", "state"];
|
|
41
|
+
const originalUrl = new URL(window.location.href);
|
|
42
|
+
for (const param of requiredParams) {
|
|
43
|
+
if (!originalUrl.searchParams.has(param)) {
|
|
44
|
+
console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const expectedState = originalUrl.searchParams.get("state") ?? throwErr("This should never happen; isn't state required above?");
|
|
49
|
+
const cookieResult = consumeVerifierAndStateCookie(expectedState);
|
|
50
|
+
if (!cookieResult) {
|
|
51
|
+
console.warn(deindent`
|
|
52
|
+
Stack found an outer OAuth callback state in the query parameters, but not in cookies.
|
|
53
|
+
|
|
54
|
+
This could have multiple reasons:
|
|
55
|
+
- The cookie expired, because the OAuth flow took too long.
|
|
56
|
+
- The user's browser deleted the cookie, either manually or because of a very strict cookie policy.
|
|
57
|
+
- The cookie was already consumed by this page, and the user already logged in.
|
|
58
|
+
- You are using another OAuth client library with the same callback URL as Stack.
|
|
59
|
+
- The user opened the OAuth callback page from their history.
|
|
60
|
+
|
|
61
|
+
Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.
|
|
62
|
+
`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const newUrl = new URL(originalUrl);
|
|
66
|
+
for (const param of requiredParams) {
|
|
67
|
+
newUrl.searchParams.delete(param);
|
|
68
|
+
}
|
|
69
|
+
window.history.replaceState({}, "", newUrl.toString());
|
|
70
|
+
return {
|
|
71
|
+
originalUrl,
|
|
72
|
+
codeVerifier: cookieResult.codeVerifier,
|
|
73
|
+
state: expectedState
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function callOAuthCallback(iface, redirectUrl) {
|
|
77
|
+
const consumed = consumeOAuthCallbackQueryParams();
|
|
78
|
+
if (!consumed) return Result.ok(void 0);
|
|
79
|
+
try {
|
|
80
|
+
return Result.ok(await iface.callOAuthCallback({
|
|
81
|
+
oauthParams: consumed.originalUrl.searchParams,
|
|
82
|
+
redirectUri: constructRedirectUrl(redirectUrl),
|
|
83
|
+
codeVerifier: consumed.codeVerifier,
|
|
84
|
+
state: consumed.state
|
|
85
|
+
}));
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (e instanceof KnownError) {
|
|
88
|
+
throw e;
|
|
89
|
+
}
|
|
90
|
+
throw new StackAssertionError("Error signing in during OAuth callback. Please try again.", { cause: e });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
addNewOAuthProviderOrScope,
|
|
95
|
+
callOAuthCallback,
|
|
96
|
+
signInWithOAuth
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/auth.ts"],"sourcesContent":["//===========================================\n// THIS FILE IS AUTO-GENERATED FROM TEMPLATE. DO NOT EDIT IT DIRECTLY\n//===========================================\n\nimport { KnownError, StackClientInterface } from \"@stackframe/stack-shared\";\nimport { InternalSession } from \"@stackframe/stack-shared/dist/sessions\";\nimport { StackAssertionError, throwErr } from \"@stackframe/stack-shared/dist/utils/errors\";\nimport { neverResolve } from \"@stackframe/stack-shared/dist/utils/promises\";\nimport { Result } from \"@stackframe/stack-shared/dist/utils/results\";\nimport { deindent } from \"@stackframe/stack-shared/dist/utils/strings\";\nimport { constructRedirectUrl } from \"../utils/url\";\nimport { consumeVerifierAndStateCookie, saveVerifierAndState } from \"./cookie\";\n\nexport async function signInWithOAuth(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n }\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),\n codeChallenge,\n state,\n type: \"authenticate\",\n providerScope: options.providerScope,\n });\n window.location.assign(location);\n await neverResolve();\n}\n\nexport async function addNewOAuthProviderOrScope(\n iface: StackClientInterface,\n options: {\n provider: string,\n redirectUrl: string,\n errorRedirectUrl: string,\n providerScope?: string,\n },\n session: InternalSession,\n) {\n const { codeChallenge, state } = await saveVerifierAndState();\n const location = await iface.getOAuthUrl({\n provider: options.provider,\n redirectUrl: constructRedirectUrl(options.redirectUrl),\n errorRedirectUrl: constructRedirectUrl(options.errorRedirectUrl),\n afterCallbackRedirectUrl: constructRedirectUrl(window.location.href),\n codeChallenge,\n state,\n type: \"link\",\n session,\n providerScope: options.providerScope,\n });\n window.location.assign(location);\n await neverResolve();\n}\n\n/**\n * Checks if the current URL has the query parameters for an OAuth callback, and if so, removes them.\n *\n * Must be synchronous for the logic in callOAuthCallback to work without race conditions.\n */\nfunction consumeOAuthCallbackQueryParams() {\n const requiredParams = [\"code\", \"state\"];\n const originalUrl = new URL(window.location.href);\n for (const param of requiredParams) {\n if (!originalUrl.searchParams.has(param)) {\n console.warn(new Error(`Missing required query parameter on OAuth callback: ${param}. Maybe you opened or reloaded the oauth-callback page from your history?`));\n return null;\n }\n }\n\n const expectedState = originalUrl.searchParams.get(\"state\") ?? throwErr(\"This should never happen; isn't state required above?\");\n const cookieResult = consumeVerifierAndStateCookie(expectedState);\n\n if (!cookieResult) {\n // If the state can't be found in the cookies, then the callback wasn't meant for us.\n // Maybe the website uses another OAuth library?\n console.warn(deindent`\n Stack found an outer OAuth callback state in the query parameters, but not in cookies.\n \n This could have multiple reasons:\n - The cookie expired, because the OAuth flow took too long.\n - The user's browser deleted the cookie, either manually or because of a very strict cookie policy.\n - The cookie was already consumed by this page, and the user already logged in.\n - You are using another OAuth client library with the same callback URL as Stack.\n - The user opened the OAuth callback page from their history.\n\n Either way, it is probably safe to ignore this warning unless you are debugging an OAuth issue.\n `);\n return null;\n }\n\n\n const newUrl = new URL(originalUrl);\n for (const param of requiredParams) {\n newUrl.searchParams.delete(param);\n }\n\n // let's get rid of the authorization code in the history as we\n // don't redirect to `redirectUrl` if there's a validation error\n // (as the redirectUrl might be malicious!).\n //\n // We use history.replaceState instead of location.assign(...) to\n // prevent an unnecessary reload\n window.history.replaceState({}, \"\", newUrl.toString());\n\n return {\n originalUrl,\n codeVerifier: cookieResult.codeVerifier,\n state: expectedState,\n };\n}\n\nexport async function callOAuthCallback(\n iface: StackClientInterface,\n redirectUrl: string,\n) {\n // note: this part of the function (until the return) needs\n // to be synchronous, to prevent race conditions when\n // callOAuthCallback is called multiple times in parallel\n const consumed = consumeOAuthCallbackQueryParams();\n if (!consumed) return Result.ok(undefined);\n\n // the rest can be asynchronous (we now know that we are the\n // intended recipient of the callback, and the only instance\n // of callOAuthCallback that's running)\n try {\n return Result.ok(await iface.callOAuthCallback({\n oauthParams: consumed.originalUrl.searchParams,\n redirectUri: constructRedirectUrl(redirectUrl),\n codeVerifier: consumed.codeVerifier,\n state: consumed.state,\n }));\n } catch (e) {\n if (e instanceof KnownError) {\n throw e;\n }\n throw new StackAssertionError(\"Error signing in during OAuth callback. Please try again.\", { cause: e });\n }\n}\n"],"mappings":";AAIA,SAAS,kBAAwC;AAEjD,SAAS,qBAAqB,gBAAgB;AAC9C,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,4BAA4B;AACrC,SAAS,+BAA+B,4BAA4B;AAEpE,eAAsB,gBACpB,OACA,SAMA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,WAAW;AAAA,IACrD,kBAAkB,qBAAqB,QAAQ,gBAAgB;AAAA,IAC/D;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAEA,eAAsB,2BACpB,OACA,SAMA,SACA;AACA,QAAM,EAAE,eAAe,MAAM,IAAI,MAAM,qBAAqB;AAC5D,QAAM,WAAW,MAAM,MAAM,YAAY;AAAA,IACvC,UAAU,QAAQ;AAAA,IAClB,aAAa,qBAAqB,QAAQ,WAAW;AAAA,IACrD,kBAAkB,qBAAqB,QAAQ,gBAAgB;AAAA,IAC/D,0BAA0B,qBAAqB,OAAO,SAAS,IAAI;AAAA,IACnE;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,eAAe,QAAQ;AAAA,EACzB,CAAC;AACD,SAAO,SAAS,OAAO,QAAQ;AAC/B,QAAM,aAAa;AACrB;AAOA,SAAS,kCAAkC;AACzC,QAAM,iBAAiB,CAAC,QAAQ,OAAO;AACvC,QAAM,cAAc,IAAI,IAAI,OAAO,SAAS,IAAI;AAChD,aAAW,SAAS,gBAAgB;AAClC,QAAI,CAAC,YAAY,aAAa,IAAI,KAAK,GAAG;AACxC,cAAQ,KAAK,IAAI,MAAM,uDAAuD,KAAK,2EAA2E,CAAC;AAC/J,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,gBAAgB,YAAY,aAAa,IAAI,OAAO,KAAK,SAAS,uDAAuD;AAC/H,QAAM,eAAe,8BAA8B,aAAa;AAEhE,MAAI,CAAC,cAAc;AAGjB,YAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAWZ;AACD,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,IAAI,IAAI,WAAW;AAClC,aAAW,SAAS,gBAAgB;AAClC,WAAO,aAAa,OAAO,KAAK;AAAA,EAClC;AAQA,SAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,OAAO,SAAS,CAAC;AAErD,SAAO;AAAA,IACL;AAAA,IACA,cAAc,aAAa;AAAA,IAC3B,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBACpB,OACA,aACA;AAIA,QAAM,WAAW,gCAAgC;AACjD,MAAI,CAAC,SAAU,QAAO,OAAO,GAAG,MAAS;AAKzC,MAAI;AACF,WAAO,OAAO,GAAG,MAAM,MAAM,kBAAkB;AAAA,MAC7C,aAAa,SAAS,YAAY;AAAA,MAClC,aAAa,qBAAqB,WAAW;AAAA,MAC7C,cAAc,SAAS;AAAA,MACvB,OAAO,SAAS;AAAA,IAClB,CAAC,CAAC;AAAA,EACJ,SAAS,GAAG;AACV,QAAI,aAAa,YAAY;AAC3B,YAAM;AAAA,IACR;AACA,UAAM,IAAI,oBAAoB,6DAA6D,EAAE,OAAO,EAAE,CAAC;AAAA,EACzG;AACF;","names":[]}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
// src/lib/cookie.ts
|
|
2
|
+
import { cookies as rscCookies, headers as rscHeaders } from "@stackframe/stack-sc/force-react-server";
|
|
3
|
+
import { isBrowserLike } from "@stackframe/stack-shared/dist/utils/env";
|
|
4
|
+
import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
|
|
5
|
+
import Cookies from "js-cookie";
|
|
6
|
+
|
|
7
|
+
// ../../node_modules/.pnpm/oauth4webapi@2.10.4/node_modules/oauth4webapi/build/index.js
|
|
8
|
+
var USER_AGENT;
|
|
9
|
+
if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) {
|
|
10
|
+
const NAME = "oauth4webapi";
|
|
11
|
+
const VERSION = "v2.10.4";
|
|
12
|
+
USER_AGENT = `${NAME}/${VERSION}`;
|
|
13
|
+
}
|
|
14
|
+
var clockSkew = Symbol();
|
|
15
|
+
var clockTolerance = Symbol();
|
|
16
|
+
var customFetch = Symbol();
|
|
17
|
+
var useMtlsAlias = Symbol();
|
|
18
|
+
var encoder = new TextEncoder();
|
|
19
|
+
var decoder = new TextDecoder();
|
|
20
|
+
function buf(input) {
|
|
21
|
+
if (typeof input === "string") {
|
|
22
|
+
return encoder.encode(input);
|
|
23
|
+
}
|
|
24
|
+
return decoder.decode(input);
|
|
25
|
+
}
|
|
26
|
+
var CHUNK_SIZE = 32768;
|
|
27
|
+
function encodeBase64Url(input) {
|
|
28
|
+
if (input instanceof ArrayBuffer) {
|
|
29
|
+
input = new Uint8Array(input);
|
|
30
|
+
}
|
|
31
|
+
const arr = [];
|
|
32
|
+
for (let i = 0; i < input.byteLength; i += CHUNK_SIZE) {
|
|
33
|
+
arr.push(String.fromCharCode.apply(null, input.subarray(i, i + CHUNK_SIZE)));
|
|
34
|
+
}
|
|
35
|
+
return btoa(arr.join("")).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
|
|
36
|
+
}
|
|
37
|
+
function decodeBase64Url(input) {
|
|
38
|
+
try {
|
|
39
|
+
const binary = atob(input.replace(/-/g, "+").replace(/_/g, "/").replace(/\s/g, ""));
|
|
40
|
+
const bytes = new Uint8Array(binary.length);
|
|
41
|
+
for (let i = 0; i < binary.length; i++) {
|
|
42
|
+
bytes[i] = binary.charCodeAt(i);
|
|
43
|
+
}
|
|
44
|
+
return bytes;
|
|
45
|
+
} catch (cause) {
|
|
46
|
+
throw new OPE("The input to be decoded is not correctly encoded.", { cause });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function b64u(input) {
|
|
50
|
+
if (typeof input === "string") {
|
|
51
|
+
return decodeBase64Url(input);
|
|
52
|
+
}
|
|
53
|
+
return encodeBase64Url(input);
|
|
54
|
+
}
|
|
55
|
+
var LRU = class {
|
|
56
|
+
constructor(maxSize) {
|
|
57
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
58
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
59
|
+
this.maxSize = maxSize;
|
|
60
|
+
}
|
|
61
|
+
get(key) {
|
|
62
|
+
let v = this.cache.get(key);
|
|
63
|
+
if (v) {
|
|
64
|
+
return v;
|
|
65
|
+
}
|
|
66
|
+
if (v = this._cache.get(key)) {
|
|
67
|
+
this.update(key, v);
|
|
68
|
+
return v;
|
|
69
|
+
}
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
has(key) {
|
|
73
|
+
return this.cache.has(key) || this._cache.has(key);
|
|
74
|
+
}
|
|
75
|
+
set(key, value) {
|
|
76
|
+
if (this.cache.has(key)) {
|
|
77
|
+
this.cache.set(key, value);
|
|
78
|
+
} else {
|
|
79
|
+
this.update(key, value);
|
|
80
|
+
}
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
delete(key) {
|
|
84
|
+
if (this.cache.has(key)) {
|
|
85
|
+
return this.cache.delete(key);
|
|
86
|
+
}
|
|
87
|
+
if (this._cache.has(key)) {
|
|
88
|
+
return this._cache.delete(key);
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
update(key, value) {
|
|
93
|
+
this.cache.set(key, value);
|
|
94
|
+
if (this.cache.size >= this.maxSize) {
|
|
95
|
+
this._cache = this.cache;
|
|
96
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var OperationProcessingError = class extends Error {
|
|
101
|
+
constructor(message, options) {
|
|
102
|
+
super(message, options);
|
|
103
|
+
this.name = this.constructor.name;
|
|
104
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var OPE = OperationProcessingError;
|
|
108
|
+
var dpopNonces = new LRU(100);
|
|
109
|
+
function validateString(input) {
|
|
110
|
+
return typeof input === "string" && input.length !== 0;
|
|
111
|
+
}
|
|
112
|
+
function randomBytes() {
|
|
113
|
+
return b64u(crypto.getRandomValues(new Uint8Array(32)));
|
|
114
|
+
}
|
|
115
|
+
function generateRandomCodeVerifier() {
|
|
116
|
+
return randomBytes();
|
|
117
|
+
}
|
|
118
|
+
function generateRandomState() {
|
|
119
|
+
return randomBytes();
|
|
120
|
+
}
|
|
121
|
+
async function calculatePKCECodeChallenge(codeVerifier) {
|
|
122
|
+
if (!validateString(codeVerifier)) {
|
|
123
|
+
throw new TypeError('"codeVerifier" must be a non-empty string');
|
|
124
|
+
}
|
|
125
|
+
return b64u(await crypto.subtle.digest("SHA-256", buf(codeVerifier)));
|
|
126
|
+
}
|
|
127
|
+
var skipSubjectCheck = Symbol();
|
|
128
|
+
var expectNoNonce = Symbol();
|
|
129
|
+
var skipAuthTimeCheck = Symbol();
|
|
130
|
+
var noSignatureCheck = Symbol();
|
|
131
|
+
var skipStateCheck = Symbol();
|
|
132
|
+
var expectNoState = Symbol();
|
|
133
|
+
|
|
134
|
+
// src/lib/cookie.ts
|
|
135
|
+
function ensureClient() {
|
|
136
|
+
if (!isBrowserLike()) {
|
|
137
|
+
throw new Error("cookieClient functions can only be called in a browser environment, yet window is undefined");
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async function createEmptyCookieHelper() {
|
|
141
|
+
function throwError() {
|
|
142
|
+
throw new StackAssertionError("Empty cookie helper is just a placeholder. This should never be called");
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
get: () => {
|
|
146
|
+
throwError();
|
|
147
|
+
return null;
|
|
148
|
+
},
|
|
149
|
+
set: throwError,
|
|
150
|
+
setOrDelete: throwError,
|
|
151
|
+
delete: throwError
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async function createCookieHelper() {
|
|
155
|
+
if (isBrowserLike()) {
|
|
156
|
+
return createBrowserCookieHelper();
|
|
157
|
+
} else {
|
|
158
|
+
return createNextCookieHelper(
|
|
159
|
+
await rscCookies(),
|
|
160
|
+
await rscHeaders()
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function createBrowserCookieHelper() {
|
|
165
|
+
return {
|
|
166
|
+
get: getCookieClient,
|
|
167
|
+
set: setCookieClient,
|
|
168
|
+
setOrDelete: setOrDeleteCookieClient,
|
|
169
|
+
delete: deleteCookieClient
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function handleCookieError(e, options) {
|
|
173
|
+
if (e instanceof Error && e.message.includes("Cookies can only be modified in")) {
|
|
174
|
+
if (options.noOpIfServerComponent) {
|
|
175
|
+
} else {
|
|
176
|
+
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");
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
throw e;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function createNextCookieHelper(rscCookiesAwaited, rscHeadersAwaited) {
|
|
183
|
+
const cookieHelper = {
|
|
184
|
+
get: (name) => {
|
|
185
|
+
try {
|
|
186
|
+
rscCookiesAwaited.set("stack-is-https", "true", { secure: true });
|
|
187
|
+
} catch (e) {
|
|
188
|
+
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")) {
|
|
189
|
+
} else {
|
|
190
|
+
throw e;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return rscCookiesAwaited.get(name)?.value ?? null;
|
|
194
|
+
},
|
|
195
|
+
set: (name, value, options) => {
|
|
196
|
+
let isSecureCookie = !!rscCookiesAwaited.get("stack-is-https");
|
|
197
|
+
if (rscHeadersAwaited.get("x-forwarded-proto") === "https") {
|
|
198
|
+
isSecureCookie = true;
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
rscCookiesAwaited.set(name, value, {
|
|
202
|
+
secure: isSecureCookie,
|
|
203
|
+
maxAge: options.maxAge
|
|
204
|
+
});
|
|
205
|
+
} catch (e) {
|
|
206
|
+
handleCookieError(e, options);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
setOrDelete(name, value, options = {}) {
|
|
210
|
+
if (value === null) {
|
|
211
|
+
this.delete(name, options);
|
|
212
|
+
} else {
|
|
213
|
+
this.set(name, value, options);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
delete(name, options = {}) {
|
|
217
|
+
try {
|
|
218
|
+
rscCookiesAwaited.delete(name);
|
|
219
|
+
} catch (e) {
|
|
220
|
+
handleCookieError(e, options);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
return cookieHelper;
|
|
225
|
+
}
|
|
226
|
+
function getCookieClient(name) {
|
|
227
|
+
ensureClient();
|
|
228
|
+
Cookies.set("stack-is-https", "true", { secure: true });
|
|
229
|
+
return Cookies.get(name) ?? null;
|
|
230
|
+
}
|
|
231
|
+
async function getCookie(name) {
|
|
232
|
+
const cookieHelper = await createCookieHelper();
|
|
233
|
+
return cookieHelper.get(name);
|
|
234
|
+
}
|
|
235
|
+
function setOrDeleteCookieClient(name, value, options = {}) {
|
|
236
|
+
ensureClient();
|
|
237
|
+
if (value === null) {
|
|
238
|
+
deleteCookieClient(name, options);
|
|
239
|
+
} else {
|
|
240
|
+
setCookieClient(name, value, options);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function setOrDeleteCookie(name, value, options = {}) {
|
|
244
|
+
const cookieHelper = await createCookieHelper();
|
|
245
|
+
cookieHelper.setOrDelete(name, value, options);
|
|
246
|
+
}
|
|
247
|
+
function deleteCookieClient(name, options = {}) {
|
|
248
|
+
ensureClient();
|
|
249
|
+
Cookies.remove(name);
|
|
250
|
+
}
|
|
251
|
+
async function deleteCookie(name, options = {}) {
|
|
252
|
+
const cookieHelper = await createCookieHelper();
|
|
253
|
+
cookieHelper.delete(name, options);
|
|
254
|
+
}
|
|
255
|
+
function setCookieClient(name, value, options = {}) {
|
|
256
|
+
ensureClient();
|
|
257
|
+
Cookies.set(name, value, {
|
|
258
|
+
expires: options.maxAge === void 0 ? void 0 : new Date(Date.now() + options.maxAge * 1e3)
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
async function setCookie(name, value, options = {}) {
|
|
262
|
+
const cookieHelper = await createCookieHelper();
|
|
263
|
+
cookieHelper.set(name, value, options);
|
|
264
|
+
}
|
|
265
|
+
async function saveVerifierAndState() {
|
|
266
|
+
const codeVerifier = generateRandomCodeVerifier();
|
|
267
|
+
const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);
|
|
268
|
+
const state = generateRandomState();
|
|
269
|
+
await setCookie("stack-oauth-outer-" + state, codeVerifier, { maxAge: 60 * 60 });
|
|
270
|
+
return {
|
|
271
|
+
codeChallenge,
|
|
272
|
+
state
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function consumeVerifierAndStateCookie(state) {
|
|
276
|
+
ensureClient();
|
|
277
|
+
const cookieName = "stack-oauth-outer-" + state;
|
|
278
|
+
const codeVerifier = getCookieClient(cookieName);
|
|
279
|
+
if (!codeVerifier) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
deleteCookieClient(cookieName);
|
|
283
|
+
return {
|
|
284
|
+
codeVerifier
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
export {
|
|
288
|
+
consumeVerifierAndStateCookie,
|
|
289
|
+
createBrowserCookieHelper,
|
|
290
|
+
createCookieHelper,
|
|
291
|
+
createEmptyCookieHelper,
|
|
292
|
+
deleteCookie,
|
|
293
|
+
deleteCookieClient,
|
|
294
|
+
getCookie,
|
|
295
|
+
getCookieClient,
|
|
296
|
+
saveVerifierAndState,
|
|
297
|
+
setCookie,
|
|
298
|
+
setCookieClient,
|
|
299
|
+
setOrDeleteCookie,
|
|
300
|
+
setOrDeleteCookieClient
|
|
301
|
+
};
|
|
302
|
+
//# sourceMappingURL=cookie.js.map
|