Server: Update resolver to use auth context

This commit is contained in:
Barry Low committed 2018-09-12 22:37:35 -07:00
1 parent 5731ec1957
commit 43f2bbceee
15 files changed
+2577 -145

No files matched your search

+34 -10
View File
@@ -1,6 +1,5 @@
const _get = require('lodash.get')
const validateAndParseIdToken = require('./helpers/validateAndParseIdToken')
const createMember = require('./index')
const { validateIdToken } = require('./validateIdToken')
const memberLocationOnContext = 'request.member'
const bearerAccessToken = 'request.headers.authorization'
@@ -8,11 +7,29 @@ const bearerAccessToken = 'request.headers.authorization'
const ctxMember = ctx => _get(ctx, memberLocationOnContext)
const ctxToken = ctx => _get(ctx, bearerAccessToken)
const createMember = async (ctx, idToken, info) => {
console.log('createMember', idToken)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
},
create: {
authId: idToken.sub,
alias: idToken.nickname
},
update: {
authId: idToken.sub,
alias: idToken.nickname
}
}, info)
return member
}
const isLoggedIn = async ctx => {
let member = ctxMember(ctx, memberLocationOnContext)
let token = ctxToken(ctx, bearerAccessToken)
let memberToken
console.log('isLoggedIn: ', member, token)
if (!member && token) {
let scheme, credentials
const tokenParts = token.split(' ')
@@ -24,21 +41,28 @@ const isLoggedIn = async ctx => {
if (/^Bearer$/i.test(scheme)) {
token = credentials
//verify token
console.log('isLoggedIn2 : ', token)
try {
memberToken = await validateAndParseIdToken(token)
const auth0id = memberToken.sub
memberToken = await validateIdToken(token)
const authId = memberToken.sub
console.log('isLoggedIn3 : ', await authId, ctx.db.query.member)
exists = await ctx.db.query.member({ where: { authId: authId } })
console.log('isLoggedIn4 : ', await exists, createMember )
if (!member && exists === null) {
member = await createMember(ctx, memberToken).then(res => {
console.log('isLoggedIn5 : ', res)
return res
})
member = await ctx.db.query.member({ where: { auth0id } })
if (!member) {
member = await createMember(ctx, memberToken)
return member
}
return member
} catch (err) {
memberToken = false
}
}
}
console.log('isLoggedIn5 : ', await member)
if (!member) {
throw new Error(`Not logged in`)
}
+2 -2
View File
@@ -7,7 +7,7 @@ const jwks = jwksClient({
jwksUri: `https://${process.env.AUTH0_DOMAIN}/.well-known/jwks.json`
})
const validateParseIdToken = idToken =>
const validateIdToken = idToken =>
new Promise((resolve, reject) => {
const { header, payload } = jwt.decode(idToken, { complete: true })
if (!header || !header.kid || !payload) reject(new Error('Invalid Token'))
@@ -25,4 +25,4 @@ const validateParseIdToken = idToken =>
})
})
module.exports = validateParseIdToken
module.exports = { validateIdToken }
File diff suppressed because it is too large. Load diff
+55 -29
View File
@@ -1,3 +1,4 @@
require('dotenv').config();
const { GraphQLServer } = require('graphql-yoga')
const {
Prisma,
@@ -8,15 +9,39 @@ const { makeExecutableSchema } = require('graphql-tools')
const { importSchema } = require('graphql-import')
const { checkJwt } = require('./auth/middleware/jwt')
const { getMember } = require('./auth/middleware/getMember')
const validateParseIdToken = require('./auth/helpers/validate-parse-id-token')
const { directiveResolvers } = require('./auth-directives')
const { validateIdToken } = require('./auth/validateIdToken')
const { directiveResolvers } = require('./auth/authDirectives')
const createMember = async function (ctx, info, idToken) {
console.log('createMember', idToken)
const member = await ctx.db.mutation.upsertMember({
where: {
authId: idToken.sub,
},
create: {
authId: idToken.sub,
alias: idToken.nickname
},
update: {
authId: idToken.sub,
alias: idToken.nickname
}
}, info)
return member
}
const ctxMember = ctx => ctx.request.member
const resolvers = {
Query: {
async member(parent, { auth0id }, ctx, info) {
return ctx.db.query.member({ where: { auth0id } }, info)
async member(parent, arg, ctx, info) {
console.log('member: ', parent, arg)
return ctx.db.query.member({ where: { authId: arg.authId } }, info)
},
async currentMember(parent, args, ctx, info) {
console.log('currentMember: ', ctx.request.res.req.user)
const authId = ctx.request.res.req.user.sub
return ctx.db.query.member({ where: { authId } }, info)
},
teams(parent, args, ctx, info) {
return ctx.db.query.teamsConnection({},
@@ -59,7 +84,7 @@ const resolvers = {
return ctx.db.query.team({ where: { name: name } }, `{ name }`)
},
async teamByOwner(parent, { ownerId }, ctx, info) {
return ctx.db.query.teamsConnection({where: { owner: { auth0id: ownerId }}},
return ctx.db.query.teamsConnection({where: { owner: { authId: ownerId }}},
`{
edges {
node {
@@ -72,7 +97,7 @@ const resolvers = {
motto
}
owner {
auth0id
authId
nickname
visible
profile {
@@ -95,28 +120,27 @@ const resolvers = {
},
async owner(parent, args, ctx, info) {
console.log('resolver.query.owner ctx: ', ctxMember(ctx))
return ctx.db.query.member({ where: { id: ctxMember(ctx).auth0id } }, info)
return ctx.db.query.member({ where: { id: ctxMember(ctx).authId } }, info)
.catch((res) => {
console.log('createTeam error: ', res)
const errors = res.graphQLErrors.map((error) => {
return error.message
})
})
},
members: forwardTo('db')
}
},
Mutation: {
async authenticate(parent, { idToken }, ctx, info) {
let memberToken = null
try {
memberToken = await validateAndParseIdToken(idToken)
memberToken = await validateIdToken(idToken)
console.log('authenticate.memberToken: ', await memberToken)
} catch (err) {
console.log('authenticat.validateAndParseIdToken err: ', err)
console.log('authenticat.validateIdToken err: ', err)
throw new Error(err.message)
}
const auth0id = memberToken.sub
let member = await ctx.db.query.member({ where: { auth0id } }, info)
const authId = memberToken.sub
let member = await ctx.db.query.member({ where: { authId } }, info)
if (!member) {
try {
@@ -124,7 +148,6 @@ const resolvers = {
} catch (error) {
throw new Error(error.message)
}
}
}
return member
},
@@ -133,15 +156,12 @@ const resolvers = {
data: {
name: name,
slug: slug,
owner: {connect:{auth0id: owner}},
members: {create: {role: 'OWNER', member: {connect: {auth0id: owner}}}}
owner: owner
}
}, info)
.catch((res) => {
console.log('createTeam error: ', res)
const errors = res.graphQLErrors.map((error) => {
return error.message
})
.catch((err) => {
console.log('createTeam error: ', err)
return err
})
},
async deleteTeam(parent, { id }, ctx, info) {
@@ -176,25 +196,30 @@ const server = new GraphQLServer({
context: req => ({
...req,
db
})
}),
})
server.express.post(
server.express.use(
server.options.endpoint,
checkJwt,
(err, req, res, next) => {
console.log('checkJwt: ', err, req.user)
if (err) return res.status(401).send(err.message)
next()
}
)
server.express.post(server.options.endpoint, (req, res, done) =>
server.express.post(server.options.endpoint, (err, req, res, done) => {
console.log('getMember: ', err, req.user)
getMember(req, res, done, db)
)
})
const whitelist = [
'http://localhost:1337',
'http://0.0.0.0:5000'
'http://localhost:3000',
'http://localhost:3001',
'http://localhost:3002',
'http://localhost:4000',
'http://localhost:4002'
]
const corsOptionsDelegate = (req, callback) => {
var corsOptions
@@ -207,12 +232,13 @@ const corsOptionsDelegate = (req, callback) => {
}
const options = {
port: 4001,
cors: corsOptionsDelegate,
endpoint: '/graphql',
subscriptions: '/graphql',
playground: '/playground'
}
server.start(options, () => console.log(`Server is running on http://localhost:4000${server.options.endpoint}`))
server.start(options, () => console.log(`Server is running on http://localhost:4001${server.options.endpoint}`))
module.exports= { createPrismaMember: createPrismaMember }
module.exports= { createMember }
@@ -12,24 +12,37 @@ type Query {
teamById(teamId: String!): Team
teamByOwner(ownerId: String!): TeamConnection
owner: Member @isAuthenticated
member(auth0id: String!): Member @isAuthenticated
currentMember: Member @isAuthenticated
member(authId: String!): Member @isAuthenticated
}
type Mutation {
authenticate(idToken: String!): Member
createTeam(name: String!, slug: String, owner: String): Team @isAuthenticated
deleteTeam(id: ID!): Team @isAuthenticated @isOwner(type: "Team")
updateProfile(data: MemberProfileInput): Member @isAuthenticated
}
input MemberProfileInput {
auth0id: String!
nickname: String!
anonymous: Boolean
visible: Boolean
avatar: String
email: String
repo: String
bio: String
status: String
authId: String!
alias: String!
}
fragment MemberInfo on Member {
id
authId
alias
isActive
profile {
...MemberProfileInfo
}
}
fragment MemberProfileInfo on MemberProfile {
firstName
lastName
email
avatar
role {
name
}
}