diff --git a/backend/database/database.sql b/backend/database/database.sql index f6154cb..efdc7b2 100644 --- a/backend/database/database.sql +++ b/backend/database/database.sql @@ -13,7 +13,6 @@ CREATE TABLE phone VARCHAR(100) NOT NULL, email VARCHAR(100) NOT NULL, address VARCHAR(155) NOT NULL, - competence VARCHAR(100) NOT NULL, password VARCHAR(100) NOT NULL, is_admin BOOL NOT NULL, UNIQUE (email) diff --git a/backend/src/app.js b/backend/src/app.js index 1489f5a..9e91516 100644 --- a/backend/src/app.js +++ b/backend/src/app.js @@ -25,7 +25,11 @@ const app = express(); const cors = require("cors"); -app.use(cors()); +app.use( + cors({ + origin: process.env.FRONTEND_URL, + }) +); /* app.use( cors({ diff --git a/backend/src/controllers/userControllers.js b/backend/src/controllers/userControllers.js index dd6ece6..1a1824d 100644 --- a/backend/src/controllers/userControllers.js +++ b/backend/src/controllers/userControllers.js @@ -69,13 +69,35 @@ const postLogin = (req, res) => { }); }; -// const putUser = (req, res) => { -// models.user.sigin(req.body).then((user) => {}); -// }; +const updateUser = async (req, res) => { + const id = parseInt(req.params.id, 10); + if (!id) { + res.sendStatus(500); + } + + models.experience + .update(id, req.body) + .then((result) => { + if (result.affectedRows === 0) { + res.sendStatus(500); + } + res.sendStatus(200); + }) + .catch((error) => { + console.error(error); + res.status(422).send({ error: error.message }); + }); +}; + +const getProfile = (req, res) => { + res.send(req.user); +}; module.exports = { getUsers, postUser, postSkills, postLogin, + updateUser, + getProfile, }; diff --git a/backend/src/middlewares/security/auth.middlewares.js b/backend/src/middlewares/security/auth.middlewares.js new file mode 100644 index 0000000..3d36fec --- /dev/null +++ b/backend/src/middlewares/security/auth.middlewares.js @@ -0,0 +1,37 @@ +const jwt = require("jsonwebtoken"); +const model = require("../../models"); + +const authMiddleware = (req, res, next) => { + if (!req.headers.authorization) { + return res.status(401).json({ error: "User not authorized" }); + } + + return jwt.verify( + req.headers.authorization.split(" ")[1], + process.env.APP_SECRET, + (err, data) => { + if (err) { + return res.status(401).json({ error: err.message }); + } // Step 3: get user data from token payload + model.user.getProfile(data.id).then(([rows]) => { + if (!rows.length) { + return res.status(401).json({ error: "Utilisateur inexistant" }); + } // Step 4: share user data between different middlewares// eslint-disable-next-line prefer-destructuring + // eslint-disable-next-line prefer-destructuring + req.user = rows[0]; + return next(); + }); + return null; + } + ); +}; + +const authAdminMiddleware = (req, res, next) => { + if (req?.user?.isAdmin !== 1) { + return res.status(403).json({ error: "Vous n'ĂȘtes pas Admin" }); + } + + return next(); +}; + +module.exports = { authMiddleware, authAdminMiddleware }; diff --git a/backend/src/models/UserManager.js b/backend/src/models/UserManager.js index 92f083e..e44ad11 100644 --- a/backend/src/models/UserManager.js +++ b/backend/src/models/UserManager.js @@ -17,7 +17,7 @@ class UserManager extends AbstractManager { user.address, user.email, hash, - user.is_admin, + 0, ] ); return rows; @@ -59,6 +59,13 @@ class UserManager extends AbstractManager { return result ? dbUser : undefined; } + getProfile(id) { + return this.database.query( + `SELECT id, email, is_admin AS isAdmin FROM ${this.table} WHERE id = ?`, + [id] + ); + } + static hashPassword(password, workFactor = 5) { return bcrypt.hash(password, workFactor); } diff --git a/backend/src/router.js b/backend/src/router.js index b03620e..833970a 100644 --- a/backend/src/router.js +++ b/backend/src/router.js @@ -7,6 +7,9 @@ const offerControllers = require("./controllers/offerControllers"); const experienceControllers = require("./controllers/experienceControllers"); const courseControllers = require("./controllers/courseControllers"); const cvControllers = require("./controllers/cvControllers"); +const { + authAdminMiddleware, +} = require("./middlewares/security/auth.middlewares"); router.get("/users", userControllers.getUsers); router.post("/users", userControllers.postUser); @@ -32,6 +35,8 @@ router.delete("/course/:id", courseControllers.deleteCourseById); router.get("/cvs/:userId", cvControllers.getCv); router.post("/cvs", cvControllers.postCv); + +router.get("users/me", authAdminMiddleware, userControllers.getProfile); // router.post("/signin", userControllers.postUser); // router.update("/signin", userControllers.putUser); module.exports = router; diff --git a/backend/src/services/api.service.jsx b/backend/src/services/api.service.jsx new file mode 100644 index 0000000..1261023 --- /dev/null +++ b/backend/src/services/api.service.jsx @@ -0,0 +1,38 @@ +import axios from "axios"; + +export default class ApiService { + #token; + + constructor() { + this.#token = localStorage.getItem("token"); + } + + getToken() { + return this.#token; + } + + setToken(token) { + this.#token = token; + + return this; + } + + getConfig() { + const config = { headers: {} }; + + if (this.#token) { + config.headers.Authorization = `bearer ${this.#token}`; + } + + return config; + } + + get(url) { + return axios.get(url, this.getConfig()); + } + + async post(url, content) { + const { data } = await axios.post(url, content, this.getConfig()); + return data; + } +} diff --git a/frontend/src/components/Competence Switch/CompetenceSwitch.jsx b/frontend/src/components/Competence Switch/CompetenceSwitch.jsx index 70dd1e0..85cadd6 100644 --- a/frontend/src/components/Competence Switch/CompetenceSwitch.jsx +++ b/frontend/src/components/Competence Switch/CompetenceSwitch.jsx @@ -6,8 +6,8 @@ import "../../default-settings.css"; function CompetenceSwitch({ textCompetence, fieldName, - valueInput, handleChange, + valueInput, }) { return (