fix(auth): JWT-Secret härten und Session-Laufzeit verkürzen

- Gemeinsames Secret-Modul (jwt-secret.ts): bricht in Produktion hart ab,
  wenn NEXTAUTH_SECRET fehlt oder <32 Zeichen – kein öffentlicher Fallback mehr
- auth.ts und middleware.ts nutzen dieselbe Secret-Quelle (kein Divergieren)
- Schwacher Compose-Fallback entfernt: Deployment ohne Secret bricht ab (:?)
- "Angemeldet bleiben" 30 → 14 Tage; Laufzeiten zentralisiert (SESSION_MAX_AGE_*)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pepe Ziberi
2026-07-18 20:11:56 +02:00
parent 08ecf4c61a
commit 93af663dd1
6 changed files with 47 additions and 17 deletions

View File

@@ -2,14 +2,7 @@ import { SignJWT, jwtVerify } from 'jose'
import { cookies } from 'next/headers'
import { prisma } from './db'
import bcrypt from 'bcryptjs'
const secretValue = process.env.NEXTAUTH_SECRET
if (!secretValue || secretValue.length < 32) {
console.warn('[AUTH] WARNING: NEXTAUTH_SECRET is missing or too short (<32 chars). Set a strong secret in production!')
}
const JWT_SECRET = new TextEncoder().encode(
secretValue || 'dev-only-fallback-do-not-use-in-production-' + Date.now()
)
import { JWT_SECRET } from './jwt-secret'
export interface UserPayload {
id: string
@@ -21,11 +14,17 @@ export interface UserPayload {
emailVerified?: boolean
}
// Zentrale Session-Laufzeiten (Sekunden) EINE Quelle für Token-Ablauf UND Cookie-maxAge,
// damit beide nie auseinanderdriften.
export const SESSION_MAX_AGE_SECONDS = 60 * 60 * 24 // 24 Stunden (Standard)
export const SESSION_MAX_AGE_REMEMBER_SECONDS = 60 * 60 * 24 * 14 // 14 Tage ("angemeldet bleiben")
export async function createToken(user: UserPayload, rememberMe = false): Promise<string> {
const maxAge = rememberMe ? SESSION_MAX_AGE_REMEMBER_SECONDS : SESSION_MAX_AGE_SECONDS
return await new SignJWT({ user })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime(rememberMe ? '30d' : '24h')
.setExpirationTime(`${maxAge}s`)
.sign(JWT_SECRET)
}