feat: Security CSRF Fix, Logout optimierung, Footer Anpassung, Rechtstexteanpassung
Docker Image bauen und veroeffentlichen / build-and-push (push) Failing after 1m33s

This commit is contained in:
Nick Szaunig committed 2026-09-03 13:51:50 +02:00
1 parent 0753a3bc8a
commit 4d3100e9ba
28 files changed
+802 -121

No files matched your search

+41
View File
@@ -174,3 +174,44 @@ export async function verifyTwoFactorBackupCodesDisplay(token: string): Promise<
return null;
}
}
// --- Entra-ID-SSO ("Mit Microsoft anmelden"): kurzlebiger Zwischenschritt
// zwischen Redirect zu Microsoft und Rueckkehr am Callback. Haelt den
// PKCE-code_verifier (darf nie an den Client/die URL, sonst waere PKCE
// wirkungslos) und einen zufaelligen state-Wert zur CSRF-Absicherung —
// genau wie beim 2FA-Challenge-Cookie oben ein eigener, separat benannter
// Token-Typ, nicht wiederverwendbar fuer irgendeinen anderen Zweck. ---
export const ENTRA_OAUTH_COOKIE = "wabenhain_entra_oauth";
const ENTRA_OAUTH_TTL_SECONDS = 10 * 60; // 10 Minuten, Microsoft-Login + Redirect zurueck muss darin passen
interface EntraOAuthStatePayload {
state: string;
codeVerifier: string;
}
export async function signEntraOAuthState(state: string, codeVerifier: string): Promise<string> {
return new SignJWT({ type: "entra-oauth-state", state, codeVerifier })
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
.setIssuer(JWT_ISSUER)
.setAudience(JWT_AUDIENCE)
.setIssuedAt()
.setExpirationTime(`${ENTRA_OAUTH_TTL_SECONDS}s`)
.sign(getSecretKey());
}
export async function verifyEntraOAuthState(token: string): Promise<EntraOAuthStatePayload | null> {
try {
const { payload } = await jwtVerify(token, getSecretKey(), {
issuer: JWT_ISSUER,
audience: JWT_AUDIENCE,
algorithms: ["HS256"],
});
if (payload.type !== "entra-oauth-state" || typeof payload.state !== "string" || typeof payload.codeVerifier !== "string") {
return null;
}
return { state: payload.state, codeVerifier: payload.codeVerifier };
} catch {
return null;
}
}