diff --git a/packages/koa/keys/privateKey.pem b/packages/koa/keys/privateKey.pem index 885aed98932389139146a3c0f8fe7b0df9a1e69e..a44068d3efc5d009eb362d37983316bd2030454a 100644 --- a/packages/koa/keys/privateKey.pem +++ b/packages/koa/keys/privateKey.pem @@ -1,15 +1,15 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDISseWqVH7QTTuzQ/HQkRMRi3IPEsHJm8gT1RoxD/R3MpWYPFR -14fVE/IXxHZa74XSPxfMfBB8eh+CJu9K9mmgnGhHovgNUMsfshLmvY7dnkepiNE7 -sZsDR63+6BPgogMzHhMxUAcP3AiwPtQz8uKRwroqWMHI1pn2zqKRVLe4+QIDAQAB -AoGAe0OyU6F+5794oSKofDvnJn3mPR4GGq9nop3P1+43TKOyDrj4qyKW4Oa2jjQF -lu9kD0FvFxSfXMwXyhTGHf9Kf0oj0fuMz87EvHRMDAYfGzIz/skqqCcN49viejK8 -09mFtE+GYC8SVKj5qw9J2/pHsUSRTxkeb2hR8CSV8fOx8hUCQQD/dyfMmGsmnou+ -WEjQ4gdYixNzsP7TtmBkS4aBug8QHHsf1L5gQ6ikmuyLa507hAH3WmOx7MNeia2y -xXn8QYdrAkEAyLYR0g1t2qdJQiubZBO8MkGKUFk1NSQSAmatjk/6EAWrJSDuIDH4 -8GOnOKyNbFQ5nG1HTK+1nE9fl+/22BJuKwJAM6UiHaF+n/sTYzKz3c6kD4lmMFBK -5AANspj2I0m6+9XWKlQ2/H0RHd3YDkN+MOb6Ash6OSEVSgppXCfCBnY06wJBAICu -yuojlgUUMBHup2gYhxapkqZFK6nwgGNttWSCvk67c6kQXdvibjqhibr6VonXzkAO -iCIQnZ2j/iQJw/dwiZUCQQDln/vKEmEcnhU+OgmgNb7k8mRhS/2F6j4LCJQ5dMwY -Lnaxh2Zsl93vYSHHm6LG784zN3sPKdGgwGCN/ldWCxo6 +MIICXAIBAAKBgQCrEzyQcCrKJvqEPxRFzG86m3secoRETL+GTS6nYk+hwQDmvqdd +BNifKfUNVVPUrAxdupe1PXPdEK1lx2sDI0Ij7f+qvI3iBjYmljnE3okFfjcdYzcK +Dq4CLzCc/zlCanF4jAJMBUWV7WHeVvBAHZ5Rx84usn3Gb7m0QzsKRzRVtwIDAQAB +AoGAIxSjw76sl52cm4fP4WxFltARVDIJe3P9hk3Hdl2LlNDeHXMVINcAkMrqzFwl +/6N0Obgsqea7Hqbv18In6JHPWvbe56V6tr6cBhFqCkZEhJ/khsb8vaDWttul3nww +5jciQR8Y0fdKJBeYtGZ5XjxwCpIoERZvqdWw3KhhBVjjsUECQQDcUpe6bHn6AKy1 +hyUNVZ/agLkYdxLv44ymLUi6MBZlNzvRWSg/a8A2l2XzcyAHduka3njmSVCvNOjg +LOqXM0jXAkEAxscavCMxWgwz9ZyNaPMISpkjg/aa8zM8Dq9vR7IDzql/bqMZmTxs +5GXt9LQ4ffdFlVxN1mahRbciatozic9eIQJAIchkTYiOl3/8+4SycL39WeK8/vxb +If9xNJXi/fGbrX9vo6UZH8hk27oRPugbNCnOinksbps1TPg+8QjSG8cYVwJBAJbd +ToE0BKTfViA3bWwV6FkV2Uqyw++JFy/eHos/pHwZUMpbp3YR0mOWqP9sOOQB5CH0 +KG9s/UG4OLr4WN1jMYECQCPKG9xjcKuwHKRGMZiA+xB/Fyg4dm2KJ5SjIHxXvxm+ +qP5aTse/013yeOyalzcWddQUD8IwnXptoy4EOJ6uwEM= -----END RSA PRIVATE KEY----- diff --git a/packages/koa/keys/publicKey.pem b/packages/koa/keys/publicKey.pem index 30b9e94e773cc98cfbc9c24708df0dbb36cf7268..8a1914c304cc0bb307f2a4c6e887bd9a203dc3be 100644 --- a/packages/koa/keys/publicKey.pem +++ b/packages/koa/keys/publicKey.pem @@ -1,6 +1,6 @@ -----BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDISseWqVH7QTTuzQ/HQkRMRi3I -PEsHJm8gT1RoxD/R3MpWYPFR14fVE/IXxHZa74XSPxfMfBB8eh+CJu9K9mmgnGhH -ovgNUMsfshLmvY7dnkepiNE7sZsDR63+6BPgogMzHhMxUAcP3AiwPtQz8uKRwroq -WMHI1pn2zqKRVLe4+QIDAQAB +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrEzyQcCrKJvqEPxRFzG86m3se +coRETL+GTS6nYk+hwQDmvqddBNifKfUNVVPUrAxdupe1PXPdEK1lx2sDI0Ij7f+q +vI3iBjYmljnE3okFfjcdYzcKDq4CLzCc/zlCanF4jAJMBUWV7WHeVvBAHZ5Rx84u +sn3Gb7m0QzsKRzRVtwIDAQAB -----END PUBLIC KEY----- diff --git a/packages/koa/package.json b/packages/koa/package.json index 59f900f10591dd6d90bfe3e322194bc3932838b7..c547180be5e7aaf9d43e2ecd5852af078de9018c 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-koa", - "version": "1.5.0", + "version": "1.5.1", "description": "jsonql Koa middleware", "main": "main.js", "module": "index.js", @@ -19,7 +19,7 @@ "test:basic": "DEBUG=jsonql* ava ./tests/koa.test.js", "test:notfound": "DEBUG=jsonql-* ava --verbose ./tests/resolverNotFound.test.js", "test:es6": "DEBUG=jsonql-* ava --verbose ./tests/es6-module.test.js", - "test:jwt": "DEBUG=jsonql-koa*,jsonql-jwt* ava ./tests/jwt.test.js", + "test:jwt": "DEBUG=jsonql-* ava ./tests/jwt.test.js", "test:jwt-auth": "DEBUG=jsonql-koa* ava ./tests/jwt-auth.test.js", "test:fail": "ava ./tests/fail.test.js", "test:contract": "DEBUG=jsonql-koa*,jsonql-contract* ava ./tests/contractWithAuth.test.js", @@ -76,11 +76,11 @@ "fs-extra": "^8.1.0", "jsonql-constants": "^1.8.13", "jsonql-contract": "^1.8.4", - "jsonql-errors": "^1.1.8", - "jsonql-jwt": "^1.3.6", - "jsonql-node-client": "^1.2.5", - "jsonql-params-validator": "^1.5.0", - "jsonql-resolver": "^0.9.11", + "jsonql-errors": "^1.1.10", + "jsonql-jwt": "^1.3.7", + "jsonql-node-client": "^1.2.6", + "jsonql-params-validator": "^1.5.1", + "jsonql-resolver": "^1.0.2", "jsonql-utils": "^0.9.2", "jsonql-web-console": "^0.4.4", "koa-compose": "^4.1.0", @@ -88,7 +88,7 @@ }, "devDependencies": { "ava": "^2.4.0", - "jsonql-ws-server": "^1.4.11", + "jsonql-ws-server": "^1.5.0", "jwt-decode": "^2.2.0", "koa": "^2.11.0", "koa-bodyparser": "^4.2.1", diff --git a/packages/koa/src/middlewares/init-middleware.js b/packages/koa/src/middlewares/init-middleware.js index 11c05436192728d3adba5a6230832f4c611924a8..219e4350ed817fb50d361f9310a82306b15eff88 100644 --- a/packages/koa/src/middlewares/init-middleware.js +++ b/packages/koa/src/middlewares/init-middleware.js @@ -40,7 +40,7 @@ export default function initMiddleware(opts) { if (isJsonql) { // its only call once ctx.state.jsonql.contract = await processContract(ctx, opts) - debug('ctx.state.jsonql.contract', ctx.state.jsonql.contract) + // debug('ctx.state.jsonql.contract', ctx.state.jsonql.contract) // @BUG makes no different to define the contract as a property, somewhere still overwrite it // @NOTE see if this works or not to make sure the contract prop is not writable // ctx.state.jsonql = injectToFn(ctx.state.jsonql, 'contract', __contract__) diff --git a/packages/koa/src/middlewares/public-method-middleware.js b/packages/koa/src/middlewares/public-method-middleware.js index 4573f2507f1ee8c510cc4092d4d2b3096c72cd17..e2dabdb734cca26b3a9a82e8d5ce2b67a4e87508 100644 --- a/packages/koa/src/middlewares/public-method-middleware.js +++ b/packages/koa/src/middlewares/public-method-middleware.js @@ -21,7 +21,7 @@ export default function publicMethodMiddleware(opts) { } else if (resolverType === AUTH_TYPE && resolverName === opts.loginHandlerName) { // @BUG some how the contract here becomes true instead of an object // somewhere changed it! - debug(`This is an auth [${opts.loginHandlerName}] call`, contract) + debug(`This is an auth [${opts.loginHandlerName}] call`) // ctx, resolverName, payload, opts, contract return handleAuthMethods(ctx, resolverName, payload, opts, contract) } diff --git a/packages/koa/tests/jwt.test.js b/packages/koa/tests/jwt.test.js index 10a9d00c94ade1e2905b922f0b09d3ae9424e374..f5b70f31db917a906c38c9e911464a3dbe357760 100644 --- a/packages/koa/tests/jwt.test.js +++ b/packages/koa/tests/jwt.test.js @@ -55,6 +55,7 @@ test('It should able to provide a token that can be decode with the client side t.is(200, res.status) let token = res.body.data; + debug('token', token) t.context.token = token; diff --git a/packages/resolver/package.json b/packages/resolver/package.json index f1a3ceb18ed9bea6d49873b35fc06abfb09d1af3..ad3d68b8fdecda874ff3760430ea9fa2f0cf7fdd 100644 --- a/packages/resolver/package.json +++ b/packages/resolver/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-resolver", - "version": "0.9.12", + "version": "1.0.2", "description": "This is NOT for general use, please do not install it directly. This module is part of the jsonql tools supporting modules.", "main": "index.js", "files": [ @@ -10,6 +10,7 @@ "scripts": { "test": "ava --verbose", "prepare": "npm run test", + "test:base": "DEBUG=jsonql* ava --verbose ./tests/base.test.js", "test:clients": "DEBUG=jsonql* ava --verbose ./tests/clients.test.js", "test:throw": "DEBUG=jsonql-resolver* ava --verbose ./tests/throw.test.js", "test:es": "DEBUG=jsonql-resolver* ava --verbose ./tests/es.test.js", @@ -30,7 +31,7 @@ "jsonql-constants": "^1.8.13", "jsonql-errors": "^1.1.10", "jsonql-jwt": "^1.3.7", - "jsonql-node-client": "^1.2.5", + "jsonql-node-client": "^1.2.6", "jsonql-params-validator": "^1.5.1", "jsonql-utils": "^0.9.2", "lodash.merge": "^4.6.2" diff --git a/packages/resolver/src/handle-auth-methods.js b/packages/resolver/src/handle-auth-methods.js index 1365c15f9ca4f5416a457e1c5074d1ce522d534f..363ed101f68ce88e685633c83907f7540b23f5b2 100644 --- a/packages/resolver/src/handle-auth-methods.js +++ b/packages/resolver/src/handle-auth-methods.js @@ -15,9 +15,9 @@ const { getErrorNameByInstance, UNKNOWN_ERROR } = require('jsonql-errors') -const { handleOutput, packResult, ctxErrorHandler } = require('jsonql-utils') +const { packResult } = require('jsonql-utils') -const { getDebug } = require('./utils') +const { getDebug, ctxErrorHandler, handleOutput, UNAUTHORIZED_STATUS } = require('./utils') const { searchResolvers } = require('./search-resolvers') const { validateAndCall } = require('./validate-and-call') @@ -79,7 +79,7 @@ const handleAuthMethods = async function(ctx, resolverName, payload, opts, contr JsonqlValidationError ], e) if (errorName === UNKNOWN_ERROR) { - return ctxErrorHandler(ctx, 401, e) + return ctxErrorHandler(ctx, UNAUTHORIZED_STATUS, e) } return ctxErrorHandler(ctx, errorName, e) } diff --git a/packages/resolver/src/resolve-methods.js b/packages/resolver/src/resolve-methods.js index 39fcb9a4146f9296f2ce205944359b21f6ca030c..667b43ca00ebc9ff958085fb814f2826de947ff2 100644 --- a/packages/resolver/src/resolve-methods.js +++ b/packages/resolver/src/resolve-methods.js @@ -13,13 +13,11 @@ const { const { provideUserdata } = require('jsonql-jwt') const { MODULE_TYPE } = require('jsonql-constants') const { - handleOutput, - ctxErrorHandler, packResult, extractArgsFromPayload, findFromContract } = require('jsonql-utils') -const { getDebug } = require('./utils') +const { getDebug, handleOutput, ctxErrorHandler } = require('./utils') const { searchResolvers, importFromModule, requireEsModule } = require('./search-resolvers') const { validateAndCall } = require('./validate-and-call') const { provideNodeClients } = require('./provide-node-clients') @@ -97,7 +95,7 @@ const executeResolver = (opts, type, resolverName, payload, contract, userdata = */ async function resolverRenderHandler(ctx, type, opts, contract) { const { payload, resolverName, userdata } = ctx.state.jsonql; - debug('resolveMethod', resolverName, payload, type) + debug('resolverRenderHandler', resolverName, payload, type) // There must be only one method call const renderHandler = handleOutput(opts) // first try to catch the resolve error diff --git a/packages/resolver/src/search-resolvers.js b/packages/resolver/src/search-resolvers.js index 99517855a7df5318a60c7615ff4f696c9f00b034..cbe29853f7f378d0dfe4a55b0e37cbee68e37593 100644 --- a/packages/resolver/src/search-resolvers.js +++ b/packages/resolver/src/search-resolvers.js @@ -69,7 +69,7 @@ function searchResolvers(name, type, opts, contract) { if (pathToResolver !== false) { return pathToResolver; } - debug(`pathToResolver not found in contract`, contract) + debug(`pathToResolver not found in contract`, type, name, json) // search by running pathToResolver = getPathToFn(name, type, opts) if (pathToResolver) { diff --git a/packages/resolver/src/utils.js b/packages/resolver/src/utils.js index ffa36f8995a5a396f3dcf2168090b0ba6c2e452c..6f31bf94729884f8424a108d9b8ad29313ce096d 100644 --- a/packages/resolver/src/utils.js +++ b/packages/resolver/src/utils.js @@ -1,6 +1,11 @@ const debug = require('debug') const MODULE_NAME = 'jsonql-resolver' +const { getDocLen, packError } = require('jsonql-utils') +const { CONTENT_TYPE, SUCCESS_STATUS } = require('jsonql-constants') +const jsonqlErrors = require('jsonql-errors') +// @TODO port this back to jsonql-constants later +const UNAUTHORIZED_STATUS = 401; /** * return the debug method @@ -11,11 +16,56 @@ const getDebug = function(name) { return debug(MODULE_NAME).extend(name) } -// The following are moved back from utils - +// The following are moved back from utils +/** + * Handle the output + * @param {object} opts configuration + * @return {function} with ctx and body as params + */ +const handleOutput = function(opts) { + return function(ctx, body) { + ctx.size = getDocLen(body) + ctx.type = opts.contentType; + ctx.status = SUCCESS_STATUS; + ctx.body = body; + } +} +/** + * this was in the jsonql-utils then move back to koa + * but now make it stand alone here + * use the ctx to generate error output + * V1.1.0 we render this as a normal output with status 200 + * then on the client side will check against the result object for error + * @param {object} ctx context + * @param {number} code 404 / 500 etc + * @param {object} e actual error + * @param {string} message if there is one + * @param {string} name custom error class name + */ +const ctxErrorHandler = function(ctx, code, e, message = '') { + const render = handleOutput({contentType: CONTENT_TYPE}) + // debug('[ctxErrorHandler]', code, e, message) + let name; + if (typeof code === 'string') { + name = code; + code = jsonqlErrors[name] ? jsonqlErrors[name].statusCode : -1; + } else { + // debug(`[ctxErrorHandler] using getErrorByStatus`) + name = jsonqlErrors.getErrorByStatus(code) + } + // debug(`[ctxErrorHandler.name]`, name) + // preserve the message + if (!message && e && e.message) { + message = e.message; + } + return render(ctx, packError(e, name, code, message)) +} module.exports = { - getDebug + UNAUTHORIZED_STATUS, + getDebug, + handleOutput, + ctxErrorHandler } diff --git a/packages/resolver/src/validate-and-call.js b/packages/resolver/src/validate-and-call.js index d1b4729b7ba37ba4a7a49dc71812966e48da7d09..7c136522b75e2d7509178a83f71c4e40f616eb82 100644 --- a/packages/resolver/src/validate-and-call.js +++ b/packages/resolver/src/validate-and-call.js @@ -1,7 +1,7 @@ // validation wrapper const { AUTH_TYPE, HSA_ALGO, RSA_ALGO } = require('jsonql-constants') const { validateSync, isString } = require('jsonql-params-validator') -const { JsonqlValidationError } = require('jsonql-errors') +const { JsonqlValidationError, JsonqlResolverAppError } = require('jsonql-errors') const { extractParamsFromContract } = require('jsonql-utils') const { loginResultToJwt } = require('jsonql-jwt') const { getDebug } = require('./utils') @@ -40,6 +40,25 @@ const applyJwtMethod = (type, name, opts, contract) => { } } +/** + * Break out from the method below, to seperate the process of running the resolver + * @param {string} name the resolver name for report error + * @param {function} fn the resolver function + * @param {array} args the argument + * @return {promise} resolve when success + */ +function runResolver(name, fn, args) { + // @NOTE here is the problem + return new Promise((resolver, rejecter) => { + try { + resolver(Reflect.apply(fn, null, args)) + } catch(e) { + debug('runResolver', e) + rejecter(new JsonqlResolverAppError(name, e)) + } + }) +} + /** * @TODO we should cut down the parameters here, the opts and contract should merge * also the type, name and args should merge together as one input for the fn @@ -60,8 +79,7 @@ function validateAndCall(fn, args, contract, type, name, opts) { throw new JsonqlValidationError(name, errors) } - return Promise - .resolve(Reflect.apply(fn, null, args)) + return runResolver(name, fn, args) .then(applyJwtMethod(type, name, opts, contract)) } diff --git a/packages/resolver/tests/fixtures/contract/es/contract.json b/packages/resolver/tests/fixtures/contract/es/contract.json index 1fca3048b662fe8a1ced13ba815eac178759afa7..9e95e5c499591fb324ed17492997fc0c01723f7c 100644 --- a/packages/resolver/tests/fixtures/contract/es/contract.json +++ b/packages/resolver/tests/fixtures/contract/es/contract.json @@ -43,6 +43,6 @@ } }, "auth": {}, - "timestamp": 1575864328, + "timestamp": 1575881837, "sourceType": "module" } diff --git a/packages/resolver/tests/throw.test.js b/packages/resolver/tests/throw.test.js index 961d918f83388f8e9e7554a9474bfdf0c53e646a..04fa7fb7819b33b4e0cc0c8421d283932e6dbe1d 100644 --- a/packages/resolver/tests/throw.test.js +++ b/packages/resolver/tests/throw.test.js @@ -40,6 +40,8 @@ test.cb(`When resolver throw error, it should able to throw back a JsonqlResolve t.context.contract ) .catch(e => { + debug(e) + let errorName = getErrorNameByInstance([ JsonqlResolverNotFoundError, JsonqlAuthorisationError, @@ -47,7 +49,7 @@ test.cb(`When resolver throw error, it should able to throw back a JsonqlResolve JsonqlResolverAppError ], e) - t.is(errorName, UNKNOWN_ERROR) + t.is(errorName, 'JsonqlResolverAppError') t.end() }) @@ -61,6 +63,6 @@ test(`The getLocalValidator should throw a JsonqlResolverNotFoundError`, t => { }, t.context.contract) }, JsonqlResolverNotFoundError, 'There is no validator and should throw error') - debug(error) + // debug(error) }) diff --git a/packages/ws-server/package.json b/packages/ws-server/package.json index 6a12df786bb669d4eda769f756b6674e3f19fc14..bda48b66624601df83e74e46134bc653ad6e88c7 100755 --- a/packages/ws-server/package.json +++ b/packages/ws-server/package.json @@ -1,6 +1,6 @@ { "name": "jsonql-ws-server", - "version": "1.4.12", + "version": "1.5.0", "description": "Setup WebSocket server for the jsonql to run on the same host, automatic generate public / private channel using contract", "main": "index.js", "files": [ @@ -34,8 +34,8 @@ "jsonql-constants": "^1.8.13", "jsonql-errors": "^1.1.10", "jsonql-jwt": "^1.3.7", - "jsonql-params-validator": "^1.5.0", - "jsonql-resolver": "^0.9.11", + "jsonql-params-validator": "^1.5.1", + "jsonql-resolver": "^1.0.2", "jsonql-utils": "^0.9.2", "lodash": "^4.17.15", "ws": "^7.2.0" diff --git a/packages/ws-server/src/index.js b/packages/ws-server/src/index.js index 142ea0b70b949c7099cd944b8cebc8e8acff5189..f68e54332c4e0aeac7eb44c88d931195fb8a4119 100644 --- a/packages/ws-server/src/index.js +++ b/packages/ws-server/src/index.js @@ -1,12 +1,13 @@ // re-export here const { wsSetup, wsCreateServer } = require('./core') const { checkConfig, defaultOptions, constProps } = require('./options') - +const wsServerDefaultOptions = defaultOptions +const wsServerConstProps = constProps // re-export module.exports = { // rename them - wsServerDefaultOptions: defaultOptions, - wsServerConstProps: constProps, + wsServerDefaultOptions, + wsServerConstProps, // rest of the exports checkConfig, wsSetup,