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

[US18]: Fazer login na Central Administrativa #96

Merged
merged 21 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
6 changes: 5 additions & 1 deletion apps/backend/.env.template
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
MONGODB_URL =
MONGODB_URI_DEV =
MONGODB_URI_PROD =
NODE_ENV =
SECRET_JWT =
SALT_BCRYPT =
2 changes: 2 additions & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
},
"author": "Requisitados - UnB",
"dependencies": {
"bcrypt": "^5.1.1",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.8.1"
},
"devDependencies": {
Expand Down
Empty file.
154 changes: 154 additions & 0 deletions apps/backend/src/controllers/user.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import userService from "../services/user.service.js";
import bcrypt from 'bcrypt';
import dotenv from 'dotenv';
dotenv.config();

// =====================================================
// DEFINIÇÃO DE CRIPTOGRAFIA:
var salt = process.env.SALT_BCRYPT;
// ==================================================================

const createUser = async (req, res) => {
try {
const{name, email} = req.body;

if(!name || !email)
res.status(400).send({ message: 'Preencha todos os campos para registro!', case: 1 });

const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email))
return res.status(400).send({ message: 'Formato de email incorreto!', case: 2 });

const user = await userService.createService({
name,
email,
});

if (!user)
return res.status(502).send({ message: 'Dados não salvos, apesar da requisição!' });

return res.status(201).send({ message: 'Usuário criado com Sucesso!', user: user });
} catch (err) {
if (err.code === 11000) { // Código de erro para violação de chave única em MongoDB/Mongoose
return res.status(400).send({ message: 'Email em uso!', case: 3 });
}
return res.status(500).send({ message: err.message });
}
};

const loginUser = async (req, res) => {
try {
const { email, password } = req.body;
if(!email, !password)
return res.status(400).send({ message: 'Preencha todos os campos para logar!'})

const user = await userService.findService({ email });
if ( user.length == 0)
return res.status(404).send({ message: 'Usuário não encontrado!'});

if (!user[0].password) {
const token = userService.generateToken(user);
return res.status(200).send({ message: 'Usuário encontrado, mas sem senha!', case: 2, token });
}

if (user[0].password != bcrypt.hashSync(password, salt))
return res.status(403).send({ message: 'Senha ou email inválido!'});

const token = userService.generateToken(user);
return res.status(200).send({ message: 'Usuário encontrado!', case: 1, token });
} catch (err) {
return res.status(500).send({ message: err.message });
}
};

const findUsers = async (req, res) => {
try {
const { name, email } = req.query;

const filter = {};
if (email) filter.email = email;
if (name) filter.name = name;

if (Object.keys(filter).length === 0)
return res.status(400).send({ message: 'Informe pelo menos um parâmetro para a busca: "email" ou "name".' });

const user = await userService.findService(filter);

return res.status(200).send({ message: "Usuário buscado com sucesso!", user: user });
} catch (err) {
return res.status(500).send({ message: err.message });
}
}

const findByIdUser = async (req, res) => {
try {
const { _id } = req.params;

if(!_id)
return res.status(400).send({ message: 'Por favor, forneça um ID válido.' });

const user = await userService.findByIdService(_id);

if (!user) {
return res.status(404).send({ message: 'Usuário não encontrado.' });
}

return res.status(200).send({ message: 'Usuário encontrado com sucesso!', user });
} catch (err) {
return res.status(500).send({ message: err.message });
}
}

const findByIdAndUpdate = async (req, res) => {
try {
const { id } = req.params;
const updateBody = req.body;

if (!id || Object.keys(updateBody).length === 0)
return res.status(400).send({ message: 'Por favor, forneça um ID e os dados para atualização.' });


if (updateBody.password) {
const hashedPassword = bcrypt.hashSync(updateBody.password, salt);
updateBody.password = hashedPassword;
}

const updatedUser = await userService.updateService(id, updateBody);

if (!updatedUser) {
return res.status(404).send({ message: 'Usuário não encontrado ou não foi possível atualizar.' });
}

return res.status(200).send({ message: 'Usuário atualizado com sucesso!', user: updatedUser });
} catch (err) {
return res.status(500).send({ message: `Erro ao atualizar o usuário: ${err.message}` });
}
};

const deleteUser = async (req, res) => {
try {
const { id } = req.params;

if (!id)
return res.status(400).send({ message: 'Por favor, forneça um ID para deletar o usuário.' });

const deletedUser = await userService.deleteService(id);

if (!deletedUser)
return res.status(404).send({ message: 'Usuário não encontrado.' });

return res.status(200).send({ message: 'Usuário deletado com sucesso!' });
} catch (err) {
return res.status(500).send({ message: `Erro ao deletar o usuário: ${err.message}` });
}
};


export default {
createUser,
loginUser,
findUsers,
findByIdUser,
findByIdAndUpdate,
deleteUser,
};
36 changes: 36 additions & 0 deletions apps/backend/src/controllers/visita.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import VisitaService from"../services/visita.service.js";

const createVisita = async (req, res) => {
try {
const { startDateTime, endDateTime } = req.body;

if(!startDateTime || !endDateTime)
return res.status(400).json({ message: "Preencha todos os campos para criar a disponibilidade!"});

const visita = await VisitaService.createService(req.body);

if (!visita)
return res.status(502).send({ message: 'Dados não salvos, apesar da requisição!' });

return res.status(201).send({ message: "Disponibilidade criada com sucesso!", visita })
} catch (err) {
return res.status(500).send({ message: "Erro ao criar disponibilidade.", error: err.message });
}
};

const findAllVisita = async (req, res) => {
try {
const visita = await VisitaService.findAllService();

return res.send(200).send({ message: "Visitas encontradas!", visita });
} catch (err) {
return res.send(500).send({ message: err.message });
}
}

export default {
createVisita,
findAllVisita,
};


21 changes: 14 additions & 7 deletions apps/backend/src/database/db.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import mongoose from 'mongoose';

const connectDatabase = () => {
console.log('Wait connection to the database');
mongoose.connect(
process.env.MONGODB_URL
)
.then(() => console.log('MongoDB Atlas Connected'))
.catch((error) => console.log(error));
const connectDatabase = async () => {
const mongoURI =
process.env.NODE_ENV === 'production'
? process.env.MONGODB_URI_PROD // Banco de produção
: process.env.MONGODB_URI_DEV; // Banco de desenvolvimento

try {
console.log('Aguardando conexão com o banco de dados...');
await mongoose.connect( mongoURI );
console.log('Conexão com o MongoDB Atlas bem-sucedida!');
} catch (error) {
console.error('Erro ao conectar ao MongoDB:', error);
process.exit(1);
}
}

export default connectDatabase;
11 changes: 9 additions & 2 deletions apps/backend/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import express from 'express';
import connectDatabase from './database/db.js';
import cors from 'cors';
import dotenv from 'dotenv';
import { UserSeed } from './scripts/seeds.js'
dotenv.config();

const port = process.env.PORT || 3001;
import router from './routes/index.js';

const port = process.env.PORT || 3002;
const app = express();

const allowedOrigins = [
'http://localhost:3000'
'http://localhost:3000',
'http://localhost:3001'
];

const corsOptionsDelegate = function(req, callback) {
Expand All @@ -23,6 +27,9 @@ const corsOptionsDelegate = function(req, callback) {

app.use(cors(corsOptionsDelegate));
app.use(express.json());
app.use(router);

connectDatabase();
UserSeed();

app.listen(port, () => console.log(`Servidor rodando na porta ${port}`));
38 changes: 38 additions & 0 deletions apps/backend/src/middlewares/auth.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import dotenv from 'dotenv';
import jwt from 'jsonwebtoken';
import userService from '../services/user.service.js';
dotenv.config();

export const authMiddleware = (req, res, next) => {
try {
const { authorization } = req.headers;

if (!authorization)
return res.status(401).send({message: 'User Unauthorized'});

const parts = authorization.split(" ");

if (parts.length !== 2)
return res.status(401).send({message: 'User Unauthorized'});

const [schema, token] = parts;

if (schema !== "Bearer")
return res.status(401).send({message: 'User Unauthorized'});

jwt.verify(token, process.env.SECRET_JWT, async (error, decoded) => {
if(error) return res.status(401).send({message: 'Token Invalid'});

const user = await userService.findByIdService({ _id: decoded._id});

if (!user || !user.id)
return res.status(401).send({message: "Invalid User!"});

req.userID = decoded._id;

return next();
});
} catch(err) {
return res.status(500).send({ message: err.message });
}
}
Empty file.
24 changes: 24 additions & 0 deletions apps/backend/src/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose from "mongoose";

const UserSchema = new mongoose.Schema({
name: {
type: String,
require: true,
},
email: {
type: String,
require: true,
unique: true,
},
password: {
type: String,
require: false,
},
sector: {
type: String,
require: true,
}
}, {timestamps: true});

const User = mongoose.model('User', UserSchema);
export default User;
32 changes: 32 additions & 0 deletions apps/backend/src/models/Visita.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import mongoose from "mongoose";

const VisitaSchema = new mongoose.Schema({
startDateTime: {
type: Date,
require: true,
},
endDateTime: {
type: Date,
require: true,
},
nameVisitor: {
type: String,
require: false,
},
emailVisitor: {
type: String,
require: false,
},
phoneVisitor: {
type: String,
require: false,
},
Institution: {
type: String,
require: false,
}
}, {timestamps: true});

const Visita = mongoose.model("Visita", VisitaSchema);

export default Visita;
Empty file removed apps/backend/src/models/model1.js
Empty file.
6 changes: 6 additions & 0 deletions apps/backend/src/routes/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Router } from "express";
import cors from 'cors';
import visitaRouter from "./visita.route.js";
import userRouter from "./user.route.js";
import { authMiddleware } from "../middlewares/auth.middleware.js";

const router = Router();

router.use('/visita', cors(), visitaRouter);
router.use('/user', cors(), userRouter);

export default router;
12 changes: 12 additions & 0 deletions apps/backend/src/routes/user.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import express from "express";
import userController from "../controllers/user.controller.js";
const userRouter = express.Router();

userRouter.post('/createUser', userController.createUser);
userRouter.post('/loginUser', userController.loginUser);
userRouter.get('/findUsers/', userController.findUsers);
userRouter.get('findByIdUser', userController.findByIdUser);
userRouter.put('updateUser/:id', userController.findByIdAndUpdate);
userRouter.delete('deleteUser/:id', userController.deleteUser);

export default userRouter;
Loading