Created
July 11, 2017 08:03
-
-
Save smooJitter/f9d4216183e71e70ab1258626844219b to your computer and use it in GitHub Desktop.
A proposal to add meteor user to the guru context object. This is based on the apollo-meteor-integration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* GraphQL rourte | |
*/ | |
'use strict'; | |
import { Meteor } from 'meteor/meteor'; | |
import { WebApp } from 'meteor/webapp'; | |
import { Accounts } from 'meteor/accounts-base'; | |
import { check } from 'meteor/check'; | |
import { graphqlExpress } from 'graphql-server-express'; | |
export default function graphqlRoute({ app, context }) { | |
app.use( | |
'/graphql', | |
graphqlExpress(req => { | |
// get the login token from the headers request, given by the Meteor's | |
// network interface middleware if enabled | |
const loginToken = req.headers['meteor-login-token']; | |
// get the current user & the user id for the context | |
const userContext = await getUserForContext(loginToken); | |
// context can accept a function returning the context object | |
const context = typeof context === 'function' | |
? context(userContext) | |
: { ...context, ...userContext }; | |
return { | |
context: { | |
...context, | |
}, | |
}; | |
}) | |
); | |
} | |
export const getUserForContext = async loginToken => { | |
// there is a possible current user connected! | |
if (loginToken) { | |
// throw an error if the token is not a string | |
check(loginToken, String); | |
// the hashed token is the key to find the possible current user in the db | |
const hashedToken = Accounts._hashLoginToken(loginToken); | |
// get the possible current user from the database | |
// note: no need of a fiber aware findOne + a fiber aware call break tests | |
// runned with practicalmeteor:mocha if eslint is enabled | |
const currentUser = await Meteor.users.rawCollection().findOne({ | |
'services.resume.loginTokens.hashedToken': hashedToken, | |
}); | |
// the current user exists | |
if (currentUser) { | |
// find the right login token corresponding, the current user may have | |
// several sessions logged on different browsers / computers | |
const tokenInformation = currentUser.services.resume.loginTokens.find( | |
tokenInfo => tokenInfo.hashedToken === hashedToken | |
); | |
// get an exploitable token expiration date | |
const expiresAt = Accounts._tokenExpiration(tokenInformation.when); | |
// true if the token is expired | |
const isExpired = expiresAt < new Date(); | |
// if the token is still valid, give access to the current user | |
// information in the resolvers context | |
if (!isExpired) { | |
// return a new context object with the current user & her id | |
return { | |
user: currentUser, | |
userId: currentUser._id, | |
}; | |
} | |
} | |
} | |
return {}; | |
}; | |
// take the existing context and return a new extended context with the current | |
// user if relevant (i.e. valid login token) | |
export const addCurrentUserToContext = async (context, loginToken) => { | |
const userContext = await getUserForContext(loginToken); | |
return { | |
...context, | |
...userContext, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment