Authentication and authorization

This commit is contained in:
Andrew Trieu
2023-07-07 19:33:54 +03:00
committed by Andrew Trieu
parent 8dd54efa6d
commit ab526cca2a
5 changed files with 159 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import User from "../models/User.js";
/**
* Register a user
*/
export const register = async (req, res) => {
try {
const {
firstName,
lastName,
email,
password,
profilePicturePath,
friends,
location,
description,
} = req.body;
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(password, salt);
const newUser = new User({
firstName,
lastName,
email,
password: hashedPassword,
profilePicturePath,
friends,
location,
description,
admin: false,
});
const savedUser = await newUser.save();
res.status(201).json(savedUser);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
/**
* Delete a user
*/
export const deleteUser = async (req, res) => {
try {
const user = await User.findById(req.params.id);
try {
await user.delete();
res.status(200).json({ msg: "User has been deleted" });
} catch (error) {
res.status;
}
} catch (error) {
res.status(500).json({ error: error.message });
}
};
/**
* Login a user
*/
export const login = async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) return res.status(404).json({ msg: "User not found" });
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) return res.status(400).json({ msg: "Wrong password" });
const accessToken = jwt.sign(
{ id: user._id, admin: user.admin },
process.env.JWT_SECRET
);
delete user.password;
res.status(200).json({ accessToken, user });
} catch (error) {
res.status(500).json({ error: error.message });
}
};

View File

@@ -8,6 +8,9 @@ import helmet from "helmet";
import morgan from "morgan";
import path from "path";
import { fileURLToPath } from "url";
import authRoutes from "./routes/auth.js";
/* Controllers */
import { register } from "./controllers/auth.js";
/**
* Config
@@ -38,6 +41,11 @@ const storage = multer.diskStorage({
});
const upload = multer({ storage });
/**
* Routes
* */
app.post("/auth/register", upload.single("profilePicture"), register);
/**
* Database
* */

15
server/middleware/auth.js Normal file
View File

@@ -0,0 +1,15 @@
import jwt from "jsonwebtoken";
export const verifyToken = (req, res, next) => {
try {
let token = req.header("Authorization");
if (!token) return res.status(403).json({ error: "Unauthorized" });
token = token.split(" ")[1];
const verifiedToken = jwt.verify(token, process.env.JWT_SECRET);
req.user = verifiedToken;
next();
} catch (error) {
res.status(500).json({ error: error.message });
}
};

45
server/models/User.js Normal file
View File

@@ -0,0 +1,45 @@
import mongoose from "mongoose";
const userSchema = mongoose.Schema(
{
firstName: {
type: String,
required: [true, "First name is required"],
min: 3,
max: 20,
},
lastName: {
type: String,
required: [true, "Last name is required"],
min: 3,
max: 20,
},
email: {
type: String,
required: [true, "Email is required"],
max: 50,
unique: true,
},
password: {
type: String,
required: [true, "Password is required"],
min: 6,
},
profilePicturePath: {
type: String,
default: "",
},
friends: {
type: Array,
default: [],
},
location: String,
description: String,
admin: Boolean,
},
{ timestamps: true }
);
const User = mongoose.model("User", userSchema);
export default User;

8
server/routes/auth.js Normal file
View File

@@ -0,0 +1,8 @@
import express from "express";
import { login } from "../controllers/auth.js";
const router = express.Router();
router.post("/login", login);
export default router;