diff --git a/packages/ws-server-core/package.json b/packages/ws-server-core/package.json index 7788d4fd5b43faf7f75a7c7ee3dbb659e9edc53a..e9bb624185d984b8ea0d324ee71518c6cce9eed2 100644 --- a/packages/ws-server-core/package.json +++ b/packages/ws-server-core/package.json @@ -33,7 +33,7 @@ "debug": "^4.1.1", "esm": "^3.2.25", "fs-extra": "^9.0.0", - "jsonql-constants": "^2.0.15", + "jsonql-constants": "^2.0.16", "jsonql-errors": "^1.2.1", "jsonql-params-validator": "^1.6.2", "jsonql-resolver": "^1.2.6", diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index 76dae9ae7a969a55cdb7deeac6278bbb094f0da7..f022ac9e6e81217090699959c395692ebd9c4a3b 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -33,9 +33,9 @@ "dependencies": { "colors": "^1.4.0", "debug": "^4.1.1", - "jsonql-constants": "^2.0.14", + "jsonql-constants": "^2.0.16", "jsonql-utils": "^1.2.6", - "jsonql-ws-server-core": "^0.8.3", + "jsonql-ws-server-core": "^0.8.4", "ws": "^7.2.3" }, "devDependencies": { diff --git a/packages/ws-server/src/core/options.js b/packages/ws-server/src/core/options.js new file mode 100644 index 0000000000000000000000000000000000000000..6f634c3d7bf9b60b920a419a9ad1f70017ccfd0f --- /dev/null +++ b/packages/ws-server/src/core/options.js @@ -0,0 +1,27 @@ +// since this is very specific to the WebSocket verify method +// we add this option to the default +// and we should do the same for those that is only applicable to socket.io +const { wsServerDefaultOptions } = require('jsonql-ws-server-core') +const { createConfig } = require('jsonql-params-validator') +const { + TOKEN_DELIVER_LOCATION_PROP_KEY, + TOKEN_IN_URL, + TOKEN_IN_HEADER, + STRING_TYPE, + ENUM_KEY +} = require('jsonql-constants') + +const AVAILABLE_PLACES = [ + TOKEN_IN_URL, + TOKEN_IN_HEADER +] + +const configCheckMap = { + [TOKEN_DELIVER_LOCATION_PROP_KEY]: createConfig(TOKEN_IN_URL, [STRING_TYPE], { + [ENUM_KEY]: AVAILABLE_PLACES + }) +} + +module.exports = { + wsServerDefaultOptions: Object.assign(wsServerDefaultOptions, configCheckMap) +} \ No newline at end of file diff --git a/packages/ws-server/src/core/security/create-verify-client.js b/packages/ws-server/src/core/security/create-verify-client.js index b7e7fa54ad0a8efe95f728ecf73074670ba36419..41bace5faedb07cba2d186596285b5227384470f 100644 --- a/packages/ws-server/src/core/security/create-verify-client.js +++ b/packages/ws-server/src/core/security/create-verify-client.js @@ -4,7 +4,14 @@ const url = require('url') const { parse } = require('querystring') const { jwtDecode } = require('jsonql-jwt') -const { TOKEN_PARAM_NAME } = require('jsonql-constants') + +const { + TOKEN_PARAM_NAME, + TOKEN_DELIVER_LOCATION_PROP_KEY, + TOKEN_IN_URL, + TOKEN_IN_HEADER, + AUTH_CHECK_HEADER +} = require('jsonql-constants') const { SOCKET_STATE_KEY } = require('../../modules') const { debug } = require('../../utils') @@ -32,6 +39,42 @@ function getTokenFromQuery(uri) { return false } +/** + * new method to get the token from the header + * @param {*} opts + * @param {*} req + */ +function getTokenFromHeader(req) { + const { headers } = req + if (headers) { + return headers[AUTH_CHECK_HEADER] || false + } + + return false +} + +/** + * New combine get token method using the options to switch + * @param {object} opts configuration + * @param {object} req request object + * @return {string|boolean} false on failed + */ +function getAuthToken(opts, req) { + switch (opts[TOKEN_DELIVER_LOCATION_PROP_KEY]) { + case TOKEN_IN_URL: + + return getTokenFromQuery(req.url) + case TOKEN_IN_HEADER: + + return getTokenFromHeader(req) + default: + + return false + } + +} + + /** * We need to check the origin from the header to make sure it's match * @param {object} opts configuration options @@ -112,9 +155,8 @@ function createVerifyClient(namespace, opts, jwtOptions = {}, cb = localCb) { // @TODO here we need to take the interceptor.validate method that created by // develop to run their own checks - // auth features - const uri = req.url - const token = getTokenFromQuery(uri) + // using a new method to group the getToken method + const token = getAuthToken(opts, req) if (token) { debug(`Got a token`) @@ -131,7 +173,7 @@ function createVerifyClient(namespace, opts, jwtOptions = {}, cb = localCb) { return done(payload) } catch(e) { - cb({e, token, uri}) + cb(e) // just show the error done(false) } } @@ -141,23 +183,4 @@ function createVerifyClient(namespace, opts, jwtOptions = {}, cb = localCb) { } } -/* -another example from ws npm page -This one is using the express session - -server.on('upgrade', function upgrade(request, socket, head) { - authenticate(request, (err, client) => { - if (err || !client) { - socket.destroy(); - return; - } - - wss.handleUpgrade(request, socket, head, function done(ws) { - wss.emit('connection', ws, request, client); - }); - }); -}); -*/ - - module.exports = { createVerifyClient } diff --git a/packages/ws-server/src/modules.js b/packages/ws-server/src/modules.js index 23715832311cd0516a60faa93a8f80e654bbf5e5..f3a91e769054eccc118384f9a17007e3b432e5f3 100644 --- a/packages/ws-server/src/modules.js +++ b/packages/ws-server/src/modules.js @@ -1,12 +1,14 @@ // keep all the import from ws-server-core in one place // for easy switching to debug const WebSocket = require('ws') +const { wsServerDefaultOptions } = require('./core/options') + const { checkSocketServerType, jsonqlWsServerCore, jsonqlWsServerCoreAction, - wsServerDefaultOptions, + // wsServerDefaultOptions, wsServerConstProps, getNamespace, diff --git a/packages/ws-server/tests/init.test.js b/packages/ws-server/tests/init.test.js index a1217ab71bba4693e95e9dcade4e1acc040cdc63..8e360147f01558d1291660da0f09ddf922bceda1 100644 --- a/packages/ws-server/tests/init.test.js +++ b/packages/ws-server/tests/init.test.js @@ -57,7 +57,9 @@ test.cb(`Testing the init ping call`, t => { // t.end() // reinit the client with an options - const newClient = basicClient(`ws://localhost:${port}/${JSONQL_PATH}`, false, {headers: json.data}) + const newClient = basicClient(`ws://localhost:${port}/${JSONQL_PATH}`, false, { + headers: json.data + }) newClient.on('open', () => { t.end()