Moved password checking to dedicated function

This commit is contained in:
Tim Howitz 2025-06-03 15:20:52 +01:00
parent 1c08f0364c
commit b0f519d058
3 changed files with 81 additions and 89 deletions

View File

@ -1,14 +1,11 @@
import bcryptjs from "bcryptjs"; import bcryptjs from "bcryptjs";
import { validatePassword } from "@utils/validation";
import { SignJWT } from "jose"; import { SignJWT } from "jose";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { env } from "@utils/env"; import { env } from "@utils/env";
import { prisma } from "@utils/prisma"; import { prisma } from "@utils/prisma";
import { passwordStrengthCheck } from "@utils/validation";
// todo check email doesn't already exist
export async function POST(req: Request) { export async function POST(req: Request) {
try { try {
const { email, password, name } = await req.json(); const { email, password, name } = await req.json();
@ -23,23 +20,11 @@ export async function POST(req: Request) {
return NextResponse.json({ message: "Sorry, this email is already in use" }, { status: 409 }); return NextResponse.json({ message: "Sorry, this email is already in use" }, { status: 409 });
} }
const passwordCheckResult = await passwordStrengthCheck(password); const passwordCheckResult = validatePassword(password);
if ("message" in passwordCheckResult) {
return NextResponse.json({ message: passwordCheckResult.message }, { status: passwordCheckResult.status });
}
if (passwordCheckResult === "short") {
return NextResponse.json({ message: "Your password is shorter than 8 characters" }, { status: 400 });
} else if (passwordCheckResult === "long") {
return NextResponse.json({ message: "Your password is longer than 16 characters" }, { status: 400 });
} else if (passwordCheckResult === "no lower") {
return NextResponse.json({ message: "Your password must contain a lowercase letters" }, { status: 400 });
} else if (passwordCheckResult === "no upper") {
return NextResponse.json({ message: "Your password must contain a uppercase letters" }, { status: 400 });
} else if (passwordCheckResult === "no digit") {
return NextResponse.json({ message: "Your password must contain a number" }, { status: 400 });
} else if (passwordCheckResult === "no special") {
return NextResponse.json({ message: "Your password must contain a special character (!@#$%^&*)" }, { status: 400 });
} else if (passwordCheckResult === "end of function") {
return NextResponse.json({ message: "Password check script failure" }, { status: 500 });
} else {
try { try {
const newUser = await prisma.user.create({ const newUser = await prisma.user.create({
data: { data: {
@ -97,7 +82,6 @@ export async function POST(req: Request) {
console.error("Error creating user:", error); console.error("Error creating user:", error);
return NextResponse.json({ message: "Internal Server Error" }, { status: 500 }); return NextResponse.json({ message: "Internal Server Error" }, { status: 500 });
} }
}
} catch (error) { } catch (error) {
console.error("Error in signup endpoint:", error); console.error("Error in signup endpoint:", error);
return NextResponse.json({ message: "Internal Server Error" }, { status: 500 }); return NextResponse.json({ message: "Internal Server Error" }, { status: 500 });

View File

@ -5,7 +5,7 @@ import { env } from "@utils/env";
import { prisma } from "@utils/prisma"; import { prisma } from "@utils/prisma";
import { apiAuthMiddleware } from "@utils/apiAuthMiddleware"; import { apiAuthMiddleware } from "@utils/apiAuthMiddleware";
import { passwordStrengthCheck } from "@utils/validation"; import { validatePassword } from "@utils/validation";
export async function POST(req: Request) { export async function POST(req: Request) {
try { try {
@ -34,25 +34,12 @@ export async function POST(req: Request) {
} }
} }
// todo move to dedicated function
// Validate password strength if provided // Validate password strength if provided
let passwordHash = user.passwordHash; let passwordHash = user.passwordHash;
if (password) { if (password) {
const passwordCheckResult = await passwordStrengthCheck(password); const passwordCheckResult = validatePassword(password);
if (passwordCheckResult === "short") { if ("message" in passwordCheckResult) {
return NextResponse.json({ message: "Password is shorter than 8 characters" }, { status: 400 }); return NextResponse.json({ message: passwordCheckResult.message }, { status: passwordCheckResult.status });
} else if (passwordCheckResult === "long") {
return NextResponse.json({ message: "Password is longer than 16 characters" }, { status: 400 });
} else if (passwordCheckResult === "no lower") {
return NextResponse.json({ message: "Password must contain lowercase letters" }, { status: 400 });
} else if (passwordCheckResult === "no upper") {
return NextResponse.json({ message: "Password must contain uppercase letters" }, { status: 400 });
} else if (passwordCheckResult === "no digit") {
return NextResponse.json({ message: "Password must contain a number" }, { status: 400 });
} else if (passwordCheckResult === "no special") {
return NextResponse.json({ message: "Password must contain a special character (!@#$%^&*)" }, { status: 400 });
} else if (passwordCheckResult === "end of function") {
return NextResponse.json({ message: "Password check script failure" }, { status: 500 });
} }
passwordHash = await bcryptjs.hash(password, 10); passwordHash = await bcryptjs.hash(password, 10);
} }

View File

@ -1,4 +1,4 @@
export async function passwordStrengthCheck(password: string): Promise<string> { export function passwordStrengthCheck(password: string): string {
if (password.length < 8) { if (password.length < 8) {
return "short"; return "short";
} else if (password.length > 16) { } else if (password.length > 16) {
@ -21,3 +21,24 @@ export async function passwordStrengthCheck(password: string): Promise<string> {
} }
return "end of function"; return "end of function";
} }
export function validatePassword(password: string) {
const result = passwordStrengthCheck(password);
switch (result) {
case "short":
return { message: "Password is shorter than 8 characters", status: 400 };
case "long":
return { message: "Password is longer than 16 characters", status: 400 };
case "no lower":
return { message: "Password must contain lowercase letters", status: 400 };
case "no upper":
return { message: "Password must contain uppercase letters", status: 400 };
case "no digit":
return { message: "Password must contain a number", status: 400 };
case "no special":
return { message: "Password must contain a special character (!@#$%^&*)", status: 400 };
default:
return {};
}
}