slower 1.1.12 → 1.1.13

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/lib/router.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const http = require('http');
2
2
  const fs = require('fs');
3
- const { noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders } = require('./utils');
3
+ const { clone, noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders } = require('./utils');
4
4
 
5
5
  class Route {
6
6
  constructor (path, type, callback) {
@@ -37,7 +37,7 @@ class SlowerRouter {
37
37
  this.routes = [];
38
38
  this.middleware = [noop];
39
39
  this.fallback = noop;
40
- this.allowedMethods = [];
40
+ this.allowedMethods = clone(SlowerRouter.http_methods);
41
41
  this.blockedMethodCallback = noop;
42
42
  }
43
43
 
@@ -72,7 +72,7 @@ class SlowerRouter {
72
72
  setRoute = function (path = '/', type = 'GET', callback) {
73
73
  let stat = new Route(path, type, callback);
74
74
  this.routes.push(stat);
75
- return stat;
75
+ return this;
76
76
  }
77
77
 
78
78
  /**
@@ -82,13 +82,10 @@ class SlowerRouter {
82
82
  * @returns {Array} The used middlewares list
83
83
  */
84
84
  setMiddleware = function (callback) {
85
- return this.middleware.push((typeof callback == 'function' ? callback : noop));
85
+ this.middleware.push((typeof callback == 'function' ? callback : noop));
86
+ return this;
86
87
  }
87
88
 
88
- // SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
89
- // Use app.setStatic('/*', __dirname+'/') for serving all local files.
90
- // or use app.setStatic('/*', __dirname+'/public/') for serving files in a specific folder (public).
91
- // This is a one-liner for the setRoute function, when the route responds with a simple page or document
92
89
  /**
93
90
  * Defines a route for a determined request method
94
91
  * @category Router
@@ -97,8 +94,6 @@ class SlowerRouter {
97
94
  * @param {String} mime The file's mime type
98
95
  * @param {Object} replacementData The replacement data map for the dynamic HTML rendering
99
96
  * @returns {Object} An Route object already configured
100
- * @example <caption> Defining a simple GET route:</caption>
101
- * setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html', 'utf8');
102
97
  */
103
98
  /**
104
99
  * Dynamic rendering example:
@@ -117,7 +112,7 @@ class SlowerRouter {
117
112
  * age: 29
118
113
  * }));
119
114
  */
120
- setDynamic = function (path, file = '', mime = '', replacementData) {
115
+ setDynamic = function (path, file = '', mime = '', replacementData = null) {
121
116
  let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
122
117
  let stat = new Route(path, 'GET', (req, res) => {
123
118
  let data, targetFile, extension, targetMime, targetEncoding;
@@ -143,7 +138,7 @@ class SlowerRouter {
143
138
  res.end();
144
139
  });
145
140
  this.routes.push(stat);
146
- return stat;
141
+ return this;
147
142
  }
148
143
 
149
144
  // SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
@@ -156,10 +151,9 @@ class SlowerRouter {
156
151
  * @param {String} path The route that will be defined
157
152
  * @param {String} file The file path that will be used to respond to the route
158
153
  * @param {String} mime The file's mime type
159
- * @param {String} encoding The file's encoding (defaults to UTF-8)
160
154
  * @returns {Object} An Route object already configured
161
155
  * @example <caption> Defining a simple GET route:</caption>
162
- * setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html', 'utf8');
156
+ * setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html');
163
157
  */
164
158
  setStatic = function (path, file = '', mime = '') {
165
159
  let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
@@ -184,7 +178,7 @@ class SlowerRouter {
184
178
  res.end();
185
179
  });
186
180
  this.routes.push(stat);
187
- return stat;
181
+ return this;
188
182
  }
189
183
 
190
184
  /**
@@ -192,10 +186,8 @@ class SlowerRouter {
192
186
  * @category Router
193
187
  * @param {String} callback The function to execute for unhandled routes
194
188
  * @returns {undefined}
195
- * @example <caption> Defining a simple GET route:</caption>
196
- * setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html', 'utf8');
197
189
  */
198
- setFallback = function (callback) { this.fallback = callback; }
190
+ setFallback = function (callback) { this.fallback = callback; return this; }
199
191
 
200
192
  // SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
201
193
  // Use app.setStatic('/*', __dirname+'/') for serving all local files.
@@ -229,7 +221,7 @@ class SlowerRouter {
229
221
  * age: 29
230
222
  * }));
231
223
  */
232
- setFallbackFile = function (file = '', mime = '', replacementData) {
224
+ setFallbackFile = function (file = '', mime = '', replacementData = null) {
233
225
  this.fallback = function fb (req,res) {
234
226
  let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
235
227
  let data, targetFile, extension, targetMime, targetEncoding;
@@ -254,6 +246,7 @@ class SlowerRouter {
254
246
  res.write(data);
255
247
  res.end();
256
248
  }
249
+ return this;
257
250
  }
258
251
 
259
252
  // Sets the methods that the application will respond to. The rest is simply discarded with empty responses.
@@ -282,7 +275,7 @@ class SlowerRouter {
282
275
  res.writeHead(405); // sends the meme error 418 'i am a teapot'
283
276
  res.end();
284
277
  };
285
- return this.allowedMethods;
278
+ return this;
286
279
  }
287
280
 
288
281
  // Starts the server - listening at <host>:<port>
@@ -290,10 +283,8 @@ class SlowerRouter {
290
283
  * @category Router
291
284
  * @param {Number} port The port number the server will listen to.
292
285
  * @param {String} host The host's network interface address the server will listen into (use a falsy value or '0.0.0.0' for listening on all).
293
- * @param {Function} methods The methods that are allowed by the application. Methods that do not conform with standards are ignored.
294
- * @returns {Object} The AllowedMethods Array object.
295
- * @example <caption> Allowing only GET and POST:</caption>
296
- * app.setAllowedMethods(['GET', 'POST']);
286
+ * @param {Function} callback The function to execute after starting the server.
287
+ * @returns {Object<http.Server>} The server instance
297
288
  */
298
289
  start = function (port = 8080, host = undefined, callback = () => {}) {
299
290
  let routes = this.routes;
@@ -339,7 +330,8 @@ class SlowerRouter {
339
330
  });
340
331
  callback(server);
341
332
  if (!host) host = undefined; // Turn falsy values into undefined, for default behaviour
342
- return server.listen(port, host);
333
+ // return server.listen(port, host);
334
+ return this;
343
335
  }
344
336
  }
345
337
 
package/lib/utils.js CHANGED
@@ -141,4 +141,6 @@ const setSocketSecurityHeaders = (req) => {
141
141
 
142
142
  const toBool = [() => true, () => false];
143
143
 
144
- module.exports = { noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders };
144
+ const clone = (object) => JSON.parse(JSON.stringify(object));
145
+
146
+ module.exports = { clone, noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slower",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "A package for simple HTTP server routing.",
5
5
  "main": "index.js",
6
6
  "directories": {
package/readme.md CHANGED
@@ -3,6 +3,106 @@
3
3
  Slower is a small web framework, express-like, but simpler and limited.
4
4
  It allows for generic route-declaration, fallback pages, and multiple middleware functions.
5
5
 
6
+ ### API Methods:
7
+
8
+ ```
9
+ app.enableStrictHeaders(): this
10
+
11
+ > Enables the use of the set of 'Strict Headers'.
12
+ > These headers increase security levels, and are a good practice to apply.
13
+ > However, using these headers in testing scenarios are not a need,
14
+ and may have buggy or negative effects. So, apply those to simulate scenarios only.
15
+ > Headers configured:
16
+ > Content-Security-Policy
17
+ > Cross-Origin-Opener-Policy
18
+ > Cross-Origin-Resource-Policy
19
+ > Origin-Agent-Cluster
20
+ > Referrer-Policy
21
+ > X-DNS-Prefetch-Control (disabled)
22
+ > X-Download-Options
23
+ > X-Frame-Options
24
+ > X-XSS-Protection (disabled)
25
+ > X-Powered-By (removed)
26
+ > Returns the own object instance, so that methods can be chained.
27
+ ```
28
+ ```
29
+ app.disableStrictHeaders(): this
30
+
31
+ > Disables the use of the set of 'Strict Headers'.
32
+ > See 'enableStrictHeaders()' for more information.
33
+ > Returns the own object instance, so that methods can be chained.
34
+ ```
35
+ ```
36
+ app.setRoute(string: path = '/', string: type = 'GET', function: callback): this
37
+
38
+ > Creates a new route for path defined in 'path', responding to the HTTP verb defined in 'type' argument.
39
+ > The callback is executed when the route is accessed.
40
+ > Returns the own object instance, so that methods can be chained.
41
+ ```
42
+ ```
43
+ app.setMiddleware(function: callback): this
44
+
45
+ > Sets a new middleware function: callback function will be accessed for every server access.
46
+ > Many middlewares can be defined, and will be applied in the order they are defined.
47
+ > Returns the own object instance, so that methods can be chained.
48
+ ```
49
+ ```
50
+ app.setDynamic(string: path, string: file = '', string: mime = '', object: replacementData = null): this
51
+
52
+ > Creates a new GET route for path defined in 'path'.
53
+ > This is a custom file-response route, configured for template rendering just before response.
54
+ > Providing an object as 'replacementData' in this format { valueToBeReplaced: valueToReplace },
55
+ allows for template rendering. The value to replace in the file, uses this notation: '<{content}>'.
56
+ > Example:
57
+ Responding a route for '/custom' with file 'custom.html':
58
+ app.setDynamic('/custom', './templates/custom.html', 'text/html', { smile: ':)' })
59
+ In file './templates/custom.html':
60
+ "<h2> This is a custom thing: <{smile}> </h2>"
61
+ Rendered in browser:
62
+ <h2> This is a custom thing: :) </h2>
63
+ > Returns the own object instance, so that methods can be chained.
64
+ ```
65
+ ```
66
+ app.setStatic(string: path, string: file = '', string: mime = ''): this
67
+
68
+ > Creates a new GET route for path defined in 'path', responding with the specified file and MIME type.
69
+ > Example: A route for '/login' page, responding with 'login.html' file
70
+ setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html');
71
+ > Returns the own object instance, so that methods can be chained.
72
+ ```
73
+ ```
74
+ app.setFallback(function: callback): this
75
+
76
+ > Creates a function for fallback state. When no other routes intercept the route, this will be used.
77
+ > Special use for 'page not found' fallback pages or highly customized routes and situations.
78
+ > Returns the own object instance, so that methods can be chained.
79
+ ```
80
+ ```
81
+ app.setFallbackFile (string: file = '', string: mime = '', object: replacementData = null): this
82
+
83
+ > Creates a function for fallback state. When no other routes intercept the route, this will be used.
84
+ > Equivalent to setFallback, but responds with a file. Allows for template rendering.
85
+ > See 'setDynamic' for more information about template rendering.
86
+ > Special use for 'page not found' fallback pages, ex: './e404.html'.
87
+ > Returns the own object instance, so that methods can be chained.
88
+ ```
89
+ ```
90
+ app.setAllowedMethods(array: methods = []): this
91
+
92
+ > Sets a list of methods to respond to.
93
+ > By using this, it is possible to restrict the application to avoid
94
+ responding to dangerous HTTP verbs, such as 'DELETE'.
95
+ > By default, all methods are allowed (see Slower.constructor.http_methods)
96
+ > Calling this function without parameters is an easy way to block responses to all requests (lock server).
97
+ > Returns the own object instance, so that methods can be chained.
98
+ ```
99
+ ```
100
+ app.start(number|string: port = 8080, string: host = undefined, function: callback = ()=>{}): this
101
+
102
+ > Starts the server, at a specific host and port, then calling the callback function.
103
+ > Not defining a specific port or host will start the server at '0.0.0.0:8080'.
104
+ > Returns the own object instance, so that methods can be chained.
105
+ ```
6
106
 
7
107
  Example usage:
8
108
  ```
@@ -46,6 +146,7 @@ app.start(port, null, () => {
46
146
  console.log(`Running on localhost:${port}`);
47
147
  console.log(app);
48
148
  });
149
+
49
150
  ```
50
151
  ### API modifications on 'net.Socket' instances:
51
152
  - The API modifies every ```net.Socket``` instance BEFORE it is passed
@@ -71,6 +172,7 @@ So, considering the common callback of ```(req, res)```, the session container w
71
172
  methods do exacly that. The strict headers are disabled by default, as some resources are too strict,
72
173
  but it is also possible to enable them all, and then set a middleware to override any header.
73
174
  - Headers set by 'enableStrictHeaders':
175
+ ```
74
176
  Content-Security-Policy: default-src=none; script-src=self; connect-src=self; img-src=self;
75
177
  style-src=self; frame-ancestors=none; form-action=self;
76
178
  Cross-Origin-Opener-Policy: same-origin
@@ -84,3 +186,4 @@ So, considering the common callback of ```(req, res)```, the session container w
84
186
  X-Frame-Options: DENY
85
187
  X-Powered-By: (This header is removed if a response includes it)
86
188
  X-XSS-Protection: 0
189
+ ```