@mimik/mongooser 1.3.1 → 1.8.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/.eslintrc CHANGED
@@ -1,22 +1,34 @@
1
- // Use this file as a starting point for your project's .eslintrc.
2
- // Copy this file, and add rule overrides as needed.
3
1
  {
2
+ "plugins": [
3
+ "@mimik/document-env",
4
+ "@mimik/dependencies"
5
+ ],
4
6
  "env": {
5
7
  "node": true
6
8
  },
9
+ "parserOptions": {
10
+ "ecmaVersion": 2020
11
+ },
7
12
  "extends": "airbnb",
8
13
  "rules": {
9
- "import/no-extraneous-dependencies": ["error", {"devDependencies": true}],
10
- "brace-style": [1, "stroustrup", {"allowSingleLine": true}],
14
+ "import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
15
+ "import/no-unresolved": ["error", { "amd": true, "commonjs": true, "caseSensitiveStrict": true }],
16
+ "brace-style": [1, "stroustrup", { "allowSingleLine": true }],
11
17
  "no-confusing-arrow": [0], // arrow isnt confusing
12
18
  "max-len": [1, 180, { "ignoreComments": true }],
13
19
  "linebreak-style": 0,
14
20
  "quotes": [1, "single"],
15
- "semi": [1, "always"]
21
+ "semi": [1, "always"],
22
+ "no-process-env": ["error"],
23
+ "@mimik/document-env/validate-document-env": 2,
24
+ "@mimik/dependencies/case-sensitive": 2,
25
+ "@mimik/dependencies/no-cycles": 2,
26
+ "@mimik/dependencies/no-unresolved": 2,
27
+ "@mimik/dependencies/require-json-ext": 2
16
28
  },
17
29
  "settings":{
18
30
  "react": {
19
- "version": "latest"
31
+ "version": "detect"
20
32
  }
21
33
  },
22
34
  "globals": {
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run commit-ready
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run test
package/README.md CHANGED
@@ -10,7 +10,8 @@ const mongodb = require('@mimik/mongooser');
10
10
  * _async_
11
11
  * [~validate()](#module_mongooser..validate) ⇒ <code>Promise</code>
12
12
  * _sync_
13
- * [~initializeSync()](#module_mongooser..initializeSync) ⇒ <code>object</code>
13
+ * [~getKMSProviders()](#module_mongooser..getKMSProviders) ⇒ <code>object</code>
14
+ * [~initializeSync(autoEncryption)](#module_mongooser..initializeSync) ⇒ <code>object</code>
14
15
  * [~replicat()](#module_mongooser..replicat) ⇒ <code>boolean</code>
15
16
 
16
17
  <a name="module_mongooser..validate"></a>
@@ -29,17 +30,44 @@ Will exit 1 if the connection request times out and the connection state is not
29
30
 
30
31
  **Requires**: <code>module:@mimik/sumologic-winston-logger</code>
31
32
  **Fulfil**: Return `null`.
33
+ <a name="module_mongooser..getKMSProviders"></a>
34
+
35
+ ### mongooser~getKMSProviders() ⇒ <code>object</code>
36
+ AutoEncryption KMSProvider.
37
+
38
+ **Kind**: inner method of [<code>mongooser</code>](#module_mongooser)
39
+ **Returns**: <code>object</code> - The KMSProviders object.
40
+
41
+ Will return the kmsProvider settings for the service.
42
+ **Category**: sync
32
43
  <a name="module_mongooser..initializeSync"></a>
33
44
 
34
- ### mongooser~initializeSync() ⇒ <code>object</code>
45
+ ### mongooser~initializeSync(autoEncryption) ⇒ <code>object</code>
35
46
  Database initialization.
36
47
 
37
48
  **Kind**: inner method of [<code>mongooser</code>](#module_mongooser)
38
49
  **Returns**: <code>object</code> - The database object.
39
50
 
51
+ The autoEncryption has the following strucuture:
52
+ ``` javascript
53
+ {
54
+ "keyVaultClient" : <object>,
55
+ "keyVaultNamespace": <string>, // namespace for the keyvault collection
56
+ "kmsProviders": <object>, // KeyManager service settings
57
+ "schemaMap": <object>, // json object for defining encryption schema
58
+ "bypassAutoEncryption": <boolean>
59
+ }
60
+ ```
61
+ Check MongoDB documentation for more details. https://docs.mongodb.com/manual/reference/method/Mongo/#clientsidefieldlevelencryptionoptions
62
+
40
63
  Will exit 1 if the connection request generates an error or the connection state is `disconnected` or `disconnecting`.
41
64
  **Category**: sync
42
65
  **Requires**: <code>module:sumologic-winston-logger</code>
66
+
67
+ | Param | Type | Description |
68
+ | --- | --- | --- |
69
+ | autoEncryption | <code>object</code> | Encryption settings for mongo connection. |
70
+
43
71
  <a name="module_mongooser..replicat"></a>
44
72
 
45
73
  ### mongooser~replicat() ⇒ <code>boolean</code>
package/index.js CHANGED
@@ -1,6 +1,11 @@
1
1
  const mongoose = require('mongoose');
2
2
  const Promise = require('bluebird');
3
+ const _ = require('lodash');
4
+
5
+ const { getCorrelationId } = require('@mimik/request-helper');
3
6
  const logger = require('@mimik/sumologic-winston-logger');
7
+ const { isProd, MASK } = require('@mimik/lib-filters');
8
+
4
9
  /**
5
10
  * @module mongooser
6
11
  * @example
@@ -9,8 +14,8 @@ const logger = require('@mimik/sumologic-winston-logger');
9
14
 
10
15
  mongoose.Promise = Promise;
11
16
 
12
- const correlationId = 'database-start';
13
17
  const type = 'mongo';
18
+ const correlationId = getCorrelationId(`${type}-database-start`);
14
19
 
15
20
  const VALIDATION_CHECK = 100; // in ms
16
21
  const DISCONNECTED = 0;
@@ -18,41 +23,99 @@ const CONNECTED = 1;
18
23
  const CONNECTING = 2;
19
24
  const DISCONNECTING = 3;
20
25
 
26
+ let fatal = false;
27
+
21
28
  module.exports = (config) => {
29
+ const { mongoSettings, encryption } = config;
30
+ const { options } = mongoSettings;
31
+
32
+ /**
33
+ * AutoEncryption KMSProvider.
34
+ *
35
+ * @function getKMSProviders
36
+ * @category sync
37
+ * @return {object} The KMSProviders object.
38
+ *
39
+ * Will return the kmsProvider settings for the service.
40
+ */
41
+ const getKMSProviders = () => {
42
+ const kmsProviders = {};
43
+ const provider = encryption.kmsProvider.toLowerCase();
44
+
45
+ if (provider === 'local') {
46
+ kmsProviders.local = { key: Buffer.from(encryption.localMasterKey, 'base64') };
47
+ }
48
+ else {
49
+ kmsProviders.aws = encryption.aws;
50
+ }
51
+ return kmsProviders;
52
+ };
53
+
22
54
  /**
23
55
  * Database initialization.
24
56
  *
25
57
  * @requires sumologic-winston-logger
26
58
  *
27
- * @function initializeSync
59
+ * @param {object} autoEncryption - Encryption settings for mongo connection.
28
60
  * @category sync
29
61
  * @return {object} The database object.
30
62
  *
63
+ * The autoEncryption has the following strucuture:
64
+ * ``` javascript
65
+ * {
66
+ * "keyVaultClient" : <object>,
67
+ * "keyVaultNamespace": <string>, // namespace for the keyvault collection
68
+ * "kmsProviders": <object>, // KeyManager service settings
69
+ * "schemaMap": <object>, // json object for defining encryption schema
70
+ * "bypassAutoEncryption": <boolean>
71
+ * }
72
+ *```
73
+ * Check MongoDB documentation for more details. https://docs.mongodb.com/manual/reference/method/Mongo/#clientsidefieldlevelencryptionoptions
74
+ *
31
75
  * Will exit 1 if the connection request generates an error or the connection state is `disconnected` or `disconnecting`.
32
76
  */
33
77
  const initializeSync = () => {
34
- let interval = {};
78
+ let interval;
35
79
 
36
- if (mongoose.connection.readyState === 0) {
37
- logger.info('creating a database connection', { type, settings: config.mongoSettings }, correlationId);
38
- mongoose.connect(config.mongoSettings.url, config.mongoSettings.options).then(() => mongoose).catch((error) => {
39
- logger.error('Fatal error: Could not connect to database', { type, error }, correlationId);
40
- logger.flushAndExit(1);
41
- });
80
+ if (encryption.set === 'on') {
81
+ options.autoEncryption = {
82
+ keyVaultNamespace: `${encryption.database}.${encryption.keyVaultTable}`,
83
+ kmsProviders: getKMSProviders(),
84
+ };
85
+ }
86
+
87
+ if (mongoose.connection.readyState === DISCONNECTED && !fatal) {
88
+ if (isProd(config.nodeEnvironment) && mongoSettings.password) {
89
+ const mongoSettingsClone = { ...mongoSettings };
90
+
91
+ mongoSettingsClone.url = _.replace(mongoSettingsClone.url, mongoSettings.password, MASK);
92
+ logger.info('creating a database connection', { type, settings: mongoSettingsClone }, correlationId);
93
+ }
94
+ else logger.info('creating a database connection', { type, settings: mongoSettings }, correlationId);
95
+ mongoose.connect(mongoSettings.url, options)
96
+ .then(() => mongoose)
97
+ .catch((error) => {
98
+ fatal = true;
99
+ logger.error('Fatal error: Could not connect to database', { type, error }, correlationId);
100
+ if (interval) clearInterval(interval);
101
+ logger.flushAndExit(1);
102
+ });
42
103
  }
43
104
 
44
105
  mongoose.connection.on('disconnected', () => {
45
106
  interval = setInterval(() => {
46
107
  const state = mongoose.connection.readyState;
47
108
 
48
- if (state === DISCONNECTED || state === DISCONNECTING) {
109
+ if ((state === DISCONNECTED || state === DISCONNECTING) && !fatal) {
110
+ fatal = true;
49
111
  logger.error('Fatal error: Could not connect to database', { type, error: state }, correlationId);
112
+ clearInterval(interval);
50
113
  logger.flushAndExit(1);
51
114
  }
52
- }, (config.mongoSettings.options.reconnectTries * config.mongoSettings.options.reconnectInterval));
115
+ }, (options.heartbeatFrequencyMS + (mongoSettings.reconnectOffset * 1000)));
53
116
  });
54
117
  mongoose.connection.on('connected', () => {
55
- clearInterval(interval);
118
+ if (interval) clearInterval(interval);
56
119
  });
57
120
  return mongoose;
58
121
  };
@@ -75,13 +138,15 @@ module.exports = (config) => {
75
138
  const interval = setInterval(() => {
76
139
  const state = mongoose.connection.readyState;
77
140
 
78
- if (state !== CONNECTED) {
141
+ if (state !== CONNECTED && !fatal) {
142
+ fatal = true;
79
143
  logger.error('Fatal error: Timeout in connecting to database', {
80
- type, error: state, timeout: config.mongoSettings.connectTimeout,
144
+ type, error: state, timeout: mongoSettings.connectTimeout,
81
145
  }, correlationId);
146
+ clearInterval(interval);
82
147
  logger.flushAndExit(1);
83
148
  }
84
- }, config.mongoSettings.connectTimeout * 1000); // convert in seconds
149
+ }, mongoSettings.connectTimeout * 1000); // convert in seconds
85
150
 
86
151
  return Promise.delay(VALIDATION_CHECK).then(() => {
87
152
  const state = mongoose.connection.readyState;
@@ -109,11 +174,12 @@ module.exports = (config) => {
109
174
  * @category sync
110
175
  * @return {boolean} `True` if replica is set, `False` if not.
111
176
  */
112
- const replicat = () => config.mongoSettings.replicat;
177
+ const replicat = () => mongoSettings.replicat;
113
178
 
114
179
  return {
115
180
  initializeSync,
116
181
  validate,
117
182
  replicat,
183
+ getKMSProviders,
118
184
  };
119
185
  };
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "name": "@mimik/mongooser",
3
- "version": "1.3.1",
3
+ "version": "1.8.1",
4
4
  "description": "Helper for setting up mongodb using mongoose for mimik microservices",
5
5
  "main": "index.js",
6
+ "engines": {
7
+ "node": ">=12.0.0"
8
+ },
6
9
  "scripts": {
7
- "lint": "gulp lint",
8
- "docs": "gulp docs",
9
- "test": "exit 0",
10
- "commit-ready": "gulp docs; gulp lint; npm run test"
10
+ "lint": "eslint --ignore-path .gitignore .",
11
+ "docs": "jsdoc2md index.js > README.md",
12
+ "test": "echo \"Error: no test specified\" && exit 0",
13
+ "test-ci": "echo \"Error: no test specified\" && exit 0",
14
+ "prepublishOnly": "npm run docs && npm run lint && npm run test-ci",
15
+ "commit-ready": "npm run docs && npm run lint && npm run test-ci",
16
+ "prepare": "husky install"
11
17
  },
12
18
  "husky": {
13
19
  "hooks": {
@@ -19,29 +25,30 @@
19
25
  "mimik",
20
26
  "microservice"
21
27
  ],
22
- "author": "mimik",
28
+ "author": "mimik technology inc <support@mimik.com> (https://developer.mimik.com/)",
23
29
  "license": "Apache-2.0",
24
30
  "repository": {
25
31
  "type": "git",
26
32
  "url": "https://bitbucket.org/mimiktech/mongooser"
27
33
  },
28
34
  "dependencies": {
29
- "@mimik/sumologic-winston-logger": "1.3.0",
30
- "bluebird": "3.7.1",
31
- "mongoose": "5.7.10"
35
+ "@mimik/lib-filters": "^1.4.4",
36
+ "@mimik/request-helper": "^1.7.5",
37
+ "@mimik/sumologic-winston-logger": "^1.6.8",
38
+ "bluebird": "3.7.2",
39
+ "lodash": "4.17.21",
40
+ "mongoose": "6.3.3"
32
41
  },
33
42
  "devDependencies": {
34
- "eslint": "6.6.0",
35
- "eslint-config-airbnb": "18.0.1",
36
- "eslint-plugin-import": "2.18.2",
37
- "eslint-plugin-jsx-a11y": "6.2.3",
38
- "eslint-plugin-react": "7.16.0",
39
- "eslint-plugin-react-hooks": "2.2.0",
40
- "fancy-log": "1.3.3",
41
- "gulp": "4.0.2",
42
- "gulp-eslint": "6.0.0",
43
- "gulp-git": "2.9.0",
44
- "husky": "3.0.9",
45
- "jsdoc-to-markdown": "5.0.2"
43
+ "@mimik/eslint-plugin-dependencies": "^2.4.3",
44
+ "@mimik/eslint-plugin-document-env": "^1.0.3",
45
+ "eslint": "8.15.0",
46
+ "eslint-config-airbnb": "19.0.4",
47
+ "eslint-plugin-import": "2.26.0",
48
+ "eslint-plugin-jsx-a11y": "6.5.1",
49
+ "eslint-plugin-react": "7.29.4",
50
+ "eslint-plugin-react-hooks": "4.5.0",
51
+ "husky": "8.0.1",
52
+ "jsdoc-to-markdown": "7.1.1"
46
53
  }
47
54
  }
package/Gulpfile.js DELETED
@@ -1,34 +0,0 @@
1
- //* eslint-disable import/no-extraneous-dependencies */
2
- const fs = require('fs');
3
- const log = require('fancy-log');
4
- const gulp = require('gulp');
5
- const eslint = require('gulp-eslint');
6
- const git = require('gulp-git');
7
- const jsdoc2md = require('jsdoc-to-markdown');
8
-
9
- const files = [
10
- 'index.js',
11
- 'Gulpfile.js',
12
- 'test/**.js',
13
- 'lib/**.js',
14
- ];
15
-
16
- const createDocs = (done) => {
17
- jsdoc2md.render({ files: 'index.js' })
18
- .then((output) => fs.writeFileSync('README.md', output))
19
- .catch((err) => log.error('docs creation failed:', err.message));
20
- return done();
21
- };
22
-
23
- const lint = () => gulp.src(files)
24
- .pipe(eslint({}))
25
- .pipe(eslint.format())
26
- .pipe(eslint.failOnError());
27
-
28
- const add = () => gulp.src('README.md')
29
- .pipe(git.add({ quiet: true }));
30
-
31
- const docs = gulp.series(createDocs, add);
32
-
33
- gulp.task('docs', docs);
34
- gulp.task('lint', lint);
package/package.json.bak DELETED
@@ -1,48 +0,0 @@
1
- {
2
- "name": "@mimik/mongooser",
3
- "version": "1.3.1",
4
- "description": "Helper for setting up mongodb using mongoose for mimik microservices",
5
- "main": "index.js",
6
- "scripts": {
7
- "lint": "gulp lint",
8
- "docs": "gulp docs",
9
- "test": "exit 0",
10
- "prepublishOnly": "gulp docs; gulp lint; npm run test",
11
- "commit-ready": "gulp docs; gulp lint; npm run test"
12
- },
13
- "husky": {
14
- "hooks": {
15
- "pre-commit": "npm run commit-ready",
16
- "pre-push": "npm run test"
17
- }
18
- },
19
- "keywords": [
20
- "mimik",
21
- "microservice"
22
- ],
23
- "author": "mimik",
24
- "license": "Apache-2.0",
25
- "repository": {
26
- "type": "git",
27
- "url": "https://bitbucket.org/mimiktech/mongooser"
28
- },
29
- "dependencies": {
30
- "@mimik/sumologic-winston-logger": "1.3.0",
31
- "bluebird": "3.7.1",
32
- "mongoose": "5.7.10"
33
- },
34
- "devDependencies": {
35
- "eslint": "6.6.0",
36
- "eslint-config-airbnb": "18.0.1",
37
- "eslint-plugin-import": "2.18.2",
38
- "eslint-plugin-jsx-a11y": "6.2.3",
39
- "eslint-plugin-react": "7.16.0",
40
- "eslint-plugin-react-hooks": "2.2.0",
41
- "fancy-log": "1.3.3",
42
- "gulp": "4.0.2",
43
- "gulp-eslint": "6.0.0",
44
- "gulp-git": "2.9.0",
45
- "husky": "3.0.9",
46
- "jsdoc-to-markdown": "5.0.2"
47
- }
48
- }