Files
smart-city-digital-twin-mar…/smart-app-city/backend/auth-service/server.js

176 lines
6.1 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Smart App City — Auth Service (Node.js + Express)
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const app = express();
const PORT = 3001;
const JWT_SECRET = process.env.JWT_SECRET || 'smart-app-city-jwt-secret-2024';
const DB_PATH = path.join(__dirname, 'users.json');
app.use(cors());
app.use(express.json());
// ── Database helpers ──
function loadUsers() {
if (!fs.existsSync(DB_PATH)) {
fs.writeFileSync(DB_PATH, JSON.stringify({ users: [] }, null, 2));
}
return JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
}
function saveUsers(db) {
fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2));
}
// ── Create admin user on startup ──
function createAdminUser() {
const db = loadUsers();
// Admin user
if (!db.users.find(u => u.email === 'admin@digitribe.fr')) {
const hashedPassword = bcrypt.hashSync('Digitribe972', 10);
db.users.push({
id: 'admin-001',
email: 'admin@digitribe.fr',
password: hashedPassword,
firstName: 'Admin',
lastName: 'Digitribe',
roles: ['admin', 'user'],
createdAt: new Date().toISOString()
});
saveUsers(db);
console.log('✅ Admin user created: admin@digitribe.fr / Digitribe972');
} else {
console.log(' Admin user already exists');
}
// Eric user
if (!db.users.find(u => u.email === 'eric@digitribe.fr')) {
const hashedPassword = bcrypt.hashSync('Digitribe972', 10);
db.users.push({
id: 'eric-001',
email: 'eric@digitribe.fr',
password: hashedPassword,
firstName: 'Eric',
lastName: 'Felixine',
roles: ['admin', 'user'],
createdAt: new Date().toISOString()
});
saveUsers(db);
console.log('✅ Eric user created: eric@digitribe.fr / Digitribe972');
} else {
console.log(' Eric user already exists');
}
// Erol user
if (!db.users.find(u => u.email === 'erol@digitribe.fr')) {
const hashedPassword = bcrypt.hashSync('erol', 10);
db.users.push({
id: 'erol-001',
email: 'erol@digitribe.fr',
password: hashedPassword,
firstName: 'Erol',
lastName: 'Digitribe',
roles: ['user'],
createdAt: new Date().toISOString()
});
saveUsers(db);
console.log('✅ Erol user created: erol@digitribe.fr / erol');
} else {
console.log(' Erol user already exists');
}
}
// ── Routes ──
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'ok', service: 'auth-service' });
});
// Register
app.post('/api/auth/register', async (req, res) => {
try {
const { email, password, firstName, lastName } = req.body;
if (!email || !password || !firstName || !lastName) {
return res.status(400).json({ message: 'Tous les champs sont requis' });
}
if (password.length < 8) {
return res.status(400).json({ message: 'Le mot de passe doit contenir au moins 8 caractères' });
}
const db = loadUsers();
if (db.users.find(u => u.email === email)) {
return res.status(409).json({ message: 'Un compte avec cet email existe déjà' });
}
const hashedPassword = await bcrypt.hash(password, 10);
const user = {
id: 'user-' + Date.now(),
email,
password: hashedPassword,
firstName,
lastName,
roles: ['user'],
createdAt: new Date().toISOString()
};
db.users.push(user);
saveUsers(db);
const token = jwt.sign({ id: user.id, email: user.email, roles: user.roles }, JWT_SECRET, { expiresIn: '7d' });
res.json({ accessToken: token, user: { id: user.id, email: user.email, firstName: user.firstName, lastName: user.lastName, roles: user.roles } });
} catch (e) {
res.status(500).json({ message: 'Erreur serveur' });
}
});
// Login
app.post('/api/auth/login', async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Email et mot de passe requis' });
}
const db = loadUsers();
const user = db.users.find(u => u.email === email);
if (!user) {
return res.status(401).json({ message: 'Identifiants incorrects' });
}
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
return res.status(401).json({ message: 'Identifiants incorrects' });
}
const token = jwt.sign({ id: user.id, email: user.email, roles: user.roles }, JWT_SECRET, { expiresIn: '7d' });
res.json({ accessToken: token, user: { id: user.id, email: user.email, firstName: user.firstName, lastName: user.lastName, roles: user.roles } });
} catch (e) {
res.status(500).json({ message: 'Erreur serveur' });
}
});
// Get current user
app.get('/api/auth/me', (req, res) => {
try {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ message: 'Non authentifié' });
const decoded = jwt.verify(token, JWT_SECRET);
const db = loadUsers();
const user = db.users.find(u => u.id === decoded.id);
if (!user) return res.status(404).json({ message: 'Utilisateur non trouvé' });
res.json({ id: user.id, email: user.email, firstName: user.firstName, lastName: user.lastName, roles: user.roles });
} catch (e) {
res.status(401).json({ message: 'Token invalide' });
}
});
// Logout (client-side, but endpoint for completeness)
app.post('/api/auth/logout', (req, res) => {
res.json({ message: 'Déconnexion réussie' });
});
// Start server
app.listen(PORT, () => {
console.log(`🚀 Auth service running on port ${PORT}`);
createAdminUser();
});