cleaned up errors

This commit is contained in:
Kai Ritthaler 2025-05-14 18:53:25 +02:00 committed by Rudi Regentonne
parent 01e703e538
commit dee6a19e51
3 changed files with 51 additions and 18 deletions

View file

@ -11,6 +11,7 @@ const prisma = new PrismaClient();
// load environment variables from .env file // load environment variables from .env file
dotenv.config(); dotenv.config();
const JWT_SECRET: string = process.env.TOKEN_SECRET!; // this secret is used to sign the JWT token const JWT_SECRET: string = process.env.TOKEN_SECRET!; // this secret is used to sign the JWT token
// Generate a JWT token with the username as payload and a secret from the environment variables which expires in 1800 seconds (30 minutes) // Generate a JWT token with the username as payload and a secret from the environment variables which expires in 1800 seconds (30 minutes)
function generateAccessToken(username: string, userId: string) { function generateAccessToken(username: string, userId: string) {
return jwt.sign( return jwt.sign(
@ -19,15 +20,11 @@ function generateAccessToken(username: string, userId: string) {
{ expiresIn: "1800s", issuer: "VogelApi" } { expiresIn: "1800s", issuer: "VogelApi" }
); //TODO: change role to user role ); //TODO: change role to user role
} }
// Endpoint to register a new user // Endpoint to register a new user
export const registerUser = async (req: Request, res: Response) => { export const registerUser = async (req: Request, res: Response) => {
const { username, password, email } = await req.body; //gets the data from the request body const { username, password, email } = await req.body; //gets the data from the request body
if (!username || !password || !email) {
// check if username, password and email are provided and
res
.status(400)
.json({ message: "Username, password and email are required" });
}
const existingUser = await prisma.user.findUnique({ const existingUser = await prisma.user.findUnique({
// check if the user already exists // check if the user already exists
where: { where: {
@ -36,12 +33,18 @@ export const registerUser = async (req: Request, res: Response) => {
}); });
if (existingUser) { if (existingUser) {
// if the user already exists, return an error message // if the user already exists, return an error message
res.status(400).json({ message: `User "${username}" already exists` }); res.status(400).json({
error: "Invalid data",
details: [{ message: `User "${username}" already exists` }],
});
} }
const hashedPassword = await bcrypt.hash(password, 10); // hash the password with bcrypt const hashedPassword = await bcrypt.hash(password, 10); // hash the password with bcrypt
if (!hashedPassword) { if (!hashedPassword) {
// check if the password was hashed successfully // check if the password was hashed successfully
res.status(500).json({ message: "Server Error" }); res.status(500).json({
error: "Invalid data",
details: [{ message: "Server Error" }],
});
} }
const userData = { const userData = {
// create a new user object with the data from the request body and the hashed password // create a new user object with the data from the request body and the hashed password
@ -52,20 +55,28 @@ export const registerUser = async (req: Request, res: Response) => {
const user = await prisma.user.create({ data: userData }); // create a new user in the database const user = await prisma.user.create({ data: userData }); // create a new user in the database
if (!user) { if (!user) {
// check if the user was created successfully // check if the user was created successfully
res.status(500).json({ message: "Server Error" }); res.status(500).json({
error: "Server error",
details: [{ message: "Server Error while creating user" }],
});
} }
res.json({ message: "User registered successfully" }); const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload
res.set("Authorization", `Bearer ${token}`); // set the token in the response header
res.status(201).json({ res.status(201).json({
message: "user created", message: "user created",
data: { username: username, email: email }, data: { username: username, email: email },
}); // return the user object with the username and email }); // return the user object with the username and email
}; };
// Endpoint to login a user (unfinished) // Endpoint to login a user (unfinished)
export const loginUser = async (req: Request, res: Response) => { export const loginUser = async (req: Request, res: Response) => {
const { username, password } = req.body; // get the data from the request body const { username, password } = req.body; // get the data from the request body
if (!username || !password) { if (!username || !password) {
// check if username and password are provided // check if username and password are provided
res.status(400).json({ message: "Username and password are required" }); res.status(400).json({
error: "Invalid data",
details: [{ message: "Username and password are required" }],
});
} }
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
// check if the user exists // check if the user exists
@ -81,17 +92,24 @@ export const loginUser = async (req: Request, res: Response) => {
const isPasswordValid = await bcrypt.compare(password, user.password); // compare the password with the hashed password in the database const isPasswordValid = await bcrypt.compare(password, user.password); // compare the password with the hashed password in the database
if (!isPasswordValid) { if (!isPasswordValid) {
// if the password is not valid, return an error message // if the password is not valid, return an error message
res.status(401).json({ message: "Invalid password" }); res.status(401).json({
error: "invalid credentials",
details: [{ message: "Invalid password" }],
});
} }
const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload const token: string = generateAccessToken(user.username, user.id); // generate a JWT token with the username and userId as payload
res.set("Authorization", `Bearer ${token}`); // set the token in the response header res.set("Authorization", `Bearer ${token}`); // set the token in the response header
res.json({ message: "User logged in successfully" }); res.json({ message: "User logged in successfully" });
}; };
// Endpoint to get user data // Endpoint to get user data
export const getUser = async (req: Request, res: Response) => { export const getUser = async (req: Request, res: Response) => {
const username: string = req.query.username as string; const username: string = req.query.username as string;
if (!username) { if (!username) {
res.status(400).json({ message: "Username is required" }); res.status(400).json({
error: "no username",
details: [{ message: "Username is required" }],
});
} }
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
@ -99,7 +117,10 @@ export const getUser = async (req: Request, res: Response) => {
}, },
}); });
if (!user) { if (!user) {
res.status(404).json({ message: `User "${username}" not found` }); res.status(404).json({
error: "user not found",
details: [{ message: `User "${username}" not found` }],
});
return; return;
} }
res.json({ res.json({

View file

@ -36,8 +36,20 @@ export function authenticateToken() {
if (err) { if (err) {
if (err instanceof TokenExpiredError) if (err instanceof TokenExpiredError)
// check if the error is expired and return 401 // check if the error is expired and return 401
res.status(401).json({ message: "Token expired" }); res
else res.status(403).json({ message: "Invalid token" }); .status(401)
.json({
error: "Token expired",
details: [{ message: "Token expired" }],
});
// if the token is invalid, return 403 Forbidden
else
res
.status(403)
.json({
error: "Invalid token",
details: [{ message: "Invalid token" }],
});
} }
next(); next();
}); });

View file

@ -3,8 +3,8 @@ import { z } from "zod";
export const userRegistrationSchema = z.object({ export const userRegistrationSchema = z.object({
username: z.string().regex(/^\S*$/, "Username must not contain spaces"), // No whitespaces allowed, username: z.string().regex(/^\S*$/, "Username must not contain spaces"), // No whitespaces allowed,
email: z.string().email(), email: z.string().email("Invalid email address"),
password: z.string().min(8), password: z.string().min(8, "Password must be at least 8 characters long"),
}); });
export const userLoginSchema = z.object({ export const userLoginSchema = z.object({