Fix redirect OIDC (#1911)

* fix: redirect oidc not defined

* fix: construct redirect url from x-forwarded prot and host

* fix: redirect method does not support comma seperated protocol list and url starting with http(s)://

* fix: redirect_uri not specified for oidc as authorization parameter

* fix: unit test not modified

* docs: add comment why the redirect_uri is constructed

* fix: add redirect callback with forwarded headers as redirect url host and protocol

* Apply suggestions from code review
This commit is contained in:
Meier Lukas
2024-02-20 20:34:57 +01:00
committed by GitHub
parent 1bc19e7857
commit 5cd940f3cc
6 changed files with 140 additions and 19 deletions

View File

@@ -4,7 +4,8 @@ import { type GetServerSidePropsContext, type NextApiRequest, type NextApiRespon
import { type NextAuthOptions, getServerSession } from 'next-auth';
import { Adapter } from 'next-auth/adapters';
import { decode, encode } from 'next-auth/jwt';
import { adapter, onCreateUser, providers } from '~/utils/auth';
import { adapter, getProviders, onCreateUser } from '~/utils/auth';
import { createRedirectUri } from '~/utils/auth/oidc';
import EmptyNextAuthProvider from '~/utils/empty-provider';
import { fromDate, generateSessionToken } from '~/utils/session';
import { colorSchemeParser } from '~/validations/user';
@@ -19,10 +20,10 @@ const sessionMaxAgeInSeconds = 30 * 24 * 60 * 60; // 30 days
*
* @see https://next-auth.js.org/configuration/options
*/
export const constructAuthOptions = (
export const constructAuthOptions = async (
req: NextApiRequest,
res: NextApiResponse
): NextAuthOptions => ({
): Promise<NextAuthOptions> => ({
events: {
createUser: onCreateUser,
},
@@ -86,6 +87,11 @@ export const constructAuthOptions = (
return true;
},
async redirect({ url, baseUrl }) {
const pathname = new URL(url, baseUrl).pathname;
const redirectUrl = createRedirectUri(req.headers, pathname);
return redirectUrl;
},
},
session: {
strategy: 'database',
@@ -96,7 +102,7 @@ export const constructAuthOptions = (
error: '/auth/login',
},
adapter: adapter as Adapter,
providers: [...providers, EmptyNextAuthProvider()],
providers: [...(await getProviders(req.headers)), EmptyNextAuthProvider()],
jwt: {
async encode(params) {
if (!isCredentialsRequest(req)) {
@@ -134,14 +140,14 @@ const isCredentialsRequest = (req: NextApiRequest): boolean => {
*
* @see https://next-auth.js.org/configuration/nextjs
*/
export const getServerAuthSession = (ctx: {
export const getServerAuthSession = async (ctx: {
req: GetServerSidePropsContext['req'];
res: GetServerSidePropsContext['res'];
}) => {
return getServerSession(
return await getServerSession(
ctx.req,
ctx.res,
constructAuthOptions(
await constructAuthOptions(
ctx.req as unknown as NextApiRequest,
ctx.res as unknown as NextApiResponse
)