mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
Authorize and whitelist Notifications
This commit is contained in:
parent
26caff5a9b
commit
b63200ac8e
@ -7,6 +7,7 @@ import reports from './resolvers/reports.js'
|
|||||||
import posts from './resolvers/posts.js'
|
import posts from './resolvers/posts.js'
|
||||||
import moderation from './resolvers/moderation.js'
|
import moderation from './resolvers/moderation.js'
|
||||||
import rewards from './resolvers/rewards.js'
|
import rewards from './resolvers/rewards.js'
|
||||||
|
import notifications from './resolvers/notifications'
|
||||||
|
|
||||||
export const typeDefs = fs
|
export const typeDefs = fs
|
||||||
.readFileSync(
|
.readFileSync(
|
||||||
@ -17,13 +18,15 @@ export const typeDefs = fs
|
|||||||
export const resolvers = {
|
export const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
...statistics.Query,
|
...statistics.Query,
|
||||||
...userManagement.Query
|
...userManagement.Query,
|
||||||
|
...notifications.Query
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
...userManagement.Mutation,
|
...userManagement.Mutation,
|
||||||
...reports.Mutation,
|
...reports.Mutation,
|
||||||
...posts.Mutation,
|
...posts.Mutation,
|
||||||
...moderation.Mutation,
|
...moderation.Mutation,
|
||||||
...rewards.Mutation
|
...rewards.Mutation,
|
||||||
|
...notifications.Mutation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,21 @@ const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, context, info)
|
|||||||
return context.user.id === parent.id
|
return context.user.id === parent.id
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
|
||||||
|
const { driver, user: { id: userId } } = context
|
||||||
|
const { id: notificationId } = args
|
||||||
|
const session = driver.session()
|
||||||
|
const result = await session.run(`
|
||||||
|
MATCH (u:User {id: $userId})<-[:NOTIFIED]-(n:Notification {id: $notificationId})
|
||||||
|
RETURN n
|
||||||
|
`, { userId, notificationId })
|
||||||
|
const [notification] = result.records.map((record) => {
|
||||||
|
return record.get('n')
|
||||||
|
})
|
||||||
|
session.close()
|
||||||
|
return Boolean(notification)
|
||||||
|
})
|
||||||
|
|
||||||
const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => {
|
const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => {
|
||||||
const { disabled, deleted } = args
|
const { disabled, deleted } = args
|
||||||
return !(disabled || deleted)
|
return !(disabled || deleted)
|
||||||
@ -50,6 +65,7 @@ const permissions = shield({
|
|||||||
Post: or(onlyEnabledContent, isModerator)
|
Post: or(onlyEnabledContent, isModerator)
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
|
UpdateNotification: belongsToMe,
|
||||||
CreatePost: isAuthenticated,
|
CreatePost: isAuthenticated,
|
||||||
UpdatePost: isAuthor,
|
UpdatePost: isAuthor,
|
||||||
DeletePost: isAuthor,
|
DeletePost: isAuthor,
|
||||||
|
|||||||
14
backend/src/resolvers/notifications.js
Normal file
14
backend/src/resolvers/notifications.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
Query: {
|
||||||
|
Notification: (object, params, context, resolveInfo) => {
|
||||||
|
return neo4jgraphql(object, params, context, resolveInfo, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Mutation: {
|
||||||
|
UpdateNotification: (object, params, context, resolveInfo) => {
|
||||||
|
return neo4jgraphql(object, params, context, resolveInfo, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,13 +5,14 @@ import { host, login } from '../jest/helpers'
|
|||||||
|
|
||||||
const factory = Factory()
|
const factory = Factory()
|
||||||
let client
|
let client
|
||||||
|
let userParams = {
|
||||||
beforeEach(async () => {
|
|
||||||
await factory.create('User', {
|
|
||||||
id: 'you',
|
id: 'you',
|
||||||
email: 'test@example.org',
|
email: 'test@example.org',
|
||||||
password: '1234'
|
password: '1234'
|
||||||
})
|
}
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await factory.create('User', userParams)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@ -118,3 +119,63 @@ describe('currentUser { notifications }', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('UpdateNotification', () => {
|
||||||
|
const mutation = `mutation($id: ID!, $read: Boolean){
|
||||||
|
UpdateNotification(id: $id, read: $read) {
|
||||||
|
id read
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
const variables = { id: 'to-be-updated', read: true }
|
||||||
|
|
||||||
|
describe('given a notifications', () => {
|
||||||
|
let headers
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const mentionedParams = {
|
||||||
|
id: 'mentioned-1',
|
||||||
|
email: 'mentioned@example.org',
|
||||||
|
password: '1234',
|
||||||
|
slug: 'mentioned'
|
||||||
|
}
|
||||||
|
await factory.create('User', mentionedParams)
|
||||||
|
await factory.create('Notification', { id: 'to-be-updated' })
|
||||||
|
await factory.authenticateAs(userParams)
|
||||||
|
await factory.create('Post', { id: 'p1' })
|
||||||
|
await Promise.all([
|
||||||
|
factory.relate('Notification', 'User', { from: 'to-be-updated', to: 'mentioned-1' }),
|
||||||
|
factory.relate('Notification', 'Post', { from: 'p1', to: 'to-be-updated' })
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('unauthenticated', () => {
|
||||||
|
it('throws authorization error', async () => {
|
||||||
|
client = new GraphQLClient(host)
|
||||||
|
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('authenticated', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
headers = await login({ email: 'test@example.org', password: '1234' })
|
||||||
|
client = new GraphQLClient(host, { headers })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws authorization error', async () => {
|
||||||
|
await expect(client.request(mutation, variables)).rejects.toThrow('Not Authorised')
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('and owner', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
headers = await login({ email: 'mentioned@example.org', password: '1234' })
|
||||||
|
client = new GraphQLClient(host, { headers })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('updates notification', async () => {
|
||||||
|
const expected = { UpdateNotification: { id: 'to-be-updated', read: true } }
|
||||||
|
await expect(client.request(mutation, variables)).resolves.toEqual(expected)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -28,10 +28,10 @@ let schema = makeAugmentedSchema({
|
|||||||
resolvers,
|
resolvers,
|
||||||
config: {
|
config: {
|
||||||
query: {
|
query: {
|
||||||
exclude: ['Statistics', 'LoggedInUser']
|
exclude: ['Notfication', 'Statistics', 'LoggedInUser']
|
||||||
},
|
},
|
||||||
mutation: {
|
mutation: {
|
||||||
exclude: ['Statistics', 'LoggedInUser']
|
exclude: ['Notfication', 'Statistics', 'LoggedInUser']
|
||||||
},
|
},
|
||||||
debug: debug
|
debug: debug
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user