webspresso 0.0.0 → 0.0.2

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/README.md CHANGED
@@ -44,24 +44,6 @@ npm run dev
44
44
 
45
45
  > **Note:** New projects include Tailwind CSS by default. Use `--no-tailwind` flag to skip it.
46
46
 
47
- ### Manual Setup
48
-
49
- ```javascript
50
- // server.js
51
- const { createApp } = require('webspresso');
52
- const path = require('path');
53
-
54
- const { app } = createApp({
55
- pagesDir: path.join(__dirname, 'pages'),
56
- viewsDir: path.join(__dirname, 'views'),
57
- publicDir: path.join(__dirname, 'public')
58
- });
59
-
60
- app.listen(3000, () => {
61
- console.log('Server running at http://localhost:3000');
62
- });
63
- ```
64
-
65
47
  ## CLI Commands
66
48
 
67
49
  ### `webspresso new <project-name>`
@@ -198,6 +180,15 @@ Creates and configures the Express app.
198
180
  - `viewsDir` (optional): Path to views/layouts directory
199
181
  - `publicDir` (optional): Path to public/static directory
200
182
  - `logging` (optional): Enable request logging (default: true in development)
183
+ - `helmet` (optional): Helmet security configuration
184
+ - `true` or `undefined`: Use default secure configuration
185
+ - `false`: Disable Helmet
186
+ - `Object`: Custom Helmet configuration (merged with defaults)
187
+
188
+ **Default Helmet Configuration:**
189
+ - CSP disabled in development, enabled in production
190
+ - HSTS, XSS protection, frame guard, and other security headers enabled
191
+ - Tailwind CSS inline styles allowed in CSP
201
192
 
202
193
  **Returns:** `{ app, nunjucksEnv }`
203
194
 
package/bin/webspresso.js CHANGED
@@ -53,7 +53,7 @@ program
53
53
  start: 'NODE_ENV=production node server.js'
54
54
  },
55
55
  dependencies: {
56
- webspresso: '^1.0.0',
56
+ webspresso: '*',
57
57
  dotenv: '^16.3.1'
58
58
  }
59
59
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webspresso",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "description": "Minimal, production-ready SSR framework for Node.js with file-based routing, Nunjucks templating, built-in i18n, and CLI tooling",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -34,6 +34,7 @@
34
34
  "dependencies": {
35
35
  "commander": "^11.1.0",
36
36
  "express": "^4.18.2",
37
+ "helmet": "^7.2.0",
37
38
  "inquirer": "^8.2.6",
38
39
  "nunjucks": "^3.2.4"
39
40
  },
package/src/server.js CHANGED
@@ -4,10 +4,53 @@
4
4
  */
5
5
 
6
6
  const express = require('express');
7
+ const helmet = require('helmet');
7
8
  const nunjucks = require('nunjucks');
8
- const path = require('path');
9
+
9
10
  const { mountPages } = require('./file-router');
10
11
 
12
+ /**
13
+ * Get default Helmet configuration
14
+ * @param {boolean} isDev - Whether in development mode
15
+ * @returns {Object} Helmet configuration
16
+ */
17
+ function getDefaultHelmetConfig(isDev) {
18
+ return {
19
+ // Disable CSP in development for easier development (Nunjucks hot reload, etc.)
20
+ contentSecurityPolicy: isDev ? false : {
21
+ directives: {
22
+ defaultSrc: ["'self'"],
23
+ styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles for Tailwind
24
+ scriptSrc: ["'self'"],
25
+ imgSrc: ["'self'", "data:", "https:"],
26
+ fontSrc: ["'self'", "data:"],
27
+ connectSrc: ["'self'"],
28
+ frameSrc: ["'none'"],
29
+ objectSrc: ["'none'"],
30
+ upgradeInsecureRequests: []
31
+ }
32
+ },
33
+ // Other security headers
34
+ crossOriginEmbedderPolicy: false, // Disable for better compatibility
35
+ crossOriginOpenerPolicy: { policy: 'same-origin' },
36
+ crossOriginResourcePolicy: { policy: 'cross-origin' },
37
+ dnsPrefetchControl: true,
38
+ frameguard: { action: 'deny' },
39
+ hidePoweredBy: true,
40
+ hsts: {
41
+ maxAge: 31536000,
42
+ includeSubDomains: true,
43
+ preload: true
44
+ },
45
+ ieNoOpen: true,
46
+ noSniff: true,
47
+ originAgentCluster: true,
48
+ permittedCrossDomainPolicies: false,
49
+ referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
50
+ xssFilter: true
51
+ };
52
+ }
53
+
11
54
  /**
12
55
  * Create and configure the Express app
13
56
  * @param {Object} options - Configuration options
@@ -15,6 +58,7 @@ const { mountPages } = require('./file-router');
15
58
  * @param {string} options.viewsDir - Path to views directory
16
59
  * @param {string} options.publicDir - Path to public/static directory
17
60
  * @param {boolean} options.logging - Enable request logging (default: isDev)
61
+ * @param {Object|boolean} options.helmet - Helmet configuration (default: auto-configured, false to disable)
18
62
  * @returns {Object} { app, nunjucksEnv }
19
63
  */
20
64
  function createApp(options = {}) {
@@ -26,7 +70,8 @@ function createApp(options = {}) {
26
70
  pagesDir,
27
71
  viewsDir,
28
72
  publicDir,
29
- logging = isDev && !isTest
73
+ logging = isDev && !isTest,
74
+ helmet: helmetConfig
30
75
  } = options;
31
76
 
32
77
  if (!pagesDir) {
@@ -35,6 +80,16 @@ function createApp(options = {}) {
35
80
 
36
81
  const app = express();
37
82
 
83
+ // Security headers with Helmet
84
+ if (helmetConfig !== false) {
85
+ const defaultConfig = getDefaultHelmetConfig(isDev);
86
+ const finalConfig = helmetConfig === undefined || helmetConfig === true
87
+ ? defaultConfig
88
+ : { ...defaultConfig, ...helmetConfig };
89
+
90
+ app.use(helmet(finalConfig));
91
+ }
92
+
38
93
  // Trust proxy (for correct req.ip, req.protocol behind reverse proxy)
39
94
  app.set('trust proxy', 1);
40
95