Authentication and authorization
This commit is contained in:
committed by
Andrew Trieu
parent
8dd54efa6d
commit
ab526cca2a
83
server/controllers/auth.js
Normal file
83
server/controllers/auth.js
Normal 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 });
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -8,6 +8,9 @@ import helmet from "helmet";
|
|||||||
import morgan from "morgan";
|
import morgan from "morgan";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
|
import authRoutes from "./routes/auth.js";
|
||||||
|
/* Controllers */
|
||||||
|
import { register } from "./controllers/auth.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config
|
* Config
|
||||||
@@ -38,6 +41,11 @@ const storage = multer.diskStorage({
|
|||||||
});
|
});
|
||||||
const upload = multer({ storage });
|
const upload = multer({ storage });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes
|
||||||
|
* */
|
||||||
|
app.post("/auth/register", upload.single("profilePicture"), register);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
* */
|
* */
|
||||||
|
|||||||
15
server/middleware/auth.js
Normal file
15
server/middleware/auth.js
Normal 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
45
server/models/User.js
Normal 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
8
server/routes/auth.js
Normal 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;
|
||||||
Reference in New Issue
Block a user