fix: added better UI form validation for password registration
This commit is contained in:
@@ -888,7 +888,11 @@ app.post(
|
|||||||
authRateLimit,
|
authRateLimit,
|
||||||
async (req, reply) => {
|
async (req, reply) => {
|
||||||
const parsed = RegisterBody.safeParse(req.body);
|
const parsed = RegisterBody.safeParse(req.body);
|
||||||
if (!parsed.success) return reply.code(400).send({ ok: false, message: "Invalid payload" });
|
if (!parsed.success) {
|
||||||
|
const firstIssue = parsed.error.issues[0];
|
||||||
|
const message = firstIssue?.message || "Invalid payload";
|
||||||
|
return reply.code(400).send({ ok: false, message });
|
||||||
|
}
|
||||||
const { email, password } = parsed.data;
|
const { email, password } = parsed.data;
|
||||||
const normalizedEmail = normalizeEmail(email);
|
const normalizedEmail = normalizeEmail(email);
|
||||||
const existing = await app.prisma.user.findUnique({
|
const existing = await app.prisma.user.findUnique({
|
||||||
|
|||||||
@@ -37,8 +37,13 @@ export default function RegisterPage() {
|
|||||||
const passwordError =
|
const passwordError =
|
||||||
(touched.password || submitted) && !password
|
(touched.password || submitted) && !password
|
||||||
? "Password is required."
|
? "Password is required."
|
||||||
: (touched.password || submitted) && password.length < 8
|
: (touched.password || submitted) &&
|
||||||
? "Password must be at least 8 characters."
|
(password.length < 12 ||
|
||||||
|
!/[a-z]/.test(password) ||
|
||||||
|
!/[A-Z]/.test(password) ||
|
||||||
|
!/\d/.test(password) ||
|
||||||
|
!/[^A-Za-z0-9]/.test(password))
|
||||||
|
? "Use 12+ chars with upper, lower, number, and symbol."
|
||||||
: "";
|
: "";
|
||||||
const confirmError =
|
const confirmError =
|
||||||
(touched.confirmPassword || submitted) && !confirmPassword
|
(touched.confirmPassword || submitted) && !confirmPassword
|
||||||
@@ -87,7 +92,7 @@ export default function RegisterPage() {
|
|||||||
status === 409
|
status === 409
|
||||||
? "That email is already registered. Try signing in."
|
? "That email is already registered. Try signing in."
|
||||||
: status === 400
|
: status === 400
|
||||||
? "Enter a valid email and password."
|
? (err instanceof Error ? err.message : "Enter a valid email and password.")
|
||||||
: err instanceof Error
|
: err instanceof Error
|
||||||
? err.message
|
? err.message
|
||||||
: "Unable to register. Try again.";
|
: "Unable to register. Try again.";
|
||||||
@@ -134,11 +139,16 @@ export default function RegisterPage() {
|
|||||||
onBlur={() => setTouched((prev) => ({ ...prev, password: true }))}
|
onBlur={() => setTouched((prev) => ({ ...prev, password: true }))}
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
required
|
required
|
||||||
minLength={8}
|
minLength={12}
|
||||||
/>
|
/>
|
||||||
{passwordError && (
|
{passwordError && (
|
||||||
<span className="text-xs text-red-400">{passwordError}</span>
|
<span className="text-xs text-red-400">{passwordError}</span>
|
||||||
)}
|
)}
|
||||||
|
{!passwordError && (
|
||||||
|
<span className="text-xs muted">
|
||||||
|
Must be 12+ chars and include uppercase, lowercase, number, and symbol.
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</label>
|
</label>
|
||||||
<label className="stack gap-1">
|
<label className="stack gap-1">
|
||||||
<span className="text-sm font-medium">Confirm password</span>
|
<span className="text-sm font-medium">Confirm password</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user