🔐 Bibliothèque d'authentification complète avec système de rôles avancé (RBAC) pour Node.js/Express
npm install @falandyjean/lockbox-auth/admin, /write-article)
👤 VISITEUR
↓ S'inscrit sur /auth/register
👤 UTILISATEUR CONNECTÉ (role: USER)
↓ Admin lui donne le rôle BLOG_WRITER
👤 RÉDACTEUR (peut écrire des articles)
↓ Promotion → rôle BLOG_EDITOR
👤 ÉDITEUR (peut écrire + modifier + supprimer)
↓ Promotion → rôle BLOG_CHIEF_EDITOR
👤 RÉDACTEUR EN CHEF (contrôle total du blog)
`
#### 3. Système de hiérarchie automatique
`
BLOG_CHIEF_EDITOR (niveau 15)
↓ peut faire tout ce que fait...
BLOG_EDITOR (niveau 10)
↓ peut faire tout ce que fait...
BLOG_WRITER (niveau 5)
↓ peut faire tout ce que fait...
BLOG_READER (niveau 1)
`
💡 Magie de lockbox-auth : Si quelqu'un a le rôle BLOG_EDITOR, il peut automatiquement accéder aux pages BLOG_WRITER et BLOG_READER !
$3
#### Étape 1 : Inscription
`
Utilisateur remplit un formulaire → POST /auth/register
↓
Lockbox-auth crée le compte + hash le mot de passe
↓
Utilisateur reçoit un email de confirmation (optionnel)
↓
Utilisateur peut se connecter
`
#### Étape 2 : Connexion
`
Utilisateur remplit login/password → POST /auth/login
↓
Lockbox-auth vérifie les identifiants
↓
Si OK : génère un JWT token (expire dans 1h)
↓
Renvoie { accessToken, refreshToken, user: {...} }
↓
Frontend stocke le token (localStorage/cookie)
`
#### Étape 3 : Navigation protégée
`
Utilisateur clique sur "Écrire un article"
↓
Frontend fait GET /write-article
↓
Lockbox-auth intercepte et lit le token JWT
↓
Vérifie : "A-t-il le rôle BLOG_WRITER ou supérieur ?"
↓
OUI → Page s'affiche | NON → Erreur 403
`
#### Étape 4 : Renouvellement automatique
`
Token expire (1h) → Frontend reçoit erreur 401
↓
Frontend utilise automatiquement le refreshToken
↓
POST /auth/refresh avec le refreshToken
↓
Lockbox-auth génère un nouveau accessToken
↓
Navigation continue sans interruption
`
$3
$3
- Fini les centaines de rôles ! Choisissez seulement les modèles dont vous avez besoin
- Package plus léger : Importez uniquement ce que vous utilisez
- Plus simple à comprendre : Logique claire et modèles sectoriels
- Totalement modulaire : Créez vos propres modèles facilement
$3
- Hachage Argon2 (résistant aux GPU/ASIC)
- JWT + Refresh Tokens avec expiration automatique
- Protection CSRF intégrée
- Rate limiting sur les tentatives de connexion
- Mots de passe temporaires sécurisés
- Validation stricte des entrées utilisateur
$3
- Middleware ultra-rapide (< 1ms de latence)
- Cache intelligent des rôles en mémoire
- Base de données optimisée avec Prisma
- Lazy loading des modèles de rôles
$3
- Sites e-commerce : Gérer clients, vendeurs, admins
- Plateformes de contenu : Lecteurs, rédacteurs, éditeurs
- Applications SaaS : Utilisateurs gratuits, premium, support
- Intranets d'entreprise : Employés, managers, direction
�🔥 Comparaison : Ancien vs Nouveau
❌ Ancien système (statique) :
`typescript
// Vous étiez forcé d'avoir TOUS ces rôles même si vous n'en utilisiez que 5
import { USER_ROLES } from 'lockbox-auth'; // 500+ rôles importés !
// BLOG_READER, HOSPITAL_SURGEON, BANK_TRADER, SCHOOL_STUDENT, etc.
`
✅ Nouveau système (modèles) :
`typescript
// Vous choisissez EXACTEMENT ce dont vous avez besoin
import { deployTemplate, BLOG_TEMPLATE } from 'lockbox-auth';
// En une ligne, vous déployez seulement les rôles blog
deployTemplate('BLOG', BLOG_TEMPLATE);
`
🚀 Installation Ultra-Rapide
`bash
npm install @falandy/lockbox-auth
npx lockbox-init
`
🏗️ Implémentation complète dans un site réel
$3
`typescript
// server.js - Configuration Express + Lockbox
import express from 'express';
import {
deployTemplate,
BLOG_TEMPLATE,
createAuthRouter,
requireAuth,
requireRole
} from '@falandy/lockbox-auth';
const app = express();
app.use(express.json());
// 1. Déployer vos modèles de rôles
deployTemplate('BLOG', BLOG_TEMPLATE);
// 2. Configuration auth
const authConfig = {
jwtSecret: process.env.JWT_SECRET || 'your-secret-key',
refreshTTL: 7, // 7 jours
temporaryPassword: {
enabled: true,
length: 12,
expiryHours: 24,
},
};
// 3. Routes d'authentification automatiques
app.use('/auth', createAuthRouter(authConfig));
// Crée automatiquement : /auth/register, /auth/login, /auth/refresh, /auth/logout
app.listen(3000);
`
$3
`html
Connexion
`
$3
`typescript
// server.js - Ajout des routes protégées
// 🌍 Pages publiques (accessibles à tous)
app.get('/', (req, res) => {
res.send('Accueil
Se connecter');
});
// 🔒 Pages protégées (connexion requise)
app.get('/dashboard', requireAuth(authConfig.jwtSecret), (req, res) => {
res.json({
message: Bienvenue ${req.user.email},
role: req.user.role,
canWrite: req.user.role.includes('BLOG_WRITER')
});
});
// ✍️ Zone rédaction (rôle BLOG_WRITER minimum)
app.get('/write-article', requireRole('BLOG_WRITER'), (req, res) => {
res.send(
Bonjour ${req.user.email}, vous pouvez écrire des articles
);
});
// 🛠️ Zone d'édition (rôle BLOG_EDITOR minimum)
app.get('/manage-articles', requireRole('BLOG_EDITOR'), (req, res) => {
res.send(
Vous pouvez modifier et supprimer tous les articles
);
});
// 👑 Zone admin (rôle BLOG_CHIEF_EDITOR)
app.get('/admin', requireRole('BLOG_CHIEF_EDITOR'), (req, res) => {
res.send(
Contrôle total du système
);
});
// 📝 API pour créer des articles
app.post('/api/articles', requireRole('BLOG_WRITER'), async (req, res) => {
// req.user contient automatiquement les infos de l'utilisateur connecté
const article = {
title: req.body.title,
content: req.body.content,
authorId: req.user.id,
authorEmail: req.user.email, createdAt: new Date()
};
res.json({ message: 'Article créé !', article });
});
`
$3
`javascript
// auth.js - Middleware côté client
class AuthManager {
constructor() {
this.token = localStorage.getItem('accessToken');
this.refreshToken = localStorage.getItem('refreshToken');
}
// Faire une requête authentifiée
async fetch(url, options = {}) {
const headers = {
'Content-Type': 'application/json',
...options.headers
};
if (this.token) {
headers['Authorization'] = Bearer ${this.token};
}
let response = await fetch(url, { ...options, headers });
if (response.status === 401 && this.refreshToken) {
const renewed = await this.renewToken();
if (renewed) {
headers['Authorization'] = Bearer ${this.token};
response = await fetch(url, { ...options, headers });
}
}
return response;
}
// Renouveler le token automatiquement
async renewToken() {
try {
const response = await fetch('/auth/refresh', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ refreshToken: this.refreshToken })
});
if (response.ok) {
const data = await response.json();
this.token = data.accessToken;
localStorage.setItem('accessToken', data.accessToken);
return true;
}
} catch (error) { console.error('Erreur renouvellement token:', error);
}
this.logout();
return false;
}
// Déconnexion
logout() {
localStorage.removeItem('accessToken');
localStorage.removeItem('refreshToken');
window.location.href = '/login.html';
}
// Vérifier si l'utilisateur a un rôle
async hasRole(role) {
try {
const response = await this.fetch('/auth/me');
if (response.ok) {
const user = await response.json();
return user.role.includes(role);
}
} catch (error) {
console.error('Erreur vérification rôle:', error);
}
return false;
}
}
// Instance globale
const auth = new AuthManager();
// Utilisation dans vos pages
document.addEventListener('DOMContentLoaded', async () => {
// Cacher/afficher des éléments selon le rôle
if (await auth.hasRole('BLOG_WRITER')) {
document.getElementById('writeButton').style.display = 'block';
}
if (await auth.hasRole('BLOG_EDITOR')) {
document.getElementById('adminPanel').style.display = 'block';
}
});
`
$3
`typescript
// admin-routes.js - Routes pour gérer les utilisateurs
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Promouvoir un utilisateur
app.post('/admin/promote-user', requireRole('BLOG_CHIEF_EDITOR'), async (req, res) => {
try {
const { userId, newRole } = req.body;
const updatedUser = await prisma.user.update({
where: { id: userId },
data: { role: newRole }
});
res.json({
message: Utilisateur promu au rôle ${newRole},
user: updatedUser
});
} catch (error) {
res.status(500).json({ error: 'Erreur promotion utilisateur' });
}
});
// Lister tous les utilisateurs avec leurs rôles
app.get('/admin/users', requireRole('BLOG_EDITOR'), async (req, res) => {
try {
const users = await prisma.user.findMany({
select: {
id: true,
email: true,
role: true,
createdAt: true,
lastLoginAt: true
}
});
res.json({ users });
} catch (error) {
res.status(500).json({ error: 'Erreur récupération utilisateurs' });
}
});
// Statistiques du site
app.get('/admin/stats', requireRole('BLOG_CHIEF_EDITOR'), async (req, res) => {
try {
const stats = {
totalUsers: await prisma.user.count(),
usersByRole: await prisma.user.groupBy({
by: ['role'],
_count: { role: true }
}),
totalArticles: await prisma.article?.count() || 0,
recentLogins: await prisma.user.count({
where: {
lastLoginAt: {
gte: new Date(Date.now() - 24 60 60 * 1000) // 24h
}
}
})
};
res.json({ stats });
} catch (error) {
res.status(500).json({ error: 'Erreur récupération statistiques' });
}
});
`
🎨 Usage par Secteur
$3
`typescript
import { deployTemplate, BLOG_TEMPLATE, requireAuth } from '@falandy/lockbox-auth';
// Déployer le modèle blog
deployTemplate('BLOG', BLOG_TEMPLATE);
// Utiliser les rôles
app.get('/write-article', requireRole('BLOG_WRITER'), (req, res) => {
// Seuls les rédacteurs peuvent écrire
});
`
$3
`typescript
import { deployTemplate, ECOMMERCE_TEMPLATE } from '@falandy/lockbox-auth';
// Déployer le modèle e-commerce
deployTemplate('SHOP', ECOMMERCE_TEMPLATE);
`
$3
`typescript
import { deployTemplate, HOSPITAL_TEMPLATE } from '@falandy/lockbox-auth';
deployTemplate('HOSPITAL', HOSPITAL_TEMPLATE);
`
$3
`typescript
import { deployTemplate, SCHOOL_TEMPLATE } from '@falandy/lockbox-auth';
deployTemplate('SCHOOL', SCHOOL_TEMPLATE);
`
📦 Modèles Disponibles
| Secteur | Modèle | Rôles Inclus |
|---------|--------|--------------|
| 📝 Média | BLOG_TEMPLATE | READER, WRITER, EDITOR, CHIEF_EDITOR |
| 📺 Journalisme | JOURNALISM_TEMPLATE | READER, JOURNALIST, PHOTOGRAPHER, EDITOR_IN_CHIEF |
| 🎥 Streaming | STREAMING_TEMPLATE | VIEWER, STREAMER, MODERATOR, PLATFORM_ADMIN |
| 🛒 E-commerce | ECOMMERCE_TEMPLATE | CUSTOMER, VENDOR, STORE_MANAGER, MARKETPLACE_ADMIN |
| 🏪 Marketplace | MARKETPLACE_TEMPLATE | BUYER, SELLER, AFFILIATE, PLATFORM_OWNER |
| 🎓 École | SCHOOL_TEMPLATE | STUDENT, TEACHER, PRINCIPAL, SUPERINTENDENT |
| 🏛️ Université | UNIVERSITY_TEMPLATE | STUDENT, PROFESSOR, DEAN, CHANCELLOR |
| 🏥 Hôpital | HOSPITAL_TEMPLATE | PATIENT, NURSE, DOCTOR, MEDICAL_DIRECTOR |
| 🍽️ Restaurant | RESTAURANT_TEMPLATE | CUSTOMER, SERVER, CHEF, OWNER |
| 🏨 Hôtel | HOTEL_TEMPLATE | GUEST, RECEPTIONIST, MANAGER, OWNER |
| 🚚 Livraison | DELIVERY_TEMPLATE | CUSTOMER, DRIVER, DISPATCHER, OPERATIONS_MANAGER |
| 💻 SaaS | SAAS_TEMPLATE | FREE_USER, PREMIUM_USER, SUPPORT_AGENT, PLATFORM_ADMIN |
| 🎮 Gaming | GAMING_TEMPLATE | PLAYER, STREAMER, MODERATOR, GAME_MASTER |
| 🏦 Banque | BANK_TEMPLATE | CUSTOMER, ADVISOR, MANAGER, DIRECTOR |
| 🏛️ Gouvernement | GOVERNMENT_TEMPLATE | CITIZEN, EMPLOYEE, MANAGER, DIRECTOR |
💡 Utilisation Avancée
$3
`typescript
import { CustomRole, deployTemplate } from '@falandy/lockbox-auth';
// Définir vos rôles personnalisés
const myCustomRoles: CustomRole[] = [
{ key: 'VISITOR', value: 'VISITOR', level: 1, description: 'Visiteur' },
{ key: 'MEMBER', value: 'MEMBER', level: 5, description: 'Membre' },
{ key: 'PREMIUM', value: 'PREMIUM', level: 8, description: 'Membre premium' },
{ key: 'ADMIN', value: 'ADMIN', level: 15, description: 'Administrateur' },
];
// Déployer votre modèle
deployTemplate('MYAPP', myCustomRoles);
`
$3
`typescript
// Déployer plusieurs modèles pour une app complexe
deployTemplate('BLOG', BLOG_TEMPLATE);
deployTemplate('SHOP', ECOMMERCE_TEMPLATE);
deployTemplate('SUPPORT', SAAS_TEMPLATE);
// Maintenant vous avez tous ces rôles :
// BLOG_WRITER, SHOP_VENDOR, SUPPORT_AGENT, etc.
`
$3
`typescript
import {
getDeployedRoles,
getActiveTemplates,
getRoleStats,
hasRolePermission
} from '@falandy/lockbox-auth';
// Voir tous les rôles déployés
console.log(getDeployedRoles());
// Voir les modèles actifs
console.log(getActiveTemplates());
console.log(getRoleStats());
const canEdit = hasRolePermission('BLOG_WRITER', 'BLOG_READER');
`
🔐 Authentification Complète
`typescript
import express from 'express';
import {
createAuthRouter,
requireAuth,
requireRole,
deployTemplate,
BLOG_TEMPLATE,
} from '@falandy/lockbox-auth';
const app = express();
// 1. Déployer vos modèles
deployTemplate('BLOG', BLOG_TEMPLATE);
// 2. Configuration auth
const authConfig = {
jwtSecret: process.env.JWT_SECRET!,
refreshTTL: 7, // 7 jours
temporaryPassword: {
enabled: true,
length: 12,
expiryHours: 24,
},
};
// 3. Routes d'authentification
app.use('/auth', createAuthRouter(authConfig));
// 4. Routes protégées
app.get('/profile', requireAuth(authConfig.jwtSecret), (req, res) => {
res.json({ user: req.user });
});
app.get('/write', requireRole('BLOG_WRITER'), (req, res) => {
res.json({ message: 'Zone de rédaction' });
});
app.get('/admin', requireRole('BLOG_CHIEF_EDITOR'), (req, res) => {
res.json({ message: 'Zone d\'administration' });
});
`
⚡ Configuration Rapide
$3
`bash
.env
JWT_SECRET=your-super-secret-key
LOCKBOX_COMPANY_NAME="Mon Entreprise"
LOCKBOX_EMAIL_FROM="noreply@monentreprise.com"
Email (optionnel)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASSWORD=your-app-password
`
$3
`bash
Initialiser Prisma
npx prisma init
npx prisma migrate dev
`
�️ Interface CLI
Lockbox Auth inclut un CLI puissant pour gérer vos modèles et configurations depuis le terminal :
`bash
Voir l'état de vos rôles
lockbox-auth status
Afficher les informations du package
lockbox-auth info
Exporter votre configuration
lockbox-auth export ./backup-roles.json
Synchroniser la base de données
lockbox-auth db-sync
Réinitialiser tous les rôles
lockbox-auth reset-all
`
$3
- Surveillance en temps réel de vos rôles déployés
- Sauvegarde/restauration facile de vos configurations
- Debug rapide pour voir l'état du système
- Synchronisation DB en une commande
👉 Guide CLI Complet
�📚 Documentation Complète
- 🚀 Guide de Démarrage Rapide
- 🎨 Modèles Sectoriels
- 🔧 Rôles Personnalisés
- 🖥️ Utilisation du CLI
- 📧 Configuration Email
- 🔑 Mots de Passe Temporaires
- 🚀 Déploiement
- 📖 Référence Rapide
🌟 Avantages du Système de Modèles
$3
- ❌ Créer un système de rôles from scratch
- ❌ Gérer manuellement les hiérarchies
- ❌ Coder les middlewares d'autorisation
- ❌ Écrire les fonctions de validation
- ❌ Temps : 2-3 semaines
$3
- ✅ deployTemplate('BLOG', BLOG_TEMPLATE) - 1 ligne
- ✅ Hiérarchies automatiques
- ✅ Middlewares inclus
- ✅ Validation intégrée
- ✅ Temps : 5 minutes
🛠️ Migration depuis l'Ancien Système
Si vous utilisiez l'ancienne version avec USER_ROLES statique :
`typescript
// ❌ Ancien (ne marche plus)
import { USER_ROLES } from '@falandy/lockbox-auth';
// ✅ Nouveau (recommandé)
import { deployTemplate, BLOG_TEMPLATE } from '@falandy/lockbox-auth';
deployTemplate('BLOG', BLOG_TEMPLATE);
`
🤝 Contribuer
`bash
git clone https://github.com/falandy/lockbox-auth
cd lockbox-auth
npm install
npm run dev
`
📄 Licence
MIT © Falandy
---
🎉 Application Blog Complète - Configuration Rapide
`typescript
import express from 'express';
import { deployTemplate, BLOG_TEMPLATE, createAuthRouter, requireRole } from '@falandy/lockbox-auth';
const app = express();
app.use(express.json());
// 1. Déployer le modèle blog
deployTemplate('BLOG', BLOG_TEMPLATE);
// 2. Configuration
const authConfig = { jwtSecret: 'secret', refreshTTL: 7 };
// 3. Routes
app.use('/auth', createAuthRouter(authConfig));
// 4. Routes protégées
app.get('/articles', requireRole('BLOG_READER'), (req, res) => {
res.json({ articles: ['Article 1', 'Article 2'] });
});
app.post('/articles', requireRole('BLOG_WRITER'), (req, res) => {
res.json({ message: 'Article créé !' });
});
app.delete('/articles/:id', requireRole('BLOG_EDITOR'), (req, res) => {
res.json({ message: 'Article supprimé !' });
});
app.listen(3000);
console.log('🚀 App blog avec système de rôles en quelques lignes !');
``