Merge branch 'bug/api-delete-member'
This commit is contained in:
commit
2aec42485c
6 files changed
+54
-20
No files matched your search
@@ -73,7 +73,7 @@ const isLoggedIn = async ctx => {
|
||||
|
||||
console.log('member: ', await member)
|
||||
|
||||
if (!token && !member) {
|
||||
if (!member) {
|
||||
throw new Error(`Not logged in`)
|
||||
}
|
||||
return member
|
||||
@@ -81,17 +81,18 @@ const isLoggedIn = async ctx => {
|
||||
|
||||
|
||||
const isRequestingMemberAlsoOwner = ({ ctx, memberId, type, typeId }) =>
|
||||
ctx.db.exists[type]({ id: typeId, member: { id: memberId } })
|
||||
const isRequestingMember = ({ ctx, memberId }) => ctx.db.exists.Member({ id: memberId })
|
||||
ctx.db.exists[type]({ id: typeId, owner: { auth0id: memberId } })
|
||||
const isRequestingMember = ({ ctx, memberId }) => ctx.db.exists.Member({ auth0id: memberId })
|
||||
|
||||
const directiveResolvers = {
|
||||
isAuthenticated: async (next, source, args, ctx) => {
|
||||
let result = await isLoggedIn(ctx)
|
||||
console.log('isAuthenticated: ', result)
|
||||
return next()
|
||||
console.log('directive isAuthenticated: ', result)
|
||||
return next(result)
|
||||
},
|
||||
hasRole: (next, source, { roles }, ctx) => {
|
||||
const { role } = isLoggedIn(ctx)
|
||||
console.log('directive hasRole: ', role)
|
||||
if (roles.includes(role)) {
|
||||
return next()
|
||||
}
|
||||
@@ -102,30 +103,34 @@ const directiveResolvers = {
|
||||
source && source.id
|
||||
? source
|
||||
: ctx.request.body.variables ? ctx.request.body.variables : { id: null }
|
||||
const { id: memberId } = isLoggedIn(ctx)
|
||||
const { auth0id: memberId } = await isLoggedIn(ctx)
|
||||
console.log('directive isOwner 0: ', type, typeId, memberId)
|
||||
const isOwner =
|
||||
type === `Member`
|
||||
? memberId === typeId
|
||||
: await isRequestingMemberAlsoOwner({ ctx, memberId, type, typeId })
|
||||
console.log('directive isOwner 1: ', source, isOwner, type, typeId, memberId)
|
||||
if (isOwner) {
|
||||
return next()
|
||||
}
|
||||
throw new Error(`Unauthorized, must be owner`)
|
||||
},
|
||||
isOwnerOrHasRole: async (next, source, { roles, type }, ctx, ...p) => {
|
||||
const { id: memberId, role } = isLoggedIn(ctx)
|
||||
const { auth0id: memberId } = await isLoggedIn(ctx)
|
||||
console.log('directive isOwnerOrHasRole 1: ', memberId, roles, type)
|
||||
if(memberId === undefined && role=== undefined) throw new Error(`Not logged in`)
|
||||
if (roles.includes(role)) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const { id: typeId } = ctx.request.body.variables
|
||||
const { auth0id: typeId } = ctx.request.body.variables
|
||||
const isOwner = await isRequestingMemberAlsoOwner({
|
||||
ctx,
|
||||
memberId,
|
||||
type,
|
||||
typeId
|
||||
})
|
||||
|
||||
console.log('directive isOwnerOrHasRole 2: ', typeId, memberId, role, isOwner)
|
||||
if (isOwner) {
|
||||
return next()
|
||||
}
|
||||
|
||||
@@ -125,6 +125,12 @@ 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)
|
||||
.catch((res) => {
|
||||
console.log('createTeam error: ', res)
|
||||
const errors = res.graphQLErrors.map((error) => {
|
||||
return error.message
|
||||
})
|
||||
})
|
||||
},
|
||||
members: forwardTo('db')
|
||||
},
|
||||
@@ -155,7 +161,7 @@ const resolvers = {
|
||||
return member
|
||||
},
|
||||
async createTeam(parent, { name, slug, owner }, ctx, info) {
|
||||
ctx.db.mutation.createTeam({
|
||||
return ctx.db.mutation.createTeam({
|
||||
data: {
|
||||
name: name,
|
||||
slug: slug,
|
||||
@@ -163,9 +169,21 @@ const resolvers = {
|
||||
members: {create: {role: 'OWNER', member: {connect: {auth0id: owner}}}}
|
||||
}
|
||||
}, info)
|
||||
.catch((res) => {
|
||||
console.log('createTeam error: ', res)
|
||||
const errors = res.graphQLErrors.map((error) => {
|
||||
return error.message
|
||||
})
|
||||
})
|
||||
},
|
||||
async deleteTeam(parent, { id, owner }, ctx, info) {
|
||||
ctx.db.mutation.deleteTeam({ where: { id } }, info)
|
||||
async deleteTeam(parent, { id }, ctx, info) {
|
||||
return ctx.db.mutation.deleteTeam({ where: { id } }, info)
|
||||
.catch((res) => {
|
||||
console.log('deleteTeam error: ', res)
|
||||
const errors = res.graphQLErrors.map((error) => {
|
||||
return error.message
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ type Query {
|
||||
type Mutation {
|
||||
authenticate(idToken: String!): Member
|
||||
createTeam(name: String!, slug: String, owner: String): Team @isAuthenticated
|
||||
deleteTeam(id: ID!): Team @isOwnerOrHasRole(type: "Member", roles: ["OWNER"])
|
||||
deleteTeam(id: ID!): Team @isAuthenticated @isOwner(type: "Team")
|
||||
updateProfile(data: MemberProfileInput): Member @isAuthenticated
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { HttpLink } from 'apollo-link-http'
|
||||
import { InMemoryCache } from 'apollo-cache-inmemory'
|
||||
import { ApolloLink, concat, split, Observable } from 'apollo-link'
|
||||
import { onError } from 'apollo-link-error'
|
||||
import { setContext } from 'apollo-link-context'
|
||||
import { WebSocketLink } from 'apollo-link-ws'
|
||||
import { SubscriptionClient } from 'subscriptions-transport-ws'
|
||||
import { getMainDefinition } from 'apollo-utilities'
|
||||
@@ -65,7 +66,7 @@ const link = split(
|
||||
httpLink
|
||||
)
|
||||
|
||||
const authLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
|
||||
const authRetryLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
|
||||
if (graphQLErrors) {
|
||||
// User access token has expired
|
||||
// console.log('authLink: ', graphQLErrors) // check for error message to intercept and resend with Auth0 access token
|
||||
@@ -103,14 +104,24 @@ const authLink = onError(({ graphQLErrors, networkError, operation, forward }) =
|
||||
}
|
||||
})
|
||||
|
||||
const linkWithAuth = concat(authLink, link)
|
||||
const authLink = setContext((_, { headers }) => {
|
||||
// get the authentication token from local storage if it exists
|
||||
const token = window.localStorage.getItem('access_token')
|
||||
// return the headers to the context so httpLink can read them
|
||||
return {
|
||||
headers: {
|
||||
...headers,
|
||||
Authorization: token ? `Bearer ${token}` : ``
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let apolloClient
|
||||
|
||||
const cache = new InMemoryCache().restore(window.__APOLLO_STATE__)
|
||||
|
||||
export const client = new ApolloClient({
|
||||
link: linkWithAuth,
|
||||
link: ApolloLink.from([authRetryLink, authLink, link]),
|
||||
cache,
|
||||
connectToDevTools: true
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import { DeleteTeamMutation } from '../graphql/DeleteTeamMutation'
|
||||
|
||||
import { client } from '../../../index'
|
||||
|
||||
import { mergeDeep } from '../../../utils/js-helpers'
|
||||
import { mergeDeep, validObject } from '../../../utils/js-helpers'
|
||||
|
||||
export const team = {
|
||||
form: ({ form, message }) => state => {
|
||||
@@ -203,10 +203,10 @@ export const team = {
|
||||
return actions.form({ form: 'deleteTeamError', message: errors })
|
||||
})
|
||||
|
||||
if (result.data.deleteTeam.id !== null) {
|
||||
if (validObject(result, 'data') && result.data.deleteTeam !== null) {
|
||||
return actions.deleteTeamSuccess({ name: '' })
|
||||
} else {
|
||||
return actions.form({ form: 'deleteTeamError', message: 'No team found' })
|
||||
return actions.form({ form: 'deleteTeamError', message: result })
|
||||
}
|
||||
},
|
||||
deleteTeamSuccess: profile => [
|
||||
|
||||
@@ -26,7 +26,7 @@ export const TeamPanel = props => (state, actions) => {
|
||||
if (team[0].node.name !== '' && team[0].node.name !== null) {
|
||||
const initial = team[0].node.name.substring(0, 1)
|
||||
return (
|
||||
<div class='section' key='teamList' class='is-marginless is-paddingless'>
|
||||
<div class='section' key='teamPanel' class='is-marginless is-paddingless'>
|
||||
<h2 class='title is-size-4 m-t-1'>Team</h2>
|
||||
{team[0].node.profile !== null && team[0].node.profile.avatar !== '' ? (
|
||||
<div class='image is-32x32 avatar'>
|
||||
|
||||
Reference in new issue
Block a user