Server: Update resolver to use auth context
This commit is contained in:
1 parent
5731ec1957
commit
43f2bbceee
15 files changed
+2577
-145
No files matched your search
@@ -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`)
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user