mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-21 16:52:03 -07:00
fix(tests): Increased coverage of REST API validators
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"srcDir": "",
|
||||||
|
"destDir": "",
|
||||||
|
"files": "**/*.js",
|
||||||
|
"command": "npm run lint"
|
||||||
|
}
|
||||||
|
]
|
||||||
+1
-1
@@ -27,7 +27,7 @@ import AdminLib from '../src/adapters/admin.js'
|
|||||||
import errorMiddleware from '../src/controllers/rest-api/middleware/error.js'
|
import errorMiddleware from '../src/controllers/rest-api/middleware/error.js'
|
||||||
import wlogger from '../src/adapters/wlogger.js'
|
import wlogger from '../src/adapters/wlogger.js'
|
||||||
import Controllers from '../src/controllers/index.js'
|
import Controllers from '../src/controllers/index.js'
|
||||||
import applyPassportMods from '../config/passport.js'
|
import { applyPassportMods } from '../config/passport.js'
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
constructor () {
|
constructor () {
|
||||||
|
|||||||
Vendored
+6
-1
@@ -5,9 +5,14 @@
|
|||||||
|
|
||||||
/* eslint no-unneeded-ternary:0 */
|
/* eslint no-unneeded-ternary:0 */
|
||||||
|
|
||||||
|
// Hack to get __dirname back.
|
||||||
|
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
||||||
|
import * as url from 'url'
|
||||||
|
|
||||||
// Get the version from the package.json file.
|
// Get the version from the package.json file.
|
||||||
import { readFileSync } from 'fs'
|
import { readFileSync } from 'fs'
|
||||||
const pkgInfo = JSON.parse(readFileSync('package.json'))
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
const pkgInfo = JSON.parse(readFileSync(`${__dirname.toString()}/../../package.json`))
|
||||||
|
|
||||||
const version = pkgInfo.version
|
const version = pkgInfo.version
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -5,11 +5,12 @@ import production from './env/production.js'
|
|||||||
import test from './env/test.js'
|
import test from './env/test.js'
|
||||||
|
|
||||||
const env = process.env.SVC_ENV || 'development'
|
const env = process.env.SVC_ENV || 'development'
|
||||||
|
console.log(`Loading config for this environment: ${env}`)
|
||||||
|
|
||||||
let config = development
|
let config = development
|
||||||
if (env === 'test') {
|
if (env === 'test') {
|
||||||
config = test
|
config = test
|
||||||
} else if (env === 'production') {
|
} else if (env === 'prod') {
|
||||||
config = production
|
config = production
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -49,8 +49,11 @@ function applyPassportMods (passport) {
|
|||||||
passportCallback
|
passportCallback
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing
|
// For testing
|
||||||
// export default { passport, passportCallback };
|
// export default { passport, passportCallback };
|
||||||
export default applyPassportMods
|
// export default applyPassportMods
|
||||||
|
export { applyPassportMods, passportCallback }
|
||||||
|
|||||||
Generated
+39
-151
@@ -12,7 +12,7 @@
|
|||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"glob": "7.1.6",
|
"glob": "7.1.6",
|
||||||
"ipfs-coord-esm": "9.1.2",
|
"ipfs-coord-esm": "../ipfs-coord-esm/",
|
||||||
"ipfs-http-client": "58.0.0",
|
"ipfs-http-client": "58.0.0",
|
||||||
"jsonrpc-lite": "2.2.0",
|
"jsonrpc-lite": "2.2.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
@@ -51,6 +51,28 @@
|
|||||||
"uuid": "8.3.2"
|
"uuid": "8.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"../ipfs-coord-esm": {
|
||||||
|
"version": "9.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"bch-encrypt-lib": "2.0.0",
|
||||||
|
"uuid": "9.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@istanbuljs/esm-loader-hook": "0.2.0",
|
||||||
|
"chai": "4.3.6",
|
||||||
|
"cross-env": "7.0.3",
|
||||||
|
"lodash.clonedeep": "4.5.0",
|
||||||
|
"minimal-slp-wallet": "5.0.3",
|
||||||
|
"mocha": "10.0.0",
|
||||||
|
"nyc": "15.1.0",
|
||||||
|
"sinon": "14.0.0",
|
||||||
|
"standard": "17.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"ipfs-http-client": ">= 58.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.18.6",
|
"version": "7.18.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
|
||||||
@@ -1489,11 +1511,6 @@
|
|||||||
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/aes-js": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ=="
|
|
||||||
},
|
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
@@ -2053,15 +2070,6 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bch-encrypt-lib": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/bch-encrypt-lib/-/bch-encrypt-lib-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-EAfcw2vzcKMkdO004tfLmQEEpGZA9QeIgzG9sbxDweFiGr2BP6/06G5SIJdvsJhcAd9OS9Rw5bLlPAy25kX8HQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"eccrypto-js": "^5.3.0",
|
|
||||||
"wif": "^2.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/bchaddrjs-slp": {
|
"node_modules/bchaddrjs-slp": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.5.tgz",
|
||||||
@@ -3550,28 +3558,6 @@
|
|||||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
|
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/eccrypto-js": {
|
|
||||||
"version": "5.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eccrypto-js/-/eccrypto-js-5.4.0.tgz",
|
|
||||||
"integrity": "sha512-W4xBr0UANgpkSIu2FBHG5wjhvOR4L19HwAUm9xiA4c3bzB9gGbH8+E9hSMTNF+QbmEi+TDvt373JHKA6NnW38A==",
|
|
||||||
"dependencies": {
|
|
||||||
"aes-js": "3.1.2",
|
|
||||||
"enc-utils": "2.1.0",
|
|
||||||
"hash.js": "1.1.7",
|
|
||||||
"js-sha3": "0.8.0",
|
|
||||||
"pbkdf2": "^3.0.17",
|
|
||||||
"randombytes": "2.1.0",
|
|
||||||
"secp256k1": "3.8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eccrypto-js/node_modules/randombytes": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"safe-buffer": "^5.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ecdsa-sig-formatter": {
|
"node_modules/ecdsa-sig-formatter": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
@@ -3648,16 +3634,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
||||||
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
||||||
},
|
},
|
||||||
"node_modules/enc-utils": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/enc-utils/-/enc-utils-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-VD0eunGDyzhojePzkORWDnW88gi6tIeGb5Z6QVHugux6mMAPiXyw94fb/7WdDQEWhKMSoYRyzFFUebCqeH20PA==",
|
|
||||||
"dependencies": {
|
|
||||||
"bn.js": "4.11.8",
|
|
||||||
"is-typedarray": "1.0.0",
|
|
||||||
"typedarray-to-buffer": "3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/encodeurl": {
|
"node_modules/encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@@ -6072,24 +6048,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ipfs-coord-esm": {
|
"node_modules/ipfs-coord-esm": {
|
||||||
"version": "9.1.2",
|
"resolved": "../ipfs-coord-esm",
|
||||||
"resolved": "https://registry.npmjs.org/ipfs-coord-esm/-/ipfs-coord-esm-9.1.2.tgz",
|
"link": true
|
||||||
"integrity": "sha512-tZZMtBS7TTatDJD2gWdu9EOPt5E2kxwSRr5GMeRKRPnP4z1Z4QTpP94nmDhcDDABpdD4IseVQjcwUED5fd+IgQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"bch-encrypt-lib": "2.0.0",
|
|
||||||
"uuid": "9.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"ipfs-http-client": ">= 58.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ipfs-coord-esm/node_modules/uuid": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
|
|
||||||
"bin": {
|
|
||||||
"uuid": "dist/bin/uuid"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"node_modules/ipfs-http-client": {
|
"node_modules/ipfs-http-client": {
|
||||||
"version": "58.0.0",
|
"version": "58.0.0",
|
||||||
@@ -6645,7 +6605,8 @@
|
|||||||
"node_modules/is-typedarray": {
|
"node_modules/is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/is-unicode-supported": {
|
"node_modules/is-unicode-supported": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@@ -6880,11 +6841,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
||||||
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
||||||
},
|
},
|
||||||
"node_modules/js-sha3": {
|
|
||||||
"version": "0.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
|
|
||||||
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
|
|
||||||
},
|
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -14153,14 +14109,6 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typedarray-to-buffer": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
|
|
||||||
"dependencies": {
|
|
||||||
"is-typedarray": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/typeforce": {
|
"node_modules/typeforce": {
|
||||||
"version": "1.18.0",
|
"version": "1.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
||||||
@@ -16068,11 +16016,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"aes-js": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ=="
|
|
||||||
},
|
|
||||||
"agent-base": {
|
"agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
@@ -16485,15 +16428,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bch-encrypt-lib": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/bch-encrypt-lib/-/bch-encrypt-lib-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-EAfcw2vzcKMkdO004tfLmQEEpGZA9QeIgzG9sbxDweFiGr2BP6/06G5SIJdvsJhcAd9OS9Rw5bLlPAy25kX8HQ==",
|
|
||||||
"requires": {
|
|
||||||
"eccrypto-js": "^5.3.0",
|
|
||||||
"wif": "^2.0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bchaddrjs-slp": {
|
"bchaddrjs-slp": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/bchaddrjs-slp/-/bchaddrjs-slp-0.2.5.tgz",
|
||||||
@@ -17669,30 +17603,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eccrypto-js": {
|
|
||||||
"version": "5.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/eccrypto-js/-/eccrypto-js-5.4.0.tgz",
|
|
||||||
"integrity": "sha512-W4xBr0UANgpkSIu2FBHG5wjhvOR4L19HwAUm9xiA4c3bzB9gGbH8+E9hSMTNF+QbmEi+TDvt373JHKA6NnW38A==",
|
|
||||||
"requires": {
|
|
||||||
"aes-js": "3.1.2",
|
|
||||||
"enc-utils": "2.1.0",
|
|
||||||
"hash.js": "1.1.7",
|
|
||||||
"js-sha3": "0.8.0",
|
|
||||||
"pbkdf2": "^3.0.17",
|
|
||||||
"randombytes": "2.1.0",
|
|
||||||
"secp256k1": "3.8.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"randombytes": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
|
||||||
"requires": {
|
|
||||||
"safe-buffer": "^5.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ecdsa-sig-formatter": {
|
"ecdsa-sig-formatter": {
|
||||||
"version": "1.0.11",
|
"version": "1.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
@@ -17765,16 +17675,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
||||||
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
||||||
},
|
},
|
||||||
"enc-utils": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/enc-utils/-/enc-utils-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-VD0eunGDyzhojePzkORWDnW88gi6tIeGb5Z6QVHugux6mMAPiXyw94fb/7WdDQEWhKMSoYRyzFFUebCqeH20PA==",
|
|
||||||
"requires": {
|
|
||||||
"bn.js": "4.11.8",
|
|
||||||
"is-typedarray": "1.0.0",
|
|
||||||
"typedarray-to-buffer": "3.1.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"encodeurl": {
|
"encodeurl": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
@@ -19425,19 +19325,19 @@
|
|||||||
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q=="
|
"integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q=="
|
||||||
},
|
},
|
||||||
"ipfs-coord-esm": {
|
"ipfs-coord-esm": {
|
||||||
"version": "9.1.2",
|
"version": "file:../ipfs-coord-esm",
|
||||||
"resolved": "https://registry.npmjs.org/ipfs-coord-esm/-/ipfs-coord-esm-9.1.2.tgz",
|
|
||||||
"integrity": "sha512-tZZMtBS7TTatDJD2gWdu9EOPt5E2kxwSRr5GMeRKRPnP4z1Z4QTpP94nmDhcDDABpdD4IseVQjcwUED5fd+IgQ==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"@istanbuljs/esm-loader-hook": "0.2.0",
|
||||||
"bch-encrypt-lib": "2.0.0",
|
"bch-encrypt-lib": "2.0.0",
|
||||||
|
"chai": "4.3.6",
|
||||||
|
"cross-env": "7.0.3",
|
||||||
|
"lodash.clonedeep": "4.5.0",
|
||||||
|
"minimal-slp-wallet": "5.0.3",
|
||||||
|
"mocha": "10.0.0",
|
||||||
|
"nyc": "15.1.0",
|
||||||
|
"sinon": "14.0.0",
|
||||||
|
"standard": "17.0.0",
|
||||||
"uuid": "9.0.0"
|
"uuid": "9.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"uuid": {
|
|
||||||
"version": "9.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
|
|
||||||
"integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ipfs-http-client": {
|
"ipfs-http-client": {
|
||||||
@@ -19832,7 +19732,8 @@
|
|||||||
"is-typedarray": {
|
"is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-unicode-supported": {
|
"is-unicode-supported": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
@@ -20021,11 +19922,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
|
||||||
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
"integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA=="
|
||||||
},
|
},
|
||||||
"js-sha3": {
|
|
||||||
"version": "0.8.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
|
|
||||||
"integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
|
|
||||||
},
|
|
||||||
"js-tokens": {
|
"js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
@@ -25451,14 +25347,6 @@
|
|||||||
"mime-types": "~2.1.24"
|
"mime-types": "~2.1.24"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typedarray-to-buffer": {
|
|
||||||
"version": "3.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
|
||||||
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
|
|
||||||
"requires": {
|
|
||||||
"is-typedarray": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"typeforce": {
|
"typeforce": {
|
||||||
"version": "1.18.0",
|
"version": "1.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@
|
|||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"glob": "7.1.6",
|
"glob": "7.1.6",
|
||||||
"ipfs-coord-esm": "9.1.2",
|
"ipfs-coord-esm": "../ipfs-coord-esm/",
|
||||||
"ipfs-http-client": "58.0.0",
|
"ipfs-http-client": "58.0.0",
|
||||||
"jsonrpc-lite": "2.2.0",
|
"jsonrpc-lite": "2.2.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ import JsonFiles from '../adapters/json-files.js'
|
|||||||
// Hack to get __dirname back.
|
// Hack to get __dirname back.
|
||||||
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
||||||
import * as url from 'url'
|
import * as url from 'url'
|
||||||
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||||
|
|
||||||
const jsonFiles = new JsonFiles()
|
const jsonFiles = new JsonFiles()
|
||||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
||||||
|
|
||||||
const JSON_FILE = `system-user-${config.env}.json`
|
const JSON_FILE = `system-user-${config.env}.json`
|
||||||
const JSON_PATH = `${__dirname.toString()}/../../config/${JSON_FILE}`
|
const JSON_PATH = `${__dirname.toString()}/../../config/${JSON_FILE}`
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
REST API validator middleware.
|
REST API validator middleware.
|
||||||
|
|
||||||
|
These are a series of functions that ensure the user making a REST API
|
||||||
|
matches a user in the database (or not). In can do fine-grain user control
|
||||||
|
such as telling the difference between an admin, a normal user, and an
|
||||||
|
anonymous user.
|
||||||
|
|
||||||
|
This middleware is used to gatekeep access to different REST API resources.
|
||||||
|
|
||||||
|
CT 9/17/22:
|
||||||
|
This library was lightly refactored to make it work with the new unit tests.
|
||||||
|
This not and the commented code below can be deleted once it is verified that
|
||||||
|
this refactor did not result in any breaking changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import User from '../../../adapters/localdb/models/users.js'
|
import User from '../../../adapters/localdb/models/users.js'
|
||||||
@@ -21,12 +33,10 @@ class Validators {
|
|||||||
|
|
||||||
async ensureUser (ctx, next) {
|
async ensureUser (ctx, next) {
|
||||||
try {
|
try {
|
||||||
// console.log(`getToken: ${typeof (getToken)}`)
|
|
||||||
const token = _this.getToken(ctx)
|
const token = _this.getToken(ctx)
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
// console.log(`Err: Token not provided.`)
|
throw new Error('Token could not be retrieved from header')
|
||||||
ctx.throw(401)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let decoded = null
|
let decoded = null
|
||||||
@@ -35,20 +45,23 @@ class Validators {
|
|||||||
// console.log(`config: ${JSON.stringify(config, null, 2)}`)
|
// console.log(`config: ${JSON.stringify(config, null, 2)}`)
|
||||||
decoded = _this.jwt.verify(token, config.token)
|
decoded = _this.jwt.verify(token, config.token)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.log(`Err: Token could not be decoded: ${err}`)
|
throw new Error('Could not verify JWT')
|
||||||
ctx.throw(401)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
||||||
|
|
||||||
if (!ctx.state.user) {
|
if (!ctx.state.user) {
|
||||||
// console.log(`Err: Could not find user.`)
|
// console.log('Err: Could not find user.')
|
||||||
ctx.throw(401)
|
throw new Error('Could not find user')
|
||||||
}
|
}
|
||||||
|
|
||||||
// return next()
|
// return next()
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ctx.throw(401)
|
// console.log('Ensure user error: ', error)
|
||||||
|
// console.log('ctx: ', ctx)
|
||||||
|
ctx.status = 401
|
||||||
|
ctx.throw(401, error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +74,8 @@ class Validators {
|
|||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
// console.log(`Err: Token not provided.`)
|
// console.log(`Err: Token not provided.`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Token could not be retrieved from header')
|
||||||
}
|
}
|
||||||
|
|
||||||
let decoded = null
|
let decoded = null
|
||||||
@@ -71,22 +85,26 @@ class Validators {
|
|||||||
decoded = _this.jwt.verify(token, config.token)
|
decoded = _this.jwt.verify(token, config.token)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.log(`Err: Token could not be decoded: ${err}`)
|
// console.log(`Err: Token could not be decoded: ${err}`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Could not verify JWT')
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
||||||
if (!ctx.state.user) {
|
if (!ctx.state.user) {
|
||||||
// console.log(`Err: Could not find user.`)
|
// console.log(`Err: Could not find user.`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Could not find user')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.state.user.type !== 'admin') {
|
if (ctx.state.user.type !== 'admin') {
|
||||||
ctx.throw(401, 'not admin')
|
// ctx.throw(401, 'not admin')
|
||||||
|
throw new Error('User is not an admin')
|
||||||
}
|
}
|
||||||
|
|
||||||
// return next()
|
// return next()
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
ctx.status = 401
|
||||||
ctx.throw(401, error.message)
|
ctx.throw(401, error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +120,8 @@ class Validators {
|
|||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
// console.log(`Err: Token not provided.`)
|
// console.log(`Err: Token not provided.`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Token could not be retrieved from header')
|
||||||
}
|
}
|
||||||
|
|
||||||
// The user ID targeted in this API call.
|
// The user ID targeted in this API call.
|
||||||
@@ -115,14 +134,16 @@ class Validators {
|
|||||||
// console.log(`config: ${JSON.stringify(config, null, 2)}`)
|
// console.log(`config: ${JSON.stringify(config, null, 2)}`)
|
||||||
decoded = _this.jwt.verify(token, config.token)
|
decoded = _this.jwt.verify(token, config.token)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.log(`Err: Token could not be decoded: ${err}`)
|
console.log(`Err: Token could not be decoded: ${err}`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Could not verify JWT')
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
ctx.state.user = await _this.User.findById(decoded.id, '-password')
|
||||||
if (!ctx.state.user) {
|
if (!ctx.state.user) {
|
||||||
// console.log(`Err: Could not find user.`)
|
// console.log(`Err: Could not find user.`)
|
||||||
ctx.throw(401)
|
// ctx.throw(401)
|
||||||
|
throw new Error('Could not find user')
|
||||||
}
|
}
|
||||||
// console.log('ctx.state.user: ', ctx.state.user)
|
// console.log('ctx.state.user: ', ctx.state.user)
|
||||||
|
|
||||||
@@ -136,7 +157,8 @@ class Validators {
|
|||||||
|
|
||||||
// If they don't match, then the calling user better be an admin.
|
// If they don't match, then the calling user better be an admin.
|
||||||
if (ctx.state.user.type !== 'admin') {
|
if (ctx.state.user.type !== 'admin') {
|
||||||
ctx.throw(401, 'not admin')
|
// ctx.throw(401, 'not admin')
|
||||||
|
throw new Error('User is not an admin')
|
||||||
} else {
|
} else {
|
||||||
wlogger.verbose("It's ok. The user is an admin.")
|
wlogger.verbose("It's ok. The user is an admin.")
|
||||||
}
|
}
|
||||||
@@ -145,6 +167,8 @@ class Validators {
|
|||||||
// return next()
|
// return next()
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// console.log('Error in ensureTargetUserOrAdmin(): ', error)
|
||||||
|
ctx.status = 401
|
||||||
ctx.throw(401, error.message)
|
ctx.throw(401, error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class UserRESTControllerLib {
|
|||||||
* @apiGroup REST Users
|
* @apiGroup REST Users
|
||||||
*
|
*
|
||||||
* @apiExample Example usage:
|
* @apiExample Example usage:
|
||||||
* curl -H "Content-Type: application/json" -X POST -d '{ "user": { "email": "email@format.com", "name": "my name", "password": "secretpasas" } }' localhost:5001/users
|
* curl -H "Content-Type: application/json" -X POST -d '{ "user": { "email": "email@format.com", "name": "my name", "password": "secretpasas" } }' localhost:5010/users
|
||||||
*
|
*
|
||||||
* @apiParam {Object} user User object (required)
|
* @apiParam {Object} user User object (required)
|
||||||
* @apiParam {String} user.email Email
|
* @apiParam {String} user.email Email
|
||||||
@@ -136,7 +136,7 @@ class UserRESTControllerLib {
|
|||||||
* @apiGroup REST Users
|
* @apiGroup REST Users
|
||||||
*
|
*
|
||||||
* @apiExample Example usage:
|
* @apiExample Example usage:
|
||||||
* curl -H "Content-Type: application/json" -X GET localhost:5000/users/56bd1da600a526986cf65c80
|
* curl -H "Content-Type: application/json" -X GET localhost:5010/users/56bd1da600a526986cf65c80
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object} users User object
|
* @apiSuccess {Object} users User object
|
||||||
* @apiSuccess {ObjectId} users._id User id
|
* @apiSuccess {ObjectId} users._id User id
|
||||||
|
|||||||
@@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
Unit tests for the REST API middleware that validates users.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Public npm libraries
|
||||||
|
import { assert } from 'chai'
|
||||||
|
import sinon from 'sinon'
|
||||||
|
|
||||||
|
// Local libraries
|
||||||
|
import Validators from '../../../../../src/controllers/rest-api/middleware/validators.js'
|
||||||
|
import { context as mockContext } from '../../../../unit/mocks/ctx-mock.js'
|
||||||
|
|
||||||
|
describe('#Validators', () => {
|
||||||
|
let uut
|
||||||
|
let ctx
|
||||||
|
let sandbox
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
uut = new Validators()
|
||||||
|
|
||||||
|
// Mock the context object.
|
||||||
|
ctx = mockContext()
|
||||||
|
|
||||||
|
sandbox = sinon.createSandbox()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => sandbox.restore())
|
||||||
|
|
||||||
|
describe('#getToken', () => {
|
||||||
|
it('should return null if no header is provided', () => {
|
||||||
|
const result = uut.getToken(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, null)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return null if header is not in two parts', () => {
|
||||||
|
ctx.request.header.authorization = 'Bearer'
|
||||||
|
|
||||||
|
const result = uut.getToken(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, null)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return null if first part of header does not container the word bearer', () => {
|
||||||
|
ctx.request.header.authorization = 'some thing'
|
||||||
|
|
||||||
|
const result = uut.getToken(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, null)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return the JWT token from the header', () => {
|
||||||
|
const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYzMjNiNTUwNzgxYWYzNTc4YzI0ZmU5YiIsImlhdCI6MTY2MzQ0NDczNCwiZXhwIjoxNjYzNTMxMTM0fQ.BY5sOfXc4z5axS98CdTfyqnO9y2wijOlwnv52rcvxHA'
|
||||||
|
ctx.request.header.authorization = `Bearer ${jwt}`
|
||||||
|
|
||||||
|
const result = uut.getToken(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, jwt)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#ensureUser', () => {
|
||||||
|
it('should throw error if token is not provided', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns()
|
||||||
|
|
||||||
|
await uut.ensureUser(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if token can not be verified', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||||||
|
|
||||||
|
await uut.ensureUser(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if user can not be found in database', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||||||
|
|
||||||
|
await uut.ensureUser(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true if the user is verified', async () => {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ user: 'alice' })
|
||||||
|
|
||||||
|
const result = await uut.ensureUser(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#ensureUser', () => {
|
||||||
|
it('should throw error if token is not provided', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns()
|
||||||
|
|
||||||
|
await uut.ensureAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if token can not be verified', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||||||
|
|
||||||
|
await uut.ensureAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if user can not be found in database', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||||||
|
|
||||||
|
await uut.ensureAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if user is not an admin', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
|
||||||
|
|
||||||
|
await uut.ensureAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true if the user is an admin', async () => {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin' })
|
||||||
|
|
||||||
|
const result = await uut.ensureAdmin(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('#ensureTargetUserOrAdmin', () => {
|
||||||
|
it('should throw error if token is not provided', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns()
|
||||||
|
|
||||||
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if token can not be verified', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').throws(new Error('test error'))
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '456'
|
||||||
|
}
|
||||||
|
|
||||||
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if user can not be found in database', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves(false)
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '456'
|
||||||
|
}
|
||||||
|
|
||||||
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if user is not an admin', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user' })
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '456'
|
||||||
|
}
|
||||||
|
|
||||||
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error is user is not admin or target user', async () => {
|
||||||
|
try {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '456'
|
||||||
|
}
|
||||||
|
|
||||||
|
await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.fail('Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.equal(ctx.status, 401)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true if the user is an admin', async () => {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'admin', _id: '123' })
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '456'
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true if the user is the target user', async () => {
|
||||||
|
// Mock dependencies and force desired code path
|
||||||
|
sandbox.stub(uut, 'getToken').returns('fake-jwt')
|
||||||
|
sandbox.stub(uut.jwt, 'verify').returns({})
|
||||||
|
sandbox.stub(uut.User, 'findById').resolves({ type: 'user', _id: '123' })
|
||||||
|
|
||||||
|
ctx.params = {
|
||||||
|
id: '123'
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await uut.ensureTargetUserOrAdmin(ctx)
|
||||||
|
|
||||||
|
assert.equal(result, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -4,12 +4,10 @@
|
|||||||
|
|
||||||
// Public npm libraries
|
// Public npm libraries
|
||||||
import { assert } from 'chai'
|
import { assert } from 'chai'
|
||||||
|
|
||||||
import sinon from 'sinon'
|
import sinon from 'sinon'
|
||||||
|
|
||||||
// Local support libraries
|
// Local support libraries
|
||||||
import adapters from '../../../mocks/adapters/index.js'
|
import adapters from '../../../mocks/adapters/index.js'
|
||||||
|
|
||||||
import UseCasesMock from '../../../mocks/use-cases/index.js'
|
import UseCasesMock from '../../../mocks/use-cases/index.js'
|
||||||
import UserController from '../../../../../src/controllers/rest-api/users/controller.js'
|
import UserController from '../../../../../src/controllers/rest-api/users/controller.js'
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
Unit tests for the config directory
|
Unit tests for the config directory
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
let currentEnv
|
let currentEnv
|
||||||
|
|
||||||
describe('#config', () => {
|
describe('#config', () => {
|
||||||
@@ -15,8 +17,34 @@ describe('#config', () => {
|
|||||||
process.env.SVC_ENV = currentEnv
|
process.env.SVC_ENV = currentEnv
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return development environment config', () => {
|
it('Should return development environment config by default', async () => {
|
||||||
// import config from '../../../config/index.js'
|
const importedConfig = await import('../../../config/index.js')
|
||||||
|
const config = importedConfig.default
|
||||||
// console.log('config: ', config)
|
// console.log('config: ', config)
|
||||||
|
|
||||||
|
assert.equal(config.env, 'dev')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return test environment config', async () => {
|
||||||
|
// Hack to dynamically import a library multiple times:
|
||||||
|
// https://github.com/denoland/deno/issues/6946
|
||||||
|
|
||||||
|
process.env.SVC_ENV = 'test'
|
||||||
|
|
||||||
|
const importedConfig2 = await import('../../../config/index.js?foo=bar1')
|
||||||
|
const config = importedConfig2.default
|
||||||
|
// console.log('config: ', config)
|
||||||
|
|
||||||
|
assert.equal(config.env, 'test')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should return test environment config', async () => {
|
||||||
|
process.env.SVC_ENV = 'prod'
|
||||||
|
|
||||||
|
const importedConfig3 = await import('../../../config/index.js?foo=bar2')
|
||||||
|
const config = importedConfig3.default
|
||||||
|
// console.log('config: ', config)
|
||||||
|
|
||||||
|
assert.equal(config.env, 'prod')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,78 +1,93 @@
|
|||||||
// /*
|
/*
|
||||||
// Unit tests for the passport library.
|
Unit tests for the passport library.
|
||||||
// */
|
*/
|
||||||
//
|
|
||||||
// // Public npm libraries
|
// Public npm libraries
|
||||||
// // const assert = require('chai').assert
|
import { assert } from 'chai'
|
||||||
// import sinon from 'sinon';
|
import sinon from 'sinon'
|
||||||
//
|
import passport from 'koa-passport'
|
||||||
// // Local libraries
|
|
||||||
// import User from '../../../src/adapters/localdb/models/users.js';
|
// Local libraries
|
||||||
//
|
import User from '../../../src/adapters/localdb/models/users.js'
|
||||||
// import { passport, passportCallback } from '../../../config/passport.js';
|
|
||||||
// import adaptersMock from '../mocks/adapters/index.js';
|
import { applyPassportMods, passportCallback } from '../../../config/passport.js'
|
||||||
//
|
import adaptersMock from '../mocks/adapters/index.js'
|
||||||
// describe('#passport', () => {
|
|
||||||
// let sandbox
|
describe('#passport', () => {
|
||||||
// let id
|
let sandbox
|
||||||
// let done
|
let id
|
||||||
//
|
let done
|
||||||
// beforeEach(() => {
|
|
||||||
// sandbox = sinon.createSandbox()
|
beforeEach(() => {
|
||||||
//
|
sandbox = sinon.createSandbox()
|
||||||
// id = 'abc123'
|
|
||||||
// done = () => {}
|
id = 'abc123'
|
||||||
// })
|
done = () => {}
|
||||||
//
|
})
|
||||||
// afterEach(() => sandbox.restore())
|
|
||||||
//
|
afterEach(() => sandbox.restore())
|
||||||
// describe('#serializeUser', () => {
|
|
||||||
// it('should serialize a user', () => {
|
describe('#passportCallback', () => {
|
||||||
// const user = {
|
it('should return if user is found', () => {
|
||||||
// id: 'abc123'
|
// Mock Users model.
|
||||||
// }
|
sandbox.stub(User, 'findOne').resolves({ id })
|
||||||
// const done = () => {}
|
|
||||||
//
|
passportCallback(id, 'password', done)
|
||||||
// passport.serializeUser(user, done)
|
})
|
||||||
// })
|
|
||||||
// })
|
it('should return if password is validated', () => {
|
||||||
//
|
// Mock Users model.
|
||||||
// describe('#deserializeUser', () => {
|
sandbox.stub(User, 'findOne').resolves(new adaptersMock.localdb.Users())
|
||||||
// it('should deserialize a user', () => {
|
|
||||||
// // Mock Users model.
|
passportCallback(id, 'password', done)
|
||||||
// sandbox.stub(User, 'findById').resolves({ id })
|
})
|
||||||
//
|
|
||||||
// passport.deserializeUser(id, done)
|
it('should catch a high-level error', () => {
|
||||||
// })
|
// Force an error
|
||||||
//
|
sandbox.stub(User, 'findOne').rejects(new Error('test error'))
|
||||||
// it('should catch and handle errors', () => {
|
|
||||||
// // Force an error
|
passportCallback(id, 'password', done)
|
||||||
// sandbox.stub(User, 'findById').rejects(new Error('test error'))
|
})
|
||||||
//
|
})
|
||||||
// passport.deserializeUser(id, done)
|
|
||||||
// })
|
describe('#applyPassportMods', () => {
|
||||||
// })
|
it('should apply modifications to default passport behavior', () => {
|
||||||
//
|
const result = applyPassportMods(passport)
|
||||||
// describe('#passportCallback', () => {
|
|
||||||
// it('should return if user is found', () => {
|
assert.equal(result, true)
|
||||||
// // Mock Users model.
|
})
|
||||||
// sandbox.stub(User, 'findOne').resolves({ id })
|
})
|
||||||
//
|
|
||||||
// passportCallback(id, 'password', done)
|
describe('#serializeUser', () => {
|
||||||
// })
|
it('should serialize a user', () => {
|
||||||
//
|
const user = {
|
||||||
// it('should return if password is validated', () => {
|
id: 'abc123'
|
||||||
// // Mock Users model.
|
}
|
||||||
// sandbox.stub(User, 'findOne').resolves(new adaptersMock.localdb.Users())
|
const done = () => {}
|
||||||
//
|
|
||||||
// passportCallback(id, 'password', done)
|
applyPassportMods(passport)
|
||||||
// })
|
|
||||||
//
|
passport.serializeUser(user, done)
|
||||||
// it('should catch a high-level error', () => {
|
})
|
||||||
// // Force an error
|
})
|
||||||
// sandbox.stub(User, 'findOne').rejects(new Error('test error'))
|
|
||||||
//
|
describe('#deserializeUser', () => {
|
||||||
// passportCallback(id, 'password', done)
|
it('should deserialize a user', () => {
|
||||||
// })
|
// Mock Users model.
|
||||||
// })
|
sandbox.stub(User, 'findById').resolves({ id })
|
||||||
// })
|
|
||||||
|
applyPassportMods(passport)
|
||||||
|
|
||||||
|
passport.deserializeUser(id, done)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should catch and handle errors', () => {
|
||||||
|
// Force an error
|
||||||
|
sandbox.stub(User, 'findById').rejects(new Error('test error'))
|
||||||
|
|
||||||
|
applyPassportMods(passport)
|
||||||
|
|
||||||
|
passport.deserializeUser(id, done)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
// Public npm libraries
|
// Public npm libraries
|
||||||
import { assert } from 'chai'
|
import { assert } from 'chai'
|
||||||
|
|
||||||
import sinon from 'sinon'
|
import sinon from 'sinon'
|
||||||
|
|
||||||
// Local libraries
|
// Local libraries
|
||||||
|
|||||||
Reference in New Issue
Block a user