From df0ab7c1dc4158e4738109da96e394917dd4a32d Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 19 Dec 2017 15:11:11 -0700 Subject: [PATCH 1/3] removed body-parser in favor of express.json() --- package.json | 1 - routes/index.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index de3b617a2..c46a4caaa 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "babel-preset-es2015": "6.24.1", "babel-preset-react": "^6.23.0", "bcryptjs": "^2.4.3", - "body-parser": "1.18.2", "bowser": "^1.7.2", "cli-table": "^0.3.1", "clipboard": "^1.7.1", diff --git a/routes/index.js b/routes/index.js index 454e32f58..af7edec3b 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,7 +1,6 @@ const accepts = require('accepts'); const apollo = require('graphql-server-express'); const authentication = require('../middleware/authentication'); -const bodyParser = require('body-parser'); const cookieParser = require('cookie-parser'); const debug = require('debug')('talk:routes'); const enabled = require('debug').enabled; @@ -82,7 +81,7 @@ router.use('/embed', staticTemplate, require('./embed')); router.use(cookieParser()); // Parse the body json if it's there. -router.use(bodyParser.json()); +router.use(express.json()); const passportDebug = require('debug')('talk:passport'); From b46b392af4e15a87c9218821027cdeb2ef38e15c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 20 Dec 2017 09:31:59 -0700 Subject: [PATCH 2/3] added subscription hooks --- graph/subscriptions.js | 37 ++++++++++++++++++++++++++++++++++--- plugins.js | 4 ++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/graph/subscriptions.js b/graph/subscriptions.js index 59dd6e923..60afc9c45 100644 --- a/graph/subscriptions.js +++ b/graph/subscriptions.js @@ -5,6 +5,7 @@ const debug = require('debug')('talk:graph:subscriptions'); const pubsub = require('../services/pubsub'); const schema = require('./schema'); const Context = require('./context'); +const plugins = require('../services/plugins'); const {deserializeUser} = require('../services/subscriptions'); const setupFunctions = require('./setupFunctions'); @@ -16,16 +17,42 @@ const { const {BASE_PATH} = require('../url'); -const onConnect = ({token}, connection) => { +// Collect all the plugin hooks that should be executed onConnect and +// onDisconnect. +const hooks = plugins.get('server', 'websockets') + .map(({plugin, websockets}) => { + debug(`added websocket hooks ${Object.keys(websockets)} from plugin '${plugin.name}'`); + + return websockets; + }) + .reduce((hooks, {onConnect = null, onDisconnect = null}) => { + if (onConnect) { + hooks.onConnect.push(onConnect); + } + + if (onDisconnect) { + hooks.onDisconnect.push(onDisconnect); + } + + return hooks; + }, { + onConnect: [], + onDisconnect: [], + }); + +const onConnect = async (connectionParams, connection) => { // Attach the token from the connection options if it was provided. - if (token) { + if (connectionParams.token) { debug('token sent via onConnect, attaching to the headers of the upgrade request'); // Attach it to the upgrade request. - connection.upgradeReq.headers['authorization'] = `Bearer ${token}`; + connection.upgradeReq.headers['authorization'] = `Bearer ${connectionParams.token}`; } + + // Call all the hooks. + await Promise.all(hooks.onConnect.map((hook) => hook(connectionParams, connection))); }; const onOperation = (parsedMessage, baseParams, connection) => { @@ -52,6 +79,9 @@ const onOperation = (parsedMessage, baseParams, connection) => { return baseParams; }; +const onDisconnect = (connection) => + Promise.all(hooks.onDisconnect.map((hook) => hook(connection))); + /** * This creates a new subscription manager. */ @@ -62,6 +92,7 @@ const createSubscriptionManager = (server) => new SubscriptionServer({ setupFunctions, }), onConnect, + onDisconnect, onOperation, keepAlive: ms(KEEP_ALIVE) }, { diff --git a/plugins.js b/plugins.js index 487825be7..577289b25 100644 --- a/plugins.js +++ b/plugins.js @@ -57,6 +57,10 @@ const hookSchemas = { resolvers: Joi.object().pattern(/\w/, Joi.object().pattern(/(?:__resolveType|\w+)/, Joi.func())), typeDefs: Joi.string(), schemaLevelResolveFunction: Joi.func(), + websockets: Joi.object({ + onConnect: Joi.func(), + onDisconnect: Joi.func(), + }), }; /** From 2233d993c21ee2db32a4a7ce3abe80ff38702417 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Wed, 20 Dec 2017 15:27:55 -0700 Subject: [PATCH 3/3] fixed expiry loading --- graph/loaders/util.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/graph/loaders/util.js b/graph/loaders/util.js index fe2a4e3d0..4d43d1811 100644 --- a/graph/loaders/util.js +++ b/graph/loaders/util.js @@ -72,8 +72,10 @@ class SharedCacheDataLoader extends DataLoader { constructor(prefix, expiry, batchLoadFn, options) { super(SharedCacheDataLoader.batchLoadFn(prefix, expiry, batchLoadFn), options); + // Expiry is provided as a number in ms, we're using commands optimized for + // seconds, so convert this to seconds. + this._expiry = Math.floor(expiry / 1000); this._prefix = prefix; - this._expiry = expiry; this._keyFunc = SharedCacheDataLoader.keyFunc(this._prefix); }