Skip to content

Commit 425c306

Browse files
authored
Merge pull request #73 from RustyRory/feat/72-serveur-express
feat(backend): Fixes #72 - Modèle Users
2 parents 5c55e29 + 47c5fd0 commit 425c306

7 files changed

Lines changed: 379 additions & 123 deletions

File tree

app/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"author": "",
1414
"license": "ISC",
1515
"dependencies": {
16+
"bcrypt": "^6.0.0",
1617
"cors": "^2.8.5",
1718
"dotenv": "^17.2.3",
1819
"express": "^5.2.1",

app/backend/server.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const dotenv = require('dotenv');
2+
dotenv.config();
3+
4+
const app = require('./src/app');
5+
const mongoose = require('mongoose');
6+
7+
const PORT = process.env.PORT ;
8+
const MONGO_URI = process.env.MONGO_URI;
9+
10+
mongoose.connect(MONGO_URI)
11+
.then(() => {
12+
console.log('MongoDB connecté');
13+
app.listen(PORT, () => {
14+
console.log(`Serveur lancé sur http://localhost:${PORT}`);
15+
});
16+
})
17+
.catch(err => console.error(err));

app/backend/src/app.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const express = require('express');
2+
const cors = require('cors');
3+
4+
const app = express();
5+
6+
app.use(cors());
7+
app.use(express.json());
8+
9+
// Route test
10+
app.get('/', (req, res) => {
11+
res.send('API Volley fonctionne !');
12+
});
13+
14+
// Importer les routes
15+
const usersRoutes = require('./routes/users');
16+
app.use('/api/users', usersRoutes);
17+
18+
19+
module.exports = app;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
const User = require('../models/User');
2+
3+
// GET all users
4+
exports.getAllUsers = async (req, res) => {
5+
try {
6+
const users = await User.find().select('-passwordHash'); // Ne jamais renvoyer les passwords
7+
res.json(users);
8+
} catch (err) {
9+
res.status(500).json({ message: err.message });
10+
}
11+
};
12+
13+
// GET single user
14+
exports.getUserById = async (req, res) => {
15+
try {
16+
const user = await User.findById(req.params.id).select('-passwordHash');
17+
if (!user) return res.status(404).json({ message: 'Utilisateur non trouvé' });
18+
res.json(user);
19+
} catch (err) {
20+
res.status(500).json({ message: err.message });
21+
}
22+
};
23+
24+
// POST create user
25+
exports.createUser = async (req, res) => {
26+
try {
27+
const { email, password, role, firstName, lastName } = req.body;
28+
const user = new User({ email, role, firstName, lastName });
29+
await user.setPassword(password);
30+
await user.save();
31+
res.status(201).json({ message: 'Utilisateur créé', userId: user._id });
32+
} catch (err) {
33+
res.status(400).json({ message: err.message });
34+
}
35+
};
36+
37+
// PUT update user
38+
exports.updateUser = async (req, res) => {
39+
try {
40+
const { email, role, firstName, lastName, isActive, password } = req.body;
41+
const user = await User.findById(req.params.id);
42+
if (!user) return res.status(404).json({ message: 'Utilisateur non trouvé' });
43+
44+
if (email) user.email = email;
45+
if (role) user.role = role;
46+
if (firstName) user.firstName = firstName;
47+
if (lastName) user.lastName = lastName;
48+
if (isActive !== undefined) user.isActive = isActive;
49+
if (password) await user.setPassword(password);
50+
51+
await user.save();
52+
res.json({ message: 'Utilisateur mis à jour' });
53+
} catch (err) {
54+
res.status(400).json({ message: err.message });
55+
}
56+
};
57+
58+
// DELETE user
59+
exports.deleteUser = async (req, res) => {
60+
try {
61+
const user = await User.findByIdAndDelete(req.params.id);
62+
if (!user) return res.status(404).json({ message: 'Utilisateur non trouvé' });
63+
res.json({ message: 'Utilisateur supprimé' });
64+
} catch (err) {
65+
res.status(500).json({ message: err.message });
66+
}
67+
};

app/backend/src/models/User.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const mongoose = require('mongoose');
2+
const bcrypt = require('bcrypt');
3+
4+
const UserSchema = new mongoose.Schema({
5+
email: {
6+
type: String,
7+
required: true,
8+
unique: true,
9+
lowercase: true,
10+
trim: true
11+
},
12+
passwordHash: { type: String, required: true },
13+
role: { type: String, enum: ['admin', 'editor'], default: 'editor' },
14+
firstName: { type: String, required: true },
15+
lastName: { type: String, required: true },
16+
isActive: { type: Boolean, default: true },
17+
lastLoginAt: { type: Date, default: null },
18+
passwordUpdatedAt: { type: Date, default: null }
19+
}, { timestamps: true });
20+
21+
// Comparer un mot de passe
22+
UserSchema.methods.comparePassword = async function(password) {
23+
return await bcrypt.compare(password, this.passwordHash);
24+
};
25+
26+
// Définir ou changer le mot de passe
27+
UserSchema.methods.setPassword = async function(password) {
28+
const salt = await bcrypt.genSalt(10);
29+
this.passwordHash = await bcrypt.hash(password, salt);
30+
this.passwordUpdatedAt = new Date();
31+
};
32+
33+
module.exports = mongoose.model('User', UserSchema);

app/backend/src/routes/users.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const express =require('express');
2+
const router = express.Router();
3+
const usersController =require('../controllers/usersController');
4+
5+
// Routes CRUD utilisateurs
6+
router.get('/', usersController.getAllUsers);
7+
router.get('/:id', usersController.getUserById);
8+
router.post('/', usersController.createUser);
9+
router.put('/:id', usersController.updateUser);
10+
router.delete('/:id', usersController.deleteUser);
11+
12+
module.exports = router;

0 commit comments

Comments
 (0)