eslint and prettier added
This commit is contained in:
parent
f59c2d8e97
commit
f5a5955656
27
.eslintrc.js
Normal file
27
.eslintrc.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
commonjs: true,
|
||||||
|
es2021: true,
|
||||||
|
},
|
||||||
|
extends: 'standard',
|
||||||
|
plugins: ['prettier'],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
files: ['.eslintrc.{js,cjs}'],
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'script',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'comma-dangle': ['error', 'never'],
|
||||||
|
'no-extra-semi': ['error', 'never'],
|
||||||
|
},
|
||||||
|
};
|
7
.prettierrc
Normal file
7
.prettierrc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"semi": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"endOfLine": "lf"
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
## Important Information
|
## Important Information
|
||||||
|
|
||||||
This repository is exclusively meant for presenting samples of code.
|
This repository is exclusively meant for presenting samples of code.
|
||||||
|
|
||||||
The Files and Codes present in this repository are part of a running project. In order to ensure the security of the project several files have been intentionally removed. The codes are exclusively for viewing purpose and will not execute properly if tried.
|
The Files and Codes present in this repository are part of a running project. In order to ensure the security of the project several files have been intentionally removed. The codes are exclusively for viewing purpose and will not execute properly if tried.
|
||||||
|
|
||||||
# Express ES2017 REST API Boilerplate
|
# Express ES2017 REST API Boilerplate
|
||||||
|
|
||||||
|
|
||||||
Boilerplate/Generator/Starter Project for building RESTful APIs and microservices using Node.js, Express and MongoDB
|
Boilerplate/Generator/Starter Project for building RESTful APIs and microservices using Node.js, Express and MongoDB
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
@ -155,4 +155,3 @@ Run deploy script:
|
|||||||
```bash
|
```bash
|
||||||
yarn deploy
|
yarn deploy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "2"
|
version: '2'
|
||||||
services:
|
services:
|
||||||
boilerplate-api:
|
boilerplate-api:
|
||||||
command: yarn dev -- -L
|
command: yarn dev -- -L
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "2"
|
version: '2'
|
||||||
services:
|
services:
|
||||||
boilerplate-api:
|
boilerplate-api:
|
||||||
command: yarn start
|
command: yarn start
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "2"
|
version: '2'
|
||||||
services:
|
services:
|
||||||
boilerplate-api:
|
boilerplate-api:
|
||||||
command: yarn test
|
command: yarn test
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
version: "2"
|
version: '2'
|
||||||
services:
|
services:
|
||||||
boilerplate-api:
|
boilerplate-api:
|
||||||
build: .
|
build: .
|
||||||
@ -7,11 +7,11 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- '3000:3000'
|
||||||
depends_on:
|
depends_on:
|
||||||
- mongodb
|
- mongodb
|
||||||
|
|
||||||
mongodb:
|
mongodb:
|
||||||
image: mongo
|
image: mongo
|
||||||
ports:
|
ports:
|
||||||
- "27017:27017"
|
- '27017:27017'
|
||||||
|
350
package-lock.json
generated
350
package-lock.json
generated
@ -14,8 +14,8 @@
|
|||||||
"body-parser": "^1.19.1",
|
"body-parser": "^1.19.1",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"dotenv-cli": "^7.4.1",
|
||||||
"email-templates": "^11.1.1",
|
"email-templates": "^11.1.1",
|
||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"express-validation": "^4.1.0",
|
"express-validation": "^4.1.0",
|
||||||
@ -24,6 +24,7 @@
|
|||||||
"joi": "^17.5.0",
|
"joi": "^17.5.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"method-override": "^3.0.0",
|
"method-override": "^3.0.0",
|
||||||
|
"moment-timezone": "^0.5.45",
|
||||||
"mongoose": "^8.2.1",
|
"mongoose": "^8.2.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
@ -40,14 +41,18 @@
|
|||||||
"chai": "^4.4.1",
|
"chai": "^4.4.1",
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"coveralls": "^3.1.1",
|
"coveralls": "^3.1.1",
|
||||||
"eslint": "^8.5.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
|
"eslint-plugin-n": "^16.6.2",
|
||||||
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
"husky": "^9.0.11",
|
"husky": "^9.0.11",
|
||||||
"mocha": "^10.3.0",
|
"mocha": "^10.3.0",
|
||||||
"nodemon": "^3.1.0",
|
"nodemon": "^3.1.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"opn-cli": "^5.0.0",
|
"opn-cli": "^5.0.0",
|
||||||
|
"prettier": "^3.2.5",
|
||||||
"sinon": "^17.0.1",
|
"sinon": "^17.0.1",
|
||||||
"sinon-chai": "^3.7.0",
|
"sinon-chai": "^3.7.0",
|
||||||
"supertest": "^6.1.6"
|
"supertest": "^6.1.6"
|
||||||
@ -1341,6 +1346,18 @@
|
|||||||
"uuid": "bin/uuid"
|
"uuid": "bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@pkgr/core": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/unts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@pm2/agent": {
|
"node_modules/@pm2/agent": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.3.tgz",
|
||||||
@ -2898,6 +2915,27 @@
|
|||||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/builtin-modules": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/builtins": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
@ -3369,12 +3407,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||||
},
|
},
|
||||||
"node_modules/confusing-browser-globals": {
|
|
||||||
"version": "1.0.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
|
|
||||||
"integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/constantinople": {
|
"node_modules/constantinople": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
|
||||||
@ -3498,23 +3530,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz",
|
"resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz",
|
||||||
"integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ=="
|
"integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ=="
|
||||||
},
|
},
|
||||||
"node_modules/cross-env": {
|
|
||||||
"version": "7.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
|
|
||||||
"integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
|
|
||||||
"dependencies": {
|
|
||||||
"cross-spawn": "^7.0.1"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"cross-env": "src/bin/cross-env.js",
|
|
||||||
"cross-env-shell": "src/bin/cross-env-shell.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10.14",
|
|
||||||
"npm": ">=6",
|
|
||||||
"yarn": ">=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@ -3891,6 +3906,28 @@
|
|||||||
"url": "https://dotenvx.com"
|
"url": "https://dotenvx.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv-cli": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-fE1aywjRrWGxV3miaiUr3d2zC/VAiuzEGghi+QzgIA9fEf/M5hLMaRSXb4IxbUAwGmaLi0IozdZddnVU96acag==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-spawn": "^7.0.3",
|
||||||
|
"dotenv": "^16.3.0",
|
||||||
|
"dotenv-expand": "^10.0.0",
|
||||||
|
"minimist": "^1.2.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"dotenv": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dotenv-expand": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ecc-jsbn": {
|
"node_modules/ecc-jsbn": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||||
@ -4352,32 +4389,45 @@
|
|||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-airbnb-base": {
|
"node_modules/eslint-compat-utils": {
|
||||||
"version": "15.0.0",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz",
|
||||||
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
|
"integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
|
||||||
"confusing-browser-globals": "^1.0.10",
|
|
||||||
"object.assign": "^4.1.2",
|
|
||||||
"object.entries": "^1.1.5",
|
|
||||||
"semver": "^6.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^7.32.0 || ^8.2.0",
|
"eslint": ">=6.0.0"
|
||||||
"eslint-plugin-import": "^2.25.2"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-airbnb-base/node_modules/semver": {
|
"node_modules/eslint-config-standard": {
|
||||||
"version": "6.3.1",
|
"version": "17.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"funding": [
|
||||||
"semver": "bin/semver.js"
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^8.0.1",
|
||||||
|
"eslint-plugin-import": "^2.25.2",
|
||||||
|
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
|
||||||
|
"eslint-plugin-promise": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-import-resolver-node": {
|
"node_modules/eslint-import-resolver-node": {
|
||||||
@ -4438,6 +4488,26 @@
|
|||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-es-x": {
|
||||||
|
"version": "7.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz",
|
||||||
|
"integrity": "sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint-community/eslint-utils": "^4.1.2",
|
||||||
|
"@eslint-community/regexpp": "^4.6.0",
|
||||||
|
"eslint-compat-utils": "^0.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ota-meshi"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-import": {
|
"node_modules/eslint-plugin-import": {
|
||||||
"version": "2.29.1",
|
"version": "2.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
|
||||||
@ -4505,6 +4575,76 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-n": {
|
||||||
|
"version": "16.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz",
|
||||||
|
"integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
|
"builtins": "^5.0.1",
|
||||||
|
"eslint-plugin-es-x": "^7.5.0",
|
||||||
|
"get-tsconfig": "^4.7.0",
|
||||||
|
"globals": "^13.24.0",
|
||||||
|
"ignore": "^5.2.4",
|
||||||
|
"is-builtin-module": "^3.2.1",
|
||||||
|
"is-core-module": "^2.12.1",
|
||||||
|
"minimatch": "^3.1.2",
|
||||||
|
"resolve": "^1.22.2",
|
||||||
|
"semver": "^7.5.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/mysticatea"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": ">=7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-prettier": {
|
||||||
|
"version": "5.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
|
||||||
|
"integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"prettier-linter-helpers": "^1.0.0",
|
||||||
|
"synckit": "^0.8.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint-plugin-prettier"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/eslint": ">=8.0.0",
|
||||||
|
"eslint": ">=8.0.0",
|
||||||
|
"eslint-config-prettier": "*",
|
||||||
|
"prettier": ">=3.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/eslint": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"eslint-config-prettier": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-plugin-promise": {
|
||||||
|
"version": "6.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz",
|
||||||
|
"integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^7.0.0 || ^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-scope": {
|
"node_modules/eslint-scope": {
|
||||||
"version": "7.2.2",
|
"version": "7.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
||||||
@ -4876,6 +5016,12 @@
|
|||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-diff": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/fast-json-patch": {
|
"node_modules/fast-json-patch": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
|
||||||
@ -5361,6 +5507,18 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/get-tsconfig": {
|
||||||
|
"version": "4.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
|
||||||
|
"integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/get-uri": {
|
"node_modules/get-uri": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz",
|
||||||
@ -6117,6 +6275,21 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-builtin-module": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"builtin-modules": "^3.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-callable": {
|
"node_modules/is-callable": {
|
||||||
"version": "1.2.7",
|
"version": "1.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||||
@ -7673,6 +7846,25 @@
|
|||||||
"resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
|
||||||
"integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A=="
|
"integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/moment-timezone": {
|
||||||
|
"version": "0.5.45",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
|
||||||
|
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.29.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mongodb": {
|
"node_modules/mongodb": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz",
|
||||||
@ -8393,20 +8585,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object.entries": {
|
|
||||||
"version": "1.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
|
|
||||||
"integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"call-bind": "^1.0.2",
|
|
||||||
"define-properties": "^1.2.0",
|
|
||||||
"es-abstract": "^1.22.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object.fromentries": {
|
"node_modules/object.fromentries": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
|
||||||
@ -9288,6 +9466,33 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||||
|
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prettier-linter-helpers": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fast-diff": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/preview-email": {
|
"node_modules/preview-email": {
|
||||||
"version": "3.0.19",
|
"version": "3.0.19",
|
||||||
"resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.0.19.tgz",
|
"resolved": "https://registry.npmjs.org/preview-email/-/preview-email-3.0.19.tgz",
|
||||||
@ -10040,6 +10245,15 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/resolve-pkg-maps": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reusify": {
|
"node_modules/reusify": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||||
@ -10897,6 +11111,22 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/synckit": {
|
||||||
|
"version": "0.8.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
|
||||||
|
"integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@pkgr/core": "^0.1.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/unts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/systeminformation": {
|
"node_modules/systeminformation": {
|
||||||
"version": "5.22.0",
|
"version": "5.22.0",
|
||||||
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.0.tgz",
|
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.0.tgz",
|
||||||
|
30
package.json
30
package.json
@ -11,15 +11,16 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"precommit": "yarn lint",
|
"precommit": "yarn lint",
|
||||||
"prestart": "yarn docs",
|
"prestart": "yarn docs",
|
||||||
"start": "cross-env NODE_ENV=production pm2 start ./src/index.js",
|
"start:dev": "dotenv -v NODE_ENV=development -- nodemon ./src/index.js",
|
||||||
"dev": "nodemon ./src/index.js",
|
"start:prod": "dotenv -v NODE_ENV=production -- pm2 start ./src/index.js",
|
||||||
"lint": "eslint ./src/ --ignore-path .gitignore --ignore-pattern internals/scripts",
|
"lint": "eslint ./src/ --ignore-path .gitignore --ignore-pattern internals/scripts",
|
||||||
"lint:fix": "yarn lint --fix",
|
"lint:fix": "npx eslint --fix",
|
||||||
"lint:watch": "yarn lint --watch",
|
"lint:watch": "npx eslint --watch",
|
||||||
"test": "cross-env NODE_ENV=test nyc --reporter=html --reporter=text mocha --timeout 20000 --exit --recursive src/api/tests",
|
"format": "npx prettier --write .",
|
||||||
"test:unit": "cross-env NODE_ENV=test mocha src/api/tests/unit",
|
"test": "dotenv -v NODE_ENV=test -- nyc --reporter=html --reporter=text mocha --timeout 20000 --exit --recursive src/api/tests",
|
||||||
"test:integration": "cross-env NODE_ENV=test mocha --timeout 20000 --exit src/api/tests/integration",
|
"test:unit": "dotenv -v NODE_ENV=test -- mocha src/api/tests/unit",
|
||||||
"test:watch": "cross-env NODE_ENV=test mocha --watch src/api/tests/unit",
|
"test:integration": "dotenv -v NODE_ENV=test -- mocha --timeout 20000 --exit src/api/tests/integration",
|
||||||
|
"test:watch": "dotenv -v NODE_ENV=test -- mocha --watch src/api/tests/unit",
|
||||||
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
"coverage": "nyc report --reporter=text-lcov | coveralls",
|
||||||
"postcoverage": "open-cli coverage/lcov-report/index.html",
|
"postcoverage": "open-cli coverage/lcov-report/index.html",
|
||||||
"validate": "yarn lint && yarn test",
|
"validate": "yarn lint && yarn test",
|
||||||
@ -66,8 +67,8 @@
|
|||||||
"body-parser": "^1.19.1",
|
"body-parser": "^1.19.1",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cross-env": "^7.0.3",
|
|
||||||
"dotenv": "^16.4.5",
|
"dotenv": "^16.4.5",
|
||||||
|
"dotenv-cli": "^7.4.1",
|
||||||
"email-templates": "^11.1.1",
|
"email-templates": "^11.1.1",
|
||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"express-validation": "^4.1.0",
|
"express-validation": "^4.1.0",
|
||||||
@ -76,6 +77,7 @@
|
|||||||
"joi": "^17.5.0",
|
"joi": "^17.5.0",
|
||||||
"jwt-simple": "^0.5.6",
|
"jwt-simple": "^0.5.6",
|
||||||
"method-override": "^3.0.0",
|
"method-override": "^3.0.0",
|
||||||
|
"moment-timezone": "^0.5.45",
|
||||||
"mongoose": "^8.2.1",
|
"mongoose": "^8.2.1",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
@ -92,14 +94,18 @@
|
|||||||
"chai": "^4.4.1",
|
"chai": "^4.4.1",
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
"coveralls": "^3.1.1",
|
"coveralls": "^3.1.1",
|
||||||
"eslint": "^8.5.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-config-airbnb-base": "^15.0.0",
|
"eslint-config-standard": "^17.1.0",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-import": "^2.29.1",
|
||||||
|
"eslint-plugin-n": "^16.6.2",
|
||||||
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
"husky": "^9.0.11",
|
"husky": "^9.0.11",
|
||||||
"mocha": "^10.3.0",
|
"mocha": "^10.3.0",
|
||||||
"nodemon": "^3.1.0",
|
"nodemon": "^3.1.0",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"opn-cli": "^5.0.0",
|
"opn-cli": "^5.0.0",
|
||||||
|
"prettier": "^3.2.5",
|
||||||
"sinon": "^17.0.1",
|
"sinon": "^17.0.1",
|
||||||
"sinon-chai": "^3.7.0",
|
"sinon-chai": "^3.7.0",
|
||||||
"supertest": "^6.1.6"
|
"supertest": "^6.1.6"
|
||||||
|
@ -84,7 +84,10 @@ exports.refresh = async (req, res, next) => {
|
|||||||
userEmail: email,
|
userEmail: email,
|
||||||
token: refreshToken,
|
token: refreshToken,
|
||||||
});
|
});
|
||||||
const { user, accessToken } = await User.findAndGenerateToken({ email, refreshObject });
|
const { user, accessToken } = await User.findAndGenerateToken({
|
||||||
|
email,
|
||||||
|
refreshObject,
|
||||||
|
});
|
||||||
const response = generateTokenResponse(user, accessToken);
|
const response = generateTokenResponse(user, accessToken);
|
||||||
return res.json(response);
|
return res.json(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -133,7 +136,9 @@ exports.resetPassword = async (req, res, next) => {
|
|||||||
throw new APIError(err);
|
throw new APIError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await User.findOne({ email: resetTokenObject.userEmail }).exec();
|
const user = await User.findOne({
|
||||||
|
email: resetTokenObject.userEmail,
|
||||||
|
}).exec();
|
||||||
user.password = password;
|
user.password = password;
|
||||||
await user.save();
|
await user.save();
|
||||||
emailProvider.sendPasswordChangeEmail(user);
|
emailProvider.sendPasswordChangeEmail(user);
|
||||||
|
@ -54,7 +54,6 @@ exports.replace = async (req, res, next) => {
|
|||||||
const ommitRole = user.role !== 'admin' ? 'role' : '';
|
const ommitRole = user.role !== 'admin' ? 'role' : '';
|
||||||
const newUserObject = omit(newUser.toObject(), '_id', ommitRole);
|
const newUserObject = omit(newUser.toObject(), '_id', ommitRole);
|
||||||
|
|
||||||
|
|
||||||
res.json(savedUser.transform());
|
res.json(savedUser.transform());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(User.checkDuplicateEmail(error));
|
next(User.checkDuplicateEmail(error));
|
||||||
@ -70,9 +69,10 @@ exports.update = (req, res, next) => {
|
|||||||
const updatedUser = omit(req.body, ommitRole);
|
const updatedUser = omit(req.body, ommitRole);
|
||||||
const user = Object.assign(req.locals.user, updatedUser);
|
const user = Object.assign(req.locals.user, updatedUser);
|
||||||
|
|
||||||
user.save()
|
user
|
||||||
.then(savedUser => res.json(savedUser.transform()))
|
.save()
|
||||||
.catch(e => next(User.checkDuplicateEmail(e)));
|
.then((savedUser) => res.json(savedUser.transform()))
|
||||||
|
.catch((e) => next(User.checkDuplicateEmail(e)));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +82,7 @@ exports.update = (req, res, next) => {
|
|||||||
exports.list = async (req, res, next) => {
|
exports.list = async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const users = await User.list(req.query);
|
const users = await User.list(req.query);
|
||||||
const transformedUsers = users.map(user => user.transform());
|
const transformedUsers = users.map((user) => user.transform());
|
||||||
res.json(transformedUsers);
|
res.json(transformedUsers);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
@ -96,7 +96,8 @@ exports.list = async (req, res, next) => {
|
|||||||
exports.remove = (req, res, next) => {
|
exports.remove = (req, res, next) => {
|
||||||
const { user } = req.locals;
|
const { user } = req.locals;
|
||||||
|
|
||||||
user.remove()
|
user
|
||||||
|
.remove()
|
||||||
.then(() => res.status(httpStatus.NO_CONTENT).end())
|
.then(() => res.status(httpStatus.NO_CONTENT).end())
|
||||||
.catch(e => next(e));
|
.catch((e) => next(e));
|
||||||
};
|
};
|
||||||
|
@ -44,11 +44,13 @@ const handleJWT = (req, res, next, roles) => async (err, user, info) => {
|
|||||||
exports.ADMIN = ADMIN;
|
exports.ADMIN = ADMIN;
|
||||||
exports.LOGGED_USER = LOGGED_USER;
|
exports.LOGGED_USER = LOGGED_USER;
|
||||||
|
|
||||||
exports.authorize = (roles = User.roles) => (req, res, next) =>
|
exports.authorize =
|
||||||
|
(roles = User.roles) =>
|
||||||
|
(req, res, next) =>
|
||||||
passport.authenticate(
|
passport.authenticate(
|
||||||
'jwt', { session: false },
|
'jwt',
|
||||||
|
{ session: false },
|
||||||
handleJWT(req, res, next, roles),
|
handleJWT(req, res, next, roles),
|
||||||
)(req, res, next);
|
)(req, res, next);
|
||||||
|
|
||||||
exports.oAuth = service =>
|
exports.oAuth = (service) => passport.authenticate(service, { session: false });
|
||||||
passport.authenticate(service, { session: false });
|
|
||||||
|
@ -36,9 +36,7 @@ passwordResetTokenSchema.statics = {
|
|||||||
const userId = user._id;
|
const userId = user._id;
|
||||||
const userEmail = user.email;
|
const userEmail = user.email;
|
||||||
const resetToken = `${userId}.${crypto.randomBytes(40).toString('hex')}`;
|
const resetToken = `${userId}.${crypto.randomBytes(40).toString('hex')}`;
|
||||||
const expires = moment()
|
const expires = moment().add(2, 'hours').toDate();
|
||||||
.add(2, 'hours')
|
|
||||||
.toDate();
|
|
||||||
const ResetTokenObject = new PasswordResetToken({
|
const ResetTokenObject = new PasswordResetToken({
|
||||||
resetToken,
|
resetToken,
|
||||||
userId,
|
userId,
|
||||||
@ -53,5 +51,8 @@ passwordResetTokenSchema.statics = {
|
|||||||
/**
|
/**
|
||||||
* @typedef RefreshToken
|
* @typedef RefreshToken
|
||||||
*/
|
*/
|
||||||
const PasswordResetToken = mongoose.model('PasswordResetToken', passwordResetTokenSchema);
|
const PasswordResetToken = mongoose.model(
|
||||||
|
'PasswordResetToken',
|
||||||
|
passwordResetTokenSchema,
|
||||||
|
);
|
||||||
module.exports = PasswordResetToken;
|
module.exports = PasswordResetToken;
|
||||||
|
@ -26,7 +26,6 @@ const refreshTokenSchema = new mongoose.Schema({
|
|||||||
});
|
});
|
||||||
|
|
||||||
refreshTokenSchema.statics = {
|
refreshTokenSchema.statics = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a refresh token object and saves it into the database
|
* Generate a refresh token object and saves it into the database
|
||||||
*
|
*
|
||||||
@ -39,12 +38,14 @@ refreshTokenSchema.statics = {
|
|||||||
const token = `${userId}.${crypto.randomBytes(40).toString('hex')}`;
|
const token = `${userId}.${crypto.randomBytes(40).toString('hex')}`;
|
||||||
const expires = moment().add(30, 'days').toDate();
|
const expires = moment().add(30, 'days').toDate();
|
||||||
const tokenObject = new RefreshToken({
|
const tokenObject = new RefreshToken({
|
||||||
token, userId, userEmail, expires,
|
token,
|
||||||
|
userId,
|
||||||
|
userEmail,
|
||||||
|
expires,
|
||||||
});
|
});
|
||||||
tokenObject.save();
|
tokenObject.save();
|
||||||
return tokenObject;
|
return tokenObject;
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,8 @@ const roles = ['user', 'admin'];
|
|||||||
* User Schema
|
* User Schema
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const userSchema = new mongoose.Schema({
|
const userSchema = new mongoose.Schema(
|
||||||
|
{
|
||||||
email: {
|
email: {
|
||||||
type: String,
|
type: String,
|
||||||
match: /^\S+@\S+\.\S+$/,
|
match: /^\S+@\S+\.\S+$/,
|
||||||
@ -51,9 +52,11 @@ const userSchema = new mongoose.Schema({
|
|||||||
type: String,
|
type: String,
|
||||||
trim: true,
|
trim: true,
|
||||||
},
|
},
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add your
|
* Add your
|
||||||
@ -109,7 +112,6 @@ userSchema.method({
|
|||||||
* Statics
|
* Statics
|
||||||
*/
|
*/
|
||||||
userSchema.statics = {
|
userSchema.statics = {
|
||||||
|
|
||||||
roles,
|
roles,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,7 +148,10 @@ userSchema.statics = {
|
|||||||
*/
|
*/
|
||||||
async findAndGenerateToken(options) {
|
async findAndGenerateToken(options) {
|
||||||
const { email, password, refreshObject } = options;
|
const { email, password, refreshObject } = options;
|
||||||
if (!email) throw new APIError({ message: 'An email is required to generate a token' });
|
if (!email)
|
||||||
|
throw new APIError({
|
||||||
|
message: 'An email is required to generate a token',
|
||||||
|
});
|
||||||
|
|
||||||
const user = await this.findOne({ email }).exec();
|
const user = await this.findOne({ email }).exec();
|
||||||
const err = {
|
const err = {
|
||||||
@ -154,7 +159,7 @@ userSchema.statics = {
|
|||||||
isPublic: true,
|
isPublic: true,
|
||||||
};
|
};
|
||||||
if (password) {
|
if (password) {
|
||||||
if (user && await user.passwordMatches(password)) {
|
if (user && (await user.passwordMatches(password))) {
|
||||||
return { user, accessToken: user.token() };
|
return { user, accessToken: user.token() };
|
||||||
}
|
}
|
||||||
err.message = 'Incorrect email or password';
|
err.message = 'Incorrect email or password';
|
||||||
@ -177,9 +182,7 @@ userSchema.statics = {
|
|||||||
* @param {number} limit - Limit number of users to be returned.
|
* @param {number} limit - Limit number of users to be returned.
|
||||||
* @returns {Promise<User[]>}
|
* @returns {Promise<User[]>}
|
||||||
*/
|
*/
|
||||||
list({
|
list({ page = 1, perPage = 30, name, email, role }) {
|
||||||
page = 1, perPage = 30, name, email, role,
|
|
||||||
}) {
|
|
||||||
const options = omitBy({ name, email, role }, isNil);
|
const options = omitBy({ name, email, role }, isNil);
|
||||||
|
|
||||||
return this.find(options)
|
return this.find(options)
|
||||||
@ -200,11 +203,13 @@ userSchema.statics = {
|
|||||||
if (error.name === 'MongoError' && error.code === 11000) {
|
if (error.name === 'MongoError' && error.code === 11000) {
|
||||||
return new APIError({
|
return new APIError({
|
||||||
message: 'Validation Error',
|
message: 'Validation Error',
|
||||||
errors: [{
|
errors: [
|
||||||
|
{
|
||||||
field: 'email',
|
field: 'email',
|
||||||
location: 'body',
|
location: 'body',
|
||||||
messages: ['"email" already exists'],
|
messages: ['"email" already exists'],
|
||||||
}],
|
},
|
||||||
|
],
|
||||||
status: httpStatus.CONFLICT,
|
status: httpStatus.CONFLICT,
|
||||||
isPublic: true,
|
isPublic: true,
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
@ -213,10 +218,10 @@ userSchema.statics = {
|
|||||||
return error;
|
return error;
|
||||||
},
|
},
|
||||||
|
|
||||||
async oAuthLogin({
|
async oAuthLogin({ service, id, email, name, picture }) {
|
||||||
service, id, email, name, picture,
|
const user = await this.findOne({
|
||||||
}) {
|
$or: [{ [`services.${service}`]: id }, { email }],
|
||||||
const user = await this.findOne({ $or: [{ [`services.${service}`]: id }, { email }] });
|
});
|
||||||
if (user) {
|
if (user) {
|
||||||
user.services[service] = id;
|
user.services[service] = id;
|
||||||
if (!user.name) user.name = name;
|
if (!user.name) user.name = name;
|
||||||
@ -225,7 +230,11 @@ userSchema.statics = {
|
|||||||
}
|
}
|
||||||
const password = uuidv4();
|
const password = uuidv4();
|
||||||
return this.create({
|
return this.create({
|
||||||
services: { [service]: id }, email, password, name, picture,
|
services: { [service]: id },
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
name,
|
||||||
|
picture,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { validate, ValidationError, Joi } = require('express-validation')
|
const { validate, ValidationError, Joi } = require('express-validation');
|
||||||
const controller = require('../../controllers/auth.controller');
|
const controller = require('../../controllers/auth.controller');
|
||||||
const oAuthLogin = require('../../middlewares/auth').oAuth;
|
const oAuthLogin = require('../../middlewares/auth').oAuth;
|
||||||
const {
|
const {
|
||||||
@ -40,9 +40,7 @@ const router = express.Router();
|
|||||||
*
|
*
|
||||||
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
||||||
*/
|
*/
|
||||||
router.route('/register')
|
router.route('/register').post(validate(register), controller.register);
|
||||||
.post(validate(register), controller.register);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} v1/auth/login Login
|
* @api {post} v1/auth/login Login
|
||||||
@ -71,9 +69,7 @@ router.route('/register')
|
|||||||
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
||||||
* @apiError (Unauthorized 401) Unauthorized Incorrect email or password
|
* @apiError (Unauthorized 401) Unauthorized Incorrect email or password
|
||||||
*/
|
*/
|
||||||
router.route('/login')
|
router.route('/login').post(validate(login), controller.login);
|
||||||
.post(validate(login), controller.login);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} v1/auth/refresh-token Refresh Token
|
* @api {post} v1/auth/refresh-token Refresh Token
|
||||||
@ -94,14 +90,14 @@ router.route('/login')
|
|||||||
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
||||||
* @apiError (Unauthorized 401) Unauthorized Incorrect email or refreshToken
|
* @apiError (Unauthorized 401) Unauthorized Incorrect email or refreshToken
|
||||||
*/
|
*/
|
||||||
router.route('/refresh-token')
|
router.route('/refresh-token').post(validate(refresh), controller.refresh);
|
||||||
.post(validate(refresh), controller.refresh);
|
|
||||||
|
|
||||||
|
router
|
||||||
router.route('/send-password-reset')
|
.route('/send-password-reset')
|
||||||
.post(validate(sendPasswordReset), controller.sendPasswordReset);
|
.post(validate(sendPasswordReset), controller.sendPasswordReset);
|
||||||
|
|
||||||
router.route('/reset-password')
|
router
|
||||||
|
.route('/reset-password')
|
||||||
.post(validate(passwordReset), controller.resetPassword);
|
.post(validate(passwordReset), controller.resetPassword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,7 +118,8 @@ router.route('/reset-password')
|
|||||||
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
||||||
* @apiError (Unauthorized 401) Unauthorized Incorrect access_token
|
* @apiError (Unauthorized 401) Unauthorized Incorrect access_token
|
||||||
*/
|
*/
|
||||||
router.route('/facebook')
|
router
|
||||||
|
.route('/facebook')
|
||||||
.post(validate(oAuth), oAuthLogin('facebook'), controller.oAuth);
|
.post(validate(oAuth), oAuthLogin('facebook'), controller.oAuth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,8 +140,8 @@ router.route('/facebook')
|
|||||||
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
* @apiError (Bad Request 400) ValidationError Some parameters may contain invalid values
|
||||||
* @apiError (Unauthorized 401) Unauthorized Incorrect access_token
|
* @apiError (Unauthorized 401) Unauthorized Incorrect access_token
|
||||||
*/
|
*/
|
||||||
router.route('/google')
|
router
|
||||||
|
.route('/google')
|
||||||
.post(validate(oAuth), oAuthLogin('google'), controller.oAuth);
|
.post(validate(oAuth), oAuthLogin('google'), controller.oAuth);
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const { validate, ValidationError, Joi } = require('express-validation')
|
const { validate, ValidationError, Joi } = require('express-validation');
|
||||||
const controller = require('../../controllers/user.controller');
|
const controller = require('../../controllers/user.controller');
|
||||||
const { authorize, ADMIN, LOGGED_USER } = require('../../middlewares/auth');
|
const { authorize, ADMIN, LOGGED_USER } = require('../../middlewares/auth');
|
||||||
const {
|
const {
|
||||||
@ -16,7 +16,6 @@ const router = express.Router();
|
|||||||
*/
|
*/
|
||||||
router.param('userId', controller.load);
|
router.param('userId', controller.load);
|
||||||
|
|
||||||
|
|
||||||
router
|
router
|
||||||
.route('/')
|
.route('/')
|
||||||
/**
|
/**
|
||||||
@ -68,7 +67,6 @@ router
|
|||||||
*/
|
*/
|
||||||
.post(authorize(ADMIN), validate(createUser), controller.create);
|
.post(authorize(ADMIN), validate(createUser), controller.create);
|
||||||
|
|
||||||
|
|
||||||
router
|
router
|
||||||
.route('/profile')
|
.route('/profile')
|
||||||
/**
|
/**
|
||||||
@ -91,7 +89,6 @@ router
|
|||||||
*/
|
*/
|
||||||
.get(authorize(), controller.loggedIn);
|
.get(authorize(), controller.loggedIn);
|
||||||
|
|
||||||
|
|
||||||
router
|
router
|
||||||
.route('/:userId')
|
.route('/:userId')
|
||||||
/**
|
/**
|
||||||
@ -189,5 +186,4 @@ router
|
|||||||
*/
|
*/
|
||||||
.delete(authorize(LOGGED_USER), controller.remove);
|
.delete(authorize(LOGGED_USER), controller.remove);
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -6,9 +6,7 @@ exports.facebook = async (access_token) => {
|
|||||||
const url = 'https://graph.facebook.com/me';
|
const url = 'https://graph.facebook.com/me';
|
||||||
const params = { access_token, fields };
|
const params = { access_token, fields };
|
||||||
const response = await axios.get(url, { params });
|
const response = await axios.get(url, { params });
|
||||||
const {
|
const { id, name, email, picture } = response.data;
|
||||||
id, name, email, picture,
|
|
||||||
} = response.data;
|
|
||||||
return {
|
return {
|
||||||
service: 'facebook',
|
service: 'facebook',
|
||||||
picture: picture.data.url,
|
picture: picture.data.url,
|
||||||
@ -22,9 +20,7 @@ exports.google = async (access_token) => {
|
|||||||
const url = 'https://www.googleapis.com/oauth2/v3/userinfo';
|
const url = 'https://www.googleapis.com/oauth2/v3/userinfo';
|
||||||
const params = { access_token };
|
const params = { access_token };
|
||||||
const response = await axios.get(url, { params });
|
const response = await axios.get(url, { params });
|
||||||
const {
|
const { sub, name, email, picture } = response.data;
|
||||||
sub, name, email, picture,
|
|
||||||
} = response.data;
|
|
||||||
return {
|
return {
|
||||||
service: 'google',
|
service: 'google',
|
||||||
picture,
|
picture,
|
||||||
|
@ -49,9 +49,7 @@ describe('Authentication API', () => {
|
|||||||
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
userId: '5947397b323ae82d8c3a333b',
|
userId: '5947397b323ae82d8c3a333b',
|
||||||
userEmail: dbUser.email,
|
userEmail: dbUser.email,
|
||||||
expires: moment()
|
expires: moment().add(1, 'day').toDate(),
|
||||||
.add(1, 'day')
|
|
||||||
.toDate(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
resetToken = {
|
resetToken = {
|
||||||
@ -59,9 +57,7 @@ describe('Authentication API', () => {
|
|||||||
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
userId: '5947397b323ae82d8c3a333b',
|
userId: '5947397b323ae82d8c3a333b',
|
||||||
userEmail: dbUser.email,
|
userEmail: dbUser.email,
|
||||||
expires: moment()
|
expires: moment().add(2, 'hours').toDate(),
|
||||||
.add(2, 'hours')
|
|
||||||
.toDate(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
expiredRefreshToken = {
|
expiredRefreshToken = {
|
||||||
@ -69,9 +65,7 @@ describe('Authentication API', () => {
|
|||||||
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
userId: '5947397b323ae82d8c3a333b',
|
userId: '5947397b323ae82d8c3a333b',
|
||||||
userEmail: dbUser.email,
|
userEmail: dbUser.email,
|
||||||
expires: moment()
|
expires: moment().subtract(1, 'day').toDate(),
|
||||||
.subtract(1, 'day')
|
|
||||||
.toDate(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
expiredResetToken = {
|
expiredResetToken = {
|
||||||
@ -79,9 +73,7 @@ describe('Authentication API', () => {
|
|||||||
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
userId: '5947397b323ae82d8c3a333b',
|
userId: '5947397b323ae82d8c3a333b',
|
||||||
userEmail: dbUser.email,
|
userEmail: dbUser.email,
|
||||||
expires: moment()
|
expires: moment().subtract(2, 'hours').toDate(),
|
||||||
.subtract(2, 'hours')
|
|
||||||
.toDate(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
await User.deleteMany({});
|
await User.deleteMany({});
|
||||||
@ -373,12 +365,16 @@ describe('Authentication API', () => {
|
|||||||
it('should send an email with password reset link when email matches a user', async () => {
|
it('should send an email with password reset link when email matches a user', async () => {
|
||||||
const PasswordResetTokenObj = await PasswordResetToken.create(resetToken);
|
const PasswordResetTokenObj = await PasswordResetToken.create(resetToken);
|
||||||
|
|
||||||
expect(PasswordResetTokenObj.resetToken).to.be.equal('5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d');
|
expect(PasswordResetTokenObj.resetToken).to.be.equal(
|
||||||
expect(PasswordResetTokenObj.userId.toString()).to.be.equal('5947397b323ae82d8c3a333b');
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
|
);
|
||||||
|
expect(PasswordResetTokenObj.userId.toString()).to.be.equal(
|
||||||
|
'5947397b323ae82d8c3a333b',
|
||||||
|
);
|
||||||
expect(PasswordResetTokenObj.userEmail).to.be.equal(dbUser.email);
|
expect(PasswordResetTokenObj.userEmail).to.be.equal(dbUser.email);
|
||||||
expect(PasswordResetTokenObj.expires).to.be.above(moment()
|
expect(PasswordResetTokenObj.expires).to.be.above(
|
||||||
.add(1, 'hour')
|
moment().add(1, 'hour').toDate(),
|
||||||
.toDate());
|
);
|
||||||
|
|
||||||
sandbox
|
sandbox
|
||||||
.stub(emailProvider, 'sendPasswordReset')
|
.stub(emailProvider, 'sendPasswordReset')
|
||||||
@ -463,7 +459,10 @@ describe('Authentication API', () => {
|
|||||||
it('should report error when email is not provided', () => {
|
it('should report error when email is not provided', () => {
|
||||||
return request(app)
|
return request(app)
|
||||||
.post('/v1/auth/reset-password')
|
.post('/v1/auth/reset-password')
|
||||||
.send({ password: 'updatedPassword', resetToken: resetToken.resetToken })
|
.send({
|
||||||
|
password: 'updatedPassword',
|
||||||
|
resetToken: resetToken.resetToken,
|
||||||
|
})
|
||||||
.expect(httpStatus.BAD_REQUEST)
|
.expect(httpStatus.BAD_REQUEST)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const field1 = res.body.errors[0].field;
|
const field1 = res.body.errors[0].field;
|
||||||
@ -504,12 +503,19 @@ describe('Authentication API', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should report error when the resetToken is expired', async () => {
|
it('should report error when the resetToken is expired', async () => {
|
||||||
const expiredPasswordResetTokenObj = await PasswordResetToken.create(expiredResetToken);
|
const expiredPasswordResetTokenObj =
|
||||||
|
await PasswordResetToken.create(expiredResetToken);
|
||||||
|
|
||||||
expect(expiredPasswordResetTokenObj.resetToken).to.be.equal('5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d');
|
expect(expiredPasswordResetTokenObj.resetToken).to.be.equal(
|
||||||
expect(expiredPasswordResetTokenObj.userId.toString()).to.be.equal('5947397b323ae82d8c3a333b');
|
'5947397b323ae82d8c3a333b.c69d0435e62c9f4953af912442a3d064e20291f0d228c0552ed4be473e7d191ba40b18c2c47e8b9d',
|
||||||
|
);
|
||||||
|
expect(expiredPasswordResetTokenObj.userId.toString()).to.be.equal(
|
||||||
|
'5947397b323ae82d8c3a333b',
|
||||||
|
);
|
||||||
expect(expiredPasswordResetTokenObj.userEmail).to.be.equal(dbUser.email);
|
expect(expiredPasswordResetTokenObj.userEmail).to.be.equal(dbUser.email);
|
||||||
expect(expiredPasswordResetTokenObj.expires).to.be.below(moment().toDate());
|
expect(expiredPasswordResetTokenObj.expires).to.be.below(
|
||||||
|
moment().toDate(),
|
||||||
|
);
|
||||||
|
|
||||||
return request(app)
|
return request(app)
|
||||||
.post('/v1/auth/reset-password')
|
.post('/v1/auth/reset-password')
|
||||||
|
@ -69,8 +69,10 @@ describe('Users API', async () => {
|
|||||||
await User.insertMany([dbUsers.branStark, dbUsers.jonSnow]);
|
await User.insertMany([dbUsers.branStark, dbUsers.jonSnow]);
|
||||||
dbUsers.branStark.password = password;
|
dbUsers.branStark.password = password;
|
||||||
dbUsers.jonSnow.password = password;
|
dbUsers.jonSnow.password = password;
|
||||||
adminAccessToken = (await User.findAndGenerateToken(dbUsers.branStark)).accessToken;
|
adminAccessToken = (await User.findAndGenerateToken(dbUsers.branStark))
|
||||||
userAccessToken = (await User.findAndGenerateToken(dbUsers.jonSnow)).accessToken;
|
.accessToken;
|
||||||
|
userAccessToken = (await User.findAndGenerateToken(dbUsers.jonSnow))
|
||||||
|
.accessToken;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /v1/users', () => {
|
describe('POST /v1/users', () => {
|
||||||
@ -147,7 +149,9 @@ describe('Users API', async () => {
|
|||||||
const { messages } = res.body.errors[0];
|
const { messages } = res.body.errors[0];
|
||||||
expect(field).to.be.equal('password');
|
expect(field).to.be.equal('password');
|
||||||
expect(location).to.be.equal('body');
|
expect(location).to.be.equal('body');
|
||||||
expect(messages).to.include('"password" length must be at least 6 characters long');
|
expect(messages).to.include(
|
||||||
|
'"password" length must be at least 6 characters long',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -224,7 +228,7 @@ describe('Users API', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should report error when pagination\'s parameters are not a number', () => {
|
it("should report error when pagination's parameters are not a number", () => {
|
||||||
return request(app)
|
return request(app)
|
||||||
.get('/v1/users')
|
.get('/v1/users')
|
||||||
.set('Authorization', `Bearer ${adminAccessToken}`)
|
.set('Authorization', `Bearer ${adminAccessToken}`)
|
||||||
@ -362,7 +366,9 @@ describe('Users API', async () => {
|
|||||||
const { messages } = res.body.errors[0];
|
const { messages } = res.body.errors[0];
|
||||||
expect(field).to.be.equal('password');
|
expect(field).to.be.equal('password');
|
||||||
expect(location).to.be.equal('body');
|
expect(location).to.be.equal('body');
|
||||||
expect(messages).to.include('"password" length must be at least 6 characters long');
|
expect(messages).to.include(
|
||||||
|
'"password" length must be at least 6 characters long',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -516,7 +522,7 @@ describe('Users API', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /v1/users/profile', () => {
|
describe('GET /v1/users/profile', () => {
|
||||||
it('should get the logged user\'s info', () => {
|
it("should get the logged user's info", () => {
|
||||||
delete dbUsers.jonSnow.password;
|
delete dbUsers.jonSnow.password;
|
||||||
|
|
||||||
return request(app)
|
return request(app)
|
||||||
@ -531,10 +537,12 @@ describe('Users API', async () => {
|
|||||||
it('should report error without stacktrace when accessToken is expired', async () => {
|
it('should report error without stacktrace when accessToken is expired', async () => {
|
||||||
// fake time
|
// fake time
|
||||||
const clock = sinon.useFakeTimers();
|
const clock = sinon.useFakeTimers();
|
||||||
const expiredAccessToken = (await User.findAndGenerateToken(dbUsers.branStark)).accessToken;
|
const expiredAccessToken = (
|
||||||
|
await User.findAndGenerateToken(dbUsers.branStark)
|
||||||
|
).accessToken;
|
||||||
|
|
||||||
// move clock forward by minutes set in config + 1 minute
|
// move clock forward by minutes set in config + 1 minute
|
||||||
clock.tick((JWT_EXPIRATION * 60000) + 60000);
|
clock.tick(JWT_EXPIRATION * 60000 + 60000);
|
||||||
|
|
||||||
return request(app)
|
return request(app)
|
||||||
.get('/v1/users/profile')
|
.get('/v1/users/profile')
|
||||||
|
@ -4,9 +4,7 @@ const httpStatus = require('http-status');
|
|||||||
* @extends Error
|
* @extends Error
|
||||||
*/
|
*/
|
||||||
class ExtendableError extends Error {
|
class ExtendableError extends Error {
|
||||||
constructor({
|
constructor({ message, errors, status, isPublic, stack }) {
|
||||||
message, errors, status, isPublic, stack,
|
|
||||||
}) {
|
|
||||||
super(message);
|
super(message);
|
||||||
this.name = this.constructor.name;
|
this.name = this.constructor.name;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
@ -38,7 +36,11 @@ class APIError extends ExtendableError {
|
|||||||
isPublic = false,
|
isPublic = false,
|
||||||
}) {
|
}) {
|
||||||
super({
|
super({
|
||||||
message, errors, status, isPublic, stack,
|
message,
|
||||||
|
errors,
|
||||||
|
status,
|
||||||
|
isPublic,
|
||||||
|
stack,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<!DOCTYPE html
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta name="x-apple-disable-message-reformatting" />
|
<meta name="x-apple-disable-message-reformatting" />
|
||||||
@ -10,7 +8,7 @@
|
|||||||
<style type="text/css" rel="stylesheet" media="all">
|
<style type="text/css" rel="stylesheet" media="all">
|
||||||
/* Base ------------------------------ */
|
/* Base ------------------------------ */
|
||||||
|
|
||||||
@import url("https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap");
|
@import url('https://fonts.googleapis.com/css?family=Nunito+Sans:400,700&display=swap');
|
||||||
|
|
||||||
body {
|
body {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
@ -20,7 +18,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #3869D4;
|
color: #3869d4;
|
||||||
}
|
}
|
||||||
|
|
||||||
a img {
|
a img {
|
||||||
@ -48,7 +46,7 @@
|
|||||||
body,
|
body,
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -84,7 +82,7 @@
|
|||||||
ul,
|
ul,
|
||||||
ol,
|
ol,
|
||||||
blockquote {
|
blockquote {
|
||||||
margin: .4em 0 1.1875em;
|
margin: 0.4em 0 1.1875em;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.625;
|
line-height: 1.625;
|
||||||
}
|
}
|
||||||
@ -110,13 +108,13 @@
|
|||||||
/* Buttons ------------------------------ */
|
/* Buttons ------------------------------ */
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background-color: #3869D4;
|
background-color: #3869d4;
|
||||||
border-top: 10px solid #3869D4;
|
border-top: 10px solid #3869d4;
|
||||||
border-right: 18px solid #3869D4;
|
border-right: 18px solid #3869d4;
|
||||||
border-bottom: 10px solid #3869D4;
|
border-bottom: 10px solid #3869d4;
|
||||||
border-left: 18px solid #3869D4;
|
border-left: 18px solid #3869d4;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #FFF;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
|
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
|
||||||
@ -125,19 +123,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button--green {
|
.button--green {
|
||||||
background-color: #22BC66;
|
background-color: #22bc66;
|
||||||
border-top: 10px solid #22BC66;
|
border-top: 10px solid #22bc66;
|
||||||
border-right: 18px solid #22BC66;
|
border-right: 18px solid #22bc66;
|
||||||
border-bottom: 10px solid #22BC66;
|
border-bottom: 10px solid #22bc66;
|
||||||
border-left: 18px solid #22BC66;
|
border-left: 18px solid #22bc66;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--red {
|
.button--red {
|
||||||
background-color: #FF6136;
|
background-color: #ff6136;
|
||||||
border-top: 10px solid #FF6136;
|
border-top: 10px solid #ff6136;
|
||||||
border-right: 18px solid #FF6136;
|
border-right: 18px solid #ff6136;
|
||||||
border-bottom: 10px solid #FF6136;
|
border-bottom: 10px solid #ff6136;
|
||||||
border-left: 18px solid #FF6136;
|
border-left: 18px solid #ff6136;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
@media only screen and (max-width: 500px) {
|
||||||
@ -154,7 +152,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.attributes_content {
|
.attributes_content {
|
||||||
background-color: #F4F4F7;
|
background-color: #f4f4f7;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,14 +173,14 @@
|
|||||||
|
|
||||||
.related_item {
|
.related_item {
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
color: #CBCCCF;
|
color: #cbcccf;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.related_item-title {
|
.related_item-title {
|
||||||
display: block;
|
display: block;
|
||||||
margin: .5em 0 0;
|
margin: 0.5em 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.related_item-thumb {
|
.related_item-thumb {
|
||||||
@ -191,7 +189,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.related_heading {
|
.related_heading {
|
||||||
border-top: 1px solid #CBCCCF;
|
border-top: 1px solid #cbcccf;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 25px 0 10px;
|
padding: 25px 0 10px;
|
||||||
}
|
}
|
||||||
@ -205,8 +203,8 @@
|
|||||||
-premailer-width: 100%;
|
-premailer-width: 100%;
|
||||||
-premailer-cellpadding: 0;
|
-premailer-cellpadding: 0;
|
||||||
-premailer-cellspacing: 0;
|
-premailer-cellspacing: 0;
|
||||||
background-color: #F4F4F7;
|
background-color: #f4f4f7;
|
||||||
border: 2px dashed #CBCCCF;
|
border: 2px dashed #cbcccf;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discount_heading {
|
.discount_heading {
|
||||||
@ -257,25 +255,25 @@
|
|||||||
|
|
||||||
.purchase_item {
|
.purchase_item {
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
color: #51545E;
|
color: #51545e;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.purchase_heading {
|
.purchase_heading {
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
border-bottom: 1px solid #EAEAEC;
|
border-bottom: 1px solid #eaeaec;
|
||||||
}
|
}
|
||||||
|
|
||||||
.purchase_heading p {
|
.purchase_heading p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #85878E;
|
color: #85878e;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.purchase_footer {
|
.purchase_footer {
|
||||||
padding-top: 15px;
|
padding-top: 15px;
|
||||||
border-top: 1px solid #EAEAEC;
|
border-top: 1px solid #eaeaec;
|
||||||
}
|
}
|
||||||
|
|
||||||
.purchase_total {
|
.purchase_total {
|
||||||
@ -290,7 +288,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #FFF;
|
background-color: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +328,7 @@
|
|||||||
.email-masthead_name {
|
.email-masthead_name {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #A8AAAF;
|
color: #a8aaaf;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-shadow: 0 1px 0 white;
|
text-shadow: 0 1px 0 white;
|
||||||
}
|
}
|
||||||
@ -366,7 +364,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.email-footer p {
|
.email-footer p {
|
||||||
color: #A8AAAF;
|
color: #a8aaaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
.body-action {
|
.body-action {
|
||||||
@ -382,7 +380,7 @@
|
|||||||
.body-sub {
|
.body-sub {
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
border-top: 1px solid #EAEAEC;
|
border-top: 1px solid #eaeaec;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-cell {
|
.content-cell {
|
||||||
@ -392,7 +390,6 @@
|
|||||||
/*Media Queries ------------------------------ */
|
/*Media Queries ------------------------------ */
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
@media only screen and (max-width: 600px) {
|
||||||
|
|
||||||
.email-body_inner,
|
.email-body_inner,
|
||||||
.email-footer {
|
.email-footer {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
@ -402,7 +399,7 @@
|
|||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
background-color: #333333 !important;
|
background-color: #333333 !important;
|
||||||
color: #FFF !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
p,
|
p,
|
||||||
@ -412,7 +409,7 @@
|
|||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3 {
|
h3 {
|
||||||
color: #FFF !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attributes_content,
|
.attributes_content,
|
||||||
@ -441,107 +438,331 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Nunito Sans", Helvetica, Arial, sans-serif;
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #FFF;
|
background-color: #fff;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body
|
<body
|
||||||
style="width: 100% !important; height: 100%; -webkit-text-size-adjust: none; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; background-color: #FFF; color: #333; margin: 0;"
|
style="
|
||||||
bgcolor="#FFF">
|
width: 100% !important;
|
||||||
<span class="preheader"
|
height: 100%;
|
||||||
style="display: none !important; visibility: hidden; mso-hide: all; font-size: 1px; line-height: 1px; max-height: 0; max-width: 0; opacity: 0; overflow: hidden;">Use
|
-webkit-text-size-adjust: none;
|
||||||
this link to reset your password. The link is only valid for 24 hours.</span>
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation"
|
background-color: #fff;
|
||||||
style="width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 0;">
|
color: #333;
|
||||||
|
margin: 0;
|
||||||
|
"
|
||||||
|
bgcolor="#FFF"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="preheader"
|
||||||
|
style="
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden;
|
||||||
|
mso-hide: all;
|
||||||
|
font-size: 1px;
|
||||||
|
line-height: 1px;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
"
|
||||||
|
>Use this link to reset your password. The link is only valid for 24
|
||||||
|
hours.</span
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
class="email-wrapper"
|
||||||
|
width="100%"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
|
role="presentation"
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;">
|
align="center"
|
||||||
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" role="presentation"
|
style="
|
||||||
style="width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0; padding: 0;">
|
word-break: break-word;
|
||||||
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
class="email-content"
|
||||||
|
width="100%"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
|
role="presentation"
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="email-masthead"
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; text-align: center; padding: 25px 0;"
|
class="email-masthead"
|
||||||
align="center">
|
style="
|
||||||
<a href="https://example.com" class="f-fallback email-masthead_name"
|
word-break: break-word;
|
||||||
style="color: #A8AAAF; font-size: 16px; font-weight: bold; text-decoration: none; text-shadow: 0 1px 0 white;">
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 25px 0;
|
||||||
|
"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://example.com"
|
||||||
|
class="f-fallback email-masthead_name"
|
||||||
|
style="
|
||||||
|
color: #a8aaaf;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 1px 0 white;
|
||||||
|
"
|
||||||
|
>
|
||||||
[Product Name]
|
[Product Name]
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- Email Body -->
|
<!-- Email Body -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="email-body" width="570" cellpadding="0" cellspacing="0"
|
<td
|
||||||
style="word-break: break-word; margin: 0; padding: 0; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0;">
|
class="email-body"
|
||||||
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0"
|
width="570"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
width: 100%;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
class="email-body_inner"
|
||||||
|
align="center"
|
||||||
|
width="570"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
style="width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; margin: 0 auto; padding: 0;">
|
style="
|
||||||
|
width: 570px;
|
||||||
|
-premailer-width: 570px;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
<!-- Body content -->
|
<!-- Body content -->
|
||||||
<tr>
|
<tr>
|
||||||
<td class="content-cell"
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;">
|
class="content-cell"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 35px;
|
||||||
|
"
|
||||||
|
>
|
||||||
<div class="f-fallback">
|
<div class="f-fallback">
|
||||||
<h1 style="margin-top: 0; color: #333333; font-size: 22px; font-weight: bold; text-align: left;"
|
<h1
|
||||||
align="left">Hi {{name}},</h1>
|
style="
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
"
|
||||||
|
align="left"
|
||||||
|
>
|
||||||
|
Hi {{name}},
|
||||||
|
</h1>
|
||||||
<p
|
<p
|
||||||
style="font-size: 16px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
|
style="
|
||||||
You recently requested to reset your password for your [Product Name]
|
font-size: 16px;
|
||||||
account. Use the button below to reset it. <strong>This password reset
|
line-height: 1.625;
|
||||||
is only valid for the next 2 hours.</strong></p>
|
color: #333;
|
||||||
<!-- Action -->
|
margin: 0.4em 0 1.1875em;
|
||||||
<table class="body-action" align="center" width="100%" cellpadding="0"
|
"
|
||||||
cellspacing="0" role="presentation"
|
>
|
||||||
style="width: 100%; -premailer-width: 100%; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 30px auto; padding: 0;">
|
You recently requested to reset your password for your
|
||||||
<tr>
|
[Product Name] account. Use the button below to reset
|
||||||
<td align="center"
|
it.
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;">
|
<strong
|
||||||
<!-- Border based button
|
>This password reset is only valid for the next 2
|
||||||
https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->
|
hours.</strong
|
||||||
<table width="100%" border="0" cellspacing="0" cellpadding="0"
|
>
|
||||||
role="presentation">
|
|
||||||
<tr>
|
|
||||||
<td align="center"
|
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;">
|
|
||||||
<a href="{{action_url}}"
|
|
||||||
class="f-fallback button button--green"
|
|
||||||
target="_blank"
|
|
||||||
style="color: #FFF; border-color: #22bc66; border-style: solid; border-width: 10px 18px; background-color: #22BC66; display: inline-block; text-decoration: none; border-radius: 3px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); -webkit-text-size-adjust: none; box-sizing: border-box;">Reset
|
|
||||||
your password</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<p
|
|
||||||
style="font-size: 16px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
|
|
||||||
For security, this request was received from a {{operating_system}}
|
|
||||||
device using {{browser_name}}. If you did not request a password reset,
|
|
||||||
please ignore this email or <a href="{{support_url}}"
|
|
||||||
style="color: #3869D4;">contact support</a> if you have questions.
|
|
||||||
</p>
|
</p>
|
||||||
<p
|
<!-- Action -->
|
||||||
style="font-size: 16px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
|
<table
|
||||||
Thanks,
|
class="body-action"
|
||||||
<br />The [Product Name] Team</p>
|
align="center"
|
||||||
<!-- Sub copy -->
|
width="100%"
|
||||||
<table class="body-sub" role="presentation"
|
cellpadding="0"
|
||||||
style="margin-top: 25px; padding-top: 25px; border-top-width: 1px; border-top-color: #EAEAEC; border-top-style: solid;">
|
cellspacing="0"
|
||||||
|
role="presentation"
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 30px auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;">
|
align="center"
|
||||||
<p class="f-fallback sub"
|
style="
|
||||||
style="font-size: 13px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
|
word-break: break-word;
|
||||||
If you’re having trouble with the button above, copy and
|
font-family: 'Nunito Sans', Helvetica, Arial,
|
||||||
paste the URL below into your web browser.</p>
|
sans-serif;
|
||||||
<p class="f-fallback sub"
|
font-size: 16px;
|
||||||
style="font-size: 13px; line-height: 1.625; color: #333; margin: .4em 0 1.1875em;">
|
"
|
||||||
{{action_url}}</p>
|
>
|
||||||
|
<!-- Border based button
|
||||||
|
https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design -->
|
||||||
|
<table
|
||||||
|
width="100%"
|
||||||
|
border="0"
|
||||||
|
cellspacing="0"
|
||||||
|
cellpadding="0"
|
||||||
|
role="presentation"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
align="center"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
font-family: 'Nunito Sans', Helvetica,
|
||||||
|
Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="{{action_url}}"
|
||||||
|
class="f-fallback button button--green"
|
||||||
|
target="_blank"
|
||||||
|
style="
|
||||||
|
color: #fff;
|
||||||
|
border-color: #22bc66;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 10px 18px;
|
||||||
|
background-color: #22bc66;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0 2px 3px
|
||||||
|
rgba(0, 0, 0, 0.16);
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
"
|
||||||
|
>Reset your password</a
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p
|
||||||
|
style="
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.625;
|
||||||
|
color: #333;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
For security, this request was received from a
|
||||||
|
{{operating_system}} device using {{browser_name}}. If
|
||||||
|
you did not request a password reset, please ignore
|
||||||
|
this email or
|
||||||
|
<a href="{{support_url}}" style="color: #3869d4"
|
||||||
|
>contact support</a
|
||||||
|
>
|
||||||
|
if you have questions.
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
style="
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.625;
|
||||||
|
color: #333;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
Thanks,
|
||||||
|
<br />The [Product Name] Team
|
||||||
|
</p>
|
||||||
|
<!-- Sub copy -->
|
||||||
|
<table
|
||||||
|
class="body-sub"
|
||||||
|
role="presentation"
|
||||||
|
style="
|
||||||
|
margin-top: 25px;
|
||||||
|
padding-top: 25px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-top-color: #eaeaec;
|
||||||
|
border-top-style: solid;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
font-family: 'Nunito Sans', Helvetica, Arial,
|
||||||
|
sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="f-fallback sub"
|
||||||
|
style="
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.625;
|
||||||
|
color: #333;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
If you’re having trouble with the button above,
|
||||||
|
copy and paste the URL below into your web
|
||||||
|
browser.
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="f-fallback sub"
|
||||||
|
style="
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.625;
|
||||||
|
color: #333;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{{action_url}}
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -553,22 +774,66 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px;">
|
style="
|
||||||
<table class="email-footer" align="center" width="570" cellpadding="0" cellspacing="0"
|
word-break: break-word;
|
||||||
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
class="email-footer"
|
||||||
|
align="center"
|
||||||
|
width="570"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
role="presentation"
|
role="presentation"
|
||||||
style="width: 570px; -premailer-width: 570px; -premailer-cellpadding: 0; -premailer-cellspacing: 0; text-align: center; margin: 0 auto; padding: 0;">
|
style="
|
||||||
|
width: 570px;
|
||||||
|
-premailer-width: 570px;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="content-cell" align="center"
|
<td
|
||||||
style="word-break: break-word; font-family: "Nunito Sans", Helvetica, Arial, sans-serif; font-size: 16px; padding: 35px;">
|
class="content-cell"
|
||||||
<p class="f-fallback sub align-center"
|
align="center"
|
||||||
style="font-size: 13px; line-height: 1.625; text-align: center; color: #A8AAAF; margin: .4em 0 1.1875em;"
|
style="
|
||||||
align="center">© 2019 [Product Name]. All rights reserved.</p>
|
word-break: break-word;
|
||||||
<p class="f-fallback sub align-center"
|
font-family: 'Nunito Sans', Helvetica, Arial, sans-serif;
|
||||||
style="font-size: 13px; line-height: 1.625; text-align: center; color: #A8AAAF; margin: .4em 0 1.1875em;"
|
font-size: 16px;
|
||||||
align="center">
|
padding: 35px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="f-fallback sub align-center"
|
||||||
|
style="
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.625;
|
||||||
|
text-align: center;
|
||||||
|
color: #a8aaaf;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
© 2019 [Product Name]. All rights reserved.
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="f-fallback sub align-center"
|
||||||
|
style="
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.625;
|
||||||
|
text-align: center;
|
||||||
|
color: #a8aaaf;
|
||||||
|
margin: 0.4em 0 1.1875em;
|
||||||
|
"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
[Company Name, LLC]
|
[Company Name, LLC]
|
||||||
<br />1234 Street Rd.
|
<br />1234 Street Rd. <br />Suite 1234
|
||||||
<br />Suite 1234
|
|
||||||
</p>
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -580,5 +845,4 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -4,25 +4,16 @@ module.exports = {
|
|||||||
// POST /v1/auth/register
|
// POST /v1/auth/register
|
||||||
register: {
|
register: {
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
email: Joi.string()
|
email: Joi.string().email().required(),
|
||||||
.email()
|
password: Joi.string().required().min(6).max(128),
|
||||||
.required(),
|
|
||||||
password: Joi.string()
|
|
||||||
.required()
|
|
||||||
.min(6)
|
|
||||||
.max(128),
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
// POST /v1/auth/login
|
// POST /v1/auth/login
|
||||||
login: {
|
login: {
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
email: Joi.string()
|
email: Joi.string().email().required(),
|
||||||
.email()
|
password: Joi.string().required().max(128),
|
||||||
.required(),
|
|
||||||
password: Joi.string()
|
|
||||||
.required()
|
|
||||||
.max(128),
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -37,9 +28,7 @@ module.exports = {
|
|||||||
// POST /v1/auth/refresh
|
// POST /v1/auth/refresh
|
||||||
refresh: {
|
refresh: {
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
email: Joi.string()
|
email: Joi.string().email().required(),
|
||||||
.email()
|
|
||||||
.required(),
|
|
||||||
refreshToken: Joi.string().required(),
|
refreshToken: Joi.string().required(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@ -47,22 +36,15 @@ module.exports = {
|
|||||||
// POST /v1/auth/refresh
|
// POST /v1/auth/refresh
|
||||||
sendPasswordReset: {
|
sendPasswordReset: {
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
email: Joi.string()
|
email: Joi.string().email().required(),
|
||||||
.email()
|
|
||||||
.required(),
|
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
// POST /v1/auth/password-reset
|
// POST /v1/auth/password-reset
|
||||||
passwordReset: {
|
passwordReset: {
|
||||||
body: Joi.object({
|
body: Joi.object({
|
||||||
email: Joi.string()
|
email: Joi.string().email().required(),
|
||||||
.email()
|
password: Joi.string().required().min(6).max(128),
|
||||||
.required(),
|
|
||||||
password: Joi.string()
|
|
||||||
.required()
|
|
||||||
.min(6)
|
|
||||||
.max(128),
|
|
||||||
resetToken: Joi.string().required(),
|
resetToken: Joi.string().required(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,6 @@ const Joi = require('joi');
|
|||||||
const User = require('../models/user.model');
|
const User = require('../models/user.model');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
// GET /v1/users
|
// GET /v1/users
|
||||||
listUsers: {
|
listUsers: {
|
||||||
query: Joi.object({
|
query: Joi.object({
|
||||||
@ -20,7 +19,7 @@ module.exports = {
|
|||||||
email: Joi.string().email().required(),
|
email: Joi.string().email().required(),
|
||||||
password: Joi.string().min(6).max(128).required(),
|
password: Joi.string().min(6).max(128).required(),
|
||||||
name: Joi.string().max(128),
|
name: Joi.string().max(128),
|
||||||
role: Joi.string()
|
role: Joi.string(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -30,10 +29,12 @@ module.exports = {
|
|||||||
email: Joi.string().email().required(),
|
email: Joi.string().email().required(),
|
||||||
password: Joi.string().min(6).max(128).required(),
|
password: Joi.string().min(6).max(128).required(),
|
||||||
name: Joi.string().max(128),
|
name: Joi.string().max(128),
|
||||||
role: Joi.string()
|
role: Joi.string(),
|
||||||
}),
|
}),
|
||||||
params: {
|
params: {
|
||||||
userId: Joi.string().regex(/^[a-fA-F0-9]{24}$/).required(),
|
userId: Joi.string()
|
||||||
|
.regex(/^[a-fA-F0-9]{24}$/)
|
||||||
|
.required(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -46,7 +47,9 @@ module.exports = {
|
|||||||
role: Joi.string(),
|
role: Joi.string(),
|
||||||
}),
|
}),
|
||||||
params: {
|
params: {
|
||||||
userId: Joi.string().regex(/^[a-fA-F0-9]{24}$/).required(),
|
userId: Joi.string()
|
||||||
|
.regex(/^[a-fA-F0-9]{24}$/)
|
||||||
|
.required(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -18,9 +18,11 @@ const logger = winston.createLogger({
|
|||||||
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
|
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
|
||||||
//
|
//
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
logger.add(new winston.transports.Console({
|
logger.add(
|
||||||
|
new winston.transports.Console({
|
||||||
format: winston.format.simple(),
|
format: winston.format.simple(),
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.stream = {
|
logger.stream = {
|
||||||
|
@ -20,7 +20,7 @@ const jwt = async (payload, done) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const oAuth = service => async (token, done) => {
|
const oAuth = (service) => async (token, done) => {
|
||||||
try {
|
try {
|
||||||
const userData = await authProviders[service](token);
|
const userData = await authProviders[service](token);
|
||||||
const user = await User.oAuthLogin(userData);
|
const user = await User.oAuthLogin(userData);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
// import .env variables
|
// import .env variables
|
||||||
require('dotenv-safe').load({
|
require('dotenv').config({
|
||||||
path: path.join(__dirname, '../../.env'),
|
path: path.join(__dirname, `../../.env.${process.env.NODE_ENV}`),
|
||||||
sample: path.join(__dirname, '../../.env.example'),
|
sample: path.join(__dirname, '../../.env.example'),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -12,7 +12,10 @@ module.exports = {
|
|||||||
jwtSecret: process.env.JWT_SECRET,
|
jwtSecret: process.env.JWT_SECRET,
|
||||||
jwtExpirationInterval: process.env.JWT_EXPIRATION_MINUTES,
|
jwtExpirationInterval: process.env.JWT_EXPIRATION_MINUTES,
|
||||||
mongo: {
|
mongo: {
|
||||||
uri: process.env.NODE_ENV === 'test' ? process.env.MONGO_URI_TESTS : process.env.MONGO_URI,
|
uri:
|
||||||
|
process.env.NODE_ENV === 'test'
|
||||||
|
? process.env.MONGO_URI_TESTS
|
||||||
|
: process.env.MONGO_URI,
|
||||||
},
|
},
|
||||||
logs: process.env.NODE_ENV === 'production' ? 'combined' : 'dev',
|
logs: process.env.NODE_ENV === 'production' ? 'combined' : 'dev',
|
||||||
emailConfig: {
|
emailConfig: {
|
||||||
|
194
yarn.lock
194
yarn.lock
@ -218,14 +218,14 @@
|
|||||||
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz"
|
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz"
|
||||||
integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==
|
integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==
|
||||||
|
|
||||||
"@eslint-community/eslint-utils@^4.2.0":
|
"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
||||||
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
|
integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-visitor-keys "^3.3.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
"@eslint-community/regexpp@^4.6.1":
|
"@eslint-community/regexpp@^4.6.0", "@eslint-community/regexpp@^4.6.1":
|
||||||
version "4.10.0"
|
version "4.10.0"
|
||||||
resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz"
|
resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz"
|
||||||
integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
|
integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==
|
||||||
@ -478,6 +478,11 @@
|
|||||||
"@opencensus/core" "^0.0.8"
|
"@opencensus/core" "^0.0.8"
|
||||||
uuid "^3.2.1"
|
uuid "^3.2.1"
|
||||||
|
|
||||||
|
"@pkgr/core@^0.1.0":
|
||||||
|
version "0.1.1"
|
||||||
|
resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz"
|
||||||
|
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
|
||||||
|
|
||||||
"@pm2/agent@~2.0.0":
|
"@pm2/agent@~2.0.0":
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.3.tgz"
|
resolved "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.3.tgz"
|
||||||
@ -619,7 +624,7 @@
|
|||||||
"@types/eslint" "*"
|
"@types/eslint" "*"
|
||||||
"@types/estree" "*"
|
"@types/estree" "*"
|
||||||
|
|
||||||
"@types/eslint@*":
|
"@types/eslint@*", "@types/eslint@>=8.0.0":
|
||||||
version "8.56.5"
|
version "8.56.5"
|
||||||
resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz"
|
resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz"
|
||||||
integrity sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==
|
integrity sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==
|
||||||
@ -1394,6 +1399,18 @@ buffer-from@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
||||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||||
|
|
||||||
|
builtin-modules@^3.3.0:
|
||||||
|
version "3.3.0"
|
||||||
|
resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz"
|
||||||
|
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
||||||
|
|
||||||
|
builtins@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz"
|
||||||
|
integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==
|
||||||
|
dependencies:
|
||||||
|
semver "^7.0.0"
|
||||||
|
|
||||||
bytes@3.0.0:
|
bytes@3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz"
|
||||||
@ -1760,11 +1777,6 @@ concat-map@0.0.1:
|
|||||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
||||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
confusing-browser-globals@^1.0.10:
|
|
||||||
version "1.0.11"
|
|
||||||
resolved "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz"
|
|
||||||
integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==
|
|
||||||
|
|
||||||
constantinople@^4.0.1:
|
constantinople@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz"
|
resolved "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz"
|
||||||
@ -1847,13 +1859,6 @@ croner@~4.1.92:
|
|||||||
resolved "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz"
|
resolved "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz"
|
||||||
integrity sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==
|
integrity sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==
|
||||||
|
|
||||||
cross-env@^7.0.3:
|
|
||||||
version "7.0.3"
|
|
||||||
resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz"
|
|
||||||
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
|
|
||||||
dependencies:
|
|
||||||
cross-spawn "^7.0.1"
|
|
||||||
|
|
||||||
cross-spawn@^6.0.0:
|
cross-spawn@^6.0.0:
|
||||||
version "6.0.5"
|
version "6.0.5"
|
||||||
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz"
|
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz"
|
||||||
@ -1865,7 +1870,7 @@ cross-spawn@^6.0.0:
|
|||||||
shebang-command "^1.2.0"
|
shebang-command "^1.2.0"
|
||||||
which "^1.2.9"
|
which "^1.2.9"
|
||||||
|
|
||||||
cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||||
version "7.0.3"
|
version "7.0.3"
|
||||||
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
|
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
|
||||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
@ -2240,7 +2245,22 @@ domutils@^3.0.1:
|
|||||||
domelementtype "^2.3.0"
|
domelementtype "^2.3.0"
|
||||||
domhandler "^5.0.3"
|
domhandler "^5.0.3"
|
||||||
|
|
||||||
dotenv@^16.4.5:
|
dotenv-cli@^7.4.1:
|
||||||
|
version "7.4.1"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.1.tgz"
|
||||||
|
integrity sha512-fE1aywjRrWGxV3miaiUr3d2zC/VAiuzEGghi+QzgIA9fEf/M5hLMaRSXb4IxbUAwGmaLi0IozdZddnVU96acag==
|
||||||
|
dependencies:
|
||||||
|
cross-spawn "^7.0.3"
|
||||||
|
dotenv "^16.3.0"
|
||||||
|
dotenv-expand "^10.0.0"
|
||||||
|
minimist "^1.2.6"
|
||||||
|
|
||||||
|
dotenv-expand@^10.0.0:
|
||||||
|
version "10.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz"
|
||||||
|
integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==
|
||||||
|
|
||||||
|
dotenv@^16.3.0, dotenv@^16.4.5:
|
||||||
version "16.4.5"
|
version "16.4.5"
|
||||||
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz"
|
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz"
|
||||||
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==
|
||||||
@ -2538,15 +2558,15 @@ escodegen@^2.1.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
|
|
||||||
eslint-config-airbnb-base@^15.0.0:
|
eslint-compat-utils@^0.1.2:
|
||||||
version "15.0.0"
|
version "0.1.2"
|
||||||
resolved "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz"
|
resolved "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz"
|
||||||
integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==
|
integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==
|
||||||
dependencies:
|
|
||||||
confusing-browser-globals "^1.0.10"
|
eslint-config-standard@^17.1.0:
|
||||||
object.assign "^4.1.2"
|
version "17.1.0"
|
||||||
object.entries "^1.1.5"
|
resolved "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz"
|
||||||
semver "^6.3.0"
|
integrity sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==
|
||||||
|
|
||||||
eslint-import-resolver-node@^0.3.9:
|
eslint-import-resolver-node@^0.3.9:
|
||||||
version "0.3.9"
|
version "0.3.9"
|
||||||
@ -2564,7 +2584,16 @@ eslint-module-utils@^2.8.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "^3.2.7"
|
debug "^3.2.7"
|
||||||
|
|
||||||
eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3:
|
eslint-plugin-es-x@^7.5.0:
|
||||||
|
version "7.5.0"
|
||||||
|
resolved "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.5.0.tgz"
|
||||||
|
integrity sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==
|
||||||
|
dependencies:
|
||||||
|
"@eslint-community/eslint-utils" "^4.1.2"
|
||||||
|
"@eslint-community/regexpp" "^4.6.0"
|
||||||
|
eslint-compat-utils "^0.1.2"
|
||||||
|
|
||||||
|
eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.29.1:
|
||||||
version "2.29.1"
|
version "2.29.1"
|
||||||
resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz"
|
resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz"
|
||||||
integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==
|
integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==
|
||||||
@ -2587,6 +2616,36 @@ eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.25.3:
|
|||||||
semver "^6.3.1"
|
semver "^6.3.1"
|
||||||
tsconfig-paths "^3.15.0"
|
tsconfig-paths "^3.15.0"
|
||||||
|
|
||||||
|
"eslint-plugin-n@^15.0.0 || ^16.0.0 ", eslint-plugin-n@^16.6.2:
|
||||||
|
version "16.6.2"
|
||||||
|
resolved "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz"
|
||||||
|
integrity sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==
|
||||||
|
dependencies:
|
||||||
|
"@eslint-community/eslint-utils" "^4.4.0"
|
||||||
|
builtins "^5.0.1"
|
||||||
|
eslint-plugin-es-x "^7.5.0"
|
||||||
|
get-tsconfig "^4.7.0"
|
||||||
|
globals "^13.24.0"
|
||||||
|
ignore "^5.2.4"
|
||||||
|
is-builtin-module "^3.2.1"
|
||||||
|
is-core-module "^2.12.1"
|
||||||
|
minimatch "^3.1.2"
|
||||||
|
resolve "^1.22.2"
|
||||||
|
semver "^7.5.3"
|
||||||
|
|
||||||
|
eslint-plugin-prettier@^5.1.3:
|
||||||
|
version "5.1.3"
|
||||||
|
resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz"
|
||||||
|
integrity sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==
|
||||||
|
dependencies:
|
||||||
|
prettier-linter-helpers "^1.0.0"
|
||||||
|
synckit "^0.8.6"
|
||||||
|
|
||||||
|
eslint-plugin-promise@^6.0.0, eslint-plugin-promise@^6.1.1:
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz"
|
||||||
|
integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==
|
||||||
|
|
||||||
eslint-scope@^7.2.2:
|
eslint-scope@^7.2.2:
|
||||||
version "7.2.2"
|
version "7.2.2"
|
||||||
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz"
|
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz"
|
||||||
@ -2608,7 +2667,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4
|
|||||||
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
|
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
|
||||||
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
||||||
|
|
||||||
"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.32.0 || ^8.2.0", eslint@^8.5.0:
|
"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.0.1, eslint@^8.57.0, eslint@>=6.0.0, eslint@>=7.0.0, eslint@>=8, eslint@>=8.0.0:
|
||||||
version "8.57.0"
|
version "8.57.0"
|
||||||
resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz"
|
resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz"
|
||||||
integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
|
integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==
|
||||||
@ -2821,6 +2880,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
|||||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
|
fast-diff@^1.1.2:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz"
|
||||||
|
integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
|
||||||
|
|
||||||
fast-json-patch@^3.0.0-1:
|
fast-json-patch@^3.0.0-1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz"
|
resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz"
|
||||||
@ -3151,6 +3215,13 @@ get-symbol-description@^1.0.2:
|
|||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
get-intrinsic "^1.2.4"
|
get-intrinsic "^1.2.4"
|
||||||
|
|
||||||
|
get-tsconfig@^4.7.0:
|
||||||
|
version "4.7.3"
|
||||||
|
resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz"
|
||||||
|
integrity sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==
|
||||||
|
dependencies:
|
||||||
|
resolve-pkg-maps "^1.0.0"
|
||||||
|
|
||||||
get-uri@^6.0.1:
|
get-uri@^6.0.1:
|
||||||
version "6.0.3"
|
version "6.0.3"
|
||||||
resolved "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz"
|
resolved "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz"
|
||||||
@ -3225,7 +3296,7 @@ globals@^11.1.0:
|
|||||||
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
|
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
|
||||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||||
|
|
||||||
globals@^13.19.0:
|
globals@^13.19.0, globals@^13.24.0:
|
||||||
version "13.24.0"
|
version "13.24.0"
|
||||||
resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz"
|
resolved "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz"
|
||||||
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
|
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
|
||||||
@ -3482,7 +3553,7 @@ ignore-by-default@^1.0.1:
|
|||||||
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz"
|
||||||
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==
|
||||||
|
|
||||||
ignore@^5.2.0:
|
ignore@^5.2.0, ignore@^5.2.4:
|
||||||
version "5.3.1"
|
version "5.3.1"
|
||||||
resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz"
|
resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz"
|
||||||
integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==
|
integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==
|
||||||
@ -3603,12 +3674,19 @@ is-boolean-object@^1.1.0:
|
|||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
has-tostringtag "^1.0.0"
|
has-tostringtag "^1.0.0"
|
||||||
|
|
||||||
|
is-builtin-module@^3.2.1:
|
||||||
|
version "3.2.1"
|
||||||
|
resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz"
|
||||||
|
integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==
|
||||||
|
dependencies:
|
||||||
|
builtin-modules "^3.3.0"
|
||||||
|
|
||||||
is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
|
is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
|
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
|
||||||
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
||||||
|
|
||||||
is-core-module@^2.13.0, is-core-module@^2.13.1:
|
is-core-module@^2.12.1, is-core-module@^2.13.0, is-core-module@^2.13.1:
|
||||||
version "2.13.1"
|
version "2.13.1"
|
||||||
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz"
|
resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz"
|
||||||
integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
|
integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==
|
||||||
@ -4557,6 +4635,18 @@ module-details-from-path@^1.0.3:
|
|||||||
resolved "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz"
|
||||||
integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
|
integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
|
||||||
|
|
||||||
|
moment-timezone@^0.5.45:
|
||||||
|
version "0.5.45"
|
||||||
|
resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz"
|
||||||
|
integrity sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==
|
||||||
|
dependencies:
|
||||||
|
moment "^2.29.4"
|
||||||
|
|
||||||
|
moment@^2.29.4:
|
||||||
|
version "2.30.1"
|
||||||
|
resolved "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz"
|
||||||
|
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
||||||
|
|
||||||
mongodb-connection-string-url@^3.0.0:
|
mongodb-connection-string-url@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz"
|
||||||
@ -4859,7 +4949,7 @@ object-keys@^1.1.1:
|
|||||||
resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
|
resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
|
||||||
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
||||||
|
|
||||||
object.assign@^4.1.2, object.assign@^4.1.5:
|
object.assign@^4.1.5:
|
||||||
version "4.1.5"
|
version "4.1.5"
|
||||||
resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz"
|
resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz"
|
||||||
integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==
|
integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==
|
||||||
@ -4869,15 +4959,6 @@ object.assign@^4.1.2, object.assign@^4.1.5:
|
|||||||
has-symbols "^1.0.3"
|
has-symbols "^1.0.3"
|
||||||
object-keys "^1.1.1"
|
object-keys "^1.1.1"
|
||||||
|
|
||||||
object.entries@^1.1.5:
|
|
||||||
version "1.1.7"
|
|
||||||
resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz"
|
|
||||||
integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==
|
|
||||||
dependencies:
|
|
||||||
call-bind "^1.0.2"
|
|
||||||
define-properties "^1.2.0"
|
|
||||||
es-abstract "^1.22.1"
|
|
||||||
|
|
||||||
object.fromentries@^2.0.7:
|
object.fromentries@^2.0.7:
|
||||||
version "2.0.7"
|
version "2.0.7"
|
||||||
resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz"
|
resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz"
|
||||||
@ -5375,6 +5456,18 @@ prelude-ls@^1.2.1:
|
|||||||
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
|
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
|
||||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||||
|
|
||||||
|
prettier-linter-helpers@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz"
|
||||||
|
integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
|
||||||
|
dependencies:
|
||||||
|
fast-diff "^1.1.2"
|
||||||
|
|
||||||
|
prettier@^3.2.5, prettier@>=3.0.0:
|
||||||
|
version "3.2.5"
|
||||||
|
resolved "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz"
|
||||||
|
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
|
||||||
|
|
||||||
preview-email@^3.0.17:
|
preview-email@^3.0.17:
|
||||||
version "3.0.19"
|
version "3.0.19"
|
||||||
resolved "https://registry.npmjs.org/preview-email/-/preview-email-3.0.19.tgz"
|
resolved "https://registry.npmjs.org/preview-email/-/preview-email-3.0.19.tgz"
|
||||||
@ -5761,7 +5854,12 @@ resolve-from@^5.0.0:
|
|||||||
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
|
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz"
|
||||||
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
|
||||||
|
|
||||||
resolve@^1.10.0, resolve@^1.15.1, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.9.0:
|
resolve-pkg-maps@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz"
|
||||||
|
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
|
||||||
|
|
||||||
|
resolve@^1.10.0, resolve@^1.15.1, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4, resolve@^1.9.0:
|
||||||
version "1.22.8"
|
version "1.22.8"
|
||||||
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
|
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
|
||||||
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
|
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
|
||||||
@ -5906,7 +6004,7 @@ semver@^6.3.1:
|
|||||||
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
|
||||||
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
|
||||||
|
|
||||||
semver@^7.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4:
|
semver@^7.0.0, semver@^7.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4:
|
||||||
version "7.6.0"
|
version "7.6.0"
|
||||||
resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz"
|
resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz"
|
||||||
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
|
integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==
|
||||||
@ -6385,6 +6483,14 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
|
||||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||||
|
|
||||||
|
synckit@^0.8.6:
|
||||||
|
version "0.8.8"
|
||||||
|
resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz"
|
||||||
|
integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==
|
||||||
|
dependencies:
|
||||||
|
"@pkgr/core" "^0.1.0"
|
||||||
|
tslib "^2.6.2"
|
||||||
|
|
||||||
systeminformation@^5.7:
|
systeminformation@^5.7:
|
||||||
version "5.22.0"
|
version "5.22.0"
|
||||||
resolved "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.0.tgz"
|
resolved "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.0.tgz"
|
||||||
@ -6535,7 +6641,7 @@ tsconfig-paths@^3.15.0:
|
|||||||
minimist "^1.2.6"
|
minimist "^1.2.6"
|
||||||
strip-bom "^3.0.0"
|
strip-bom "^3.0.0"
|
||||||
|
|
||||||
tslib@^2.0.1:
|
tslib@^2.0.1, tslib@^2.6.2:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
||||||
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
||||||
|
Loading…
x
Reference in New Issue
Block a user