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.
@@ -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>&copy; ${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
- // Create auth routes and middleware
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', { title: '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
- // Implement login logic here
1268
- res.redirect('/');
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
- // Implement logout logic here
1273
- res.redirect('/');
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>&copy; ${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>&copy; ${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
@@ -21,7 +21,7 @@ const program = new Command();
21
21
  program
22
22
  .name('vako')
23
23
  .description('Vako Framework CLI')
24
- .version('1.3.18');
24
+ .version('1.3.19');
25
25
 
26
26
  // ============= DEV COMMAND =============
27
27
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vako",
3
- "version": "1.3.18",
3
+ "version": "1.3.19",
4
4
  "description": "🚀 Ultra-modern Node.js framework with hot reload, plugins, authentication, TypeScript support, and Next.js integration",
5
5
  "main": "index.js",
6
6
  "types": "types/index.d.ts",