@propelauth/nextjs 0.0.100 → 0.0.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.d.ts +12 -5
- package/dist/client/index.js +40 -9
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +42 -9
- package/dist/client/index.mjs.map +1 -1
- package/dist/server/app-router/index.js +37 -26
- package/dist/server/app-router/index.js.map +1 -1
- package/dist/server/app-router/index.mjs +37 -26
- package/dist/server/app-router/index.mjs.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/pages/index.js +1 -1
- package/dist/server/pages/index.js.map +1 -1
- package/dist/server/pages/index.mjs +1 -1
- package/dist/server/pages/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -231,6 +231,7 @@ var ACCESS_TOKEN_COOKIE_NAME = "__pa_at";
|
|
|
231
231
|
var REFRESH_TOKEN_COOKIE_NAME = "__pa_rt";
|
|
232
232
|
var STATE_COOKIE_NAME = "__pa_state";
|
|
233
233
|
var CUSTOM_HEADER_FOR_ACCESS_TOKEN = "x-propelauth-access-token";
|
|
234
|
+
var RETURN_TO_PATH_COOKIE_NAME = "__pa_return_to_path";
|
|
234
235
|
var COOKIE_OPTIONS = {
|
|
235
236
|
httpOnly: true,
|
|
236
237
|
sameSite: "lax",
|
|
@@ -311,7 +312,7 @@ function validateAccessTokenOrUndefined(accessToken) {
|
|
|
311
312
|
} else if (err instanceof UnauthorizedException) {
|
|
312
313
|
return void 0;
|
|
313
314
|
} else {
|
|
314
|
-
console.
|
|
315
|
+
console.info("Error validating access token", err);
|
|
315
316
|
return void 0;
|
|
316
317
|
}
|
|
317
318
|
}
|
|
@@ -425,31 +426,39 @@ function getRouteHandlers(args) {
|
|
|
425
426
|
const authUrlOrigin = getAuthUrlOrigin();
|
|
426
427
|
const redirectUri = getRedirectUri();
|
|
427
428
|
const integrationApiKey = getIntegrationApiKey();
|
|
428
|
-
function loginGetHandler() {
|
|
429
|
-
|
|
430
|
-
const authorize_url = authUrlOrigin + "/propelauth/ssr/authorize?redirect_uri=" + redirectUri + "&state=" + state;
|
|
431
|
-
return new Response(null, {
|
|
432
|
-
status: 302,
|
|
433
|
-
headers: {
|
|
434
|
-
Location: authorize_url,
|
|
435
|
-
"Set-Cookie": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
|
436
|
-
}
|
|
437
|
-
});
|
|
429
|
+
function loginGetHandler(req) {
|
|
430
|
+
return signupOrLoginHandler(req, false);
|
|
438
431
|
}
|
|
439
|
-
function signupGetHandler() {
|
|
432
|
+
function signupGetHandler(req) {
|
|
433
|
+
return signupOrLoginHandler(req, true);
|
|
434
|
+
}
|
|
435
|
+
function signupOrLoginHandler(req, isSignup) {
|
|
436
|
+
const returnToPath = req.nextUrl.searchParams.get("return_to_path");
|
|
440
437
|
const state = randomState();
|
|
441
|
-
const
|
|
438
|
+
const authorizeUrlSearchParams = new URLSearchParams({
|
|
439
|
+
redirect_uri: redirectUri,
|
|
440
|
+
state,
|
|
441
|
+
signup: isSignup ? "true" : "false"
|
|
442
|
+
});
|
|
443
|
+
const authorize_url = getAuthUrlOrigin() + "/propelauth/ssr/authorize?" + authorizeUrlSearchParams.toString();
|
|
444
|
+
const headers2 = new Headers();
|
|
445
|
+
headers2.append("Location", authorize_url);
|
|
446
|
+
headers2.append("Set-Cookie", `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
447
|
+
if (returnToPath) {
|
|
448
|
+
if (returnToPath.startsWith("/")) {
|
|
449
|
+
headers2.append("Set-Cookie", `${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`);
|
|
450
|
+
} else {
|
|
451
|
+
console.warn("return_to_path must start with /");
|
|
452
|
+
}
|
|
453
|
+
}
|
|
442
454
|
return new Response(null, {
|
|
443
455
|
status: 302,
|
|
444
|
-
headers:
|
|
445
|
-
Location: authorize_url,
|
|
446
|
-
"Set-Cookie": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
|
447
|
-
}
|
|
456
|
+
headers: headers2
|
|
448
457
|
});
|
|
449
458
|
}
|
|
450
459
|
function callbackGetHandler(req) {
|
|
451
460
|
return __async(this, null, function* () {
|
|
452
|
-
var _a;
|
|
461
|
+
var _a, _b;
|
|
453
462
|
const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
|
|
454
463
|
if (!oauthState || oauthState.length !== 64) {
|
|
455
464
|
return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
|
|
@@ -476,15 +485,17 @@ function getRouteHandlers(args) {
|
|
|
476
485
|
if (response.ok) {
|
|
477
486
|
const data = yield response.json();
|
|
478
487
|
const accessToken = data.access_token;
|
|
479
|
-
const
|
|
480
|
-
|
|
481
|
-
|
|
488
|
+
const returnToPathFromCookie = (_b = req.cookies.get(RETURN_TO_PATH_COOKIE_NAME)) == null ? void 0 : _b.value;
|
|
489
|
+
const returnToPath = returnToPathFromCookie != null ? returnToPathFromCookie : (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
|
|
490
|
+
if (!returnToPath) {
|
|
491
|
+
console.error("postLoginRedirectPathFn returned undefined");
|
|
482
492
|
return new Response("Unexpected error", { status: 500 });
|
|
483
493
|
}
|
|
484
494
|
const headers2 = new Headers();
|
|
485
|
-
headers2.append("Location",
|
|
495
|
+
headers2.append("Location", returnToPath);
|
|
486
496
|
headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
487
497
|
headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
498
|
+
headers2.append("Set-Cookie", `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
|
|
488
499
|
return new Response(null, {
|
|
489
500
|
status: 302,
|
|
490
501
|
headers: headers2
|
|
@@ -558,7 +569,7 @@ function getRouteHandlers(args) {
|
|
|
558
569
|
var _a;
|
|
559
570
|
const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
|
|
560
571
|
if (!path) {
|
|
561
|
-
console.
|
|
572
|
+
console.error("postLoginPathFn returned undefined");
|
|
562
573
|
return new Response("Unexpected error", { status: 500 });
|
|
563
574
|
}
|
|
564
575
|
const refreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
|
|
@@ -616,7 +627,7 @@ function getRouteHandlers(args) {
|
|
|
616
627
|
}
|
|
617
628
|
});
|
|
618
629
|
if (!response.ok) {
|
|
619
|
-
console.
|
|
630
|
+
console.warn(
|
|
620
631
|
"Unable to logout, clearing cookies and continuing anyway",
|
|
621
632
|
response.status,
|
|
622
633
|
response.statusText
|
|
@@ -630,9 +641,9 @@ function getRouteHandlers(args) {
|
|
|
630
641
|
}
|
|
631
642
|
function getRouteHandler(req, { params }) {
|
|
632
643
|
if (params.slug === "login") {
|
|
633
|
-
return loginGetHandler();
|
|
644
|
+
return loginGetHandler(req);
|
|
634
645
|
} else if (params.slug === "signup") {
|
|
635
|
-
return signupGetHandler();
|
|
646
|
+
return signupGetHandler(req);
|
|
636
647
|
} else if (params.slug === "callback") {
|
|
637
648
|
return callbackGetHandler(req);
|
|
638
649
|
} else if (params.slug === "userinfo") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/server/app-router-index.ts","../../../src/server/exceptions.ts","../../../src/server/app-router.ts","../../../src/user.ts","../../../src/server/shared.ts"],"sourcesContent":["export {UnauthorizedException, ConfigurationException} from \"./exceptions\"\nexport {getRouteHandlers, getUser, getUserOrRedirect, getAccessToken, authMiddleware} from \"./app-router\"\nexport type {RouteHandlerArgs} from \"./app-router\"\n","export class UnauthorizedException extends Error {\n readonly message: string\n readonly status: number\n\n constructor(message: string) {\n super(message)\n this.message = message\n this.status = 401\n }\n}\n\nexport class ConfigurationException extends Error {\n readonly message: string\n readonly status: number\n\n constructor(message: string) {\n super(message)\n this.message = message\n this.status = 500\n }\n}\n","import {redirect} from \"next/navigation.js\";\nimport {cookies, headers} from \"next/headers.js\";\nimport {NextRequest, NextResponse} from \"next/server.js\";\nimport {\n ACCESS_TOKEN_COOKIE_NAME,\n CALLBACK_PATH,\n COOKIE_OPTIONS,\n CUSTOM_HEADER_FOR_ACCESS_TOKEN,\n getAuthUrlOrigin,\n getIntegrationApiKey,\n getRedirectUri,\n LOGIN_PATH,\n LOGOUT_PATH,\n REFRESH_TOKEN_COOKIE_NAME,\n refreshTokenWithAccessAndRefreshToken,\n STATE_COOKIE_NAME,\n USERINFO_PATH,\n validateAccessToken,\n validateAccessTokenOrUndefined\n} from \"./shared\";\nimport {UserFromToken} from \"./index\"\n\nexport async function getUserOrRedirect(): Promise<UserFromToken> {\n const user = await getUser()\n if (user) {\n return user\n } else {\n redirect(LOGIN_PATH)\n throw new Error(\"Redirecting to login\")\n }\n}\n\nexport async function getUser(): Promise<UserFromToken | undefined> {\n const accessToken = headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || cookies().get(ACCESS_TOKEN_COOKIE_NAME)?.value\n if (accessToken) {\n const user = await validateAccessTokenOrUndefined(accessToken)\n if (user) {\n return user\n }\n }\n return undefined\n}\n\nexport async function getAccessToken(): Promise<string | undefined> {\n return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || cookies().get(ACCESS_TOKEN_COOKIE_NAME)?.value\n}\n\n// Purpose of this middleware is just to keep the access token cookie alive\n// In an ideal world, this could be done in `getUser`, however, you can't\n// set a cookie in a server component.\n// There also doesn't seem to be any way right now to set a cookie in a\n// middleware and pass it forward (you can only set them on the response).\n// You CAN, however, pass in custom headers,\n// so we'll use CUSTOM_HEADER_FOR_ACCESS_TOKEN as a workaround\nexport async function authMiddleware(req: NextRequest): Promise<Response> {\n if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {\n throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`)\n } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {\n // Don't do anything for the callback, logout, or userinfo paths, as they will modify the cookies themselves\n return NextResponse.next()\n }\n\n const accessToken = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n\n // If we are authenticated, we can continue\n if (accessToken) {\n const user = await validateAccessTokenOrUndefined(accessToken)\n if (user) {\n return NextResponse.next()\n }\n }\n\n // Otherwise, we need to refresh the access token\n if (refreshToken) {\n const response = await refreshTokenWithAccessAndRefreshToken(refreshToken)\n if (response.error === \"unexpected\") {\n throw new Error(\"Unexpected error while refreshing access token\")\n } else if (response.error === \"unauthorized\") {\n const response = NextResponse.next()\n response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME)\n response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME)\n return response\n } else {\n const headers = new Headers(req.headers)\n // Pass along the new access token in a header since cookies don't work\n headers.append(CUSTOM_HEADER_FOR_ACCESS_TOKEN, response.accessToken)\n const nextResponse = NextResponse.next({\n request: {\n headers\n }\n })\n nextResponse.cookies.set(ACCESS_TOKEN_COOKIE_NAME, response.accessToken, COOKIE_OPTIONS)\n nextResponse.cookies.set(REFRESH_TOKEN_COOKIE_NAME, response.refreshToken, COOKIE_OPTIONS)\n return nextResponse\n }\n }\n\n return NextResponse.next()\n}\n\nexport type RouteHandlerArgs = {\n postLoginRedirectPathFn?: (req: NextRequest) => string\n}\n\nexport function getRouteHandlers(args?: RouteHandlerArgs) {\n const authUrlOrigin = getAuthUrlOrigin()\n const redirectUri = getRedirectUri()\n const integrationApiKey = getIntegrationApiKey()\n\n function loginGetHandler() {\n const state = randomState()\n const authorize_url =\n authUrlOrigin + \"/propelauth/ssr/authorize?redirect_uri=\" + redirectUri + \"&state=\" + state\n return new Response(null, {\n status: 302,\n headers: {\n Location: authorize_url,\n \"Set-Cookie\": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`,\n }\n })\n }\n\n function signupGetHandler() {\n const state = randomState()\n const authorize_url =\n getAuthUrlOrigin() + \"/propelauth/ssr/authorize?redirect_uri=\" + redirectUri + \"&state=\" + state + \"&signup=true\"\n return new Response(null, {\n status: 302,\n headers: {\n Location: authorize_url,\n \"Set-Cookie\": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`,\n }\n })\n }\n\n async function callbackGetHandler(req: NextRequest) {\n const oauthState = req.cookies.get(STATE_COOKIE_NAME)?.value\n if (!oauthState || oauthState.length !== 64) {\n return new Response(null, {status: 302, headers: {Location: LOGIN_PATH}})\n }\n\n const queryParams = req.nextUrl.searchParams\n const state = queryParams.get(\"state\")\n const code = queryParams.get(\"code\")\n if (state !== oauthState) {\n return new Response(null, {status: 302, headers: {Location: LOGIN_PATH}})\n }\n\n const oauth_token_body = {\n redirect_uri: redirectUri,\n code,\n }\n const url = `${authUrlOrigin}/propelauth/ssr/token`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(oauth_token_body),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + integrationApiKey,\n },\n })\n\n if (response.ok) {\n const data = await response.json()\n\n const accessToken = data.access_token\n const path = args?.postLoginRedirectPathFn ? args.postLoginRedirectPathFn(req) : \"/\"\n if (!path) {\n console.log(\"postLoginPathFn returned undefined\")\n return new Response(\"Unexpected error\", {status: 500})\n }\n\n const headers = new Headers()\n headers.append(\"Location\", path)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n return new Response(null, {\n status: 302,\n headers\n })\n } else if (response.status === 401) {\n return new Response(\"Unexpected error\", {status: 500})\n } else {\n return new Response(\"Unexpected error\", {status: 500})\n }\n }\n\n async function userinfoGetHandler(req: NextRequest) {\n const oldRefreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n\n // For the userinfo endpoint, we want to get the most up-to-date info, so we'll refresh the access token\n if (oldRefreshToken) {\n const refreshResponse = await refreshTokenWithAccessAndRefreshToken(oldRefreshToken)\n if (refreshResponse.error === \"unexpected\") {\n throw new Error(\"Unexpected error while refreshing access token\")\n } else if (refreshResponse.error === \"unauthorized\") {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(\"Unauthorized\", {status: 401, headers})\n }\n\n const refreshToken = refreshResponse.refreshToken\n const accessToken = refreshResponse.accessToken\n\n const path = `${authUrlOrigin}/propelauth/oauth/userinfo`\n const response = await fetch(path, {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": \"Bearer \" + accessToken,\n }\n })\n if (response.ok) {\n const userFromToken = await validateAccessToken(accessToken)\n const data = await response.json()\n const jsonResponse = {\n userinfo: data,\n accessToken,\n impersonatorUserId: userFromToken.impersonatorUserId\n }\n\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Content-Type\", \"application/json\")\n return new Response(JSON.stringify(jsonResponse), {\n status: 200,\n headers\n })\n } else if (response.status === 401) {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 401,\n headers\n })\n } else {\n return new Response(null, {status: 500})\n }\n }\n\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 401})\n }\n\n async function logoutGetHandler(req: NextRequest) {\n // Real logout requests will go to the logout POST handler\n // This endpoint is a landing page for when people logout from the hosted UIs\n // Instead of doing a logout we'll check the refresh token.\n // If it's invalid, we'll clear the cookies and redirect using the postLoginRedirectPathFn\n const path = args?.postLoginRedirectPathFn ? args.postLoginRedirectPathFn(req) : \"/\"\n if (!path) {\n console.log(\"postLoginPathFn returned undefined\")\n return new Response(\"Unexpected error\", {status: 500})\n }\n\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n if (!refreshToken) {\n const headers = new Headers()\n headers.append(\"Location\", path)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 302,\n headers\n })\n }\n\n const refreshResponse = await refreshTokenWithAccessAndRefreshToken(refreshToken)\n if (refreshResponse.error === \"unexpected\") {\n console.error(\"Unexpected error while refreshing access token\")\n return new Response(\"Unexpected error\", {status: 500})\n } else if (refreshResponse.error === \"unauthorized\") {\n const headers = new Headers()\n headers.append(\"Location\", path)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 302,\n headers\n })\n } else {\n const headers = new Headers()\n headers.append(\"Location\", path)\n return new Response(null, {\n status: 302,\n headers\n })\n }\n }\n\n async function logoutPostHandler(req: NextRequest) {\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n if (!refreshToken) {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 200, headers})\n }\n\n const logoutBody = {refresh_token: refreshToken}\n const url = `${authUrlOrigin}/api/backend/v1/logout`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(logoutBody),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + integrationApiKey,\n },\n })\n\n if (!response.ok) {\n console.log(\n \"Unable to logout, clearing cookies and continuing anyway\",\n response.status,\n response.statusText\n )\n }\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 200, headers})\n }\n\n function getRouteHandler(req: NextRequest, {params}: { params: { slug: string } }) {\n if (params.slug === \"login\") {\n return loginGetHandler()\n } else if (params.slug === \"signup\") {\n return signupGetHandler()\n } else if (params.slug === \"callback\") {\n return callbackGetHandler(req)\n } else if (params.slug === \"userinfo\") {\n return userinfoGetHandler(req)\n } else if (params.slug === \"logout\") {\n return logoutGetHandler(req)\n } else {\n return new Response(\"\", {status: 404})\n }\n }\n\n function postRouteHandler(req: NextRequest, {params}: { params: { slug: string } }) {\n if (params.slug === \"logout\") {\n return logoutPostHandler(req)\n } else {\n return new Response(\"\", {status: 404})\n }\n }\n\n return {\n getRouteHandler,\n postRouteHandler\n }\n}\n\nfunction randomState(): string {\n const randomBytes = crypto.getRandomValues(new Uint8Array(32))\n return Array.from(randomBytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n}\n\n","export class UserFromToken {\n public userId: string\n public orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo\n\n // Metadata about the user\n public email: string\n public firstName?: string\n public lastName?: string\n public username?: string\n\n // If you used our migration APIs to migrate this user from a different system,\n // this is their original ID from that system.\n public legacyUserId?: string\n public impersonatorUserId?: string\n\n constructor(\n userId: string,\n email: string,\n orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo,\n firstName?: string,\n lastName?: string,\n username?: string,\n legacyUserId?: string,\n impersonatorUserId?: string\n ) {\n this.userId = userId\n this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo\n\n this.email = email\n this.firstName = firstName\n this.lastName = lastName\n this.username = username\n\n this.legacyUserId = legacyUserId\n this.impersonatorUserId = impersonatorUserId\n }\n\n public getOrg(orgId: string): OrgMemberInfo | undefined {\n if (!this.orgIdToOrgMemberInfo) {\n return undefined\n }\n\n return this.orgIdToOrgMemberInfo[orgId]\n }\n\n public getOrgByName(orgName: string): OrgMemberInfo | undefined {\n if (!this.orgIdToOrgMemberInfo) {\n return undefined\n }\n\n const urlSafeOrgName = orgName.toLowerCase().replace(/ /g, \"-\")\n for (const orgId in this.orgIdToOrgMemberInfo) {\n const orgMemberInfo = this.orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo.urlSafeOrgName === urlSafeOrgName) {\n return orgMemberInfo\n }\n }\n\n return undefined\n }\n\n public getOrgs(): OrgMemberInfo[] {\n if (!this.orgIdToOrgMemberInfo) {\n return []\n }\n\n return Object.values(this.orgIdToOrgMemberInfo)\n }\n\n public isImpersonating(): boolean {\n return !!this.impersonatorUserId\n }\n\n public static fromJSON(json: string): UserFromToken {\n const obj = JSON.parse(json)\n const orgIdToOrgMemberInfo: OrgIdToOrgMemberInfo = {}\n for (const orgId in obj.orgIdToOrgMemberInfo) {\n orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(\n JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])\n )\n }\n return new UserFromToken(\n obj.userId,\n obj.email,\n orgIdToOrgMemberInfo,\n obj.firstName,\n obj.lastName,\n obj.username,\n obj.legacyUserId,\n obj.impersonatorUserId\n )\n }\n}\n\nexport type OrgIdToOrgMemberInfo = {\n [orgId: string]: OrgMemberInfo\n}\n\nexport class OrgMemberInfo {\n public orgId: string\n public orgName: string\n public orgMetadata: { [key: string]: any }\n public urlSafeOrgName: string\n\n private userAssignedRole: string\n private userInheritedRolesPlusCurrentRole: string[]\n private userPermissions: string[]\n\n constructor(\n orgId: string,\n orgName: string,\n orgMetadata: { [key: string]: any },\n urlSafeOrgName: string,\n userAssignedRole: string,\n userInheritedRolesPlusCurrentRole: string[],\n userPermissions: string[]\n ) {\n this.orgId = orgId\n this.orgName = orgName\n this.orgMetadata = orgMetadata\n this.urlSafeOrgName = urlSafeOrgName\n\n this.userAssignedRole = userAssignedRole\n this.userInheritedRolesPlusCurrentRole = userInheritedRolesPlusCurrentRole\n this.userPermissions = userPermissions\n }\n\n // validation methods\n\n public isRole(role: string): boolean {\n return this.userAssignedRole === role\n }\n\n public isAtLeastRole(role: string): boolean {\n return this.userInheritedRolesPlusCurrentRole.includes(role)\n }\n\n public hasPermission(permission: string): boolean {\n return this.userPermissions.includes(permission)\n }\n\n public hasAllPermissions(permissions: string[]): boolean {\n return permissions.every((permission) => this.hasPermission(permission))\n }\n\n public static fromJSON(json: string): OrgMemberInfo {\n const obj = JSON.parse(json)\n return new OrgMemberInfo(\n obj.orgId,\n obj.orgName,\n obj.orgMetadata,\n obj.urlSafeOrgName,\n obj.userAssignedRole,\n obj.userInheritedRolesPlusCurrentRole,\n obj.userPermissions\n )\n }\n\n // getters for the private fields\n\n get assignedRole(): string {\n return this.userAssignedRole\n }\n\n get inheritedRolesPlusCurrentRole(): string[] {\n return this.userInheritedRolesPlusCurrentRole\n }\n\n get permissions(): string[] {\n return this.userPermissions\n }\n}\n\n// These Internal types exist since the server returns snake case, but typescript/javascript\n// convention is camelCase.\nexport type InternalOrgMemberInfo = {\n org_id: string\n org_name: string\n org_metadata: { [key: string]: any }\n url_safe_org_name: string\n user_role: string\n inherited_user_roles_plus_current_role: string[]\n user_permissions: string[]\n}\nexport type InternalUser = {\n user_id: string\n org_id_to_org_member_info?: { [org_id: string]: InternalOrgMemberInfo }\n\n email: string\n first_name?: string\n last_name?: string\n username?: string\n\n // If you used our migration APIs to migrate this user from a different system, this is their original ID from that system.\n legacy_user_id?: string\n impersonatorUserId?: string\n}\n\nexport function toUser(snake_case: InternalUser): UserFromToken {\n return new UserFromToken(\n snake_case.user_id,\n snake_case.email,\n toOrgIdToOrgMemberInfo(snake_case.org_id_to_org_member_info),\n snake_case.first_name,\n snake_case.last_name,\n snake_case.username,\n snake_case.legacy_user_id,\n snake_case.impersonatorUserId\n )\n}\n\nexport function toOrgIdToOrgMemberInfo(snake_case?: {\n [org_id: string]: InternalOrgMemberInfo\n}): OrgIdToOrgMemberInfo | undefined {\n if (snake_case === undefined) {\n return undefined\n }\n const camelCase: OrgIdToOrgMemberInfo = {}\n\n for (const key of Object.keys(snake_case)) {\n const snakeCaseValue = snake_case[key]\n if (snakeCaseValue) {\n camelCase[key] = new OrgMemberInfo(\n snakeCaseValue.org_id,\n snakeCaseValue.org_name,\n snakeCaseValue.org_metadata,\n snakeCaseValue.url_safe_org_name,\n snakeCaseValue.user_role,\n snakeCaseValue.inherited_user_roles_plus_current_role,\n snakeCaseValue.user_permissions\n )\n }\n }\n\n return camelCase\n}\n","import {ResponseCookie} from \"next/dist/compiled/@edge-runtime/cookies\";\nimport {InternalUser, toUser, UserFromToken} from \"../user\";\nimport {ConfigurationException, UnauthorizedException} from \"./exceptions\";\nimport * as jose from \"jose\";\n\ntype RefreshAndAccessTokens = {\n refreshToken: string\n accessToken: string\n error: \"none\"\n}\n\ntype RefreshAndAccessTokensUnauthorizedError = {\n error: \"unauthorized\"\n}\n\ntype RefreshAndAccessTokensUnexpectedError = {\n error: \"unexpected\"\n}\n\nexport type RefreshTokenResponse =\n RefreshAndAccessTokens\n | RefreshAndAccessTokensUnauthorizedError\n | RefreshAndAccessTokensUnexpectedError\n\nexport const LOGIN_PATH = \"/api/auth/login\"\nexport const CALLBACK_PATH = \"/api/auth/callback\"\nexport const USERINFO_PATH = \"/api/auth/userinfo\"\nexport const LOGOUT_PATH = \"/api/auth/logout\"\nexport const ACCESS_TOKEN_COOKIE_NAME = \"__pa_at\"\nexport const REFRESH_TOKEN_COOKIE_NAME = \"__pa_rt\"\nexport const STATE_COOKIE_NAME = \"__pa_state\"\nexport const CUSTOM_HEADER_FOR_ACCESS_TOKEN = \"x-propelauth-access-token\"\n\nexport const COOKIE_OPTIONS: Partial<ResponseCookie> = {\n httpOnly: true,\n sameSite: \"lax\",\n secure: true,\n path: \"/\",\n}\n\nexport function getAuthUrlOrigin() {\n return getAuthUrl().origin\n}\n\nexport function getAuthUrl() {\n const authUrl = process.env.NEXT_PUBLIC_AUTH_URL\n if (!authUrl) {\n throw new Error(\"NEXT_PUBLIC_AUTH_URL is not set\")\n }\n return new URL(authUrl)\n}\n\nexport function getRedirectUri() {\n const redirectUri = process.env.PROPELAUTH_REDIRECT_URI\n if (!redirectUri) {\n throw new Error(\"PROPELAUTH_REDIRECT_URI is not set\")\n }\n return redirectUri\n}\n\nexport function getIntegrationApiKey() {\n const integrationApiKey = process.env.PROPELAUTH_API_KEY\n if (!integrationApiKey) {\n throw new Error(\"PROPELAUTH_API_KEY is not set\")\n }\n return integrationApiKey\n}\n\nexport function getVerifierKey() {\n const verifierKey = process.env.PROPELAUTH_VERIFIER_KEY\n if (!verifierKey) {\n throw new Error(\"PROPELAUTH_VERIFIER_KEY is not set\")\n }\n return verifierKey.replace(/\\\\n/g, \"\\n\")\n}\n\nexport async function refreshTokenWithAccessAndRefreshToken(refreshToken: string): Promise<RefreshTokenResponse> {\n const body = {\n refresh_token: refreshToken,\n }\n const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + getIntegrationApiKey(),\n },\n })\n\n if (response.ok) {\n const data = await response.json()\n const newRefreshToken = data.refresh_token\n const {\n access_token: accessToken,\n expires_at_seconds: expiresAtSeconds,\n } = data.access_token\n\n return {\n refreshToken: newRefreshToken,\n accessToken,\n error: \"none\",\n }\n } else if (response.status === 400 || response.status === 401) {\n return {error: \"unauthorized\"}\n } else {\n return {error: \"unexpected\"}\n }\n}\n\nexport async function validateAccessTokenOrUndefined(accessToken: string | undefined): Promise<UserFromToken | undefined> {\n try {\n return await validateAccessToken(accessToken)\n } catch (err) {\n if (err instanceof ConfigurationException) {\n throw err\n } else if (err instanceof UnauthorizedException) {\n return undefined\n } else {\n console.log(\"Error validating access token\", err)\n return undefined\n }\n }\n}\n\nexport async function validateAccessToken(accessToken: string | undefined): Promise<UserFromToken> {\n let publicKey\n try {\n publicKey = await jose.importSPKI(getVerifierKey(), \"RS256\")\n } catch (err) {\n console.error(\"Verifier key is invalid. Make sure it's specified correctly, including the newlines.\", err)\n throw new ConfigurationException(\"Invalid verifier key\")\n }\n\n if (!accessToken) {\n throw new UnauthorizedException(\"No access token provided\")\n }\n\n let accessTokenWithoutBearer = accessToken\n if (accessToken.toLowerCase().startsWith(\"bearer \")) {\n accessTokenWithoutBearer = accessToken.substring(\"bearer \".length)\n }\n\n try {\n const {payload} = await jose.jwtVerify(accessTokenWithoutBearer, publicKey, {\n issuer: getAuthUrlOrigin(),\n algorithms: [\"RS256\"],\n })\n\n return toUser(<InternalUser>payload)\n } catch (e) {\n if (e instanceof Error) {\n throw new UnauthorizedException(e.message)\n } else {\n throw new UnauthorizedException(\"Unable to decode jwt\")\n }\n }\n}\n"],"mappings":"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","names":["response","headers"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/server/app-router-index.ts","../../../src/server/exceptions.ts","../../../src/server/app-router.ts","../../../src/user.ts","../../../src/server/shared.ts"],"sourcesContent":["export {UnauthorizedException, ConfigurationException} from \"./exceptions\"\nexport {getRouteHandlers, getUser, getUserOrRedirect, getAccessToken, authMiddleware} from \"./app-router\"\nexport type {RouteHandlerArgs} from \"./app-router\"\n","export class UnauthorizedException extends Error {\n readonly message: string\n readonly status: number\n\n constructor(message: string) {\n super(message)\n this.message = message\n this.status = 401\n }\n}\n\nexport class ConfigurationException extends Error {\n readonly message: string\n readonly status: number\n\n constructor(message: string) {\n super(message)\n this.message = message\n this.status = 500\n }\n}\n","import {redirect} from \"next/navigation.js\";\nimport {cookies, headers} from \"next/headers.js\";\nimport {NextRequest, NextResponse} from \"next/server.js\";\nimport {\n ACCESS_TOKEN_COOKIE_NAME,\n CALLBACK_PATH,\n COOKIE_OPTIONS,\n CUSTOM_HEADER_FOR_ACCESS_TOKEN,\n getAuthUrlOrigin,\n getIntegrationApiKey,\n getRedirectUri,\n LOGIN_PATH,\n LOGOUT_PATH,\n REFRESH_TOKEN_COOKIE_NAME,\n refreshTokenWithAccessAndRefreshToken,\n RETURN_TO_PATH_COOKIE_NAME,\n STATE_COOKIE_NAME,\n USERINFO_PATH,\n validateAccessToken,\n validateAccessTokenOrUndefined\n} from \"./shared\";\nimport {UserFromToken} from \"./index\"\n\nexport async function getUserOrRedirect(): Promise<UserFromToken> {\n const user = await getUser()\n if (user) {\n return user\n } else {\n redirect(LOGIN_PATH)\n throw new Error(\"Redirecting to login\")\n }\n}\n\nexport async function getUser(): Promise<UserFromToken | undefined> {\n const accessToken = headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || cookies().get(ACCESS_TOKEN_COOKIE_NAME)?.value\n if (accessToken) {\n const user = await validateAccessTokenOrUndefined(accessToken)\n if (user) {\n return user\n }\n }\n return undefined\n}\n\nexport async function getAccessToken(): Promise<string | undefined> {\n return headers().get(CUSTOM_HEADER_FOR_ACCESS_TOKEN) || cookies().get(ACCESS_TOKEN_COOKIE_NAME)?.value\n}\n\n// Purpose of this middleware is just to keep the access token cookie alive\n// In an ideal world, this could be done in `getUser`, however, you can't\n// set a cookie in a server component.\n// There also doesn't seem to be any way right now to set a cookie in a\n// middleware and pass it forward (you can only set them on the response).\n// You CAN, however, pass in custom headers,\n// so we'll use CUSTOM_HEADER_FOR_ACCESS_TOKEN as a workaround\nexport async function authMiddleware(req: NextRequest): Promise<Response> {\n if (req.headers.has(CUSTOM_HEADER_FOR_ACCESS_TOKEN)) {\n throw new Error(`${CUSTOM_HEADER_FOR_ACCESS_TOKEN} is set which is for internal use only`)\n } else if (req.nextUrl.pathname === CALLBACK_PATH || req.nextUrl.pathname === LOGOUT_PATH || req.nextUrl.pathname === USERINFO_PATH) {\n // Don't do anything for the callback, logout, or userinfo paths, as they will modify the cookies themselves\n return NextResponse.next()\n }\n\n const accessToken = req.cookies.get(ACCESS_TOKEN_COOKIE_NAME)?.value\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n\n // If we are authenticated, we can continue\n if (accessToken) {\n const user = await validateAccessTokenOrUndefined(accessToken)\n if (user) {\n return NextResponse.next()\n }\n }\n\n // Otherwise, we need to refresh the access token\n if (refreshToken) {\n const response = await refreshTokenWithAccessAndRefreshToken(refreshToken)\n if (response.error === \"unexpected\") {\n throw new Error(\"Unexpected error while refreshing access token\")\n } else if (response.error === \"unauthorized\") {\n const response = NextResponse.next()\n response.cookies.delete(ACCESS_TOKEN_COOKIE_NAME)\n response.cookies.delete(REFRESH_TOKEN_COOKIE_NAME)\n return response\n } else {\n const headers = new Headers(req.headers)\n // Pass along the new access token in a header since cookies don't work\n headers.append(CUSTOM_HEADER_FOR_ACCESS_TOKEN, response.accessToken)\n const nextResponse = NextResponse.next({\n request: {\n headers\n }\n })\n nextResponse.cookies.set(ACCESS_TOKEN_COOKIE_NAME, response.accessToken, COOKIE_OPTIONS)\n nextResponse.cookies.set(REFRESH_TOKEN_COOKIE_NAME, response.refreshToken, COOKIE_OPTIONS)\n return nextResponse\n }\n }\n\n return NextResponse.next()\n}\n\nexport type RouteHandlerArgs = {\n postLoginRedirectPathFn?: (req: NextRequest) => string\n}\n\nexport function getRouteHandlers(args?: RouteHandlerArgs) {\n const authUrlOrigin = getAuthUrlOrigin()\n const redirectUri = getRedirectUri()\n const integrationApiKey = getIntegrationApiKey()\n\n function loginGetHandler(req: NextRequest) {\n return signupOrLoginHandler(req, false)\n }\n\n function signupGetHandler(req: NextRequest) {\n return signupOrLoginHandler(req, true)\n }\n\n function signupOrLoginHandler(req: NextRequest, isSignup: boolean) {\n const returnToPath = req.nextUrl.searchParams.get(\"return_to_path\")\n const state = randomState()\n\n const authorizeUrlSearchParams = new URLSearchParams({\n redirect_uri: redirectUri,\n state,\n signup: isSignup ? \"true\" : \"false\"\n })\n const authorize_url =\n getAuthUrlOrigin() + \"/propelauth/ssr/authorize?\" + authorizeUrlSearchParams.toString()\n\n const headers = new Headers();\n headers.append(\"Location\", authorize_url);\n headers.append(\"Set-Cookie\", `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`);\n if (returnToPath) {\n if (returnToPath.startsWith(\"/\")) {\n headers.append(\"Set-Cookie\", `${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`);\n } else {\n console.warn(\"return_to_path must start with /\")\n }\n }\n\n return new Response(null, {\n status: 302,\n headers\n })\n }\n\n async function callbackGetHandler(req: NextRequest) {\n const oauthState = req.cookies.get(STATE_COOKIE_NAME)?.value\n if (!oauthState || oauthState.length !== 64) {\n return new Response(null, {status: 302, headers: {Location: LOGIN_PATH}})\n }\n\n const queryParams = req.nextUrl.searchParams\n const state = queryParams.get(\"state\")\n const code = queryParams.get(\"code\")\n if (state !== oauthState) {\n return new Response(null, {status: 302, headers: {Location: LOGIN_PATH}})\n }\n\n const oauth_token_body = {\n redirect_uri: redirectUri,\n code,\n }\n const url = `${authUrlOrigin}/propelauth/ssr/token`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(oauth_token_body),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + integrationApiKey,\n },\n })\n\n if (response.ok) {\n const data = await response.json()\n\n const accessToken = data.access_token\n\n // If we have a return_to_path cookie, we'll use that\n // Otherwise, we'll use the postLoginRedirectPathFn\n const returnToPathFromCookie = req.cookies.get(RETURN_TO_PATH_COOKIE_NAME)?.value;\n const returnToPath = returnToPathFromCookie ?? (args?.postLoginRedirectPathFn ? args.postLoginRedirectPathFn(req) : \"/\")\n if (!returnToPath) {\n console.error(\"postLoginRedirectPathFn returned undefined\")\n return new Response(\"Unexpected error\", {status: 500})\n }\n\n const headers = new Headers()\n headers.append(\"Location\", returnToPath)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Set-Cookie\", `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 302,\n headers\n })\n } else if (response.status === 401) {\n return new Response(\"Unexpected error\", {status: 500})\n } else {\n return new Response(\"Unexpected error\", {status: 500})\n }\n }\n\n async function userinfoGetHandler(req: NextRequest) {\n const oldRefreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n\n // For the userinfo endpoint, we want to get the most up-to-date info, so we'll refresh the access token\n if (oldRefreshToken) {\n const refreshResponse = await refreshTokenWithAccessAndRefreshToken(oldRefreshToken)\n if (refreshResponse.error === \"unexpected\") {\n throw new Error(\"Unexpected error while refreshing access token\")\n } else if (refreshResponse.error === \"unauthorized\") {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(\"Unauthorized\", {status: 401, headers})\n }\n\n const refreshToken = refreshResponse.refreshToken\n const accessToken = refreshResponse.accessToken\n\n const path = `${authUrlOrigin}/propelauth/oauth/userinfo`\n const response = await fetch(path, {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": \"Bearer \" + accessToken,\n }\n })\n if (response.ok) {\n const userFromToken = await validateAccessToken(accessToken)\n const data = await response.json()\n const jsonResponse = {\n userinfo: data,\n accessToken,\n impersonatorUserId: userFromToken.impersonatorUserId\n }\n\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`)\n headers.append(\"Content-Type\", \"application/json\")\n return new Response(JSON.stringify(jsonResponse), {\n status: 200,\n headers\n })\n } else if (response.status === 401) {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 401,\n headers\n })\n } else {\n return new Response(null, {status: 500})\n }\n }\n\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 401})\n }\n\n async function logoutGetHandler(req: NextRequest) {\n // Real logout requests will go to the logout POST handler\n // This endpoint is a landing page for when people logout from the hosted UIs\n // Instead of doing a logout we'll check the refresh token.\n // If it's invalid, we'll clear the cookies and redirect using the postLoginRedirectPathFn\n const path = args?.postLoginRedirectPathFn ? args.postLoginRedirectPathFn(req) : \"/\"\n if (!path) {\n console.error(\"postLoginPathFn returned undefined\")\n return new Response(\"Unexpected error\", {status: 500})\n }\n\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n if (!refreshToken) {\n const headers = new Headers()\n headers.append(\"Location\", path)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 302,\n headers\n })\n }\n\n const refreshResponse = await refreshTokenWithAccessAndRefreshToken(refreshToken)\n if (refreshResponse.error === \"unexpected\") {\n console.error(\"Unexpected error while refreshing access token\")\n return new Response(\"Unexpected error\", {status: 500})\n } else if (refreshResponse.error === \"unauthorized\") {\n const headers = new Headers()\n headers.append(\"Location\", path)\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {\n status: 302,\n headers\n })\n } else {\n const headers = new Headers()\n headers.append(\"Location\", path)\n return new Response(null, {\n status: 302,\n headers\n })\n }\n }\n\n async function logoutPostHandler(req: NextRequest) {\n const refreshToken = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)?.value\n if (!refreshToken) {\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 200, headers})\n }\n\n const logoutBody = {refresh_token: refreshToken}\n const url = `${authUrlOrigin}/api/backend/v1/logout`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(logoutBody),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + integrationApiKey,\n },\n })\n\n if (!response.ok) {\n console.warn(\n \"Unable to logout, clearing cookies and continuing anyway\",\n response.status,\n response.statusText\n )\n }\n const headers = new Headers()\n headers.append(\"Set-Cookie\", `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n headers.append(\"Set-Cookie\", `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`)\n return new Response(null, {status: 200, headers})\n }\n\n function getRouteHandler(req: NextRequest, {params}: { params: { slug: string } }) {\n if (params.slug === \"login\") {\n return loginGetHandler(req)\n } else if (params.slug === \"signup\") {\n return signupGetHandler(req)\n } else if (params.slug === \"callback\") {\n return callbackGetHandler(req)\n } else if (params.slug === \"userinfo\") {\n return userinfoGetHandler(req)\n } else if (params.slug === \"logout\") {\n return logoutGetHandler(req)\n } else {\n return new Response(\"\", {status: 404})\n }\n }\n\n function postRouteHandler(req: NextRequest, {params}: { params: { slug: string } }) {\n if (params.slug === \"logout\") {\n return logoutPostHandler(req)\n } else {\n return new Response(\"\", {status: 404})\n }\n }\n\n return {\n getRouteHandler,\n postRouteHandler\n }\n}\n\nfunction randomState(): string {\n const randomBytes = crypto.getRandomValues(new Uint8Array(32))\n return Array.from(randomBytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n}\n\n","export class UserFromToken {\n public userId: string\n public orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo\n\n // Metadata about the user\n public email: string\n public firstName?: string\n public lastName?: string\n public username?: string\n\n // If you used our migration APIs to migrate this user from a different system,\n // this is their original ID from that system.\n public legacyUserId?: string\n public impersonatorUserId?: string\n\n constructor(\n userId: string,\n email: string,\n orgIdToOrgMemberInfo?: OrgIdToOrgMemberInfo,\n firstName?: string,\n lastName?: string,\n username?: string,\n legacyUserId?: string,\n impersonatorUserId?: string\n ) {\n this.userId = userId\n this.orgIdToOrgMemberInfo = orgIdToOrgMemberInfo\n\n this.email = email\n this.firstName = firstName\n this.lastName = lastName\n this.username = username\n\n this.legacyUserId = legacyUserId\n this.impersonatorUserId = impersonatorUserId\n }\n\n public getOrg(orgId: string): OrgMemberInfo | undefined {\n if (!this.orgIdToOrgMemberInfo) {\n return undefined\n }\n\n return this.orgIdToOrgMemberInfo[orgId]\n }\n\n public getOrgByName(orgName: string): OrgMemberInfo | undefined {\n if (!this.orgIdToOrgMemberInfo) {\n return undefined\n }\n\n const urlSafeOrgName = orgName.toLowerCase().replace(/ /g, \"-\")\n for (const orgId in this.orgIdToOrgMemberInfo) {\n const orgMemberInfo = this.orgIdToOrgMemberInfo[orgId]\n if (orgMemberInfo.urlSafeOrgName === urlSafeOrgName) {\n return orgMemberInfo\n }\n }\n\n return undefined\n }\n\n public getOrgs(): OrgMemberInfo[] {\n if (!this.orgIdToOrgMemberInfo) {\n return []\n }\n\n return Object.values(this.orgIdToOrgMemberInfo)\n }\n\n public isImpersonating(): boolean {\n return !!this.impersonatorUserId\n }\n\n public static fromJSON(json: string): UserFromToken {\n const obj = JSON.parse(json)\n const orgIdToOrgMemberInfo: OrgIdToOrgMemberInfo = {}\n for (const orgId in obj.orgIdToOrgMemberInfo) {\n orgIdToOrgMemberInfo[orgId] = OrgMemberInfo.fromJSON(\n JSON.stringify(obj.orgIdToOrgMemberInfo[orgId])\n )\n }\n return new UserFromToken(\n obj.userId,\n obj.email,\n orgIdToOrgMemberInfo,\n obj.firstName,\n obj.lastName,\n obj.username,\n obj.legacyUserId,\n obj.impersonatorUserId\n )\n }\n}\n\nexport type OrgIdToOrgMemberInfo = {\n [orgId: string]: OrgMemberInfo\n}\n\nexport class OrgMemberInfo {\n public orgId: string\n public orgName: string\n public orgMetadata: { [key: string]: any }\n public urlSafeOrgName: string\n\n private userAssignedRole: string\n private userInheritedRolesPlusCurrentRole: string[]\n private userPermissions: string[]\n\n constructor(\n orgId: string,\n orgName: string,\n orgMetadata: { [key: string]: any },\n urlSafeOrgName: string,\n userAssignedRole: string,\n userInheritedRolesPlusCurrentRole: string[],\n userPermissions: string[]\n ) {\n this.orgId = orgId\n this.orgName = orgName\n this.orgMetadata = orgMetadata\n this.urlSafeOrgName = urlSafeOrgName\n\n this.userAssignedRole = userAssignedRole\n this.userInheritedRolesPlusCurrentRole = userInheritedRolesPlusCurrentRole\n this.userPermissions = userPermissions\n }\n\n // validation methods\n\n public isRole(role: string): boolean {\n return this.userAssignedRole === role\n }\n\n public isAtLeastRole(role: string): boolean {\n return this.userInheritedRolesPlusCurrentRole.includes(role)\n }\n\n public hasPermission(permission: string): boolean {\n return this.userPermissions.includes(permission)\n }\n\n public hasAllPermissions(permissions: string[]): boolean {\n return permissions.every((permission) => this.hasPermission(permission))\n }\n\n public static fromJSON(json: string): OrgMemberInfo {\n const obj = JSON.parse(json)\n return new OrgMemberInfo(\n obj.orgId,\n obj.orgName,\n obj.orgMetadata,\n obj.urlSafeOrgName,\n obj.userAssignedRole,\n obj.userInheritedRolesPlusCurrentRole,\n obj.userPermissions\n )\n }\n\n // getters for the private fields\n\n get assignedRole(): string {\n return this.userAssignedRole\n }\n\n get inheritedRolesPlusCurrentRole(): string[] {\n return this.userInheritedRolesPlusCurrentRole\n }\n\n get permissions(): string[] {\n return this.userPermissions\n }\n}\n\n// These Internal types exist since the server returns snake case, but typescript/javascript\n// convention is camelCase.\nexport type InternalOrgMemberInfo = {\n org_id: string\n org_name: string\n org_metadata: { [key: string]: any }\n url_safe_org_name: string\n user_role: string\n inherited_user_roles_plus_current_role: string[]\n user_permissions: string[]\n}\nexport type InternalUser = {\n user_id: string\n org_id_to_org_member_info?: { [org_id: string]: InternalOrgMemberInfo }\n\n email: string\n first_name?: string\n last_name?: string\n username?: string\n\n // If you used our migration APIs to migrate this user from a different system, this is their original ID from that system.\n legacy_user_id?: string\n impersonatorUserId?: string\n}\n\nexport function toUser(snake_case: InternalUser): UserFromToken {\n return new UserFromToken(\n snake_case.user_id,\n snake_case.email,\n toOrgIdToOrgMemberInfo(snake_case.org_id_to_org_member_info),\n snake_case.first_name,\n snake_case.last_name,\n snake_case.username,\n snake_case.legacy_user_id,\n snake_case.impersonatorUserId\n )\n}\n\nexport function toOrgIdToOrgMemberInfo(snake_case?: {\n [org_id: string]: InternalOrgMemberInfo\n}): OrgIdToOrgMemberInfo | undefined {\n if (snake_case === undefined) {\n return undefined\n }\n const camelCase: OrgIdToOrgMemberInfo = {}\n\n for (const key of Object.keys(snake_case)) {\n const snakeCaseValue = snake_case[key]\n if (snakeCaseValue) {\n camelCase[key] = new OrgMemberInfo(\n snakeCaseValue.org_id,\n snakeCaseValue.org_name,\n snakeCaseValue.org_metadata,\n snakeCaseValue.url_safe_org_name,\n snakeCaseValue.user_role,\n snakeCaseValue.inherited_user_roles_plus_current_role,\n snakeCaseValue.user_permissions\n )\n }\n }\n\n return camelCase\n}\n","import {ResponseCookie} from \"next/dist/compiled/@edge-runtime/cookies\";\nimport {InternalUser, toUser, UserFromToken} from \"../user\";\nimport {ConfigurationException, UnauthorizedException} from \"./exceptions\";\nimport * as jose from \"jose\";\n\ntype RefreshAndAccessTokens = {\n refreshToken: string\n accessToken: string\n error: \"none\"\n}\n\ntype RefreshAndAccessTokensUnauthorizedError = {\n error: \"unauthorized\"\n}\n\ntype RefreshAndAccessTokensUnexpectedError = {\n error: \"unexpected\"\n}\n\nexport type RefreshTokenResponse =\n RefreshAndAccessTokens\n | RefreshAndAccessTokensUnauthorizedError\n | RefreshAndAccessTokensUnexpectedError\n\nexport const LOGIN_PATH = \"/api/auth/login\"\nexport const CALLBACK_PATH = \"/api/auth/callback\"\nexport const USERINFO_PATH = \"/api/auth/userinfo\"\nexport const LOGOUT_PATH = \"/api/auth/logout\"\nexport const ACCESS_TOKEN_COOKIE_NAME = \"__pa_at\"\nexport const REFRESH_TOKEN_COOKIE_NAME = \"__pa_rt\"\nexport const STATE_COOKIE_NAME = \"__pa_state\"\nexport const CUSTOM_HEADER_FOR_ACCESS_TOKEN = \"x-propelauth-access-token\"\nexport const RETURN_TO_PATH_COOKIE_NAME = \"__pa_return_to_path\"\n\nexport const COOKIE_OPTIONS: Partial<ResponseCookie> = {\n httpOnly: true,\n sameSite: \"lax\",\n secure: true,\n path: \"/\",\n}\n\nexport function getAuthUrlOrigin() {\n return getAuthUrl().origin\n}\n\nexport function getAuthUrl() {\n const authUrl = process.env.NEXT_PUBLIC_AUTH_URL\n if (!authUrl) {\n throw new Error(\"NEXT_PUBLIC_AUTH_URL is not set\")\n }\n return new URL(authUrl)\n}\n\nexport function getRedirectUri() {\n const redirectUri = process.env.PROPELAUTH_REDIRECT_URI\n if (!redirectUri) {\n throw new Error(\"PROPELAUTH_REDIRECT_URI is not set\")\n }\n return redirectUri\n}\n\nexport function getIntegrationApiKey() {\n const integrationApiKey = process.env.PROPELAUTH_API_KEY\n if (!integrationApiKey) {\n throw new Error(\"PROPELAUTH_API_KEY is not set\")\n }\n return integrationApiKey\n}\n\nexport function getVerifierKey() {\n const verifierKey = process.env.PROPELAUTH_VERIFIER_KEY\n if (!verifierKey) {\n throw new Error(\"PROPELAUTH_VERIFIER_KEY is not set\")\n }\n return verifierKey.replace(/\\\\n/g, \"\\n\")\n}\n\nexport async function refreshTokenWithAccessAndRefreshToken(refreshToken: string): Promise<RefreshTokenResponse> {\n const body = {\n refresh_token: refreshToken,\n }\n const url = `${getAuthUrlOrigin()}/api/backend/v1/refresh_token`\n const response = await fetch(url, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + getIntegrationApiKey(),\n },\n })\n\n if (response.ok) {\n const data = await response.json()\n const newRefreshToken = data.refresh_token\n const {\n access_token: accessToken,\n expires_at_seconds: expiresAtSeconds,\n } = data.access_token\n\n return {\n refreshToken: newRefreshToken,\n accessToken,\n error: \"none\",\n }\n } else if (response.status === 400 || response.status === 401) {\n return {error: \"unauthorized\"}\n } else {\n return {error: \"unexpected\"}\n }\n}\n\nexport async function validateAccessTokenOrUndefined(accessToken: string | undefined): Promise<UserFromToken | undefined> {\n try {\n return await validateAccessToken(accessToken)\n } catch (err) {\n if (err instanceof ConfigurationException) {\n throw err\n } else if (err instanceof UnauthorizedException) {\n return undefined\n } else {\n console.info(\"Error validating access token\", err)\n return undefined\n }\n }\n}\n\nexport async function validateAccessToken(accessToken: string | undefined): Promise<UserFromToken> {\n let publicKey\n try {\n publicKey = await jose.importSPKI(getVerifierKey(), \"RS256\")\n } catch (err) {\n console.error(\"Verifier key is invalid. Make sure it's specified correctly, including the newlines.\", err)\n throw new ConfigurationException(\"Invalid verifier key\")\n }\n\n if (!accessToken) {\n throw new UnauthorizedException(\"No access token provided\")\n }\n\n let accessTokenWithoutBearer = accessToken\n if (accessToken.toLowerCase().startsWith(\"bearer \")) {\n accessTokenWithoutBearer = accessToken.substring(\"bearer \".length)\n }\n\n try {\n const {payload} = await jose.jwtVerify(accessTokenWithoutBearer, publicKey, {\n issuer: getAuthUrlOrigin(),\n algorithms: [\"RS256\"],\n })\n\n return toUser(<InternalUser>payload)\n } catch (e) {\n if (e instanceof Error) {\n throw new UnauthorizedException(e.message)\n } else {\n throw new UnauthorizedException(\"Unable to decode jwt\")\n }\n }\n}\n"],"mappings":"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","names":["response","headers"]}
|
|
@@ -190,6 +190,7 @@ var ACCESS_TOKEN_COOKIE_NAME = "__pa_at";
|
|
|
190
190
|
var REFRESH_TOKEN_COOKIE_NAME = "__pa_rt";
|
|
191
191
|
var STATE_COOKIE_NAME = "__pa_state";
|
|
192
192
|
var CUSTOM_HEADER_FOR_ACCESS_TOKEN = "x-propelauth-access-token";
|
|
193
|
+
var RETURN_TO_PATH_COOKIE_NAME = "__pa_return_to_path";
|
|
193
194
|
var COOKIE_OPTIONS = {
|
|
194
195
|
httpOnly: true,
|
|
195
196
|
sameSite: "lax",
|
|
@@ -270,7 +271,7 @@ function validateAccessTokenOrUndefined(accessToken) {
|
|
|
270
271
|
} else if (err instanceof UnauthorizedException) {
|
|
271
272
|
return void 0;
|
|
272
273
|
} else {
|
|
273
|
-
console.
|
|
274
|
+
console.info("Error validating access token", err);
|
|
274
275
|
return void 0;
|
|
275
276
|
}
|
|
276
277
|
}
|
|
@@ -384,31 +385,39 @@ function getRouteHandlers(args) {
|
|
|
384
385
|
const authUrlOrigin = getAuthUrlOrigin();
|
|
385
386
|
const redirectUri = getRedirectUri();
|
|
386
387
|
const integrationApiKey = getIntegrationApiKey();
|
|
387
|
-
function loginGetHandler() {
|
|
388
|
-
|
|
389
|
-
const authorize_url = authUrlOrigin + "/propelauth/ssr/authorize?redirect_uri=" + redirectUri + "&state=" + state;
|
|
390
|
-
return new Response(null, {
|
|
391
|
-
status: 302,
|
|
392
|
-
headers: {
|
|
393
|
-
Location: authorize_url,
|
|
394
|
-
"Set-Cookie": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
|
395
|
-
}
|
|
396
|
-
});
|
|
388
|
+
function loginGetHandler(req) {
|
|
389
|
+
return signupOrLoginHandler(req, false);
|
|
397
390
|
}
|
|
398
|
-
function signupGetHandler() {
|
|
391
|
+
function signupGetHandler(req) {
|
|
392
|
+
return signupOrLoginHandler(req, true);
|
|
393
|
+
}
|
|
394
|
+
function signupOrLoginHandler(req, isSignup) {
|
|
395
|
+
const returnToPath = req.nextUrl.searchParams.get("return_to_path");
|
|
399
396
|
const state = randomState();
|
|
400
|
-
const
|
|
397
|
+
const authorizeUrlSearchParams = new URLSearchParams({
|
|
398
|
+
redirect_uri: redirectUri,
|
|
399
|
+
state,
|
|
400
|
+
signup: isSignup ? "true" : "false"
|
|
401
|
+
});
|
|
402
|
+
const authorize_url = getAuthUrlOrigin() + "/propelauth/ssr/authorize?" + authorizeUrlSearchParams.toString();
|
|
403
|
+
const headers2 = new Headers();
|
|
404
|
+
headers2.append("Location", authorize_url);
|
|
405
|
+
headers2.append("Set-Cookie", `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
406
|
+
if (returnToPath) {
|
|
407
|
+
if (returnToPath.startsWith("/")) {
|
|
408
|
+
headers2.append("Set-Cookie", `${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`);
|
|
409
|
+
} else {
|
|
410
|
+
console.warn("return_to_path must start with /");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
401
413
|
return new Response(null, {
|
|
402
414
|
status: 302,
|
|
403
|
-
headers:
|
|
404
|
-
Location: authorize_url,
|
|
405
|
-
"Set-Cookie": `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
|
406
|
-
}
|
|
415
|
+
headers: headers2
|
|
407
416
|
});
|
|
408
417
|
}
|
|
409
418
|
function callbackGetHandler(req) {
|
|
410
419
|
return __async(this, null, function* () {
|
|
411
|
-
var _a;
|
|
420
|
+
var _a, _b;
|
|
412
421
|
const oauthState = (_a = req.cookies.get(STATE_COOKIE_NAME)) == null ? void 0 : _a.value;
|
|
413
422
|
if (!oauthState || oauthState.length !== 64) {
|
|
414
423
|
return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
|
|
@@ -435,15 +444,17 @@ function getRouteHandlers(args) {
|
|
|
435
444
|
if (response.ok) {
|
|
436
445
|
const data = yield response.json();
|
|
437
446
|
const accessToken = data.access_token;
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
447
|
+
const returnToPathFromCookie = (_b = req.cookies.get(RETURN_TO_PATH_COOKIE_NAME)) == null ? void 0 : _b.value;
|
|
448
|
+
const returnToPath = returnToPathFromCookie != null ? returnToPathFromCookie : (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
|
|
449
|
+
if (!returnToPath) {
|
|
450
|
+
console.error("postLoginRedirectPathFn returned undefined");
|
|
441
451
|
return new Response("Unexpected error", { status: 500 });
|
|
442
452
|
}
|
|
443
453
|
const headers2 = new Headers();
|
|
444
|
-
headers2.append("Location",
|
|
454
|
+
headers2.append("Location", returnToPath);
|
|
445
455
|
headers2.append("Set-Cookie", `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
446
456
|
headers2.append("Set-Cookie", `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
|
457
|
+
headers2.append("Set-Cookie", `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`);
|
|
447
458
|
return new Response(null, {
|
|
448
459
|
status: 302,
|
|
449
460
|
headers: headers2
|
|
@@ -517,7 +528,7 @@ function getRouteHandlers(args) {
|
|
|
517
528
|
var _a;
|
|
518
529
|
const path = (args == null ? void 0 : args.postLoginRedirectPathFn) ? args.postLoginRedirectPathFn(req) : "/";
|
|
519
530
|
if (!path) {
|
|
520
|
-
console.
|
|
531
|
+
console.error("postLoginPathFn returned undefined");
|
|
521
532
|
return new Response("Unexpected error", { status: 500 });
|
|
522
533
|
}
|
|
523
534
|
const refreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
|
|
@@ -575,7 +586,7 @@ function getRouteHandlers(args) {
|
|
|
575
586
|
}
|
|
576
587
|
});
|
|
577
588
|
if (!response.ok) {
|
|
578
|
-
console.
|
|
589
|
+
console.warn(
|
|
579
590
|
"Unable to logout, clearing cookies and continuing anyway",
|
|
580
591
|
response.status,
|
|
581
592
|
response.statusText
|
|
@@ -589,9 +600,9 @@ function getRouteHandlers(args) {
|
|
|
589
600
|
}
|
|
590
601
|
function getRouteHandler(req, { params }) {
|
|
591
602
|
if (params.slug === "login") {
|
|
592
|
-
return loginGetHandler();
|
|
603
|
+
return loginGetHandler(req);
|
|
593
604
|
} else if (params.slug === "signup") {
|
|
594
|
-
return signupGetHandler();
|
|
605
|
+
return signupGetHandler(req);
|
|
595
606
|
} else if (params.slug === "callback") {
|
|
596
607
|
return callbackGetHandler(req);
|
|
597
608
|
} else if (params.slug === "userinfo") {
|