From 3f84d1dab924b63c4ab991613a8474252941f6d5 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 16 Mar 2020 16:13:38 +0800 Subject: [PATCH 1/5] jsonql-ws-server 1.7.4 --- packages/ws-client-core/package.json | 3 +- .../src/share/init-ping-methods.js | 34 +++++++++--- packages/ws-client-core/tests/init.test.js | 54 +++++++++++++++++++ packages/ws-server/client.js | 2 +- packages/ws-server/package.json | 5 +- 5 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 packages/ws-client-core/tests/init.test.js diff --git a/packages/ws-client-core/package.json b/packages/ws-client-core/package.json index 07db29d3..b4bf2002 100644 --- a/packages/ws-client-core/package.json +++ b/packages/ws-client-core/package.json @@ -15,6 +15,7 @@ "update:version": "node ./build.js", "test:tbd": "DEBUG=jsonql-ws* ava ./tests/tbd.test.js", "test:evt": "ava ./tests/event.test.js", + "test:init": "DEBUG=jsonql-ws* ava ./tests/init.test.js", "test:auth": "DEBUG=jsonql-ws* ava ./tests/auth.test.js", "test:node": "DEBUG=jsonql-ws-* ava ./tests/test-node.test.js", "test:opt": "DEBUG=jsonql-ws-* ava ./tests/options.test.js", @@ -54,7 +55,7 @@ }, "dependencies": { "@to1source/event": "^1.0.0", - "jsonql-constants": "^2.0.2", + "jsonql-constants": "^2.0.3", "jsonql-errors": "^1.2.1", "jsonql-params-validator": "^1.6.1", "jsonql-utils": "^1.2.0" diff --git a/packages/ws-client-core/src/share/init-ping-methods.js b/packages/ws-client-core/src/share/init-ping-methods.js index bac364a9..bd685084 100644 --- a/packages/ws-client-core/src/share/init-ping-methods.js +++ b/packages/ws-client-core/src/share/init-ping-methods.js @@ -6,24 +6,40 @@ // we use this token to create a new client and destroy the old one import { INTERCOM_RESOLVER_NAME, - SOCKET_PING_EVENT_NAME -} from 'jsonql-constants/socket' + SOCKET_PING_EVENT_NAME, + HEADERS_KEY, + DATA_KEY, + CSRF_HEADER_KEY +} from 'jsonql-constants' import { createQueryStr, extractWsPayload, timestamp, - toJson + toJson } from 'jsonql-utils/module' +import { + JsonqlError +} from 'jsonql-errors' +const CSRF_HEADER_NOT_EXIST_ERR = 'CSRF header is not in the received payload' /** * call the server to get a csrf token * @return {string} formatted payload to send to the server */ -function initPingAction() { +function createInitPing() { const ts = timestamp() return createQueryStr(INTERCOM_RESOLVER_NAME, [SOCKET_PING_EVENT_NAME, ts]) } +/** + * take the framework specific send method and do the whole action in one go + * @param {function} deliverFn + * @return {void} + */ +function initPingAction(deliverFn) { + deliverFn(createInitPing()) +} + /** * Take the raw on.message result back then decoded it * @param {*} payload the raw result from server @@ -32,9 +48,13 @@ function initPingAction() { function extractPingResult(payload) { const json = toJson(payload) const result = extractWsPayload(json) - - return {[HEADERS_KEY]: result[DATA_KEY]} + if (result[DATA_KEY] && result[DATA_KEY][CSRF_HEADER_KEY]) { + return { + [HEADERS_KEY]: result[DATA_KEY] + } + } + throw new JsonqlError('extractPingResult', CSRF_HEADER_NOT_EXIST_ERR) } -export { initPingAction, extractPingResult } \ No newline at end of file +export { createInitPing, initPingAction, extractPingResult } \ No newline at end of file diff --git a/packages/ws-client-core/tests/init.test.js b/packages/ws-client-core/tests/init.test.js new file mode 100644 index 00000000..99f66b6f --- /dev/null +++ b/packages/ws-client-core/tests/init.test.js @@ -0,0 +1,54 @@ +// testing the init connection +const test = require('ava') +const wsNodeClient = require('jsonql-ws-server/client') +const wsServer = require('./fixtures/server-setup') +const { + JSONQL_PATH +} = require('jsonql-constants') +const debug = require('debug')('jsonql-ws-server:test:ws') +const port = 8899 + +const { initPingAction, extractPingResult } = require('../src/share/init-ping-methods') + + +// let ctn = 0; + +test.before(async t => { + const { app } = await wsServer() + + t.context.server = app + t.context.server.listen(port) + + t.context.client = wsNodeClient(`ws://localhost:${port}/${JSONQL_PATH}`) +}) + +test.after(t => { + t.context.server.close() +}) + +test.cb(`Testing the init ping call`, t => { + t.plan(1) + let client = t.context.client + + client.on('open', () => { + initPingAction(client.send) + }) + + client.on('message', data => { + + debug('raw data', typeof data, data) + const header = extractPingResult(data) + + t.truthy(header) + + debug('header', header) + // t.end() + // reinit the client with an options + const newClient = wsNodeClient(`ws://localhost:${port}/${JSONQL_PATH}`, false, header) + + newClient.on('open', () => { + t.end() + }) + }) + +}) \ No newline at end of file diff --git a/packages/ws-server/client.js b/packages/ws-server/client.js index 15490cbe..089c1b01 100644 --- a/packages/ws-server/client.js +++ b/packages/ws-server/client.js @@ -10,6 +10,6 @@ const { TOKEN_PARAM_NAME } = require('jsonql-constants') * @return {object} ws instance */ module.exports = function client(url, token = false, opts = {}) { - let uri = token ? `${url}?${TOKEN_PARAM_NAME}=${token}` : url; + let uri = token ? `${url}?${TOKEN_PARAM_NAME}=${token}` : url return new WebSocket(uri, opts) } diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index fb1d0e10..4ef0fa9d 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -1,10 +1,11 @@ { "name": "jsonql-ws-server", - "version": "1.7.3", + "version": "1.7.4", "description": "Setup WebSocket server for the jsonql to run on the same host, automatic generate public / private channel using contract", "main": "index.js", "files": [ "index.js", + "client.js", "src" ], "scripts": { @@ -32,7 +33,7 @@ "dependencies": { "colors": "^1.4.0", "debug": "^4.1.1", - "jsonql-constants": "^2.0.2", + "jsonql-constants": "^2.0.3", "jsonql-utils": "^1.2.0", "jsonql-ws-server-core": "^0.7.6", "ws": "^7.2.3" -- Gitee From ddd86ab38f26909190878b619dbca7048b5f4567 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 16 Mar 2020 20:25:34 +0800 Subject: [PATCH 2/5] major change in how to init the websocket client --- .../init-websocket-client.js | 59 +++++++++++++++---- packages/@jsonql/ws/src/core/modules.js | 10 +++- packages/ws-client-core/index.js | 13 +++- packages/ws-client-core/package.json | 4 +- packages/ws-client-core/tests/init.test.js | 13 ++-- 5 files changed, 75 insertions(+), 24 deletions(-) diff --git a/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js b/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js index 47196d86..95aa66ae 100644 --- a/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js +++ b/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js @@ -2,6 +2,43 @@ // this is where the framework specific code get injected import { TOKEN_PARAM_NAME } from 'jsonql-constants' import { fixWss } from '../modules' +import { + createInitPing, + extractPingResult +} from './modules' + +/** + * Group the ping and get respond create new client in one + * @param {object} ws + * @param {object} WebSocket + * @param {string} url + * @param {function} resolver + * @param {function} rejecter + * @return {promise} resolve the confirm client + */ +function initPingAction(ws, WebSocket, url, resolver, rejecter) { + // @TODO how to we id this client can issue a CSRF + // by origin? + ws.onopen = function onOpenCallback() { + ws.send(createInitPing()) + } + + ws.onmessage = function onMessageCallback(payload) { + try { + const header = extractPingResult(payload.data) + // terminate the client + ws.terminate() + // return the new one with csrf header + resolver(new WebSocket(url, header)) + } catch(e) { + rejecter(e) + } + } + + ws.onerror = function onErrorCallback(err) { + rejecter(err) + } +} /** * The bug was in the wsOptions where ws don't need it but socket.io do @@ -14,12 +51,9 @@ function initWebSocketClient(WebSocket, auth = false, opts = {}) { if (auth === false) { return function createWsClient(url) { return new Promise((resolver, rejecter) => { - const unconfirmClient = new WebSocket(fixWss(url)) - // @TODO how to we id this client can issue a CSRF - // by origin? - - - return + const _url = fixWss(url) + const unconfirmClient = new WebSocket(_url) + initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter) }) } } @@ -33,13 +67,12 @@ function initWebSocketClient(WebSocket, auth = false, opts = {}) { return function createWsAuthClient(url, token) { const ws_url = fixWss(url) // console.log('what happen here?', url, ws_url, token) - const uri = token && typeof token === 'string' ? `${ws_url}?${TOKEN_PARAM_NAME}=${token}` : ws_url - try { - return new WebSocket(uri) - } catch(e) { - console.error('WebSocket Connection Error', e) - return false - } + const _url = token && typeof token === 'string' ? `${ws_url}?${TOKEN_PARAM_NAME}=${token}` : ws_url + + return new Promise((resolver, rejecter) => { + const unconfirmClient = new WebSocket(_url) + initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter) + }) } } diff --git a/packages/@jsonql/ws/src/core/modules.js b/packages/@jsonql/ws/src/core/modules.js index bd36ddc2..ba826144 100644 --- a/packages/@jsonql/ws/src/core/modules.js +++ b/packages/@jsonql/ws/src/core/modules.js @@ -22,7 +22,10 @@ import { EventEmitterClass, clientEventHandler, - createCombineClient + createCombineClient, + + createInitPing, + extractPingResult } from '../../../../ws-client-core/index' // 'jsonql-ws-client-core' // export @@ -48,5 +51,8 @@ export { EventEmitterClass, clientEventHandler, - createCombineClient + createCombineClient, + + createInitPing, + extractPingResult } \ No newline at end of file diff --git a/packages/ws-client-core/index.js b/packages/ws-client-core/index.js index 2398a68f..57e5abcd 100644 --- a/packages/ws-client-core/index.js +++ b/packages/ws-client-core/index.js @@ -40,7 +40,12 @@ import { import { createCombineClient } from './src/create-combine-client' - +// new ping methods +import { + createInitPing, + initPingAction, + extractPingResult +} from './src/share/init-ping-methods' // export export { @@ -67,5 +72,9 @@ export { EventEmitterClass, clientEventHandler, - createCombineClient + createCombineClient, + + createInitPing, + initPingAction, + extractPingResult } diff --git a/packages/ws-client-core/package.json b/packages/ws-client-core/package.json index b4bf2002..f2ccfade 100644 --- a/packages/ws-client-core/package.json +++ b/packages/ws-client-core/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-client-core", - "version": "0.9.0", + "version": "0.9.1", "description": "This is the jsonql Web Socket client core library for Node and Browser. Not for direct use.", "main": "main.js", "module": "index.js", @@ -65,7 +65,7 @@ "esm": "^3.2.25", "fs-extra": "^8.1.0", "jsonql-contract": "^1.8.10", - "jsonql-ws-server": "^1.7.3", + "jsonql-ws-server": "^1.7.4", "kefir": "^3.8.6", "ws": "^7.2.3" }, diff --git a/packages/ws-client-core/tests/init.test.js b/packages/ws-client-core/tests/init.test.js index 99f66b6f..35e66121 100644 --- a/packages/ws-client-core/tests/init.test.js +++ b/packages/ws-client-core/tests/init.test.js @@ -8,10 +8,7 @@ const { const debug = require('debug')('jsonql-ws-server:test:ws') const port = 8899 -const { initPingAction, extractPingResult } = require('../src/share/init-ping-methods') - - -// let ctn = 0; +const { createInitPing, extractPingResult } = require('../src/share/init-ping-methods') test.before(async t => { const { app } = await wsServer() @@ -31,7 +28,11 @@ test.cb(`Testing the init ping call`, t => { let client = t.context.client client.on('open', () => { - initPingAction(client.send) + const payload = createInitPing() + + debug(payload) + + client.send(payload) }) client.on('message', data => { @@ -41,6 +42,8 @@ test.cb(`Testing the init ping call`, t => { t.truthy(header) + client.terminate() + debug('header', header) // t.end() // reinit the client with an options -- Gitee From 6ecd6aa1b921cb89d8c306f73efd58dcf9804bf1 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 16 Mar 2020 20:26:41 +0800 Subject: [PATCH 3/5] remove the unused initPingAction --- packages/ws-client-core/index.js | 2 -- .../ws-client-core/src/share/init-ping-methods.js | 11 +---------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/packages/ws-client-core/index.js b/packages/ws-client-core/index.js index 57e5abcd..0debf854 100644 --- a/packages/ws-client-core/index.js +++ b/packages/ws-client-core/index.js @@ -43,7 +43,6 @@ import { // new ping methods import { createInitPing, - initPingAction, extractPingResult } from './src/share/init-ping-methods' @@ -75,6 +74,5 @@ export { createCombineClient, createInitPing, - initPingAction, extractPingResult } diff --git a/packages/ws-client-core/src/share/init-ping-methods.js b/packages/ws-client-core/src/share/init-ping-methods.js index bd685084..f2c433da 100644 --- a/packages/ws-client-core/src/share/init-ping-methods.js +++ b/packages/ws-client-core/src/share/init-ping-methods.js @@ -31,15 +31,6 @@ function createInitPing() { return createQueryStr(INTERCOM_RESOLVER_NAME, [SOCKET_PING_EVENT_NAME, ts]) } -/** - * take the framework specific send method and do the whole action in one go - * @param {function} deliverFn - * @return {void} - */ -function initPingAction(deliverFn) { - deliverFn(createInitPing()) -} - /** * Take the raw on.message result back then decoded it * @param {*} payload the raw result from server @@ -57,4 +48,4 @@ function extractPingResult(payload) { } -export { createInitPing, initPingAction, extractPingResult } \ No newline at end of file +export { createInitPing, extractPingResult } \ No newline at end of file -- Gitee From 6f8657bd3acddd9a262f659775e886ce83a2b924 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 16 Mar 2020 20:49:34 +0800 Subject: [PATCH 4/5] Add NSP_AUTH_CLIENT and NSP_CLIENT to socket --- .../bind-framework-to-jsonql.js | 14 ++++++++++++++ .../init-websocket-client.js | 16 ++++++++++++---- packages/constants/package.json | 2 +- packages/constants/socket.js | 3 +++ 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/packages/@jsonql/ws/src/core/create-websocket-binding/bind-framework-to-jsonql.js b/packages/@jsonql/ws/src/core/create-websocket-binding/bind-framework-to-jsonql.js index a79d94df..1b5216a7 100644 --- a/packages/@jsonql/ws/src/core/create-websocket-binding/bind-framework-to-jsonql.js +++ b/packages/@jsonql/ws/src/core/create-websocket-binding/bind-framework-to-jsonql.js @@ -2,6 +2,17 @@ import { initWebSocketClient } from './init-websocket-client' import createNsp from '../create-nsp' +/** + * This will decided how many clients we need to create based on the enableAuth + * @param {object} frameworkModule WebSocket + * @param {object} opts configuration + * @return {promise} resolve the opts with the newly created clients + */ +function createNspClients(frameworkModule, opts) { + +} + + /** * Create the framework <---> jsonql client binding * @param {object} frameworkModule the different WebSocket module @@ -21,6 +32,9 @@ function bindFrameworkToJsonql(frameworkModule) { * @return {object} passing the same 3 input out with additional in the opts */ return function createClientBindingAction(opts, nspMap, ee) { + + + opts.nspClient = nspClient opts.nspAuthClient = nspAuthClient // @1.0.7 remove later once everything fixed diff --git a/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js b/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js index 95aa66ae..182e8aea 100644 --- a/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js +++ b/packages/@jsonql/ws/src/core/create-websocket-binding/init-websocket-client.js @@ -14,9 +14,11 @@ import { * @param {string} url * @param {function} resolver * @param {function} rejecter + * @param {boolean} auth client or not * @return {promise} resolve the confirm client */ -function initPingAction(ws, WebSocket, url, resolver, rejecter) { +function initPingAction(ws, WebSocket, url, resolver, rejecter, auth) { + const name = auth ? 'nspAuthClient' : 'nspClient' // @TODO how to we id this client can issue a CSRF // by origin? ws.onopen = function onOpenCallback() { @@ -29,7 +31,7 @@ function initPingAction(ws, WebSocket, url, resolver, rejecter) { // terminate the client ws.terminate() // return the new one with csrf header - resolver(new WebSocket(url, header)) + resolver({[name]: new WebSocket(url, header)}) } catch(e) { rejecter(e) } @@ -49,11 +51,17 @@ function initPingAction(ws, WebSocket, url, resolver, rejecter) { */ function initWebSocketClient(WebSocket, auth = false, opts = {}) { if (auth === false) { + /** + * Create a non-protected client + * @param {string} url + * @return {promise} resolve to the confirmed client + */ return function createWsClient(url) { + return new Promise((resolver, rejecter) => { const _url = fixWss(url) const unconfirmClient = new WebSocket(_url) - initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter) + initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter, auth) }) } } @@ -71,7 +79,7 @@ function initWebSocketClient(WebSocket, auth = false, opts = {}) { return new Promise((resolver, rejecter) => { const unconfirmClient = new WebSocket(_url) - initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter) + initPingAction(unconfirmClient, WebSocket, _url, resolver, rejecter, auth) }) } } diff --git a/packages/constants/package.json b/packages/constants/package.json index f8791cd2..c6bb78a1 100755 --- a/packages/constants/package.json +++ b/packages/constants/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-constants", - "version": "2.0.3", + "version": "2.0.4", "description": "All the share constants for jsonql modules", "main": "main.js", "module": "index.js", diff --git a/packages/constants/socket.js b/packages/constants/socket.js index f151d6bd..b346ef53 100644 --- a/packages/constants/socket.js +++ b/packages/constants/socket.js @@ -108,3 +108,6 @@ export const PRIVATE_KEY_NAME = 'privateKey' export const DEFAULT_PUBLIC_KEY_FILE = [PUBLIC_KEY_NAME, PEM_EXT].join('.') export const DEFAULT_PRIVATE_KEY_FILE = [PRIVATE_KEY_NAME, PEM_EXT].join('.') + +export const NSP_AUTH_CLIENT = 'nspAuthClient' +export const NSP_CLIENT = 'nspClient' -- Gitee From 4cd90c69f493a2a6bcc2c2f272d756f4c3c3a706 Mon Sep 17 00:00:00 2001 From: joelchu Date: Mon, 16 Mar 2020 20:49:48 +0800 Subject: [PATCH 5/5] jsonql-constants to 2.0.4 --- packages/constants/README.md | 2 ++ packages/constants/browser.js | 2 ++ packages/constants/constants.json | 2 ++ packages/constants/index.js | 3 +++ packages/constants/main.js | 2 ++ 5 files changed, 11 insertions(+) diff --git a/packages/constants/README.md b/packages/constants/README.md index 7b893db8..9bf50ba6 100755 --- a/packages/constants/README.md +++ b/packages/constants/README.md @@ -221,6 +221,8 @@ Please consult the detail break down below. - PRIVATE_KEY_NAME - DEFAULT_PUBLIC_KEY_FILE - DEFAULT_PRIVATE_KEY_FILE +- NSP_AUTH_CLIENT +- NSP_CLIENT ### VALIDATION diff --git a/packages/constants/browser.js b/packages/constants/browser.js index 29d7822f..b3379baa 100644 --- a/packages/constants/browser.js +++ b/packages/constants/browser.js @@ -235,6 +235,8 @@ var jsonqlConstants = { "PRIVATE_KEY_NAME": "privateKey", "DEFAULT_PUBLIC_KEY_FILE": "publicKey.pem", "DEFAULT_PRIVATE_KEY_FILE": "privateKey.pem", + "NSP_AUTH_CLIENT": "nspAuthClient", + "NSP_CLIENT": "nspClient", "OR_SEPERATOR": "|", "FUNCTION_TYPE": "function", "STRING_TYPE": "string", diff --git a/packages/constants/constants.json b/packages/constants/constants.json index 09aa8328..5242ceb5 100644 --- a/packages/constants/constants.json +++ b/packages/constants/constants.json @@ -235,6 +235,8 @@ "PRIVATE_KEY_NAME": "privateKey", "DEFAULT_PUBLIC_KEY_FILE": "publicKey.pem", "DEFAULT_PRIVATE_KEY_FILE": "privateKey.pem", + "NSP_AUTH_CLIENT": "nspAuthClient", + "NSP_CLIENT": "nspClient", "OR_SEPERATOR": "|", "FUNCTION_TYPE": "function", "STRING_TYPE": "string", diff --git a/packages/constants/index.js b/packages/constants/index.js index c7018061..15237c0f 100644 --- a/packages/constants/index.js +++ b/packages/constants/index.js @@ -345,6 +345,9 @@ export const PRIVATE_KEY_NAME = 'privateKey' export const DEFAULT_PUBLIC_KEY_FILE = [PUBLIC_KEY_NAME, PEM_EXT].join('.') export const DEFAULT_PRIVATE_KEY_FILE = [PRIVATE_KEY_NAME, PEM_EXT].join('.') + +export const NSP_AUTH_CLIENT = 'nspAuthClient' +export const NSP_CLIENT = 'nspClient' /* validation.js */ // validation related constants diff --git a/packages/constants/main.js b/packages/constants/main.js index 41ef9d06..932f0f15 100644 --- a/packages/constants/main.js +++ b/packages/constants/main.js @@ -235,6 +235,8 @@ module.exports = { "PRIVATE_KEY_NAME": "privateKey", "DEFAULT_PUBLIC_KEY_FILE": "publicKey.pem", "DEFAULT_PRIVATE_KEY_FILE": "privateKey.pem", + "NSP_AUTH_CLIENT": "nspAuthClient", + "NSP_CLIENT": "nspClient", "OR_SEPERATOR": "|", "FUNCTION_TYPE": "function", "STRING_TYPE": "string", -- Gitee