diff --git a/src/app/api/admin/users/[id]/route.ts b/src/app/api/admin/users/[id]/route.ts index 56c3710..6594617 100644 --- a/src/app/api/admin/users/[id]/route.ts +++ b/src/app/api/admin/users/[id]/route.ts @@ -3,6 +3,7 @@ import { pbAdmin } from "@/lib/pb"; import { authMode } from "@/lib/auth/session"; import { isRole } from "@/lib/auth/access"; import { parseUserAccess } from "@/lib/auth/user-input"; +import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH } from "@/lib/auth/session-policy"; export async function PATCH(request: Request, { params }: { params: Promise<{ id: string }> }): Promise { if (authMode() !== "users") return Response.json({ error: "Not found" }, { status: 404 }); @@ -36,8 +37,8 @@ export async function PATCH(request: Request, { params }: { params: Promise<{ id payload.must_change_password = body.must_change_password; } if (body.password !== undefined) { - if (typeof body.password !== "string" || body.password.length < 8 || body.password.length > 128) { - return Response.json({ error: "Password must have 8–128 characters" }, { status: 400 }); + if (typeof body.password !== "string" || body.password.length < PASSWORD_MIN_LENGTH || body.password.length > PASSWORD_MAX_LENGTH) { + return Response.json({ error: `Password must have ${PASSWORD_MIN_LENGTH}–${PASSWORD_MAX_LENGTH} characters` }, { status: 400 }); } payload.password = body.password; payload.passwordConfirm = body.password; diff --git a/src/app/api/auth/change-password/route.ts b/src/app/api/auth/change-password/route.ts index 8a5ceef..fe53f11 100644 --- a/src/app/api/auth/change-password/route.ts +++ b/src/app/api/auth/change-password/route.ts @@ -3,7 +3,7 @@ import PocketBase from "pocketbase"; import { initialDestination } from "@/lib/auth/access"; import { authMode, getCurrentUser, SESSION_COOKIE } from "@/lib/auth/session"; import { PB_URL, pbAdmin } from "@/lib/pb"; -import { SESSION_MAX_AGE_SECONDS } from "@/lib/auth/session-policy"; +import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, SESSION_MAX_AGE_SECONDS } from "@/lib/auth/session-policy"; export async function POST(request: Request): Promise { if (authMode() !== "users") return Response.json({ error: "Not found" }, { status: 404 }); @@ -16,8 +16,8 @@ export async function POST(request: Request): Promise { catch { return Response.json({ error: "Enter and confirm your new password" }, { status: 400 }); } const password = typeof body.password === "string" ? body.password : ""; const passwordConfirm = typeof body.passwordConfirm === "string" ? body.passwordConfirm : ""; - if (password.length < 10 || password.length > 128 || password !== passwordConfirm) { - return Response.json({ error: "Use at least 10 characters and confirm the same password" }, { status: 400 }); + if (password.length < PASSWORD_MIN_LENGTH || password.length > PASSWORD_MAX_LENGTH || password !== passwordConfirm) { + return Response.json({ error: `Use at least ${PASSWORD_MIN_LENGTH} characters and confirm the same password` }, { status: 400 }); } try { diff --git a/src/app/api/auth/set-password/route.ts b/src/app/api/auth/set-password/route.ts index 624efff..c022975 100644 --- a/src/app/api/auth/set-password/route.ts +++ b/src/app/api/auth/set-password/route.ts @@ -4,7 +4,7 @@ import { initialDestination, userFromRecord } from "@/lib/auth/access"; import { authMode, SESSION_COOKIE } from "@/lib/auth/session"; import { findValidLink, setPasswordAndBurnLink } from "@/lib/auth/password-links"; import { PB_URL, pbAdmin } from "@/lib/pb"; -import { SESSION_MAX_AGE_SECONDS } from "@/lib/auth/session-policy"; +import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, SESSION_MAX_AGE_SECONDS } from "@/lib/auth/session-policy"; export async function POST(request: Request): Promise { if (authMode() !== "users") return Response.json({ error: "Not found" }, { status: 404 }); @@ -15,8 +15,8 @@ export async function POST(request: Request): Promise { const token = typeof body.token === "string" ? body.token : ""; const password = typeof body.password === "string" ? body.password : ""; const passwordConfirm = typeof body.passwordConfirm === "string" ? body.passwordConfirm : ""; - if (password.length < 10 || password.length > 128 || password !== passwordConfirm) { - return Response.json({ error: "Use at least 10 characters and confirm the same password" }, { status: 400 }); + if (password.length < PASSWORD_MIN_LENGTH || password.length > PASSWORD_MAX_LENGTH || password !== passwordConfirm) { + return Response.json({ error: `Use at least ${PASSWORD_MIN_LENGTH} characters and confirm the same password` }, { status: 400 }); } const pb = await pbAdmin(); diff --git a/src/app/change-password/password-form.tsx b/src/app/change-password/password-form.tsx index 6f23d89..d861be8 100644 --- a/src/app/change-password/password-form.tsx +++ b/src/app/change-password/password-form.tsx @@ -3,6 +3,7 @@ import * as React from "react"; import { Logo } from "@/components/logo"; import { Button } from "@/components/ui/button"; +import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH } from "@/lib/auth/session-policy"; export function PasswordForm({ name }: { name: string }) { const [password, setPassword] = React.useState(""); @@ -39,16 +40,16 @@ export function PasswordForm({ name }: { name: string }) {

Welcome, {name}. Set a new password before continuing.

-

Use at least 10 characters. You will not be asked again after saving.

+

Use at least {PASSWORD_MIN_LENGTH} characters. You will not be asked again after saving.

{error &&

{error}

}