This commit is contained in:
2026-02-18 22:47:44 +01:00
parent 0d084cd546
commit f218552d48
2 changed files with 23 additions and 9 deletions

View File

@@ -37,15 +37,20 @@ export function getOIDCClient(): Client {
export interface AuthSession {
codeVerifier: string;
state: string;
nonce: string;
nonce: string | undefined;
redirectUri?: string;
}
export function createAuthSession(redirectUri?: string): AuthSession {
const isNative = !!redirectUri;
return {
codeVerifier: generators.codeVerifier(),
state: generators.state(),
nonce: generators.nonce(),
// Nonce is omitted for native/PKCE-only flows. PKCE itself binds the code
// exchange so nonce provides no additional security. Some providers also
// don't echo the nonce back in the ID token for public clients, which
// causes openid-client to throw a nonce mismatch error.
nonce: isNative ? undefined : generators.nonce(),
redirectUri,
};
}
@@ -57,11 +62,14 @@ export function getAuthorizationUrl(session: AuthSession, redirectUri?: string):
const params: Record<string, string> = {
scope: 'openid profile email',
state: session.state,
nonce: session.nonce,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
};
if (session.nonce) {
params.nonce = session.nonce;
}
if (redirectUri) {
params.redirect_uri = redirectUri;
}
@@ -77,14 +85,19 @@ export async function handleCallback(
const redirectUri = session.redirectUri || config.oidc.redirectUri;
const checks: Record<string, string | undefined> = {
code_verifier: session.codeVerifier,
state: session.state,
};
if (session.nonce) {
checks.nonce = session.nonce;
}
const tokenSet = await client.callback(
redirectUri,
params,
{
code_verifier: session.codeVerifier,
state: session.state,
nonce: session.nonce,
}
checks,
);
return tokenSet;

View File

@@ -158,8 +158,9 @@ router.post("/token", async (req, res) => {
user,
});
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
console.error("Token exchange error:", error);
res.status(500).json({ error: "Failed to exchange token" });
res.status(500).json({ error: `Failed to exchange token: ${message}` });
}
});