Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 20 additions & 72 deletions app/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,28 @@
import User from "../models/userModel.js";
import md5 from "md5";
import jwt from "jsonwebtoken";
import bcrypt from "bcrypt";

const generateTokenAndPersonalKey = async (user) => {
try {
const payload = {
id: user._id,
username: user.username
};
const salt = await bcrypt.genSalt(6);
const secretKey = process.env.JWT_SECRET + salt;
const token = jwt.sign(payload, secretKey, { expiresIn: process.env.TOKEN_LIFE });
return {token: token, personalKey: salt}; //return token and "salt" to use as user personalkey
} catch (error) {
throw new Error('Token generation failed');
}
};
import generateTokenAndPersonalKey from "../middleware/generateToken.js";
import { sendResponse } from '../utils/response.js';

export const registerController = async (req, res) => {
req.body.password = md5(req.body.password);

const newUser = new User({
username: req.body.username,
password: req.body.password
password: req.body.password,
role: req.body.role
});

try {
const foundUser = await User.findOne({ username: req.body.username, password: req.body.password });
if (foundUser) {
return res.status(400).json({ message: 'Email already exists' });
return sendResponse(res, 409, "Conflict", "Email already exists" );
}
const newTokenAndKey = await generateTokenAndPersonalKey(newUser);
const token = newTokenAndKey.token;
const personalKey = newTokenAndKey.personalKey;
newUser.personalKey = personalKey;
await newUser.save();
res.status(200).json({ token });
} catch (error) {
console.error(error);
res.status(400).json({ error: error.message });
//verificação de email
let savedUser = await newUser.save();
delete savedUser.password;
return sendResponse(res, 200, savedUser, "User registered successfully" );
} catch (err) {
return sendResponse(res, 400, err.name, err.message );
}
};

Expand All @@ -49,17 +32,16 @@ export const loginController = async (req, res) => {
try {
const user = await User.findOne({ username: req.body.username, password: req.body.password });
if (!user) {
return res.status(401).json({ error: "Invalid username or password" });
return sendResponse(res, 401, "Forbidden", "Invalid username or password" );
}
const newTokenAndKey = await generateTokenAndPersonalKey(user);
const token = newTokenAndKey.token;
const personalKey = newTokenAndKey.personalKey;
user.personalKey = personalKey;
await user.save();
res.status(200).json({ token });
} catch (error) {
console.error(error);
res.status(400).json({ error: error.message });
return sendResponse(res, 200, token, "User logged successfully");
} catch (err) {
return sendResponse(res, 400, err.name, err.message);
}
};

Expand All @@ -69,48 +51,14 @@ export const logoutController = async (req, res) => {
try {
const user = await User.findOne({ username: req.body.username, password: req.body.password });
if (!user) {
return res.status(401).json({ error: "Invalid username or password" });
return sendResponse(res, 401, "Forbidden", "Invalid username or password");
}
//setting personalKey to default value, to invalidate the token
user.personalKey = "-";
await user.save();
res.status(200).json({ message: 'You have been logged out successfully' })
}
catch (error) {
console.error(error);
res.status(400).json({ error: error.message });
}
};

export const authenticateToken = async (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: "Authentication token is required" });
return sendResponse(res, 200, null, "You have been logged out successfully");
}

try {
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
return res.status(403).json({ error: "Redirect to login" });
}

const user = await User.findById(decodedToken.payload.id);
if (!user) {
return res.status(401).json({ error: "User not found" });
}

const secretKey = process.env.JWT_SECRET + user.personalKey;
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
return res.status(403).json({ error: "Redirect to login" });
}
req.user = decoded;
next();
});
} catch (error) {
console.error(error);
return res.status(403).json({ error: "Redirect to login" });
catch (err) {
return sendResponse(res, 400, err.name, err.message);
}
};


};
36 changes: 36 additions & 0 deletions app/middleware/authenticate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import jwt from "jsonwebtoken";
import User from "../models/userModel.js"
import { sendResponse } from '../utils/response.js';

const authenticateToken = async (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return sendResponse(res, 401, null, "Authentication token is required" );
}

try {
const redirectLogin = "Redirect to login";
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
return sendResponse(res, 403, "Error to decod", redirectLogin);
}

const user = await User.findById(decodedToken.payload.id);
if (!user) {
return sendResponse(res, 401, "User not found", redirectLogin);
}

const secretKey = process.env.JWT_SECRET + user.personalKey;
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
return sendResponse(res, 403, err.name, err.message);
}
req.user = decoded;
next();
});
} catch (err) {
return sendResponse(res, 403, err.name, err.message);
}
};

export default authenticateToken;
16 changes: 16 additions & 0 deletions app/middleware/generateToken.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";

const generateTokenAndPersonalKey = async (user) => {
const payload = {
id: user._id,
username: user.username,
role: user.role
};
const salt = await bcrypt.genSalt(6);
const secretKey = process.env.JWT_SECRET + salt;
const token = jwt.sign(payload, secretKey, { expiresIn: process.env.TOKEN_LIFE });
return {token: token, personalKey: salt};
};

export default generateTokenAndPersonalKey;
17 changes: 8 additions & 9 deletions app/models/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@ const userSchema = new Schema({
type: String,
required: true
},
fullName: {
type: String,
default: ''
role: {
type: Number,
retuired: true
},
contact: {
type: String,
default: ''
},
personalKey: {
type: String,
required: true,
unique: true,
default: '-',
},
isActive: {
type: Boolean,
default: false
},
});

const User = model('user', userSchema);

export default User;
export default User;
6 changes: 3 additions & 3 deletions routes.js → app/routes/routes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import express from "express";
import * as authController from "./app/controllers/authController.js";
import * as userController from "./app/controllers/userController.js";
import {authenticateToken} from "./app/controllers/authController.js";
import * as authController from "../controllers/authController.js";
import * as userController from "../controllers/userController.js";
import authenticateToken from "../middleware/authenticate.js";

const router = express.Router();

Expand Down
3 changes: 3 additions & 0 deletions app/utils/response.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function sendResponse(res, statusCode, data, message) {
return res.status(statusCode).json({ statusCode, data, message });
}
4 changes: 2 additions & 2 deletions server.js → config/server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express from "express";
import routes from "./routes.js";
import { connectToDatabase } from './config/db.js';
import routes from "../app/routes/routes.js";
import { connectToDatabase } from './db.js';
import dotenv from 'dotenv';

dotenv.config();
Expand Down
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { startServer } from './server.js';
import { startServer } from './config/server.js';

startServer();