binhend 2.0.8 → 2.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binhend",
3
- "version": "2.0.8",
3
+ "version": "2.1.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "Nguyen Duc Binh",
package/src/api/loader.js CHANGED
@@ -2,6 +2,7 @@ const { readdirSync, statSync } = require('fs');
2
2
  const { join, parse, resolve } = require('path');
3
3
  const { isUndefined } = require('../utils/typeOf');
4
4
  const { server } = require('../server');
5
+ const { cors } = require('../cors');
5
6
  const express = require('express');
6
7
  const parseBasicAuthToken = require('../middleware/parseBasicAuthToken');
7
8
 
@@ -49,7 +50,8 @@ function loadRouter(dirPath) {
49
50
  return router;
50
51
  }
51
52
 
52
- function loadRoutes(dirPath) {
53
+ function loadRoutes(dirPath, corsOptions) {
54
+ server.use(cors(corsOptions));
53
55
  const router = loadRouter(dirPath);
54
56
  server.use(router);
55
57
  }
package/src/binh.js CHANGED
@@ -2,6 +2,7 @@
2
2
  const typeOf = require('./utils/typeOf');
3
3
  const security = require('./security');
4
4
  const createCSD = require('./csd');
5
+ const cors = require('./cors');
5
6
  const { server } = require('./server');
6
7
  const { loadRouter, loadRoutes, mapRoutes, trycatch, Router, HttpError } = require('./api');
7
8
  const { ConfigLoader } = require('./configuration');
@@ -15,6 +16,7 @@ module.exports = {
15
16
  typeOf,
16
17
  security,
17
18
  createCSD,
19
+ cors,
18
20
  server,
19
21
  loadRouter, loadRoutes, mapRoutes, trycatch, Router, HttpError,
20
22
  ConfigLoader,
package/src/cors.js ADDED
@@ -0,0 +1,61 @@
1
+
2
+ const { isArray, mustArray, mustNumber } = require('./utils/typeOf');
3
+
4
+ const defaultOptions = {
5
+ origins: [],
6
+ credentials: true,
7
+ methods: ['GET', 'POST', 'PUT', 'DELETE'],
8
+ preflightContinue: false,
9
+ optionsSuccessStatus: 204, // No Content
10
+ exposedHeaders: [],
11
+ allowHeaders: ['Content-Type', 'Authorization'],
12
+ maxAge: 600 // seconds
13
+ }
14
+
15
+ function arrayToString(array) {
16
+ return isArray(array) ? array.join(',') : '';
17
+ }
18
+
19
+ function addHeader(response, key, value) {
20
+ if (value) response.header(key, value.toString());
21
+ }
22
+
23
+ module.exports = (options) => {
24
+ // Parse options
25
+ var { origins, credentials, methods, preflightContinue, optionsSuccessStatus, exposedHeaders, allowHeaders, maxAge } = Object.assign({}, defaultOptions, options);
26
+
27
+ const allowedOrigins = mustArray(origins);
28
+
29
+ // Create a new middleware
30
+ return function (req, res, next) {
31
+ const origin = req.headers.origin;
32
+
33
+ // Same-origin request, skip CORS
34
+ if (origin === undefined) return next();
35
+
36
+ // Verify allowed origins
37
+ const allowedOrigin = allowedOrigins.length === 0 || allowedOrigins.includes(origin) ? origin : '';
38
+ res.header('Access-Control-Allow-Origin', allowedOrigin);
39
+
40
+ if (!allowedOrigin) {
41
+ console.error(`Blocked by CORS: ${origin}`);
42
+ return res.sendStatus(403); // Forbidden
43
+ }
44
+
45
+ // Set CORS headers
46
+ addHeader(res, 'Access-Control-Allow-Credentials', !!credentials);
47
+ addHeader(res, 'Access-Control-Allow-Methods', arrayToString(methods));
48
+ addHeader(res, 'Access-Control-Expose-Headers', arrayToString(exposedHeaders));
49
+ addHeader(res, 'Access-Control-Allow-Headers', arrayToString(allowHeaders));
50
+
51
+ // Cache preflight response
52
+ addHeader(res, 'Access-Control-Max-Age', mustNumber(maxAge));
53
+
54
+ // Handle preflight OPTIONS request
55
+ if (req.method === 'OPTIONS' && !preflightContinue) {
56
+ return res.sendStatus(mustNumber(optionsSuccessStatus, 204));
57
+ }
58
+
59
+ return next();
60
+ }
61
+ };
@@ -11,20 +11,22 @@ function isEmptyObject(input) {
11
11
  return isObject(input) && Object.keys(input).length === 0;
12
12
  }
13
13
 
14
- function isArray(input) {
15
- return Array.isArray(input);
16
- }
14
+ const { isArray } = Array;
17
15
 
18
16
  function isEmptyArray(input) {
19
17
  return isArray(input) && input.length === 0;
20
18
  }
21
19
 
20
+ function mustArray(input, defaultOutput = []) {
21
+ return isArray(input) ? input : isArray(defaultOutput) ? defaultOutput : [defaultOutput];
22
+ }
23
+
22
24
  function isFunction(input) {
23
25
  return typeof input === 'function';
24
26
  }
25
27
 
26
28
  function isString(input) {
27
- return typeOf(input) === 'String';
29
+ return typeof input === 'string' || typeOf(input) === 'String';
28
30
  }
29
31
 
30
32
  function isEmptyString(input) {
@@ -32,7 +34,11 @@ function isEmptyString(input) {
32
34
  }
33
35
 
34
36
  function isNumber(input) {
35
- return typeOf(input) === 'Number';
37
+ return typeof input === 'number' || typeOf(input) === 'Number';
38
+ }
39
+
40
+ function mustNumber(input, defaultValue) {
41
+ return isNumber(input) ? input : isNumber(defaultValue) ? defaultValue : 0;
36
42
  }
37
43
 
38
44
  function isBigInt(input) {
@@ -44,7 +50,7 @@ function isSymbol(input) {
44
50
  }
45
51
 
46
52
  function isBoolean(input) {
47
- return typeOf(input) === 'Boolean';
53
+ return typeof input === 'boolean' || typeOf(input) === 'Boolean';
48
54
  }
49
55
 
50
56
  function isNull(input) {
@@ -65,12 +71,14 @@ module.exports = Object.assign(typeOf, {
65
71
  isEmptyObject,
66
72
  isArray,
67
73
  isEmptyArray,
74
+ mustArray,
68
75
  isFunction,
69
76
  isNull,
70
77
  isUndefined,
71
78
  isNullOrUndefined,
72
79
  isBoolean,
73
80
  isNumber,
81
+ mustNumber,
74
82
  isString,
75
83
  isEmptyString,
76
84
  isSymbol,