vako 1.3.18 → 1.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/commands/setup-executor.js +389 -6
- package/bin/vako.js +1 -1
- package/package.json +1 -1
|
@@ -398,6 +398,70 @@ router.get('/api/status', (req, res) => {
|
|
|
398
398
|
module.exports = router;
|
|
399
399
|
`;
|
|
400
400
|
|
|
401
|
+
// routes/auth.js (créé seulement si auth est activé, mais on le crée toujours pour éviter les erreurs)
|
|
402
|
+
if (this.config.auth && this.config.auth.enabled) {
|
|
403
|
+
files['routes/auth.js'] = `const { Router } = require('express');
|
|
404
|
+
const router = Router();
|
|
405
|
+
|
|
406
|
+
// Page de connexion
|
|
407
|
+
router.get('/login', (req, res) => {
|
|
408
|
+
res.render('auth/login', {
|
|
409
|
+
title: 'Login - ${projectName}',
|
|
410
|
+
error: req.query.error || null
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// Traitement de la connexion
|
|
415
|
+
router.post('/login', async (req, res) => {
|
|
416
|
+
const { username, password } = req.body;
|
|
417
|
+
|
|
418
|
+
// TODO: Implémenter la logique d'authentification
|
|
419
|
+
// Exemple basique (à remplacer par une vraie authentification)
|
|
420
|
+
if (username && password) {
|
|
421
|
+
// Ici vous devriez vérifier les credentials dans la base de données
|
|
422
|
+
req.session.userId = username; // Exemple simple
|
|
423
|
+
return res.redirect('/');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
res.redirect('/auth/login?error=invalid_credentials');
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// Page d'inscription
|
|
430
|
+
router.get('/register', (req, res) => {
|
|
431
|
+
res.render('auth/register', {
|
|
432
|
+
title: 'Register - ${projectName}',
|
|
433
|
+
error: req.query.error || null
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Traitement de l'inscription
|
|
438
|
+
router.post('/register', async (req, res) => {
|
|
439
|
+
const { username, email, password } = req.body;
|
|
440
|
+
|
|
441
|
+
// TODO: Implémenter la logique d'inscription
|
|
442
|
+
// Exemple basique (à remplacer par une vraie logique)
|
|
443
|
+
if (username && email && password) {
|
|
444
|
+
// Ici vous devriez créer l'utilisateur dans la base de données
|
|
445
|
+
return res.redirect('/auth/login?success=registered');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
res.redirect('/auth/register?error=missing_fields');
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Déconnexion
|
|
452
|
+
router.get('/logout', (req, res) => {
|
|
453
|
+
req.session.destroy((err) => {
|
|
454
|
+
if (err) {
|
|
455
|
+
console.error('Error destroying session:', err);
|
|
456
|
+
}
|
|
457
|
+
res.redirect('/');
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
module.exports = router;
|
|
462
|
+
`;
|
|
463
|
+
}
|
|
464
|
+
|
|
401
465
|
// views/index.ejs
|
|
402
466
|
const langAttr = language === 'multi' ? 'fr' : language;
|
|
403
467
|
files['views/index.ejs'] = `<!DOCTYPE html>
|
|
@@ -823,6 +887,70 @@ footer a:hover {
|
|
|
823
887
|
max-width: 300px;
|
|
824
888
|
}
|
|
825
889
|
}
|
|
890
|
+
`;
|
|
891
|
+
|
|
892
|
+
// views/error.ejs
|
|
893
|
+
files['views/error.ejs'] = `<!DOCTYPE html>
|
|
894
|
+
<html lang="${langAttr}">
|
|
895
|
+
<head>
|
|
896
|
+
<meta charset="UTF-8">
|
|
897
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
898
|
+
<title><%= title %></title>
|
|
899
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
900
|
+
<style>
|
|
901
|
+
.error-container {
|
|
902
|
+
text-align: center;
|
|
903
|
+
padding: 4rem 2rem;
|
|
904
|
+
max-width: 600px;
|
|
905
|
+
margin: 0 auto;
|
|
906
|
+
}
|
|
907
|
+
.error-code {
|
|
908
|
+
font-size: 6rem;
|
|
909
|
+
font-weight: bold;
|
|
910
|
+
color: var(--danger-color);
|
|
911
|
+
margin-bottom: 1rem;
|
|
912
|
+
}
|
|
913
|
+
.error-message {
|
|
914
|
+
font-size: 1.5rem;
|
|
915
|
+
margin-bottom: 2rem;
|
|
916
|
+
color: var(--gray);
|
|
917
|
+
}
|
|
918
|
+
</style>
|
|
919
|
+
</head>
|
|
920
|
+
<body>
|
|
921
|
+
<header>
|
|
922
|
+
<nav>
|
|
923
|
+
<div class="container">
|
|
924
|
+
<h1 class="logo">${projectName}</h1>
|
|
925
|
+
<ul class="nav-menu">
|
|
926
|
+
<li><a href="/">Home</a></li>
|
|
927
|
+
<li><a href="/about">About</a></li>
|
|
928
|
+
</ul>
|
|
929
|
+
</div>
|
|
930
|
+
</nav>
|
|
931
|
+
</header>
|
|
932
|
+
|
|
933
|
+
<main>
|
|
934
|
+
<div class="error-container">
|
|
935
|
+
<div class="error-code"><%= error.status || 500 %></div>
|
|
936
|
+
<h1><%= title %></h1>
|
|
937
|
+
<p class="error-message"><%= message %></p>
|
|
938
|
+
<% if (error.stack && process.env.NODE_ENV === 'development') { %>
|
|
939
|
+
<pre style="text-align: left; background: #f5f5f5; padding: 1rem; border-radius: 8px; overflow-x: auto;"><%= error.stack %></pre>
|
|
940
|
+
<% } %>
|
|
941
|
+
<div class="cta-buttons" style="margin-top: 2rem;">
|
|
942
|
+
<a href="/" class="btn btn-primary">Go Home</a>
|
|
943
|
+
</div>
|
|
944
|
+
</div>
|
|
945
|
+
</main>
|
|
946
|
+
|
|
947
|
+
<footer>
|
|
948
|
+
<div class="container">
|
|
949
|
+
<p>© ${new Date().getFullYear()} ${projectName}. Built with <a href="https://vako.js.org" target="_blank">Vako</a>.</p>
|
|
950
|
+
</div>
|
|
951
|
+
</footer>
|
|
952
|
+
</body>
|
|
953
|
+
</html>
|
|
826
954
|
`;
|
|
827
955
|
|
|
828
956
|
// public/js/main.js
|
|
@@ -1255,22 +1383,75 @@ coverage/
|
|
|
1255
1383
|
|
|
1256
1384
|
async setupAuthentication() {
|
|
1257
1385
|
if (this.config.auth.enabled) {
|
|
1258
|
-
//
|
|
1386
|
+
// S'assurer que le dossier routes existe
|
|
1387
|
+
const routesDir = path.join(this.projectPath, 'routes');
|
|
1388
|
+
if (!fs.existsSync(routesDir)) {
|
|
1389
|
+
fs.mkdirSync(routesDir, { recursive: true });
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
// S'assurer que le dossier views/auth existe pour les templates
|
|
1393
|
+
const authViewsDir = path.join(this.projectPath, 'views', 'auth');
|
|
1394
|
+
if (!fs.existsSync(authViewsDir)) {
|
|
1395
|
+
fs.mkdirSync(authViewsDir, { recursive: true });
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
// Create auth routes
|
|
1259
1399
|
const authRoute = `const { Router } = require('express');
|
|
1260
1400
|
const router = Router();
|
|
1261
1401
|
|
|
1402
|
+
// Page de connexion
|
|
1262
1403
|
router.get('/login', (req, res) => {
|
|
1263
|
-
res.render('auth/login', {
|
|
1404
|
+
res.render('auth/login', {
|
|
1405
|
+
title: 'Login - ${this.config.projectName}',
|
|
1406
|
+
error: req.query.error || null
|
|
1407
|
+
});
|
|
1264
1408
|
});
|
|
1265
1409
|
|
|
1410
|
+
// Traitement de la connexion
|
|
1266
1411
|
router.post('/login', async (req, res) => {
|
|
1267
|
-
|
|
1268
|
-
|
|
1412
|
+
const { username, password } = req.body;
|
|
1413
|
+
|
|
1414
|
+
// TODO: Implémenter la logique d'authentification
|
|
1415
|
+
// Exemple basique (à remplacer par une vraie authentification)
|
|
1416
|
+
if (username && password) {
|
|
1417
|
+
// Ici vous devriez vérifier les credentials dans la base de données
|
|
1418
|
+
req.session.userId = username; // Exemple simple
|
|
1419
|
+
return res.redirect('/');
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
res.redirect('/login?error=invalid_credentials');
|
|
1423
|
+
});
|
|
1424
|
+
|
|
1425
|
+
// Page d'inscription
|
|
1426
|
+
router.get('/register', (req, res) => {
|
|
1427
|
+
res.render('auth/register', {
|
|
1428
|
+
title: 'Register - ${this.config.projectName}',
|
|
1429
|
+
error: req.query.error || null
|
|
1430
|
+
});
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
// Traitement de l'inscription
|
|
1434
|
+
router.post('/register', async (req, res) => {
|
|
1435
|
+
const { username, email, password } = req.body;
|
|
1436
|
+
|
|
1437
|
+
// TODO: Implémenter la logique d'inscription
|
|
1438
|
+
// Exemple basique (à remplacer par une vraie logique)
|
|
1439
|
+
if (username && email && password) {
|
|
1440
|
+
// Ici vous devriez créer l'utilisateur dans la base de données
|
|
1441
|
+
return res.redirect('/login?success=registered');
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
res.redirect('/register?error=missing_fields');
|
|
1269
1445
|
});
|
|
1270
1446
|
|
|
1447
|
+
// Déconnexion
|
|
1271
1448
|
router.get('/logout', (req, res) => {
|
|
1272
|
-
|
|
1273
|
-
|
|
1449
|
+
req.session.destroy((err) => {
|
|
1450
|
+
if (err) {
|
|
1451
|
+
console.error('Error destroying session:', err);
|
|
1452
|
+
}
|
|
1453
|
+
res.redirect('/');
|
|
1454
|
+
});
|
|
1274
1455
|
});
|
|
1275
1456
|
|
|
1276
1457
|
module.exports = router;
|
|
@@ -1278,6 +1459,208 @@ module.exports = router;
|
|
|
1278
1459
|
|
|
1279
1460
|
const authPath = path.join(this.projectPath, 'routes/auth.js');
|
|
1280
1461
|
fs.writeFileSync(authPath, authRoute, 'utf8');
|
|
1462
|
+
|
|
1463
|
+
// Créer les vues d'authentification
|
|
1464
|
+
const loginView = `<!DOCTYPE html>
|
|
1465
|
+
<html lang="${this.config.language === 'multi' ? 'fr' : this.config.language || 'fr'}">
|
|
1466
|
+
<head>
|
|
1467
|
+
<meta charset="UTF-8">
|
|
1468
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1469
|
+
<title><%= title %></title>
|
|
1470
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
1471
|
+
<style>
|
|
1472
|
+
.auth-container {
|
|
1473
|
+
max-width: 400px;
|
|
1474
|
+
margin: 4rem auto;
|
|
1475
|
+
padding: 2rem;
|
|
1476
|
+
background: var(--white);
|
|
1477
|
+
border-radius: var(--border-radius);
|
|
1478
|
+
box-shadow: var(--shadow);
|
|
1479
|
+
}
|
|
1480
|
+
.auth-container h1 {
|
|
1481
|
+
text-align: center;
|
|
1482
|
+
margin-bottom: 2rem;
|
|
1483
|
+
color: var(--primary-color);
|
|
1484
|
+
}
|
|
1485
|
+
.form-group {
|
|
1486
|
+
margin-bottom: 1.5rem;
|
|
1487
|
+
}
|
|
1488
|
+
.form-group label {
|
|
1489
|
+
display: block;
|
|
1490
|
+
margin-bottom: 0.5rem;
|
|
1491
|
+
color: var(--dark-color);
|
|
1492
|
+
font-weight: 500;
|
|
1493
|
+
}
|
|
1494
|
+
.form-group input {
|
|
1495
|
+
width: 100%;
|
|
1496
|
+
padding: 0.75rem;
|
|
1497
|
+
border: 1px solid #ddd;
|
|
1498
|
+
border-radius: var(--border-radius);
|
|
1499
|
+
font-size: 1rem;
|
|
1500
|
+
}
|
|
1501
|
+
.form-group input:focus {
|
|
1502
|
+
outline: none;
|
|
1503
|
+
border-color: var(--primary-color);
|
|
1504
|
+
}
|
|
1505
|
+
.error-message {
|
|
1506
|
+
background: var(--danger-color);
|
|
1507
|
+
color: var(--white);
|
|
1508
|
+
padding: 0.75rem;
|
|
1509
|
+
border-radius: var(--border-radius);
|
|
1510
|
+
margin-bottom: 1rem;
|
|
1511
|
+
text-align: center;
|
|
1512
|
+
}
|
|
1513
|
+
</style>
|
|
1514
|
+
</head>
|
|
1515
|
+
<body>
|
|
1516
|
+
<header>
|
|
1517
|
+
<nav>
|
|
1518
|
+
<div class="container">
|
|
1519
|
+
<h1 class="logo">${this.config.projectName}</h1>
|
|
1520
|
+
<ul class="nav-menu">
|
|
1521
|
+
<li><a href="/">Home</a></li>
|
|
1522
|
+
<li><a href="/login" class="active">Login</a></li>
|
|
1523
|
+
<li><a href="/register">Register</a></li>
|
|
1524
|
+
</ul>
|
|
1525
|
+
</div>
|
|
1526
|
+
</nav>
|
|
1527
|
+
</header>
|
|
1528
|
+
|
|
1529
|
+
<main>
|
|
1530
|
+
<div class="auth-container">
|
|
1531
|
+
<h1>Login</h1>
|
|
1532
|
+
<% if (error) { %>
|
|
1533
|
+
<div class="error-message">Invalid credentials. Please try again.</div>
|
|
1534
|
+
<% } %>
|
|
1535
|
+
<form method="POST" action="/login">
|
|
1536
|
+
<div class="form-group">
|
|
1537
|
+
<label for="username">Username</label>
|
|
1538
|
+
<input type="text" id="username" name="username" required>
|
|
1539
|
+
</div>
|
|
1540
|
+
<div class="form-group">
|
|
1541
|
+
<label for="password">Password</label>
|
|
1542
|
+
<input type="password" id="password" name="password" required>
|
|
1543
|
+
</div>
|
|
1544
|
+
<button type="submit" class="btn btn-primary" style="width: 100%;">Login</button>
|
|
1545
|
+
</form>
|
|
1546
|
+
<p style="text-align: center; margin-top: 1rem;">
|
|
1547
|
+
Don't have an account? <a href="/register">Register here</a>
|
|
1548
|
+
</p>
|
|
1549
|
+
</div>
|
|
1550
|
+
</main>
|
|
1551
|
+
|
|
1552
|
+
<footer>
|
|
1553
|
+
<div class="container">
|
|
1554
|
+
<p>© ${new Date().getFullYear()} ${this.config.projectName}. Built with <a href="https://vako.js.org" target="_blank">Vako</a>.</p>
|
|
1555
|
+
</div>
|
|
1556
|
+
</footer>
|
|
1557
|
+
</body>
|
|
1558
|
+
</html>
|
|
1559
|
+
`;
|
|
1560
|
+
|
|
1561
|
+
const registerView = `<!DOCTYPE html>
|
|
1562
|
+
<html lang="${this.config.language === 'multi' ? 'fr' : this.config.language || 'fr'}">
|
|
1563
|
+
<head>
|
|
1564
|
+
<meta charset="UTF-8">
|
|
1565
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1566
|
+
<title><%= title %></title>
|
|
1567
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
1568
|
+
<style>
|
|
1569
|
+
.auth-container {
|
|
1570
|
+
max-width: 400px;
|
|
1571
|
+
margin: 4rem auto;
|
|
1572
|
+
padding: 2rem;
|
|
1573
|
+
background: var(--white);
|
|
1574
|
+
border-radius: var(--border-radius);
|
|
1575
|
+
box-shadow: var(--shadow);
|
|
1576
|
+
}
|
|
1577
|
+
.auth-container h1 {
|
|
1578
|
+
text-align: center;
|
|
1579
|
+
margin-bottom: 2rem;
|
|
1580
|
+
color: var(--primary-color);
|
|
1581
|
+
}
|
|
1582
|
+
.form-group {
|
|
1583
|
+
margin-bottom: 1.5rem;
|
|
1584
|
+
}
|
|
1585
|
+
.form-group label {
|
|
1586
|
+
display: block;
|
|
1587
|
+
margin-bottom: 0.5rem;
|
|
1588
|
+
color: var(--dark-color);
|
|
1589
|
+
font-weight: 500;
|
|
1590
|
+
}
|
|
1591
|
+
.form-group input {
|
|
1592
|
+
width: 100%;
|
|
1593
|
+
padding: 0.75rem;
|
|
1594
|
+
border: 1px solid #ddd;
|
|
1595
|
+
border-radius: var(--border-radius);
|
|
1596
|
+
font-size: 1rem;
|
|
1597
|
+
}
|
|
1598
|
+
.form-group input:focus {
|
|
1599
|
+
outline: none;
|
|
1600
|
+
border-color: var(--primary-color);
|
|
1601
|
+
}
|
|
1602
|
+
.error-message {
|
|
1603
|
+
background: var(--danger-color);
|
|
1604
|
+
color: var(--white);
|
|
1605
|
+
padding: 0.75rem;
|
|
1606
|
+
border-radius: var(--border-radius);
|
|
1607
|
+
margin-bottom: 1rem;
|
|
1608
|
+
text-align: center;
|
|
1609
|
+
}
|
|
1610
|
+
</style>
|
|
1611
|
+
</head>
|
|
1612
|
+
<body>
|
|
1613
|
+
<header>
|
|
1614
|
+
<nav>
|
|
1615
|
+
<div class="container">
|
|
1616
|
+
<h1 class="logo">${this.config.projectName}</h1>
|
|
1617
|
+
<ul class="nav-menu">
|
|
1618
|
+
<li><a href="/">Home</a></li>
|
|
1619
|
+
<li><a href="/login">Login</a></li>
|
|
1620
|
+
<li><a href="/register" class="active">Register</a></li>
|
|
1621
|
+
</ul>
|
|
1622
|
+
</div>
|
|
1623
|
+
</nav>
|
|
1624
|
+
</header>
|
|
1625
|
+
|
|
1626
|
+
<main>
|
|
1627
|
+
<div class="auth-container">
|
|
1628
|
+
<h1>Register</h1>
|
|
1629
|
+
<% if (error) { %>
|
|
1630
|
+
<div class="error-message">Please fill all fields.</div>
|
|
1631
|
+
<% } %>
|
|
1632
|
+
<form method="POST" action="/register">
|
|
1633
|
+
<div class="form-group">
|
|
1634
|
+
<label for="username">Username</label>
|
|
1635
|
+
<input type="text" id="username" name="username" required>
|
|
1636
|
+
</div>
|
|
1637
|
+
<div class="form-group">
|
|
1638
|
+
<label for="email">Email</label>
|
|
1639
|
+
<input type="email" id="email" name="email" required>
|
|
1640
|
+
</div>
|
|
1641
|
+
<div class="form-group">
|
|
1642
|
+
<label for="password">Password</label>
|
|
1643
|
+
<input type="password" id="password" name="password" required>
|
|
1644
|
+
</div>
|
|
1645
|
+
<button type="submit" class="btn btn-primary" style="width: 100%;">Register</button>
|
|
1646
|
+
</form>
|
|
1647
|
+
<p style="text-align: center; margin-top: 1rem;">
|
|
1648
|
+
Already have an account? <a href="/login">Login here</a>
|
|
1649
|
+
</p>
|
|
1650
|
+
</div>
|
|
1651
|
+
</main>
|
|
1652
|
+
|
|
1653
|
+
<footer>
|
|
1654
|
+
<div class="container">
|
|
1655
|
+
<p>© ${new Date().getFullYear()} ${this.config.projectName}. Built with <a href="https://vako.js.org" target="_blank">Vako</a>.</p>
|
|
1656
|
+
</div>
|
|
1657
|
+
</footer>
|
|
1658
|
+
</body>
|
|
1659
|
+
</html>
|
|
1660
|
+
`;
|
|
1661
|
+
|
|
1662
|
+
fs.writeFileSync(path.join(authViewsDir, 'login.ejs'), loginView, 'utf8');
|
|
1663
|
+
fs.writeFileSync(path.join(authViewsDir, 'register.ejs'), registerView, 'utf8');
|
|
1281
1664
|
}
|
|
1282
1665
|
}
|
|
1283
1666
|
|
package/bin/vako.js
CHANGED
package/package.json
CHANGED