diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 00000000..7af7f047 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,2 @@ +/node_modules +.env \ No newline at end of file diff --git a/backend/.sequelizerc b/backend/.sequelizerc deleted file mode 100644 index 88afbcb9..00000000 --- a/backend/.sequelizerc +++ /dev/null @@ -1,5 +0,0 @@ -const path = require("path"); - -module.exports = { - config: path.resolve("config", "config.js"), -}; \ No newline at end of file diff --git a/backend/controllers/UserControllers.js b/backend/controllers/UserControllers.js index 9fec116c..5d9af214 100644 --- a/backend/controllers/UserControllers.js +++ b/backend/controllers/UserControllers.js @@ -1,37 +1,48 @@ const { Users } = require('../models/schemas'); const bcrypt = require('bcrypt'); const { sign } = require('jsonwebtoken'); +const { createToken, validateToken } = require('./middlewares/Auth'); -exports.teste = async(req, res) =>{ - res.json('Login endpoint'); -}; - -/* exports.registerUser = async(req, res) => { +exports.userRegister = async(req, res) => { const { email, password } = req.body; - bcrypt.hash(password, 10).then((hash) => { + bcrypt.hash(password, 15).then((hash) => { Users.create({ email: email, password: hash, + }).then(() =>{ + res.json('Solicitação bem sucedida!'); + }).catch((err) => { + if(err){ + res.status(400).json({error: err}); + } }); - res.json('Solicitação bem sucedida.'); }); }; -exports.loginUser = async(req, res) => { +exports.userLogin = async(req, res) => { const { email, password } = req.body; const user = await Users.findOne({where: {email: email}}); - if(!user){ - res.json({error: 'E-mail não cadastrado no banco de dados!'}); + res.status(400).json({error: 'E-mail não cadastrado!'}); } else { - bcrypt.compare(password, user.password).then((validate) => - if(!validate){ - res.json({error: 'E-mail ou senha incorreta!'}); - }else{ - const token = sign{ - {} - } - } - ) - } -}*/ \ No newline at end of file + bcrypt.compare(password, user.password).then((match) =>{ + if(!match){ + res.status(400).json({error: 'Senha incorreta!'}); + } else { + const accessToken = createToken(user); + res.cookie('access-token', accessToken, { + maxAge: 2592000000, + httpOnly: true, + }); + Users.update( + { token: accessToken }, + { where: { email: user.email } } + ).then(() => { + res.json(accessToken); + }).catch((err) => { + res.status(500).json({ error: 'Erro ao atualizar o token no banco de dados.' }); + }); + }; + }); + }; +}; \ No newline at end of file diff --git a/backend/controllers/middlewares/Auth.js b/backend/controllers/middlewares/Auth.js new file mode 100644 index 00000000..33eea256 --- /dev/null +++ b/backend/controllers/middlewares/Auth.js @@ -0,0 +1,28 @@ +const { sign, verify } = require('jsonwebtoken'); + +const createToken = (user) => { + const accessToken = sign({username: user.email}, + process.env.SECRET + ); + return accessToken; +}; + +const validateToken = (req, res, next) => { + const accessToken = req.cookies['access-token']; + if(!accessToken) { //vê se o user já foi autenticado pelo cookie de sessão + return res.status(400).json({error: 'Usuário não autenticado!'}); + }; + + try { + const validToken = verify(accessToken, process.env.SECRET); + if(validToken){ + req.authenticated = true; + return next(); + } + } catch(err) { + return res.status(400).json({error: err}); + }; +}; + +module.exports = { createToken, validateToken }; + diff --git a/backend/index.js b/backend/index.js index 91aeed0a..c8be67b6 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,16 +1,21 @@ +const { validateToken } = require('./controllers/middlewares/Auth'); const express = require('express'); -const app = express(); const database = require('./models/schemas'); -const port = 3001; const userRoute = require('./views/routes/Users'); const electiveRoute = require('./views/routes/Electives') -const learningPathRoute = require('./views/routes/LearningPaths') +const learningPathRoute = require('./views/routes/LearningPaths')] +require("dotenv").config(); +const app = express(); +const port = 3001; app.use(express.json()); +app.use(validateToken); + app.use('/', userRoute); app.use('/elective', electiveRoute); app.use('/learning_paths', learningPathRoute); + database.sequelize.sync().then(() => { app.listen(port, () => { console.log('Server running on port 3001'); diff --git a/backend/migrations/Users.js b/backend/migrations/Users.js new file mode 100644 index 00000000..e3a0e8e6 --- /dev/null +++ b/backend/migrations/Users.js @@ -0,0 +1,26 @@ +'use strict'; + +let users = { schema: 'Users', tableName: 'Users'} + +module.exports = { + up: async (queryInterface, Sequelize) => { + const transaction = await queryInterface.sequelize.transaction(); + + try { + await queryInterface.createTable(users, { + co_users: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true }, + ds_email: { type: Sequelize.STRING, allowNull: false, unique: true, validate: {isEmail: {args: true, msg: "O formato do e-mail é inválido",},},}, + ds_password: { type: Sequelize.STRING, allowNull: false, validate: {len: [8, Infinity],},}, + ds_token: { type: Sequelize.STRING }, + }) + await transaction.commit() + }catch (e) { + await transaction.rollback() + throw e + } + }, + + down: async (queryInterface, Sequelize) => { + await queryInterface.dropTable(users) + } +} \ No newline at end of file diff --git a/backend/models/index.js b/backend/models/index.js deleted file mode 100644 index 7c9aeee9..00000000 --- a/backend/models/index.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const Sequelize = require('sequelize'); -const process = require('process'); -const basename = path.basename(__filename); -const env = process.env.NODE_ENV || 'development'; -const config = require(__dirname + '/../config/config.js')[env]; -const db = {}; - -let sequelize; -if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); -} else { - sequelize = new Sequelize(config.database, config.username, config.password, config); -} - -fs - .readdirSync(__dirname) - .filter(file => { - return ( - file.indexOf('.') !== 0 && - file !== basename && - file.slice(-3) === '.js' && - file.indexOf('.test.js') === -1 - ); - }) - .forEach(file => { - const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); - db[model.name] = model; - }); - -Object.keys(db).forEach(modelName => { - if (db[modelName].associate) { - db[modelName].associate(db); - } -}); - -db.sequelize = sequelize; -db.Sequelize = Sequelize; - -module.exports = db; diff --git a/backend/models/schemas/Users.js b/backend/models/schemas/Users.js index 83ca2c5c..cb65f1ed 100644 --- a/backend/models/schemas/Users.js +++ b/backend/models/schemas/Users.js @@ -1,8 +1,16 @@ module.exports = (sequelize, DataTypes) =>{ + const Users = sequelize.define("Users", { + id: { + type: DataTypes.INTEGER, + field: "co_users", + primaryKey: true, + autoIncrement: true + }, email: { type: DataTypes.STRING, allowNull: false, + field: "ds_email", validate: { isEmail: { args: true, @@ -10,19 +18,22 @@ module.exports = (sequelize, DataTypes) =>{ }, }, }, + password: { + field: "ds_password", type: DataTypes.STRING, allowNull: false, validate: { len: [8, Infinity], }, }, + token: { - type: DataTypes.STRING, - }, - tokenExpiration: { + field: "ds_token", type: DataTypes.STRING, }, }) + return Users; + } \ No newline at end of file diff --git a/backend/package.json b/backend/package.json index 71418d7a..f28ba2cf 100644 --- a/backend/package.json +++ b/backend/package.json @@ -12,7 +12,9 @@ "license": "ISC", "dependencies": { "bcrypt": "^5.1.1", + "cookie-parser": "^1.4.6", "cors": "^2.8.5", + "dotenv": "^16.3.1", "express": "^4.18.2", "jsonwebtoken": "^9.0.2", "mysql2": "^3.6.3", diff --git a/backend/views/routes/Users.js b/backend/views/routes/Users.js index b7764150..544d685a 100644 --- a/backend/views/routes/Users.js +++ b/backend/views/routes/Users.js @@ -1,8 +1,15 @@ const express = require('express'); const router = express.Router(); -const userController = require('../../controllers/UserControllers') +const cookieParser = require('cookie-parser'); +const userController = require('../../controllers/UserControllers'); +const { validateToken } = require('../../controllers/middlewares/Auth'); -// router.post("/", userController.registerUser); -// router.post("/teste", userController.teste); +router.use(cookieParser()); +router.post('/', userController.userRegister); +router.post('/login', userController.userLogin); + +router.get('/profile', validateToken, (req, res) => { + res.json('profile'); +}); module.exports = router;