Add Authentik OIDC login as an additional sign-in option
Local auth stays the primary/always-available login (don't want to lock out the saved admin password) — OIDC is additive, shown as a second button when OIDC_ENABLED=true. Uses openid-client v6 with PKCE. Authentik-side provider was set up via an authentik blueprint (its own declarative automation, see docs/oidc-setup.md) rather than touching any existing admin credentials. Closes #12. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import type { FastifyInstance } from "fastify";
|
||||
import type * as client from "openid-client";
|
||||
import { buildLoginRedirect, handleCallback } from "../auth/oidc.js";
|
||||
|
||||
declare module "@fastify/session" {
|
||||
interface FastifySessionObject {
|
||||
oidcState?: string;
|
||||
oidcCodeVerifier?: string;
|
||||
}
|
||||
}
|
||||
|
||||
export function registerOidcRoutes(
|
||||
app: FastifyInstance,
|
||||
oidcConfig: client.Configuration,
|
||||
redirectUri: string
|
||||
): void {
|
||||
app.get("/api/auth/oidc/login", async (req, reply) => {
|
||||
const { url, state, codeVerifier } = await buildLoginRedirect(oidcConfig, redirectUri);
|
||||
req.session.oidcState = state;
|
||||
req.session.oidcCodeVerifier = codeVerifier;
|
||||
return reply.redirect(url);
|
||||
});
|
||||
|
||||
app.get("/api/auth/oidc/callback", async (req, reply) => {
|
||||
const { oidcState, oidcCodeVerifier } = req.session;
|
||||
if (!oidcState || !oidcCodeVerifier) {
|
||||
return reply.code(400).send({ error: "no OIDC login in progress" });
|
||||
}
|
||||
try {
|
||||
const currentUrl = new URL(req.url, `http://${req.headers.host}`);
|
||||
const { username } = await handleCallback(oidcConfig, currentUrl, oidcState, oidcCodeVerifier);
|
||||
req.session.username = username;
|
||||
req.session.oidcState = undefined;
|
||||
req.session.oidcCodeVerifier = undefined;
|
||||
return reply.redirect("/");
|
||||
} catch (err) {
|
||||
req.log.error({ err }, "OIDC callback failed");
|
||||
return reply.code(401).send({ error: "OIDC login failed" });
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user