Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.2.2: nodeenv configs, member access, role and email verifications and new roles. (Dev to Main) #27

Merged
merged 31 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3a72563
fix: verify if user email already exists
Anaritamed Aug 8, 2023
b4896f2
fix: throw the error correctly
Anaritamed Aug 15, 2023
0ed3955
Refactor: Add new fields from user to member
FLuiz22 Aug 15, 2023
e3da26a
Refactor: Add bcrypt to password field
FLuiz22 Aug 15, 2023
8997267
fix: node_env setting solved
FLuiz22 Aug 17, 2023
d51dafa
Merge pull request #9 from codexjr-dev/iss#6
ManoMax Aug 17, 2023
65c8077
Merge pull request #16 from codexjr-dev/iss#15
ManoMax Aug 17, 2023
a0dd50f
feat: Transfer authentication from User to Member
matheusvictoor Aug 22, 2023
024f588
fix: Update route from authentication to Member
matheusvictoor Aug 22, 2023
5804f83
Refactor: Entry date of member requirement turned to false
FLuiz22 Aug 24, 2023
eda9db9
Refactor: EjService changed to use Member schema instead of User schema
FLuiz22 Aug 24, 2023
8e0f5c7
Refactor: presidente changed to Presidente
FLuiz22 Aug 24, 2023
20c58b4
feat: add bcrypt library for password hashing
matheusvictoor Aug 24, 2023
206c046
Feat: encryption for password when member data update added
FLuiz22 Aug 24, 2023
1a4d71a
Merge pull request #22 from codexjr-dev/iss#21
ManoMax Aug 24, 2023
77d2430
Refactor: user changed to member
FLuiz22 Aug 25, 2023
19fcfde
Refactor: autorizePresident edited to autorizeLeadership
FLuiz22 Aug 25, 2023
9fa9fc3
Refactor: autorizeUser changed to autorizeLeadership
FLuiz22 Aug 25, 2023
0fd6802
refactor: new roles added on user model
Anaritamed Aug 26, 2023
160899c
fix: verify if user email already exists
Anaritamed Aug 26, 2023
3bc3f24
refactor: undo changes on userService
Anaritamed Aug 26, 2023
555cd79
fix: verify if user email already exists
Anaritamed Aug 26, 2023
32e4248
refactor: DTO member added to response
ManoMax Aug 26, 2023
0768e1a
refactor: design pattern improvements and new validations categories …
ManoMax Aug 26, 2023
106436c
refactor: validations configs changed
ManoMax Aug 26, 2023
546a547
Merge branch 'dev' into iss#5
ManoMax Aug 26, 2023
a5c716c
refactor: isLeadership updated to make more sense
ManoMax Aug 26, 2023
956c030
Merge branch 'iss#5' of https://github.com/codexjr-dev/dashboard-code…
ManoMax Aug 26, 2023
e4003e6
Merge pull request #14 from codexjr-dev/iss#5
ManoMax Aug 28, 2023
00ff7df
Merge pull request #24 from codexjr-dev/iss#8
ManoMax Aug 28, 2023
d150889
Merge pull request #23 from codexjr-dev/iss#19
ManoMax Aug 28, 2023
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
9 changes: 7 additions & 2 deletions src/config/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ const mongoose = require('mongoose');

module.exports = async () => {
let BD_URL;
if (process.env.NODE_ENV === "prod") {
if (process.env.NODE_ENV.replace(/'/g, '').trim() === "prod") {
console.log('Conectando com o banco de dados de produção...');
BD_URL = process.env.BD_PROD;
} else if (process.env.NODE_ENV === "dev") {
} else if (process.env.NODE_ENV.replace(/'/g, '').trim() === "dev") {
console.log('Conectando com o banco de dados de desenvolvimento...');
BD_URL = process.env.BD_DEV;
} else {
console.log('Gerando banco de dados local...');
const { MongoMemoryServer } = require('mongodb-memory-server');
const mongod = new MongoMemoryServer();
const uri = await mongod.getUri();
Expand All @@ -24,6 +27,8 @@ module.exports = async () => {
console.log("Erro na conexão com o banco de dados: " + err);
});

mongoose.set("strictQuery", false);

mongoose.connect(BD_URL, {
useNewUrlParser: true,
// poolSize: 5,
Expand Down
81 changes: 48 additions & 33 deletions src/middlewares/auth.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,64 @@
const jwt = require('jsonwebtoken');
const User = require('@user/User');
const { findPresident } = require('@ej/EjService');
const jwt = require("jsonwebtoken");
const Member = require("@member/Member");

module.exports = {
authorizeUser(req, res, next) {
authorize(req, res, next, "user");
},
validatedUser(req, res, next) {
authorize(req, res, next, "valid");
},

authorizePresident(req, res, next) {
authorize(req, res, next, "presidente");
}
}
authorizedUser(req, res, next) {
authorize(req, res, next, "user");
},

authorizedLeadership(req, res, next) {
authorize(req, res, next, "leadership");
},

authorizePresident(req, res, next) {
next();
},
};

const authorize = (req, res, next, type) => {
const authHeader = req.headers.authorization;
const authHeader = req.headers.authorization;

if (!authHeader)
return res.status(401).send({ error: 'Sem token irmão' });
if (!authHeader)
return res.status(401).send({ error: "Requisição sem token." });

const parts = authHeader.split(' ');
const parts = authHeader.split(" ");

if (!parts.length === 2)
return res.status(401).send({ error: 'Erro de token' });
const [scheme, token] = parts.length === 2 ? parts : [null, null];

const [scheme, token] = parts;
if (scheme === null || !/^Bearer$/i.test(scheme))
return res.status(401).send({ error: "Token mal formatado." });

if (!/^Bearer$/i.test(scheme))
return res.status(401).send({ error: 'Token mal formatado' });
jwt.verify(token, process.env.JWT_SECRET, async (err, decoded) => {
if (err) return res.status(401).send({ error: "Token inválido." });

jwt.verify(token, process.env.JWT_SECRET, async (err, decoded) => {
if (err)
return res.status(401).send({ error: 'Token inválido' });
const member = await Member.findOne({ _id: decoded.sub });

const user = await User.findOne({ _id: decoded.sub });
switch (type) {
case "valid":
if (!member)
return res.status(404).send({ error: "Usuário não existe." });
break;

if (!user)
return res.status(404).send({ error: 'Usuário não existe!' });
case "user":
if (!isLeadership(member) && member._id.toString() !== req.body._id)
return res.status(403).send({ error: "Usuário sem permissão." });
break;

const president = await findPresident(user.ej);
case "leadership":
if (!isLeadership(member))
return res.status(403).send({ error: "Usuário sem permissão." });
break;
}

if (type === "presidente" && `${user._id}` !== `${president._id}`)
return res.status(403).send({ error: 'Usuário não permitido por aqui!' });
req.ejId = member.ej;
req.memberId = member._id;
return next();
});
};

req.ejId = user.ej;
req.userId = user._id;
return next();
})
}
const isLeadership = (member) =>
["Presidente", "Diretor(a)"].includes(`${member.role}`);
21 changes: 14 additions & 7 deletions src/modules/Ej/EjService.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
const Ej = require('@ej/Ej');
const User = require('@user/User');
const Member = require('@member/Member');
const bcrypt = require('bcrypt');

module.exports = {
async save(ejData) {
const { name } = ejData;
const { presidentData } = ejData;

const member = await Member.findOne({ email: presidentData.email });
if (member) {
throw new Error('Já existe uma EJ cadastrada para esse email!');
}

const ej = await Ej.create({
name: name
})

const psw = await bcrypt.hash(presidentData.password, parseInt(process.env.SALT_ROUNDS))
const user = await User.create({

const newMember = await Member.create({

name: presidentData.name,
email: presidentData.email,
birthDate: presidentData.birthDate,
Expand All @@ -21,8 +28,8 @@ module.exports = {
ej: ej._id
})

user.password = undefined
return { ej: ej, user: user }
newMember.password = undefined
return { ej: ej, member: newMember }
},

// only for test purposes
Expand All @@ -34,12 +41,12 @@ module.exports = {
},

async findPresident(ejId) {
const president = await User.findOne({ role: 'presidente', ej: ejId });
const president = await Member.findOne({ role: 'presidente', ej: ejId });
return president;
},

async findById(ejId) {
const ej = await Ej.findOne({ _id: ejId });
return ej
}
return ej;
},
}
20 changes: 12 additions & 8 deletions src/modules/Link/LinkRoutes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const router = require('express').Router();
const { save, findByEj, update, remove } = require('./LinkController');
const { authorizeUser } = require('@middlewares/auth')
const router = require("express").Router();
const { save, findByEj, update, remove } = require("./LinkController");
const {
validatedUser,
authorizedUser,
authorizedLeadership,
} = require("@middlewares/auth");

router.post('/link', authorizeUser, save);
router.get('/link', authorizeUser, findByEj);
router.patch('/link/:id', authorizeUser, update);
router.delete('/link/:id', authorizeUser, remove);
router.post("/link", authorizedLeadership, save);
router.get("/link", validatedUser, findByEj);
router.patch("/link/:id", authorizedUser, update);
router.delete("/link/:id", authorizedLeadership, remove);

module.exports = router;
module.exports = router;
16 changes: 16 additions & 0 deletions src/modules/Member/Auth/AuthController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const { signIn } = require('./AuthService');

module.exports = {
async signIn(req, res) {
try {
const dados = await signIn(req.body)

if (dados.hasOwnProperty('erro')) {
return res.status(401).send({ error: dados.erro })
}
return res.status(200).send({ dados: dados })
} catch (error) {
return res.status(500).send({ error: error.message })
}
},
}
6 changes: 6 additions & 0 deletions src/modules/Member/Auth/AuthRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const router = require('express').Router();
const { signIn } = require('./AuthController');

router.post('/signIn', signIn);

module.exports = router;
40 changes: 40 additions & 0 deletions src/modules/Member/Auth/AuthService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const bcrypt = require('bcrypt');
const Member = require('@member/Member');
const JWT = require('jsonwebtoken');

const signToken = member => {
return JWT.sign({
iss: 'TCC',
sub: member,
iat: new Date().getTime(),
}, process.env.JWT_SECRET);
}

module.exports = {
async signIn(dados) {
const { email, password } = dados;

// ao recuperar o objeto 'member', ele conterá o campo 'ej' preenchido com o nome da ej
const member = await Member.findOne({ email: email }).populate({ path: 'ej', select: 'name' });

if (!member)
return { erro: 'Usuário ou senha incorreta' }

const match = await bcrypt.compare(password, member.password);

if (!match)
return { erro: 'Usuário ou senha incorreta' }

delete member._doc.password

// remove o campo password de 'member' antes de retorná-lo
const token = signToken(member);


// return res.status(200).cookie("jwt", token, {sameSite: 'none', path: '/', httpOnly: false , secure: false }).send({
return {
"member": member,
"token": token // retirar isso em produção
};
},
}
12 changes: 8 additions & 4 deletions src/modules/Member/Member.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ const MemberSchema = new Schema({
},
role: {
type: String,
enum: ['assessor', 'diretor', 'trainee', 'estagiário', 'membro'],
enum: ["Presidente", "Diretor(a)", "Assessor(a)", "Conselheiro(a)"],
required: true,
default: 'membro'
},
default: "Assessor(a)",
},
password: {
type: String,
required: true,
},
ej: {
type: Schema.Types.ObjectId,
ref: Ej,
Expand All @@ -27,7 +31,7 @@ const MemberSchema = new Schema({
},
entryDate: {
type: Date,
required: true
required: false
},
phone: {
type: String,
Expand Down
20 changes: 12 additions & 8 deletions src/modules/Member/MemberRoutes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const router = require('express').Router();
const { save, findByEj, update, remove } = require('./MemberController');
const { authorizeUser } = require('@middlewares/auth')
const router = require("express").Router();
const { save, findByEj, update, remove } = require("./MemberController");
const {
validatedUser,
authorizedUser,
authorizedLeadership,
} = require("@middlewares/auth");

router.post('/member', authorizeUser, save);
router.get('/member', authorizeUser, findByEj);
router.patch('/member/:id', authorizeUser, update);
router.delete('/member/:id', authorizeUser, remove);
router.post("/member", authorizedLeadership, save);
router.get("/member", validatedUser, findByEj);
router.patch("/member/:id", authorizedUser, update);
router.delete("/member/:id", authorizedLeadership, remove);

module.exports = router;
module.exports = router;
Loading