@propelauth/nextjs 0.0.109 → 0.0.111
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/server/app-router/index.js +75 -21
- package/dist/server/app-router/index.js.map +1 -1
- package/dist/server/app-router/index.mjs +75 -21
- package/dist/server/app-router/index.mjs.map +1 -1
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +67 -67
@@ -426,9 +426,6 @@ function authMiddleware(req) {
|
|
426
426
|
});
|
427
427
|
}
|
428
428
|
function getRouteHandlers(args) {
|
429
|
-
const authUrlOrigin = getAuthUrlOrigin();
|
430
|
-
const redirectUri = getRedirectUri();
|
431
|
-
const integrationApiKey = getIntegrationApiKey();
|
432
429
|
function loginGetHandler(req) {
|
433
430
|
return signupOrLoginHandler(req, false);
|
434
431
|
}
|
@@ -438,6 +435,7 @@ function getRouteHandlers(args) {
|
|
438
435
|
function signupOrLoginHandler(req, isSignup) {
|
439
436
|
const returnToPath = req.nextUrl.searchParams.get("return_to_path");
|
440
437
|
const state = randomState();
|
438
|
+
const redirectUri = getRedirectUri();
|
441
439
|
const authorizeUrlSearchParams = new URLSearchParams({
|
442
440
|
redirect_uri: redirectUri,
|
443
441
|
state,
|
@@ -449,7 +447,10 @@ function getRouteHandlers(args) {
|
|
449
447
|
headers2.append("Set-Cookie", `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
450
448
|
if (returnToPath) {
|
451
449
|
if (returnToPath.startsWith("/")) {
|
452
|
-
headers2.append(
|
450
|
+
headers2.append(
|
451
|
+
"Set-Cookie",
|
452
|
+
`${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`
|
453
|
+
);
|
453
454
|
} else {
|
454
455
|
console.warn("return_to_path must start with /");
|
455
456
|
}
|
@@ -472,6 +473,9 @@ function getRouteHandlers(args) {
|
|
472
473
|
if (state !== oauthState) {
|
473
474
|
return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
|
474
475
|
}
|
476
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
477
|
+
const redirectUri = getRedirectUri();
|
478
|
+
const integrationApiKey = getIntegrationApiKey();
|
475
479
|
const oauth_token_body = {
|
476
480
|
redirect_uri: redirectUri,
|
477
481
|
code
|
@@ -496,15 +500,26 @@ function getRouteHandlers(args) {
|
|
496
500
|
}
|
497
501
|
const headers2 = new Headers();
|
498
502
|
headers2.append("Location", returnToPath);
|
499
|
-
headers2.append(
|
500
|
-
|
501
|
-
|
503
|
+
headers2.append(
|
504
|
+
"Set-Cookie",
|
505
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
506
|
+
);
|
507
|
+
headers2.append(
|
508
|
+
"Set-Cookie",
|
509
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
510
|
+
);
|
511
|
+
headers2.append(
|
512
|
+
"Set-Cookie",
|
513
|
+
`${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
514
|
+
);
|
502
515
|
return new Response(null, {
|
503
516
|
status: 302,
|
504
517
|
headers: headers2
|
505
518
|
});
|
506
519
|
} else if (response.status === 401) {
|
507
|
-
console.error(
|
520
|
+
console.error(
|
521
|
+
"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY."
|
522
|
+
);
|
508
523
|
return new Response("Unexpected error", { status: 500 });
|
509
524
|
} else {
|
510
525
|
return new Response("Unexpected error", { status: 500 });
|
@@ -521,17 +536,24 @@ function getRouteHandlers(args) {
|
|
521
536
|
throw new Error("Unexpected error while refreshing access token");
|
522
537
|
} else if (refreshResponse.error === "unauthorized") {
|
523
538
|
const headers3 = new Headers();
|
524
|
-
headers3.append(
|
525
|
-
|
539
|
+
headers3.append(
|
540
|
+
"Set-Cookie",
|
541
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
542
|
+
);
|
543
|
+
headers3.append(
|
544
|
+
"Set-Cookie",
|
545
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
546
|
+
);
|
526
547
|
return new Response("Unauthorized", { status: 401, headers: headers3 });
|
527
548
|
}
|
528
549
|
const refreshToken = refreshResponse.refreshToken;
|
529
550
|
const accessToken = refreshResponse.accessToken;
|
551
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
530
552
|
const path = `${authUrlOrigin}/propelauth/oauth/userinfo`;
|
531
553
|
const response = yield fetch(path, {
|
532
554
|
headers: {
|
533
555
|
"Content-Type": "application/json",
|
534
|
-
|
556
|
+
Authorization: "Bearer " + accessToken
|
535
557
|
}
|
536
558
|
});
|
537
559
|
if (response.ok) {
|
@@ -543,8 +565,14 @@ function getRouteHandlers(args) {
|
|
543
565
|
impersonatorUserId: userFromToken.impersonatorUserId
|
544
566
|
};
|
545
567
|
const headers3 = new Headers();
|
546
|
-
headers3.append(
|
547
|
-
|
568
|
+
headers3.append(
|
569
|
+
"Set-Cookie",
|
570
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
571
|
+
);
|
572
|
+
headers3.append(
|
573
|
+
"Set-Cookie",
|
574
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
575
|
+
);
|
548
576
|
headers3.append("Content-Type", "application/json");
|
549
577
|
return new Response(JSON.stringify(jsonResponse), {
|
550
578
|
status: 200,
|
@@ -552,8 +580,14 @@ function getRouteHandlers(args) {
|
|
552
580
|
});
|
553
581
|
} else if (response.status === 401) {
|
554
582
|
const headers3 = new Headers();
|
555
|
-
headers3.append(
|
556
|
-
|
583
|
+
headers3.append(
|
584
|
+
"Set-Cookie",
|
585
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
586
|
+
);
|
587
|
+
headers3.append(
|
588
|
+
"Set-Cookie",
|
589
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
590
|
+
);
|
557
591
|
return new Response(null, {
|
558
592
|
status: 401,
|
559
593
|
headers: headers3
|
@@ -580,8 +614,14 @@ function getRouteHandlers(args) {
|
|
580
614
|
if (!refreshToken) {
|
581
615
|
const headers2 = new Headers();
|
582
616
|
headers2.append("Location", path);
|
583
|
-
headers2.append(
|
584
|
-
|
617
|
+
headers2.append(
|
618
|
+
"Set-Cookie",
|
619
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
620
|
+
);
|
621
|
+
headers2.append(
|
622
|
+
"Set-Cookie",
|
623
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
624
|
+
);
|
585
625
|
return new Response(null, {
|
586
626
|
status: 302,
|
587
627
|
headers: headers2
|
@@ -594,8 +634,14 @@ function getRouteHandlers(args) {
|
|
594
634
|
} else if (refreshResponse.error === "unauthorized") {
|
595
635
|
const headers2 = new Headers();
|
596
636
|
headers2.append("Location", path);
|
597
|
-
headers2.append(
|
598
|
-
|
637
|
+
headers2.append(
|
638
|
+
"Set-Cookie",
|
639
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
640
|
+
);
|
641
|
+
headers2.append(
|
642
|
+
"Set-Cookie",
|
643
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
644
|
+
);
|
599
645
|
return new Response(null, {
|
600
646
|
status: 302,
|
601
647
|
headers: headers2
|
@@ -616,10 +662,18 @@ function getRouteHandlers(args) {
|
|
616
662
|
const refreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
|
617
663
|
if (!refreshToken) {
|
618
664
|
const headers3 = new Headers();
|
619
|
-
headers3.append(
|
620
|
-
|
665
|
+
headers3.append(
|
666
|
+
"Set-Cookie",
|
667
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
668
|
+
);
|
669
|
+
headers3.append(
|
670
|
+
"Set-Cookie",
|
671
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
672
|
+
);
|
621
673
|
return new Response(null, { status: 200, headers: headers3 });
|
622
674
|
}
|
675
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
676
|
+
const integrationApiKey = getIntegrationApiKey();
|
623
677
|
const logoutBody = { refresh_token: refreshToken };
|
624
678
|
const url = `${authUrlOrigin}/api/backend/v1/logout`;
|
625
679
|
const response = yield fetch(url, {
|
@@ -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 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 console.error(\"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY.\")\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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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"]}
|
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 (\n req.nextUrl.pathname === CALLBACK_PATH ||\n req.nextUrl.pathname === LOGOUT_PATH ||\n req.nextUrl.pathname === USERINFO_PATH\n ) {\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 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 const redirectUri = getRedirectUri()\n\n const authorizeUrlSearchParams = new URLSearchParams({\n redirect_uri: redirectUri,\n state,\n signup: isSignup ? 'true' : 'false',\n })\n const authorize_url = 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(\n 'Set-Cookie',\n `${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`\n )\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 authUrlOrigin = getAuthUrlOrigin()\n const redirectUri = getRedirectUri()\n const integrationApiKey = getIntegrationApiKey()\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 =\n 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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response(null, {\n status: 302,\n headers,\n })\n } else if (response.status === 401) {\n console.error(\n \"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY.\"\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response('Unauthorized', { status: 401, headers })\n }\n\n const refreshToken = refreshResponse.refreshToken\n const accessToken = refreshResponse.accessToken\n\n const authUrlOrigin = getAuthUrlOrigin()\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response(null, { status: 200, headers })\n }\n\n const authUrlOrigin = getAuthUrlOrigin()\n const integrationApiKey = getIntegrationApiKey()\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","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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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"]}
|
@@ -385,9 +385,6 @@ function authMiddleware(req) {
|
|
385
385
|
});
|
386
386
|
}
|
387
387
|
function getRouteHandlers(args) {
|
388
|
-
const authUrlOrigin = getAuthUrlOrigin();
|
389
|
-
const redirectUri = getRedirectUri();
|
390
|
-
const integrationApiKey = getIntegrationApiKey();
|
391
388
|
function loginGetHandler(req) {
|
392
389
|
return signupOrLoginHandler(req, false);
|
393
390
|
}
|
@@ -397,6 +394,7 @@ function getRouteHandlers(args) {
|
|
397
394
|
function signupOrLoginHandler(req, isSignup) {
|
398
395
|
const returnToPath = req.nextUrl.searchParams.get("return_to_path");
|
399
396
|
const state = randomState();
|
397
|
+
const redirectUri = getRedirectUri();
|
400
398
|
const authorizeUrlSearchParams = new URLSearchParams({
|
401
399
|
redirect_uri: redirectUri,
|
402
400
|
state,
|
@@ -408,7 +406,10 @@ function getRouteHandlers(args) {
|
|
408
406
|
headers2.append("Set-Cookie", `${STATE_COOKIE_NAME}=${state}; Path=/; HttpOnly; Secure; SameSite=Lax`);
|
409
407
|
if (returnToPath) {
|
410
408
|
if (returnToPath.startsWith("/")) {
|
411
|
-
headers2.append(
|
409
|
+
headers2.append(
|
410
|
+
"Set-Cookie",
|
411
|
+
`${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`
|
412
|
+
);
|
412
413
|
} else {
|
413
414
|
console.warn("return_to_path must start with /");
|
414
415
|
}
|
@@ -431,6 +432,9 @@ function getRouteHandlers(args) {
|
|
431
432
|
if (state !== oauthState) {
|
432
433
|
return new Response(null, { status: 302, headers: { Location: LOGIN_PATH } });
|
433
434
|
}
|
435
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
436
|
+
const redirectUri = getRedirectUri();
|
437
|
+
const integrationApiKey = getIntegrationApiKey();
|
434
438
|
const oauth_token_body = {
|
435
439
|
redirect_uri: redirectUri,
|
436
440
|
code
|
@@ -455,15 +459,26 @@ function getRouteHandlers(args) {
|
|
455
459
|
}
|
456
460
|
const headers2 = new Headers();
|
457
461
|
headers2.append("Location", returnToPath);
|
458
|
-
headers2.append(
|
459
|
-
|
460
|
-
|
462
|
+
headers2.append(
|
463
|
+
"Set-Cookie",
|
464
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
465
|
+
);
|
466
|
+
headers2.append(
|
467
|
+
"Set-Cookie",
|
468
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
469
|
+
);
|
470
|
+
headers2.append(
|
471
|
+
"Set-Cookie",
|
472
|
+
`${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
473
|
+
);
|
461
474
|
return new Response(null, {
|
462
475
|
status: 302,
|
463
476
|
headers: headers2
|
464
477
|
});
|
465
478
|
} else if (response.status === 401) {
|
466
|
-
console.error(
|
479
|
+
console.error(
|
480
|
+
"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY."
|
481
|
+
);
|
467
482
|
return new Response("Unexpected error", { status: 500 });
|
468
483
|
} else {
|
469
484
|
return new Response("Unexpected error", { status: 500 });
|
@@ -480,17 +495,24 @@ function getRouteHandlers(args) {
|
|
480
495
|
throw new Error("Unexpected error while refreshing access token");
|
481
496
|
} else if (refreshResponse.error === "unauthorized") {
|
482
497
|
const headers3 = new Headers();
|
483
|
-
headers3.append(
|
484
|
-
|
498
|
+
headers3.append(
|
499
|
+
"Set-Cookie",
|
500
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
501
|
+
);
|
502
|
+
headers3.append(
|
503
|
+
"Set-Cookie",
|
504
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
505
|
+
);
|
485
506
|
return new Response("Unauthorized", { status: 401, headers: headers3 });
|
486
507
|
}
|
487
508
|
const refreshToken = refreshResponse.refreshToken;
|
488
509
|
const accessToken = refreshResponse.accessToken;
|
510
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
489
511
|
const path = `${authUrlOrigin}/propelauth/oauth/userinfo`;
|
490
512
|
const response = yield fetch(path, {
|
491
513
|
headers: {
|
492
514
|
"Content-Type": "application/json",
|
493
|
-
|
515
|
+
Authorization: "Bearer " + accessToken
|
494
516
|
}
|
495
517
|
});
|
496
518
|
if (response.ok) {
|
@@ -502,8 +524,14 @@ function getRouteHandlers(args) {
|
|
502
524
|
impersonatorUserId: userFromToken.impersonatorUserId
|
503
525
|
};
|
504
526
|
const headers3 = new Headers();
|
505
|
-
headers3.append(
|
506
|
-
|
527
|
+
headers3.append(
|
528
|
+
"Set-Cookie",
|
529
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
530
|
+
);
|
531
|
+
headers3.append(
|
532
|
+
"Set-Cookie",
|
533
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`
|
534
|
+
);
|
507
535
|
headers3.append("Content-Type", "application/json");
|
508
536
|
return new Response(JSON.stringify(jsonResponse), {
|
509
537
|
status: 200,
|
@@ -511,8 +539,14 @@ function getRouteHandlers(args) {
|
|
511
539
|
});
|
512
540
|
} else if (response.status === 401) {
|
513
541
|
const headers3 = new Headers();
|
514
|
-
headers3.append(
|
515
|
-
|
542
|
+
headers3.append(
|
543
|
+
"Set-Cookie",
|
544
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
545
|
+
);
|
546
|
+
headers3.append(
|
547
|
+
"Set-Cookie",
|
548
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
549
|
+
);
|
516
550
|
return new Response(null, {
|
517
551
|
status: 401,
|
518
552
|
headers: headers3
|
@@ -539,8 +573,14 @@ function getRouteHandlers(args) {
|
|
539
573
|
if (!refreshToken) {
|
540
574
|
const headers2 = new Headers();
|
541
575
|
headers2.append("Location", path);
|
542
|
-
headers2.append(
|
543
|
-
|
576
|
+
headers2.append(
|
577
|
+
"Set-Cookie",
|
578
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
579
|
+
);
|
580
|
+
headers2.append(
|
581
|
+
"Set-Cookie",
|
582
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
583
|
+
);
|
544
584
|
return new Response(null, {
|
545
585
|
status: 302,
|
546
586
|
headers: headers2
|
@@ -553,8 +593,14 @@ function getRouteHandlers(args) {
|
|
553
593
|
} else if (refreshResponse.error === "unauthorized") {
|
554
594
|
const headers2 = new Headers();
|
555
595
|
headers2.append("Location", path);
|
556
|
-
headers2.append(
|
557
|
-
|
596
|
+
headers2.append(
|
597
|
+
"Set-Cookie",
|
598
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
599
|
+
);
|
600
|
+
headers2.append(
|
601
|
+
"Set-Cookie",
|
602
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
603
|
+
);
|
558
604
|
return new Response(null, {
|
559
605
|
status: 302,
|
560
606
|
headers: headers2
|
@@ -575,10 +621,18 @@ function getRouteHandlers(args) {
|
|
575
621
|
const refreshToken = (_a = req.cookies.get(REFRESH_TOKEN_COOKIE_NAME)) == null ? void 0 : _a.value;
|
576
622
|
if (!refreshToken) {
|
577
623
|
const headers3 = new Headers();
|
578
|
-
headers3.append(
|
579
|
-
|
624
|
+
headers3.append(
|
625
|
+
"Set-Cookie",
|
626
|
+
`${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
627
|
+
);
|
628
|
+
headers3.append(
|
629
|
+
"Set-Cookie",
|
630
|
+
`${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`
|
631
|
+
);
|
580
632
|
return new Response(null, { status: 200, headers: headers3 });
|
581
633
|
}
|
634
|
+
const authUrlOrigin = getAuthUrlOrigin();
|
635
|
+
const integrationApiKey = getIntegrationApiKey();
|
582
636
|
const logoutBody = { refresh_token: refreshToken };
|
583
637
|
const url = `${authUrlOrigin}/api/backend/v1/logout`;
|
584
638
|
const response = yield fetch(url, {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/server/exceptions.ts","../../../src/server/app-router.ts","../../../src/user.ts","../../../src/server/shared.ts"],"sourcesContent":["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 console.error(\"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY.\")\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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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"]}
|
1
|
+
{"version":3,"sources":["../../../src/server/exceptions.ts","../../../src/server/app-router.ts","../../../src/user.ts","../../../src/server/shared.ts"],"sourcesContent":["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 (\n req.nextUrl.pathname === CALLBACK_PATH ||\n req.nextUrl.pathname === LOGOUT_PATH ||\n req.nextUrl.pathname === USERINFO_PATH\n ) {\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 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 const redirectUri = getRedirectUri()\n\n const authorizeUrlSearchParams = new URLSearchParams({\n redirect_uri: redirectUri,\n state,\n signup: isSignup ? 'true' : 'false',\n })\n const authorize_url = 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(\n 'Set-Cookie',\n `${RETURN_TO_PATH_COOKIE_NAME}=${returnToPath}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=600`\n )\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 authUrlOrigin = getAuthUrlOrigin()\n const redirectUri = getRedirectUri()\n const integrationApiKey = getIntegrationApiKey()\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 =\n 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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=${data.refresh_token}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${RETURN_TO_PATH_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response(null, {\n status: 302,\n headers,\n })\n } else if (response.status === 401) {\n console.error(\n \"Couldn't finish the login process for this user. This is most likely caused by an incorrect PROPELAUTH_API_KEY.\"\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response('Unauthorized', { status: 401, headers })\n }\n\n const refreshToken = refreshResponse.refreshToken\n const accessToken = refreshResponse.accessToken\n\n const authUrlOrigin = getAuthUrlOrigin()\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=${accessToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=${refreshToken}; Path=/; HttpOnly; Secure; SameSite=Lax`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\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(\n 'Set-Cookie',\n `${ACCESS_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n headers.append(\n 'Set-Cookie',\n `${REFRESH_TOKEN_COOKIE_NAME}=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0`\n )\n return new Response(null, { status: 200, headers })\n }\n\n const authUrlOrigin = getAuthUrlOrigin()\n const integrationApiKey = getIntegrationApiKey()\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","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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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"]}
|
package/dist/server/index.d.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import * as _propelauth_node_apis from '@propelauth/node-apis';
|
2
|
+
export { AccessToken, AccessTokenCreationException, AddUserToOrgException, AddUserToOrgRequest, ApiKeyCreateException, ApiKeyDeleteException, ApiKeyFetchException, ApiKeyFull, ApiKeyNew, ApiKeyResultPage, ApiKeyUpdateException, ApiKeyUpdateRequest, ApiKeyValidateException, ApiKeyValidation, ApiKeysCreateRequest, ApiKeysQueryRequest, BadRequestException, ChangeUserRoleInOrgException, CreateAccessTokenRequest, CreateMagicLinkRequest, CreateOrgException, CreateOrgRequest, CreateUserException, CreateUserRequest, ForbiddenException, InviteUserToOrgRequest, MagicLink, MagicLinkCreationException, MigrateUserException, MigrateUserFromExternalSourceRequest, OrgApiKeyValidation, OrgQuery, OrgQueryResponse, PersonalApiKeyValidation, RemoveUserFromOrgException, RemoveUserFromOrgRequest, TokenVerificationMetadata, UnexpectedException, UpdateOrgException, UpdateOrgRequest, UpdateUserEmailException, UpdateUserEmailRequest, UpdateUserMetadataException, UpdateUserMetadataRequest, UpdateUserPasswordException, UpdateUserPasswordRequest, UserNotFoundException, UsersInOrgQuery, UsersPagedResponse, UsersQuery } from '@propelauth/node-apis';
|
2
3
|
|
3
4
|
declare class UserFromToken {
|
4
5
|
userId: string;
|
@@ -91,7 +92,10 @@ declare const getPropelAuthApis: () => {
|
|
91
92
|
disableUser2fa: (userId: string) => Promise<boolean>;
|
92
93
|
enableUserCanCreateOrgs: (userId: string) => Promise<boolean>;
|
93
94
|
disableUserCanCreateOrgs: (userId: string) => Promise<boolean>;
|
94
|
-
createOrg: (createOrgRequest: _propelauth_node_apis.CreateOrgRequest) => Promise<
|
95
|
+
createOrg: (createOrgRequest: _propelauth_node_apis.CreateOrgRequest) => Promise<{
|
96
|
+
orgId: string;
|
97
|
+
name: string;
|
98
|
+
}>;
|
95
99
|
addUserToOrg: (addUserToOrgRequest: _propelauth_node_apis.AddUserToOrgRequest) => Promise<boolean>;
|
96
100
|
changeUserRoleInOrg: (changeUserRoleInOrgRequest: {
|
97
101
|
userId: string;
|
@@ -103,6 +107,7 @@ declare const getPropelAuthApis: () => {
|
|
103
107
|
deleteOrg: (orgId: string) => Promise<boolean>;
|
104
108
|
allowOrgToSetupSamlConnection: (orgId: string) => Promise<boolean>;
|
105
109
|
disallowOrgToSetupSamlConnection: (orgId: string) => Promise<boolean>;
|
110
|
+
inviteUserToOrg: (inviteUserToOrgRequest: _propelauth_node_apis.InviteUserToOrgRequest) => Promise<boolean>;
|
106
111
|
fetchApiKey: (apiKeyId: string) => Promise<_propelauth_node_apis.ApiKeyFull>;
|
107
112
|
fetchCurrentApiKeys: (apiKeyQuery: _propelauth_node_apis.ApiKeysQueryRequest) => Promise<_propelauth_node_apis.ApiKeyResultPage>;
|
108
113
|
fetchArchivedApiKeys: (apiKeyQuery: _propelauth_node_apis.ApiKeysQueryRequest) => Promise<_propelauth_node_apis.ApiKeyResultPage>;
|
package/dist/server/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../src/server/index.ts","../../src/user.ts","../../src/server/exceptions.ts","../../src/server/shared.ts","../../src/server/api.ts"],"sourcesContent":["export {validateAccessToken, validateAccessTokenOrUndefined} from \"./shared\"\nexport type {OrgIdToOrgMemberInfo} from \"../user\"\nexport {UserFromToken, OrgMemberInfo} from \"../user\"\nexport {UnauthorizedException, ConfigurationException} from \"./exceptions\"\nexport {getPropelAuthApis} from \"./api\"\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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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","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 {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","import {getApis} from \"@propelauth/node-apis\";\nimport {getAuthUrl, getIntegrationApiKey} from \"./shared\";\n\nexport const getPropelAuthApis = () => {\n const authUrl = getAuthUrl()\n const integrationApiKey = getIntegrationApiKey()\n\n return getApis(authUrl, integrationApiKey)\n}"],"mappings":"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","names":[]}
|
1
|
+
{"version":3,"sources":["../../src/server/index.ts","../../src/user.ts","../../src/server/exceptions.ts","../../src/server/shared.ts","../../src/server/api.ts"],"sourcesContent":["export {validateAccessToken, validateAccessTokenOrUndefined} from \"./shared\"\nexport type {OrgIdToOrgMemberInfo} from \"../user\"\nexport {UserFromToken, OrgMemberInfo} from \"../user\"\nexport {UnauthorizedException, ConfigurationException} from \"./exceptions\"\nexport {getPropelAuthApis} from \"./api\"\nexport type {\n AccessToken,\n AccessTokenCreationException,\n AddUserToOrgException,\n AddUserToOrgRequest,\n ApiKeyCreateException,\n ApiKeyDeleteException,\n ApiKeyFetchException,\n ApiKeyFull,\n ApiKeyNew,\n ApiKeyResultPage,\n ApiKeyUpdateException,\n ApiKeyUpdateRequest,\n ApiKeyValidateException,\n ApiKeyValidation,\n ApiKeysCreateRequest,\n ApiKeysQueryRequest,\n BadRequestException,\n ChangeUserRoleInOrgException,\n CreateAccessTokenRequest,\n CreateMagicLinkRequest,\n CreateOrgException,\n CreateOrgRequest,\n CreateUserException,\n CreateUserRequest,\n ForbiddenException,\n InviteUserToOrgRequest,\n MagicLink,\n MagicLinkCreationException,\n MigrateUserException,\n MigrateUserFromExternalSourceRequest,\n OrgApiKeyValidation,\n OrgQuery,\n OrgQueryResponse,\n PersonalApiKeyValidation,\n RemoveUserFromOrgException,\n RemoveUserFromOrgRequest,\n TokenVerificationMetadata,\n UnexpectedException,\n UpdateOrgException,\n UpdateOrgRequest,\n UpdateUserEmailException,\n UpdateUserEmailRequest,\n UpdateUserMetadataException,\n UpdateUserMetadataRequest,\n UpdateUserPasswordException,\n UpdateUserPasswordRequest,\n UserNotFoundException,\n UsersInOrgQuery,\n UsersPagedResponse,\n UsersQuery,\n} from \"@propelauth/node-apis\"\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 public properties?: { [key: string]: unknown }\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 properties?: { [key: string]: unknown },\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 this.properties = properties\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 obj.properties,\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 public userAssignedRole: string\n public userInheritedRolesPlusCurrentRole: string[]\n public 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 properties?: { [key: string]: unknown }\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 snake_case.properties,\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","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 {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","import {getApis} from \"@propelauth/node-apis\";\nimport {getAuthUrl, getIntegrationApiKey} from \"./shared\";\n\nexport const getPropelAuthApis = () => {\n const authUrl = getAuthUrl()\n const integrationApiKey = getIntegrationApiKey()\n\n return getApis(authUrl, integrationApiKey)\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
@@ -1,74 +1,74 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
2
|
+
"name": "@propelauth/nextjs",
|
3
|
+
"version": "0.0.111",
|
4
|
+
"exports": {
|
5
|
+
"./server": {
|
6
|
+
"browser": "./dist/server/index.mjs",
|
7
|
+
"import": "./dist/server/index.mjs",
|
8
|
+
"require": "./dist/server/index.js",
|
9
|
+
"default": "./dist/server/index.mjs",
|
10
|
+
"types": "./dist/server/index.d.ts"
|
11
|
+
},
|
12
|
+
"./server/app-router": {
|
13
|
+
"browser": "./dist/server/app-router/index.mjs",
|
14
|
+
"import": "./dist/server/app-router/index.mjs",
|
15
|
+
"require": "./dist/server/app-router/index.js",
|
16
|
+
"default": "./dist/server/app-router/index.mjs",
|
17
|
+
"types": "./dist/server/app-router/index.d.ts"
|
18
|
+
},
|
19
|
+
"./server/pages": {
|
20
|
+
"browser": "./dist/server/pages/index.mjs",
|
21
|
+
"import": "./dist/server/pages/index.mjs",
|
22
|
+
"require": "./dist/server/pages/index.js",
|
23
|
+
"default": "./dist/server/pages/index.mjs",
|
24
|
+
"types": "./dist/server/pages/index.d.ts"
|
25
|
+
},
|
26
|
+
"./client": {
|
27
|
+
"browser": "./dist/client/index.mjs",
|
28
|
+
"import": "./dist/client/index.mjs",
|
29
|
+
"require": "./dist/client/index.js",
|
30
|
+
"default": "./dist/client/index.mjs",
|
31
|
+
"types": "./dist/client/index.d.ts"
|
32
|
+
},
|
33
|
+
"./package.json": "./package.json"
|
11
34
|
},
|
12
|
-
"
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
35
|
+
"typesVersions": {
|
36
|
+
"*": {
|
37
|
+
"server": [
|
38
|
+
"./dist/server/index.d.ts"
|
39
|
+
],
|
40
|
+
"server/app-router": [
|
41
|
+
"./dist/server/app-router/index.d.ts"
|
42
|
+
],
|
43
|
+
"server/pages": [
|
44
|
+
"./dist/server/pages/index.d.ts"
|
45
|
+
],
|
46
|
+
"client": [
|
47
|
+
"./dist/client/index.d.ts"
|
48
|
+
]
|
49
|
+
}
|
18
50
|
},
|
19
|
-
"
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
51
|
+
"files": [
|
52
|
+
"dist"
|
53
|
+
],
|
54
|
+
"scripts": {
|
55
|
+
"build": "tsup",
|
56
|
+
"dev": "tsup --watch",
|
57
|
+
"test": "jest"
|
25
58
|
},
|
26
|
-
"
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
59
|
+
"devDependencies": {
|
60
|
+
"@types/node": "^20.3.1",
|
61
|
+
"@types/react": "^18.2.0",
|
62
|
+
"@types/react-dom": "^18.2.0",
|
63
|
+
"tsup": "^6.7.0",
|
64
|
+
"typescript": "^5.1.3"
|
32
65
|
},
|
33
|
-
"
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
"
|
39
|
-
|
40
|
-
"server/app-router": [
|
41
|
-
"./dist/server/app-router/index.d.ts"
|
42
|
-
],
|
43
|
-
"server/pages": [
|
44
|
-
"./dist/server/pages/index.d.ts"
|
45
|
-
],
|
46
|
-
"client": [
|
47
|
-
"./dist/client/index.d.ts"
|
48
|
-
]
|
66
|
+
"peerDependencies": {
|
67
|
+
"next": "^13.1.0 || ^14.0.0",
|
68
|
+
"react": "^18.2.0"
|
69
|
+
},
|
70
|
+
"dependencies": {
|
71
|
+
"@propelauth/node-apis": "^2.1.4",
|
72
|
+
"jose": "^4.14.4"
|
49
73
|
}
|
50
|
-
},
|
51
|
-
"files": [
|
52
|
-
"dist"
|
53
|
-
],
|
54
|
-
"scripts": {
|
55
|
-
"build": "tsup",
|
56
|
-
"dev": "tsup --watch",
|
57
|
-
"test": "jest"
|
58
|
-
},
|
59
|
-
"devDependencies": {
|
60
|
-
"@types/node": "^20.3.1",
|
61
|
-
"@types/react": "^18.2.0",
|
62
|
-
"@types/react-dom": "^18.2.0",
|
63
|
-
"tsup": "^6.7.0",
|
64
|
-
"typescript": "^5.1.3"
|
65
|
-
},
|
66
|
-
"peerDependencies": {
|
67
|
-
"next": "^13.1.0 || ^14.0.0",
|
68
|
-
"react": "^18.2.0"
|
69
|
-
},
|
70
|
-
"dependencies": {
|
71
|
-
"@propelauth/node-apis": "^2.1.2",
|
72
|
-
"jose": "^4.14.4"
|
73
|
-
}
|
74
74
|
}
|