Skip to content

Commit

Permalink
use same context creator for resolvers and subscriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
smeijer committed Jul 10, 2019
1 parent 11a17f9 commit 96c5c56
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 38 deletions.
1 change: 1 addition & 0 deletions .npm/package/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
7 changes: 7 additions & 0 deletions .npm/package/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This directory and the files immediately inside it are automatically generated
when you change this package's NPM dependencies. Commit the files in this
directory (npm-shrinkwrap.json, .gitignore, and this README) to source control
so that others run the same versions of sub-dependencies.

You should NOT check in the node_modules directory that Meteor automatically
creates; if you are using git, the .gitignore file tells git to ignore it.
10 changes: 10 additions & 0 deletions .npm/package/npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ Package.onUse(function(api) {
api.mainModule('server/index.js', 'server');
});

Npm.depends({
cookie: '0.4.0',
});

Package.onTest(function(api) {
api.use('cultofcoders:apollo');

Expand Down
76 changes: 38 additions & 38 deletions server/initialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { db } from 'meteor/cultofcoders:grapher';
import { WebApp } from 'meteor/webapp';
import { ApolloServer } from 'apollo-server-express';
import { getSchema } from 'graphql-load';
import cookie from 'cookie';
import { AUTH_TOKEN_KEY } from '../constants';
import defaultSchemaDirectives from './directives';
import { getUserForContext } from './core/users';

/**
*
* @param {*} apolloConfig Options https://www.apollographql.com/docs/apollo-server/api/apollo-server.html#constructor-options-lt-ApolloServer-gt
Expand Down Expand Up @@ -53,8 +53,8 @@ export default function initialize(apolloConfig = {}, meteorApolloConfig = {}) {
typeDefs,
resolvers,
schemaDirectives,
context: getContextCreator(meteorApolloConfig, initialApolloConfig.context),
subscriptions: getSubscriptionConfig(meteorApolloConfig),
context: getContextCreator(meteorApolloConfig, initialApolloConfig),
subscriptions: getSubscriptionConfig(meteorApolloConfig, initialApolloConfig),
};

const server = new ApolloServer(apolloConfig);
Expand Down Expand Up @@ -83,51 +83,51 @@ export default function initialize(apolloConfig = {}, meteorApolloConfig = {}) {
};
}

function getContextCreator(meteorApolloConfig, defaultContextResolver) {
return async function getContext({ req, connection }) {
function getContextCreator(meteorApolloConfig, initialApolloConfig) {
const {
context: defaultContextResolver,
} = initialApolloConfig;

return async function getContext({ req: request, connection }) {
// This function is called whenever a normal graphql request is being made,
// as well as when a client initiates a new subscription. However, when a
// client subscribes, the request headers are not being send along. The
// websocket only send those on the onConnect event. We store them on the
// `connection.context` together with the parsed cookies, so we can
// reconstruct a fake request object to be used by the context creator.
const req = connection ? connection.context.req : request;

const defaultContext = defaultContextResolver
? await defaultContextResolver({ req, connection })
: {};

Object.assign(defaultContext, { db });

if (connection) {
return {
...defaultContext,
...connection.context,
};
} else {
let userContext = {};
if (Package['accounts-base']) {
const loginToken =
req.headers['meteor-login-token'] || req.cookies['meteor-login-token'];
userContext = await getUserForContext(loginToken, meteorApolloConfig.userFields);
}
let userContext = {};
if (Package['accounts-base']) {
const loginToken = req.headers['meteor-login-token'] || req.cookies['meteor-login-token'];
const loginToken =
req.headers['meteor-login-token'] ||
req.cookies['meteor-login-token'] ||
req.connectionParams && req.connectionParams[AUTH_TOKEN_KEY];

return {
...defaultContext,
...userContext,
};
userContext = await getUserForContext(loginToken, meteorApolloConfig.userFields);
}

return {
db,
...userContext,
...defaultContext,
};
};
}

function getSubscriptionConfig(meteorApolloConfig) {
function getSubscriptionConfig() {
return {
onConnect: async (connectionParams, webSocket, context) => {
const loginToken = connectionParams[AUTH_TOKEN_KEY];

return new Promise((resolve, reject) => {
if (loginToken) {
const userContext = getUserForContext(
loginToken,
meteorApolloConfig.userFields
).then(userContext => {
resolve(userContext);
});
} else {
resolve({});
}
onConnect: async (connectionParams, webSocket, { request }) => {
return new Promise(resolve => {
const headers = request.headers;
const cookies = cookie.parse(headers['cookie'] || '');

return resolve({ req: { headers, cookies, connectionParams } });
});
},
};
Expand Down

0 comments on commit 96c5c56

Please sign in to comment.