Security: force first-login password change, gate admin tools, validate restore
Fixes from the code review: - #1 Wire mustChangePassword: dashboard layout redirects to a new /change-password page + /api/account/change-password (verifies current pw, re-hashes, clears the flag, refreshes the session). Provisioned admins can no longer keep the default. - #2 Assert NEXTAUTH_SECRET in production (not during build); set it on authOptions. - #3 Backup page now server-gated to admins (split into server page + client panel), matching the Updates page. - #4 Restore validates input: strict zod schema for the users table (known fields, role enum) + array checks for the rest; returns generic errors instead of String(err). No version bump/changelog — left for you to fold into the next release (you're editing those live). Not pushed, not deployed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,7 +29,22 @@ declare module "next-auth/jwt" {
|
||||
}
|
||||
}
|
||||
|
||||
// Fail loudly in production if the JWT secret is missing or left at the
|
||||
// placeholder — otherwise sessions are forgeable. Skipped during `next build`
|
||||
// (no runtime env) and in development.
|
||||
const NEXTAUTH_SECRET = process.env.NEXTAUTH_SECRET;
|
||||
if (
|
||||
process.env.NODE_ENV === "production" &&
|
||||
process.env.NEXT_PHASE !== "phase-production-build" &&
|
||||
(!NEXTAUTH_SECRET || NEXTAUTH_SECRET.length < 16 || NEXTAUTH_SECRET.includes("change-me"))
|
||||
) {
|
||||
throw new Error(
|
||||
"NEXTAUTH_SECRET is missing or insecure — generate one with `openssl rand -base64 32` and set it in the environment."
|
||||
);
|
||||
}
|
||||
|
||||
export const authOptions: NextAuthOptions = {
|
||||
secret: NEXTAUTH_SECRET,
|
||||
session: { strategy: "jwt" },
|
||||
pages: { signIn: "/login", error: "/login" },
|
||||
providers: [
|
||||
|
||||
Reference in New Issue
Block a user