permissions for Signup with invite code

This commit is contained in:
Moriz Wahl 2021-03-04 19:00:53 +01:00
parent a614d11535
commit ed51c4a786
4 changed files with 143 additions and 5 deletions

View File

@ -1,6 +1,7 @@
import { rule, shield, deny, allow, or } from 'graphql-shield'
import { getNeode } from '../db/neo4j'
import CONFIG from '../config'
import { validateInviteCode } from '../schema/resolvers/transactions/inviteCodes'
const debug = !!CONFIG.DEBUG
const allowExternalErrors = true
@ -89,6 +90,13 @@ const noEmailFilter = rule({
const publicRegistration = rule()(() => !!CONFIG.PUBLIC_REGISTRATION)
const inviteRegistration = rule()(async (_parent, args, { user, driver }) => {
if (!CONFIG.INVITE_REGISTRATION) return false
const { inviteCode } = args
const session = driver.session()
return validateInviteCode(session, inviteCode)
})
// Permissions
export default shield(
{
@ -128,7 +136,7 @@ export default shield(
Mutation: {
'*': deny,
login: allow,
Signup: or(publicRegistration, isAdmin),
Signup: or(publicRegistration, inviteRegistration, isAdmin),
SignupVerification: allow,
UpdateUser: onlyYourself,
CreatePost: isAuthenticated,

View File

@ -3,11 +3,13 @@ import createServer from '../server'
import Factory, { cleanDatabase } from '../db/factories'
import { gql } from '../helpers/jest'
import { getDriver, getNeode } from '../db/neo4j'
import CONFIG from '../config'
const instance = getNeode()
const driver = getDriver()
let query, authenticatedUser, owner, anotherRegularUser, administrator, variables, moderator
let query, mutate, variables
let authenticatedUser, owner, anotherRegularUser, administrator, moderator
describe('authorization', () => {
beforeAll(async () => {
@ -20,6 +22,7 @@ describe('authorization', () => {
}),
})
query = createTestClient(server).query
mutate = createTestClient(server).mutate
})
afterEach(async () => {
@ -159,5 +162,132 @@ describe('authorization', () => {
})
})
})
describe('access Signup', () => {
const signupMutation = gql`
mutation($email: String!, $inviteCode: String) {
Signup(email: $email, inviteCode: $inviteCode) {
email
}
}
`
describe('admin invite only', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
inviteCode: 'AAAAAA',
}
CONFIG.INVITE_REGISTRATION = false
CONFIG.PUBLIC_REGISTRATION = false
await Factory.build('inviteCode', {
code: 'AAAAAA',
})
})
describe('as user', () => {
beforeEach(async () => {
authenticatedUser = await anotherRegularUser.toJson()
})
it('denies permission', async () => {
await expect(mutate({ mutation: signupMutation, variables })).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
data: { Signup: null },
})
})
})
describe('as admin', () => {
beforeEach(async () => {
authenticatedUser = await administrator.toJson()
})
it('returns an email', async () => {
await expect(mutate({ mutation: signupMutation, variables })).resolves.toMatchObject({
errors: undefined,
data: {
Signup: { email: 'some@email.org' },
},
})
})
})
})
describe('public registration', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
inviteCode: 'AAAAAA',
}
CONFIG.INVITE_REGISTRATION = false
CONFIG.PUBLIC_REGISTRATION = true
await Factory.build('inviteCode', {
code: 'AAAAAA',
})
})
describe('as anyone', () => {
beforeEach(async () => {
authenticatedUser = null
})
it('returns an email', async () => {
await expect(mutate({ mutation: signupMutation, variables })).resolves.toMatchObject({
errors: undefined,
data: {
Signup: { email: 'some@email.org' },
},
})
})
})
})
describe('invite registration', () => {
beforeEach(async () => {
CONFIG.INVITE_REGISTRATION = true
CONFIG.PUBLIC_REGISTRATION = false
await Factory.build('inviteCode', {
code: 'AAAAAA',
})
})
describe('as anyone with valid invite code', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
inviteCode: 'AAAAAA',
}
authenticatedUser = null
})
it('returns an email', async () => {
await expect(mutate({ mutation: signupMutation, variables })).resolves.toMatchObject({
errors: undefined,
data: {
Signup: { email: 'some@email.org' },
},
})
})
})
describe('as anyone without valid invite', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
inviteCode: 'no valid invite code',
}
authenticatedUser = null
})
it('denies permission', async () => {
await expect(mutate({ mutation: signupMutation, variables })).resolves.toMatchObject({
errors: [{ message: 'Not Authorised!' }],
data: { Signup: null },
})
})
})
})
})
})
})

View File

@ -39,8 +39,8 @@ export default {
const { code } = args
const session = context.driver.session()
if (!code) return false
return await validateInviteCode(session, code)
}
return validateInviteCode(session, code)
},
},
Mutation: {
GenerateInviteCode: async (_parent, args, context, _resolveInfo) => {

View File

@ -11,7 +11,7 @@ export async function validateInviteCode(session, inviteCode) {
inviteCode,
},
)
return result.records.map((record) => record.get('result'))
return result.records.map((record) => record.get('result'))
})
try {
const txResult = await readTxResultPromise