Added update-user route and made a few small other changes
This commit is contained in:
parent
9c1c696352
commit
4c4e48fcd4
@ -5,17 +5,10 @@ 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 { findUserByEmail, readUserCsv, User } from "../functions/csvReadWrite";
|
|
||||||
|
|
||||||
export async function POST(req: Request) {
|
export async function POST(req: Request) {
|
||||||
try {
|
try {
|
||||||
const { email, password } = await req.json(); // Parse incoming JSON data
|
const { email, password } = await req.json(); // Parse incoming JSON data
|
||||||
|
|
||||||
const userData = await readUserCsv();
|
|
||||||
console.log(userData);
|
|
||||||
console.log("Email:", email); // ! remove
|
|
||||||
console.log("Password:", password); // ! remove
|
|
||||||
|
|
||||||
let user = await prisma.user.findUnique({
|
let user = await prisma.user.findUnique({
|
||||||
where: {
|
where: {
|
||||||
email, // use the email to uniquely identify the user
|
email, // use the email to uniquely identify the user
|
||||||
|
|||||||
@ -7,6 +7,8 @@ import { prisma } from "@utils/prisma";
|
|||||||
|
|
||||||
import { passwordStrengthCheck } from "@utils/validation";
|
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();
|
||||||
|
|||||||
97
src/app/api/update-user/route.ts
Normal file
97
src/app/api/update-user/route.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
import bcryptjs from "bcryptjs";
|
||||||
|
|
||||||
|
import { env } from "@utils/env";
|
||||||
|
import { prisma } from "@utils/prisma";
|
||||||
|
import { apiAuthMiddleware } from "@utils/apiAuthMiddleware";
|
||||||
|
|
||||||
|
import { passwordStrengthCheck } from "@utils/validation";
|
||||||
|
|
||||||
|
export async function POST(req: Request) {
|
||||||
|
try {
|
||||||
|
const authResult = await apiAuthMiddleware();
|
||||||
|
if ("user" in authResult === false) return authResult;
|
||||||
|
|
||||||
|
const { user } = authResult;
|
||||||
|
const { email, name, password } = await req.json();
|
||||||
|
|
||||||
|
// Check if email is already in use by another user
|
||||||
|
if (email && email !== user.email) {
|
||||||
|
const foundUser = await prisma.user.findUnique({
|
||||||
|
where: { email },
|
||||||
|
});
|
||||||
|
if (foundUser) {
|
||||||
|
return NextResponse.json({ message: "This email is already in use" }, { status: 409 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate password strength if provided
|
||||||
|
let passwordHash = user.passwordHash;
|
||||||
|
if (password) {
|
||||||
|
const passwordCheckResult = await passwordStrengthCheck(password);
|
||||||
|
if (passwordCheckResult === "short") {
|
||||||
|
return NextResponse.json({ message: "Password is shorter than 8 characters" }, { status: 400 });
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update user in database
|
||||||
|
const updatedUser = await prisma.user.update({
|
||||||
|
where: { id: user.id },
|
||||||
|
data: {
|
||||||
|
name: name || user.name,
|
||||||
|
email: email || user.email,
|
||||||
|
passwordHash,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Link orders with matching email to the updated user
|
||||||
|
if (email && email !== user.email) {
|
||||||
|
await prisma.order.updateMany({
|
||||||
|
where: {
|
||||||
|
email,
|
||||||
|
userId: null,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
userId: updatedUser.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullUser = await prisma.user.findUnique({
|
||||||
|
where: { id: updatedUser.id },
|
||||||
|
include: {
|
||||||
|
earthquakes: true,
|
||||||
|
observatories: true,
|
||||||
|
artefacts: true,
|
||||||
|
purchasedOrders: true,
|
||||||
|
requests: true,
|
||||||
|
scientist: {
|
||||||
|
include: {
|
||||||
|
superior: true,
|
||||||
|
subordinates: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { passwordHash: _, ...userSansHash } = fullUser!;
|
||||||
|
|
||||||
|
return NextResponse.json({ message: "User updated successfully", user: userSansHash }, { status: 200 });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in update-user endpoint:", error);
|
||||||
|
return NextResponse.json({ message: "Internal Server Error" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,8 +34,6 @@ const store = createStore<StoreModel>({
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// todo fix user persisting on reload
|
|
||||||
|
|
||||||
function UserFetcher() {
|
function UserFetcher() {
|
||||||
const setUser = useStoreActions((actions) => actions.setUser);
|
const setUser = useStoreActions((actions) => actions.setUser);
|
||||||
const { data, error } = useSWR("/api/user", fetcher);
|
const { data, error } = useSWR("/api/user", fetcher);
|
||||||
|
|||||||
@ -23,13 +23,13 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
|
|||||||
|
|
||||||
if (!isOpen) return null; // if is open is false, the model isnt shown
|
if (!isOpen) return null; // if is open is false, the model isnt shown
|
||||||
|
|
||||||
const handleOverlayClick = (e: MouseEvent<HTMLDivElement>) => {
|
function handleOverlayClick(e: MouseEvent<HTMLDivElement>) {
|
||||||
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
|
if (modalRef.current && !modalRef.current.contains(e.target as Node)) {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
async function handleSubmit(e: FormEvent<HTMLFormElement>) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsFailed(false);
|
setIsFailed(false);
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
|
|||||||
setIsFailed(true);
|
setIsFailed(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50" onClick={handleOverlayClick}>
|
<div className="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50" onClick={handleOverlayClick}>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user