diff --git a/auth/app/api/auth/callback/[provider]/route.ts b/auth/app/api/auth/callback/[providerId]/route.ts similarity index 92% rename from auth/app/api/auth/callback/[provider]/route.ts rename to auth/app/api/auth/callback/[providerId]/route.ts index 32975c8..af734fc 100644 --- a/auth/app/api/auth/callback/[provider]/route.ts +++ b/auth/app/api/auth/callback/[providerId]/route.ts @@ -9,6 +9,7 @@ import { import { deleteCookie, setAuthSessionCookie } from "@/lib/cookie"; import { prisma } from "@/lib/prisma"; import { getWellKnown } from "@/lib/zitadel"; +import { authOptions } from "@/options"; import jwt from "jsonwebtoken"; import { cookies } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; @@ -17,12 +18,13 @@ import { v4 as uuid } from "uuid"; async function handler( request: NextRequest, - { params }: { params: { provider: "portal" | "zitadel" } } + { params: { providerId } }: { params: { providerId: "portal" | "zitadel" } } ) { try { const code = request.nextUrl.searchParams.get("code"); const state = request.nextUrl.searchParams.get("state"); - const provider = params.provider; + + const provider = authOptions.providers.find((p) => p.id === providerId); if (!provider) throw new Error("provider not found"); const requestCookie = cookies(); @@ -39,17 +41,17 @@ async function handler( if (stateCookie.value !== state) throw new Error("Invalid state"); if (!redirectCookie) throw new Error("Redirect url cookie not found"); - if (redirectCookie.value !== configuration[provider].redirectUrl) + if (redirectCookie.value !== provider.redirectUrl) throw new Error("Invalid redirect url"); const tokenParams = new URLSearchParams(); tokenParams.append("code", code as string); tokenParams.append("grant_type", "authorization_code"); - tokenParams.append("client_id", configuration[provider].clientId); - tokenParams.append("redirect_uri", configuration[provider].redirectUrl); + tokenParams.append("client_id", provider.clientId); + tokenParams.append("redirect_uri", provider.redirectUrl); tokenParams.append("code_verifier", codeVerifierCookie.value); - const wellKnown = await getWellKnown(configuration[provider].issuer); + const wellKnown = await getWellKnown(provider.wellKnown); const response = await fetch(wellKnown.token_endpoint, { method: "post", @@ -92,7 +94,7 @@ async function handler( await prisma.session.create({ data: { authSession, - providerId: provider, + providerId, accessToken: result.access_token, tokenType: result.token_type, expiresIn: result.expires_in, diff --git a/auth/app/api/auth/signin/[provider]/route.ts b/auth/app/api/auth/signin/[provider]/route.ts index 1ee1f74..1a8d7f6 100644 --- a/auth/app/api/auth/signin/[provider]/route.ts +++ b/auth/app/api/auth/signin/[provider]/route.ts @@ -13,13 +13,14 @@ import { } from "@/lib/constant"; import { deleteCookie, setShortLiveCookie } from "@/lib/cookie"; import { getWellKnown } from "@/lib/zitadel"; +import { authOptions } from "@/options"; import { cookies } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; import { URLSearchParams } from "url"; export async function POST( request: NextRequest, - { params }: { params: { provider: "portal" | "zitadel" } } + { params: { providerId } }: { params: { providerId: "portal" | "zitadel" } } ) { const body = (await request.json()) as { csrfToken: string; @@ -30,7 +31,7 @@ export async function POST( }; const { csrfToken, scope, returnUrl, prompt, loginHint } = body; - const provider = params.provider; + const provider = authOptions.providers.find((p) => p.id === providerId); if (!provider) throw new Error("provider not found"); const requestCookie = cookies(); @@ -39,7 +40,7 @@ export async function POST( if (!csrfTokenCookie) throw new Error("csrfToken cookie not found"); if (csrfTokenCookie.value !== csrfToken) throw new Error("Invalid csrfToken"); - const wellKnown = await getWellKnown(configuration[provider].issuer); + const wellKnown = await getWellKnown(provider.wellKnown); const codeVerifier = generateCodeVerifier(); const codeChallenge = generateCodeChallenge(codeVerifier); @@ -48,8 +49,8 @@ export async function POST( const requestParams = new URLSearchParams({ code_challenge: codeChallenge, code_challenge_method: "S256", - client_id: configuration[provider].clientId, - redirect_uri: configuration[provider].redirectUrl, + client_id: provider.clientId, + redirect_uri: provider.redirectUrl, response_type: "code", scope, state, @@ -60,10 +61,7 @@ export async function POST( if (returnUrl) setShortLiveCookie(returnUrlCookieName, returnUrl); setShortLiveCookie(stateCookieName, state); - setShortLiveCookie( - redirectUrlCookieName, - configuration[provider].redirectUrl - ); + setShortLiveCookie(redirectUrlCookieName, provider.redirectUrl); setShortLiveCookie(codeVerifierCookieName, codeVerifier); deleteCookie(csrfTokenCookieName); diff --git a/auth/app/api/auth/signout/route.ts b/auth/app/api/auth/signout/route.ts index 4f72f9c..4b4d260 100644 --- a/auth/app/api/auth/signout/route.ts +++ b/auth/app/api/auth/signout/route.ts @@ -3,6 +3,7 @@ import { authSessionCookieName, returnUrlCookieName } from "@/lib/constant"; import { setShortLiveCookie } from "@/lib/cookie"; import { prisma } from "@/lib/prisma"; import { getWellKnown } from "@/lib/zitadel"; +import { authOptions } from "@/options"; import { cookies } from "next/headers"; import { NextRequest, NextResponse } from "next/server"; @@ -24,12 +25,15 @@ export async function POST(request: NextRequest) { }, }); if (!session) throw new Error("session not found"); - const provider = session.providerId as "portal" | "zitadel"; - const wellKnown = await getWellKnown(configuration[provider].issuer); + const providerId = session.providerId as "portal" | "zitadel"; + const provider = authOptions.providers.find((p) => p.id === providerId); + if (!provider) throw new Error("provider not found"); + + const wellKnown = await getWellKnown(provider.wellKnown); const requestParams = new URLSearchParams({ - client_id: configuration[provider].clientId, + client_id: provider.clientId, post_logout_redirect_uri: configuration.postLogoutRedirectUri, }); diff --git a/auth/app/auth/signedout/page.tsx b/auth/app/auth/signedout/page.tsx index 6fca2d9..508db31 100644 --- a/auth/app/auth/signedout/page.tsx +++ b/auth/app/auth/signedout/page.tsx @@ -3,8 +3,7 @@ import { returnUrlCookieName } from "@/lib/constant"; import { cookies } from "next/headers"; import { redirect } from "next/navigation"; -export default async function Page({ searchParams }: { searchParams: {} }) { - console.log(`debug:searchParams`, searchParams); +export default async function Page() { const requestCookie = cookies(); const returnUrlCookie = requestCookie.get(returnUrlCookieName); const redirectUrl = returnUrlCookie?.value || configuration.appUrl; diff --git a/auth/lib/zitadel.ts b/auth/lib/zitadel.ts index 7ee51af..55869c4 100644 --- a/auth/lib/zitadel.ts +++ b/auth/lib/zitadel.ts @@ -1,7 +1,5 @@ -export async function getWellKnown(issuer: string) { - const wellKnownResponse = await fetch( - new URL(`/.well-known/openid-configuration`, issuer).toString() - ); +export async function getWellKnown(wellKnownUrl: string) { + const wellKnownResponse = await fetch(wellKnownUrl); const wellKnown = (await wellKnownResponse.json()) as { issuer: string; diff --git a/auth/options.ts b/auth/options.ts index ddbe1ed..eaa24bc 100644 --- a/auth/options.ts +++ b/auth/options.ts @@ -5,6 +5,7 @@ type AuthOptions = { id: string; wellKnown: string; clientId: string; + redirectUrl: string; }[]; }; @@ -14,11 +15,13 @@ export const authOptions: AuthOptions = { id: "portal", wellKnown: `${configuration.portal.issuer}/.well-known/openid-configuration`, clientId: configuration.portal.clientId, + redirectUrl: configuration.portal.redirectUrl, }, { id: "zitadel", wellKnown: `${configuration.zitadel.issuer}/.well-known/openid-configuration`, clientId: configuration.zitadel.clientId, + redirectUrl: configuration.zitadel.redirectUrl, }, ], }; diff --git a/auth/prisma/dev.db b/auth/prisma/dev.db index 0712857..5a6f7e1 100644 Binary files a/auth/prisma/dev.db and b/auth/prisma/dev.db differ