diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index dac3c58fa..2efa2a6bb 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -134,7 +134,7 @@ const permissions = shield( CreatePost: isAuthenticated, UpdatePost: isAuthor, DeletePost: isAuthor, - report: isAuthenticated, + fileReport: isAuthenticated, CreateSocialMedia: isAuthenticated, UpdateSocialMedia: isMySocialMedia, DeleteSocialMedia: isMySocialMedia, diff --git a/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js b/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js index 46f768384..1c97cb874 100644 --- a/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js +++ b/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js @@ -104,14 +104,14 @@ beforeAll(async () => { const trollingPost = resources[1] const trollingComment = resources[2] - const claims = await Promise.all([ - factory.create('Claim'), - factory.create('Claim'), - factory.create('Claim'), + const reports = await Promise.all([ + factory.create('Report'), + factory.create('Report'), + factory.create('Report'), ]) - const claimAgainstTroll = claims[0] - const claimAgainstTrollingPost = claims[1] - const claimAgainstTrollingComment = claims[2] + const reportAgainstTroll = reports[0] + const reportAgainstTrollingPost = reports[1] + const reportAgainstTrollingComment = reports[2] const reportVariables = { resourceId: 'undefined-resource', @@ -120,15 +120,15 @@ beforeAll(async () => { } await Promise.all([ - claimAgainstTroll.relateTo(user, 'reported', { ...reportVariables, resourceId: 'u2' }), - claimAgainstTroll.relateTo(troll, 'belongsTo'), - claimAgainstTrollingPost.relateTo(user, 'reported', { ...reportVariables, resourceId: 'p2' }), - claimAgainstTrollingPost.relateTo(trollingPost, 'belongsTo'), - claimAgainstTrollingComment.relateTo(moderator, 'reported', { + reportAgainstTroll.relateTo(user, 'filed', { ...reportVariables, resourceId: 'u2' }), + reportAgainstTroll.relateTo(troll, 'belongsTo'), + reportAgainstTrollingPost.relateTo(user, 'filed', { ...reportVariables, resourceId: 'p2' }), + reportAgainstTrollingPost.relateTo(trollingPost, 'belongsTo'), + reportAgainstTrollingComment.relateTo(moderator, 'filed', { ...reportVariables, resourceId: 'c1', }), - claimAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'), + reportAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'), ]) const disableVariables = { @@ -138,14 +138,14 @@ beforeAll(async () => { } await Promise.all([ - claimAgainstTroll.relateTo(moderator, 'reviewed', { ...disableVariables, resourceId: 'u2' }), + reportAgainstTroll.relateTo(moderator, 'reviewed', { ...disableVariables, resourceId: 'u2' }), troll.update({ disabled: true, updatedAt: new Date().toISOString() }), - claimAgainstTrollingPost.relateTo(moderator, 'reviewed', { + reportAgainstTrollingPost.relateTo(moderator, 'reviewed', { ...disableVariables, resourceId: 'p2', }), trollingPost.update({ disabled: true, updatedAt: new Date().toISOString() }), - claimAgainstTrollingComment.relateTo(moderator, 'reviewed', { + reportAgainstTrollingComment.relateTo(moderator, 'reviewed', { ...disableVariables, resourceId: 'c1', }), diff --git a/backend/src/middleware/validation/validationMiddleware.js b/backend/src/middleware/validation/validationMiddleware.js index 21890607b..ec761f49a 100644 --- a/backend/src/middleware/validation/validationMiddleware.js +++ b/backend/src/middleware/validation/validationMiddleware.js @@ -64,7 +64,7 @@ const validateReport = async (resolve, root, args, context, info) => { const session = driver.session() const reportQueryRes = await session.run( ` - MATCH (:User {id: $submitterId})-[:REPORTED]->(:Claim {closed: false})-[:BELONGS_TO]->(resource {id: $resourceId}) + MATCH (:User {id: $submitterId})-[:FILED]->(:Report {closed: false})-[:BELONGS_TO]->(resource {id: $resourceId}) WHERE resource:User OR resource:Post OR resource:Comment RETURN labels(resource)[0] AS label `, @@ -93,9 +93,9 @@ const validateReview = async (resolve, root, args, context, info) => { ` MATCH (resource {id: $resourceId}) WHERE resource:User OR resource:Post OR resource:Comment - OPTIONAL MATCH (:User)-[report:REPORTED]->(:Claim {closed: false})-[:BELONGS_TO]->(resource) + OPTIONAL MATCH (:User)-[filed:FILED]->(:Report {closed: false})-[:BELONGS_TO]->(resource) OPTIONAL MATCH (resource)<-[:WROTE]-(author:User) - RETURN labels(resource)[0] AS label, author, report + RETURN labels(resource)[0] AS label, author, filed `, { resourceId, @@ -107,12 +107,12 @@ const validateReview = async (resolve, root, args, context, info) => { return { label: record.get('label'), author: record.get('author'), - report: record.get('report'), + filed: record.get('filed'), } }) if (!existingReportedResource) throw new Error(`Resource not found!`) - if (!existingReportedResource.report) + if (!existingReportedResource.filed) throw new Error( `Before you can start the reviewing process, please report the ${existingReportedResource.label}!`, ) @@ -131,7 +131,7 @@ export default { UpdateComment: validateUpdateComment, CreatePost: validatePost, UpdatePost: validateUpdatePost, - report: validateReport, + fileReport: validateReport, review: validateReview, }, } diff --git a/backend/src/models/Claim.js b/backend/src/models/Report.js similarity index 97% rename from backend/src/models/Claim.js rename to backend/src/models/Report.js index ac41f9b77..b66aa4076 100644 --- a/backend/src/models/Claim.js +++ b/backend/src/models/Report.js @@ -13,9 +13,9 @@ module.exports = { target: ['User', 'Comment', 'Post'], direction: 'out', }, - reported: { + filed: { type: 'relationship', - relationship: 'REPORTED', + relationship: 'FILED', target: 'User', direction: 'in', properties: { diff --git a/backend/src/models/index.js b/backend/src/models/index.js index 9f6868025..b94b561f0 100644 --- a/backend/src/models/index.js +++ b/backend/src/models/index.js @@ -13,5 +13,5 @@ export default { Tag: require('./Tag.js'), Location: require('./Location.js'), Donations: require('./Donations.js'), - Claim: require('./Claim.js'), + Report: require('./Report.js'), } diff --git a/backend/src/schema/index.js b/backend/src/schema/index.js index 6f58ab131..24ccbe876 100644 --- a/backend/src/schema/index.js +++ b/backend/src/schema/index.js @@ -18,9 +18,9 @@ export default makeAugmentedSchema({ 'Location', 'SocialMedia', 'NOTIFIED', - 'REPORTED', + 'FILED', 'REVIEWED', - 'Claim', + 'Report', 'Donations', ], }, diff --git a/backend/src/schema/resolvers/comments.js b/backend/src/schema/resolvers/comments.js index 476e64b1b..57d4da2b9 100644 --- a/backend/src/schema/resolvers/comments.js +++ b/backend/src/schema/resolvers/comments.js @@ -1,6 +1,6 @@ import uuid from 'uuid/v4' import Resolver from './helpers/Resolver' -import { queryReviewedByModerator } from './helpers/claimResource.js' +import { queryReviewedByModerator } from './helpers/reportResource.js' export default { Mutation: { diff --git a/backend/src/schema/resolvers/helpers/claimResource.js b/backend/src/schema/resolvers/helpers/reportResource.js similarity index 79% rename from backend/src/schema/resolvers/helpers/claimResource.js rename to backend/src/schema/resolvers/helpers/reportResource.js index 55bc83079..ff32e4a14 100644 --- a/backend/src/schema/resolvers/helpers/claimResource.js +++ b/backend/src/schema/resolvers/helpers/reportResource.js @@ -2,10 +2,10 @@ export async function queryReviewedByModerator(label, parent, context) { if (typeof parent.reviewedByModerator !== 'undefined') return parent.reviewedByModerator const { id } = parent const statement = ` - MATCH (resource {id: $id})<-[:BELONGS_TO]-(claim:Claim)<-[review:REVIEWED]-(moderator:User) + MATCH (resource {id: $id})<-[:BELONGS_TO]-(report:Report)<-[review:REVIEWED]-(moderator:User) WHERE $label IN labels(resource) RETURN moderator - ORDER BY claim.updatedAt DESC, review.updatedAt DESC + ORDER BY report.updatedAt DESC, review.updatedAt DESC LIMIT 1 ` let reviewedByModerator diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js index bcb38d9eb..9d687dd42 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.js @@ -16,21 +16,21 @@ export default { MATCH (resource {id: $resourceId}) WHERE resource:User OR resource:Post OR resource:Comment - // no open claim, create one, update existing - MERGE (resource)<-[:BELONGS_TO]-(claim:Claim {closed: false}) - ON CREATE SET claim.id = randomUUID(), claim.createdAt = $dateTime, claim.updatedAt = claim.createdAt, claim.rule = 'latestReviewUpdatedAtRules', claim.disable = resource.disabled, claim.closed = false - ON MATCH SET claim.updatedAt = $dateTime - // claim.disable and claim.closed are set after setting them in review + // no open report, create one, update existing + MERGE (resource)<-[:BELONGS_TO]-(report:Report {closed: false}) + ON CREATE SET report.id = randomUUID(), report.createdAt = $dateTime, report.updatedAt = report.createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = resource.disabled, report.closed = false + ON MATCH SET report.updatedAt = $dateTime + // report.disable and report.closed are set after setting them in review - // Create review on claim - WITH moderator, resource, claim - MERGE (claim)<-[review:REVIEWED]-(moderator) + // Create review on report + WITH moderator, resource, report + MERGE (report)<-[review:REVIEWED]-(moderator) ON CREATE SET review.createdAt = $dateTime, review.updatedAt = review.createdAt, review.disable = CASE WHEN $disable IS NULL - THEN claim.disable + THEN report.disable ELSE $disable END, review.closed = CASE WHEN $closed IS NULL - THEN claim.closed + THEN report.closed ELSE $closed END ON MATCH SET review.updatedAt = $dateTime, @@ -41,10 +41,10 @@ export default { THEN review.closed ELSE $closed END - SET claim.disable = review.disable, claim.closed = review.closed + SET report.disable = review.disable, report.closed = review.closed SET resource.disabled = review.disable - RETURN moderator, review, claim, resource, labels(resource)[0] AS type + RETURN moderator, review, report, resource, labels(resource)[0] AS type ` const mutateDecisionWriteTxResultPromise = session.writeTransaction(async txc => { const mutateDecisionTransactionResponse = await txc.run(cypher, { @@ -57,21 +57,21 @@ export default { return mutateDecisionTransactionResponse.records.map(record => ({ moderator: record.get('moderator'), review: record.get('review'), - claim: record.get('claim'), + report: record.get('report'), resource: record.get('resource'), type: record.get('type'), })) }) const txResult = await mutateDecisionWriteTxResultPromise if (!txResult[0]) return null - const { moderator: moderatorInResult, review, claim, resource, type } = txResult[0] + const { moderator: moderatorInResult, review, report, resource, type } = txResult[0] createdRelationshipWithNestedAttributes = { ...review.properties, - claimId: claim.properties.id, - claimCreatedAt: claim.properties.createdAt, - claimUpdatedAt: claim.properties.updatedAt, - claimDisable: claim.properties.disable, - claimClosed: claim.properties.closed, + reportId: report.properties.id, + reportCreatedAt: report.properties.createdAt, + reportUpdatedAt: report.properties.updatedAt, + reportDisable: report.properties.disable, + reportClosed: report.properties.closed, moderator: moderatorInResult.properties, type, post: null, diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 43e00d7fb..1c056500e 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -19,7 +19,7 @@ let query, const reportMutation = gql` mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report( + fileReport( resourceId: $resourceId reasonCategory: $reasonCategory reasonDescription: $reasonDescription diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index f26ecc0eb..495125729 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -5,7 +5,7 @@ import { getBlockedUsers, getBlockedByUsers } from './users.js' import { mergeWith, isArray, isEmpty } from 'lodash' import { UserInputError } from 'apollo-server' import Resolver from './helpers/Resolver' -import { queryReviewedByModerator } from './helpers/claimResource.js' +import { queryReviewedByModerator } from './helpers/reportResource.js' const filterForBlockedUsers = async (params, context) => { if (!context.user) return params diff --git a/backend/src/schema/resolvers/reports.js b/backend/src/schema/resolvers/reports.js index f5b9b7d0e..af7bb3555 100644 --- a/backend/src/schema/resolvers/reports.js +++ b/backend/src/schema/resolvers/reports.js @@ -1,6 +1,6 @@ export default { Mutation: { - report: async (_parent, params, context, _resolveInfo) => { + fileReport: async (_parent, params, context, _resolveInfo) => { let createdRelationshipWithNestedAttributes const { resourceId, reasonCategory, reasonDescription } = params const { driver, user } = context @@ -11,15 +11,15 @@ export default { MATCH (submitter:User {id: $submitterId}) MATCH (resource {id: $resourceId}) WHERE resource:User OR resource:Post OR resource:Comment - // no open claim, create one - MERGE (resource)<-[:BELONGS_TO]-(claim:Claim {closed: false}) - ON CREATE SET claim.id = randomUUID(), claim.createdAt = $createdAt, claim.updatedAt = claim.createdAt, claim.rule = 'latestReviewUpdatedAtRules', claim.disable = resource.disabled, claim.closed = false - // ON MATCH: do not update claim.updatedAt !!! that is only for reviews! - // Create report to claim - WITH submitter, resource, claim - CREATE (claim)<-[report:REPORTED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) + // no open report, create one + MERGE (resource)<-[:BELONGS_TO]-(report:Report {closed: false}) + ON CREATE SET report.id = randomUUID(), report.createdAt = $createdAt, report.updatedAt = report.createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = resource.disabled, report.closed = false + // ON MATCH: do not update report.updatedAt !!! that is only for reviews! + // Create report to report + WITH submitter, resource, report + CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) - RETURN submitter, report, claim, resource, labels(resource)[0] AS type + RETURN submitter, report, filed, resource, labels(resource)[0] AS type `, { resourceId, @@ -32,7 +32,7 @@ export default { return reportRelationshipTransactionResponse.records.map(record => ({ submitter: record.get('submitter').properties, report: record.get('report').properties, - claim: record.get('claim').properties, + filed: record.get('filed').properties, resource: record.get('resource').properties, type: record.get('type'), })) @@ -40,10 +40,10 @@ export default { try { const txResult = await writeTxResultPromise if (!txResult[0]) return null - const { submitter, report, claim, resource, type } = txResult[0] + const { submitter, report, filed, resource, type } = txResult[0] createdRelationshipWithNestedAttributes = { - ...report, - claim, + ...filed, + report, post: null, comment: null, user: null, @@ -74,10 +74,10 @@ export default { let reports, orderByClause switch (params.orderBy) { case 'createdAt_asc': - orderByClause = 'ORDER BY claim.createdAt ASC, report.createdAt DESC' + orderByClause = 'ORDER BY report.createdAt ASC, filed.createdAt DESC' break case 'createdAt_desc': - orderByClause = 'ORDER BY claim.createdAt DESC, report.createdAt DESC' + orderByClause = 'ORDER BY report.createdAt DESC, filed.createdAt DESC' break default: orderByClause = '' @@ -85,9 +85,9 @@ export default { const readTxPromise = session.readTransaction(async tx => { const allReportsTransactionResponse = await tx.run( ` - MATCH (submitter:User)-[report:REPORTED]->(claim:Claim)-[:BELONGS_TO]->(resource) + MATCH (submitter:User)-[filed:FILED]->(report:Report)-[:BELONGS_TO]->(resource) WHERE resource:User OR resource:Post OR resource:Comment - RETURN submitter, report, claim, resource, labels(resource)[0] as type + RETURN submitter, report, filed, resource, labels(resource)[0] as type ${orderByClause} `, {}, @@ -95,7 +95,7 @@ export default { return allReportsTransactionResponse.records.map(record => ({ submitter: record.get('submitter').properties, report: record.get('report').properties, - claim: record.get('claim').properties, + filed: record.get('filed').properties, resource: record.get('resource').properties, type: record.get('type'), })) @@ -104,10 +104,10 @@ export default { const txResult = await readTxPromise if (!txResult[0]) return null reports = txResult.map(reportedRecord => { - const { report, submitter, claim, resource, type } = reportedRecord + const { report, submitter, filed, resource, type } = reportedRecord const relationshipWithNestedAttributes = { ...report, - claim, + filed, post: null, comment: null, user: null, diff --git a/backend/src/schema/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.js index 6f0edc9e3..adf9048f0 100644 --- a/backend/src/schema/resolvers/reports.spec.js +++ b/backend/src/schema/resolvers/reports.spec.js @@ -8,12 +8,12 @@ const factory = Factory() const instance = getNeode() const driver = getDriver() -describe('report resources', () => { +describe('file a report on a resource', () => { let authenticatedUser, currentUser, mutate, query, moderator, abusiveUser, otherReportingUser const categoryIds = ['cat9'] const reportMutation = gql` mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report( + fileReport( resourceId: $resourceId reasonCategory: $reasonCategory reasonDescription: $reasonDescription @@ -34,7 +34,7 @@ describe('report resources', () => { comment { content } - claim { + report { id createdAt updatedAt @@ -74,7 +74,7 @@ describe('report resources', () => { it('throws authorization error', async () => { authenticatedUser = null await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({ - data: { report: null }, + data: { fileReport: null }, errors: [{ message: 'Not Authorised!' }], }) }) @@ -112,14 +112,14 @@ describe('report resources', () => { describe('invalid resource id', () => { it('returns null', async () => { await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({ - data: { report: null }, + data: { fileReport: null }, errors: undefined, }) }) }) describe('valid resource', () => { - describe('creates claim', () => { + describe('creates report', () => { it('which belongs to resource', async () => { await expect( mutate({ @@ -128,9 +128,9 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { type: 'User', - claim: { + report: { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), @@ -143,7 +143,7 @@ describe('report resources', () => { }) }) - it('creates only one claim for multiple reports on the same resource', async () => { + it('creates only one report for multiple reports on the same resource', async () => { const firstReport = await mutate({ mutation: reportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, @@ -153,7 +153,7 @@ describe('report resources', () => { mutation: reportMutation, variables: { ...variables, resourceId: 'abusive-user-id' }, }) - expect(firstReport.data.report.claim).toEqual(secondReport.data.report.claim) + expect(firstReport.data.fileReport.report).toEqual(secondReport.data.fileReport.report) }) it.todo('creates multiple reports') @@ -168,7 +168,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { type: 'User', }, }, @@ -184,7 +184,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { user: { name: 'abusive-user', }, @@ -202,7 +202,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { submitter: { email: 'test@example.org', }, @@ -220,7 +220,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { createdAt: expect.any(String), }, }, @@ -240,7 +240,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { reasonCategory: 'criminal_behavior_violation_german_law', }, }, @@ -281,7 +281,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { reasonDescription: 'My reason!', }, }, @@ -301,7 +301,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { reasonDescription: 'My reason !', }, }, @@ -331,7 +331,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { type: 'Post', }, }, @@ -350,7 +350,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { post: { title: 'This is a post that is going to be reported', }, @@ -371,7 +371,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { user: null, }, }, @@ -409,7 +409,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { type: 'Comment', }, }, @@ -428,7 +428,7 @@ describe('report resources', () => { }), ).resolves.toMatchObject({ data: { - report: { + fileReport: { comment: { content: 'Post comment to be reported.', }, @@ -456,7 +456,7 @@ describe('report resources', () => { }, }), ).resolves.toMatchObject({ - data: { report: null }, + data: { fileReport: null }, errors: undefined, }) }) @@ -485,7 +485,7 @@ describe('report resources', () => { comment { id } - claim { + report { id createdAt updatedAt @@ -614,7 +614,7 @@ describe('report resources', () => { }), post: null, comment: null, - claim: { + report: { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), @@ -635,7 +635,7 @@ describe('report resources', () => { id: 'abusive-post-1', }), comment: null, - claim: { + report: { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), @@ -656,7 +656,7 @@ describe('report resources', () => { comment: expect.objectContaining({ id: 'abusive-comment-1', }), - claim: { + report: { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), diff --git a/backend/src/schema/resolvers/user_management.spec.js b/backend/src/schema/resolvers/user_management.spec.js index d88583ebb..fc7e21e6f 100644 --- a/backend/src/schema/resolvers/user_management.spec.js +++ b/backend/src/schema/resolvers/user_management.spec.js @@ -22,7 +22,7 @@ const disable = async id => { await mutate({ mutation: gql` mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report( + fileReport( resourceId: $resourceId reasonCategory: $reasonCategory reasonDescription: $reasonDescription diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 2a43a215f..7a9a1f0bc 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -3,7 +3,7 @@ import fileUpload from './fileUpload' import { neode } from '../../bootstrap/neo4j' import { UserInputError, ForbiddenError } from 'apollo-server' import Resolver from './helpers/Resolver' -import { queryReviewedByModerator } from './helpers/claimResource.js' +import { queryReviewedByModerator } from './helpers/reportResource.js' const instance = neode() diff --git a/backend/src/schema/types/type/Claim.gql b/backend/src/schema/types/type/Claim.gql deleted file mode 100644 index 23e052308..000000000 --- a/backend/src/schema/types/type/Claim.gql +++ /dev/null @@ -1,12 +0,0 @@ -type Claim { - id: ID! - createdAt: String! - updatedAt: String! - rule: ClaimRule! - disable: Boolean! - closed: Boolean! -} - -enum ClaimRule { - latestReviewUpdatedAtRules -} diff --git a/backend/src/schema/types/type/Comment.gql b/backend/src/schema/types/type/Comment.gql index b14c9c600..23ab3aae0 100644 --- a/backend/src/schema/types/type/Comment.gql +++ b/backend/src/schema/types/type/Comment.gql @@ -50,9 +50,9 @@ type Comment { reviewedByModerator: User @cypher( statement: """ - MATCH (this)<-[:BELONGS_TO]-(claim:Claim)<-[review:REVIEWED]-(moderator:User) + MATCH (this)<-[:BELONGS_TO]-(report:Report)<-[review:REVIEWED]-(moderator:User) RETURN moderator - ORDER BY claim.updatedAt DESC, review.updatedAt DESC + ORDER BY report.updatedAt DESC, review.updatedAt DESC LIMIT 1 """ ) diff --git a/backend/src/schema/types/type/REPORTED.gql b/backend/src/schema/types/type/FILED.gql similarity index 55% rename from backend/src/schema/types/type/REPORTED.gql rename to backend/src/schema/types/type/FILED.gql index f610a657c..326188660 100644 --- a/backend/src/schema/types/type/REPORTED.gql +++ b/backend/src/schema/types/type/FILED.gql @@ -1,15 +1,15 @@ -type REPORTED { +type FILED { createdAt: String! reasonCategory: ReasonCategory! reasonDescription: String! - claim: Claim @cypher( - statement: "MATCH (resource)<-[:BELONGS_TO]-(claim:Claim)<-[:REPORTED]-(:User) WHERE NOT resource.deleted = true AND NOT resource.disabled = true RETURN claim" + report: Report @cypher( + statement: "MATCH (resource)<-[:BELONGS_TO]-(report:Report)<-[:FILED]-(:User) WHERE NOT resource.deleted = true AND NOT resource.disabled = true RETURN report" ) submitter: User - # @cypher(statement: "MATCH (resource)<-[:REPORTED]-(user:User) RETURN user") + # @cypher(statement: "MATCH (resource)<-[:FILED]-(user:User) RETURN user") type: String - # @cypher(statement: "MATCH (resource)<-[:REPORTED]-(user:User) RETURN labels(resource)[0]") + # @cypher(statement: "MATCH (resource)<-[:FILED]-(user:User) RETURN labels(resource)[0]") user: User post: Post comment: Comment @@ -36,9 +36,9 @@ enum ReportOrdering { } type Query { - reports(orderBy: ReportOrdering): [REPORTED] + reports(orderBy: ReportOrdering): [FILED] } type Mutation { - report(resourceId: ID!, reasonCategory: ReasonCategory!, reasonDescription: String!): REPORTED + fileReport(resourceId: ID!, reasonCategory: ReasonCategory!, reasonDescription: String!): FILED } diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index dfcb7a0fc..eb6ab845a 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -124,9 +124,9 @@ type Post { reviewedByModerator: User @cypher( statement: """ - MATCH (this)<-[:BELONGS_TO]-(claim:Claim)<-[review:REVIEWED]-(moderator:User) + MATCH (this)<-[:BELONGS_TO]-(report:Report)<-[review:REVIEWED]-(moderator:User) RETURN moderator - ORDER BY claim.updatedAt DESC, review.updatedAt DESC + ORDER BY report.updatedAt DESC, review.updatedAt DESC LIMIT 1 """ ) diff --git a/backend/src/schema/types/type/REVIEWED.gql b/backend/src/schema/types/type/REVIEWED.gql index 3babae152..c296483ea 100644 --- a/backend/src/schema/types/type/REVIEWED.gql +++ b/backend/src/schema/types/type/REVIEWED.gql @@ -6,11 +6,11 @@ type REVIEWED { disable: Boolean! closed: Boolean! - claimId: ID! - claimCreatedAt: String! - claimUpdatedAt: String! - claimDisable: Boolean! - claimClosed: Boolean! + reportId: ID! + reportCreatedAt: String! + reportUpdatedAt: String! + reportDisable: Boolean! + reportClosed: Boolean! moderator: User type: String diff --git a/backend/src/schema/types/type/Report.gql b/backend/src/schema/types/type/Report.gql new file mode 100644 index 000000000..8bbbf096c --- /dev/null +++ b/backend/src/schema/types/type/Report.gql @@ -0,0 +1,16 @@ +type Report { + id: ID! + createdAt: String! + updatedAt: String! + rule: ReportRule! + disable: Boolean! + closed: Boolean! + resource: ReportResource + filed: [FILED] +} +# not yet supported +union ReportResource = User | Post | Comment + +enum ReportRule { + latestReviewUpdatedAtRules +} diff --git a/backend/src/schema/types/type/User.gql b/backend/src/schema/types/type/User.gql index 13f9d0cd3..499718e21 100644 --- a/backend/src/schema/types/type/User.gql +++ b/backend/src/schema/types/type/User.gql @@ -36,9 +36,9 @@ type User { reviewedByModerator: User @cypher( statement: """ - MATCH (this)<-[:BELONGS_TO]-(claim:Claim)<-[review:REVIEWED]-(moderator:User) + MATCH (this)<-[:BELONGS_TO]-(report:Report)<-[review:REVIEWED]-(moderator:User) RETURN moderator - ORDER BY claim.updatedAt DESC, review.updatedAt DESC + ORDER BY report.updatedAt DESC, review.updatedAt DESC LIMIT 1 """ ) diff --git a/backend/src/seed/factories/index.js b/backend/src/seed/factories/index.js index 27ec83621..606f569f4 100644 --- a/backend/src/seed/factories/index.js +++ b/backend/src/seed/factories/index.js @@ -10,7 +10,7 @@ import createLocation from './locations.js' import createEmailAddress from './emailAddresses.js' import createDonations from './donations.js' import createUnverifiedEmailAddresss from './unverifiedEmailAddresses.js' -import createClaim from './claims.js' +import createReport from './reports.js' const factories = { Badge: createBadge, @@ -24,7 +24,7 @@ const factories = { EmailAddress: createEmailAddress, UnverifiedEmailAddress: createUnverifiedEmailAddresss, Donations: createDonations, - Claim: createClaim, + Report: createReport, } export const cleanDatabase = async (options = {}) => { diff --git a/backend/src/seed/factories/claims.js b/backend/src/seed/factories/reports.js similarity index 68% rename from backend/src/seed/factories/claims.js rename to backend/src/seed/factories/reports.js index 0c18da783..e2d5ec4dc 100644 --- a/backend/src/seed/factories/claims.js +++ b/backend/src/seed/factories/reports.js @@ -1,7 +1,7 @@ export default function create() { return { factory: async ({ args, neodeInstance }) => { - return neodeInstance.create('Claim', args) + return neodeInstance.create('Report', args) }, } } diff --git a/backend/src/seed/seed-db.js b/backend/src/seed/seed-db.js index 6c0674d73..cf701f89b 100644 --- a/backend/src/seed/seed-db.js +++ b/backend/src/seed/seed-db.js @@ -524,7 +524,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] ]) authenticatedUser = null - await Promise.all([ + const comments = await Promise.all([ factory.create('Comment', { author: jennyRostock, id: 'c1', @@ -581,6 +581,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] postId: 'p15', }), ]) + const trollingComment = comments[0] await Promise.all([ democracy.relateTo(p3, 'post'), @@ -644,236 +645,334 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] louie.relateTo(p10, 'shouted'), ]) - // There is no error logged or the 'try' fails if this mutation is wrong. Why? - const reportMutation = gql` - mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report( - resourceId: $resourceId - reasonCategory: $reasonCategory - reasonDescription: $reasonDescription - ) { - type - } - } - ` - authenticatedUser = await huey.toJson() + const reports = await Promise.all([ + factory.create('Report'), + factory.create('Report'), + factory.create('Report'), + ]) + const reportAgainstDagobert = reports[0] + const reportAgainstTrollingPost = reports[1] + const reportAgainstTrollingComment = reports[2] + // report resource first time await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p11', - reasonCategory: 'discrimination_etc', - reasonDescription: 'I am what I am !!!', - }, + reportAgainstDagobert.relateTo(jennyRostock, 'filed', { + resourceId: 'u7', + reasonCategory: 'discrimination_etc', + reasonDescription: 'This user is harassing me with bigoted remarks!', }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'c5', - reasonCategory: 'doxing', - reasonDescription: "This shouldn't be shown to anybody else! It's my privat thing!", - }, + reportAgainstDagobert.relateTo(dagobert, 'belongsTo'), + reportAgainstTrollingPost.relateTo(jennyRostock, 'filed', { + resourceId: 'p2', + reasonCategory: 'doxing', + reasonDescription: "This shouldn't be shown to anybody else! It's my private thing!", }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'c1', - reasonCategory: 'other', - reasonDescription: 'This comment is bigoted', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p1', - reasonCategory: 'discrimination_etc', - reasonDescription: 'This post is bigoted', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'doxing', - reasonDescription: 'OMG my data !!!', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'u1', - reasonCategory: 'doxing', - reasonDescription: 'This user is harassing me with bigoted remarks', - }, + reportAgainstTrollingPost.relateTo(p2, 'belongsTo'), + reportAgainstTrollingComment.relateTo(huey, 'filed', { + resourceId: 'c1', + reasonCategory: 'other', + reasonDescription: 'This comment is bigoted', }), + reportAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'), + ]) + + // report resource a second time + await Promise.all([ + reportAgainstDagobert.relateTo(louie, 'filed', { + resourceId: 'u7', + reasonCategory: 'discrimination_etc', + reasonDescription: 'this user is attacking me for who I am!', + }), + reportAgainstDagobert.relateTo(dagobert, 'belongsTo'), + reportAgainstTrollingPost.relateTo(peterLustig, 'filed', { + resourceId: 'p2', + reasonCategory: 'discrimination_etc', + reasonDescription: 'This post is bigoted', + }), + reportAgainstTrollingPost.relateTo(p2, 'belongsTo'), + + reportAgainstTrollingComment.relateTo(bobDerBaumeister, 'filed', { + resourceId: 'c1', + reasonCategory: 'pornographic_content_links', + reasonDescription: 'This comment is porno!!!', + }), + reportAgainstTrollingComment.relateTo(trollingComment, 'belongsTo'), ]) - // report resource a second time - authenticatedUser = await dewey.toJson() - await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'c5', - reasonCategory: 'doxing', - reasonDescription: "That's my friends privat data!", - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'c1', - reasonCategory: 'pornographic_content_links', - reasonDescription: 'This comment is porno!!!', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p1', - reasonCategory: 'intentional_intimidation_stalking_persecution', - reasonDescription: '', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'intentional_intimidation_stalking_persecution', - reasonDescription: '', - }, - }), - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'u1', - reasonCategory: 'glorific_trivia_of_cruel_inhuman_acts', - reasonDescription: 'murder', - }, - }), - ]) - authenticatedUser = null - // only review resource after report !!! - const reviewMutation = gql` - mutation($resourceId: ID!, $disable: Boolean, $closed: Boolean) { - review(resourceId: $resourceId, disable: $disable, closed: $closed) { - disable - } - } - ` const disableVariables = { resourceId: 'undefined-resource', disable: true, closed: false, } + // review resource first time - authenticatedUser = await bobDerBaumeister.toJson() await Promise.all([ - mutate({ - mutation: reviewMutation, - variables: { - ...disableVariables, - resourceId: 'p2', - }, + reportAgainstDagobert.relateTo(bobDerBaumeister, 'reviewed', { + ...disableVariables, + resourceId: 'u7', }), - mutate({ - mutation: reviewMutation, - variables: { - ...disableVariables, - resourceId: 'p11', - }, + dagobert.update({ disabled: true, updatedAt: new Date().toISOString() }), + reportAgainstTrollingPost.relateTo(peterLustig, 'reviewed', { + ...disableVariables, + resourceId: 'p2', }), - mutate({ - mutation: reviewMutation, - variables: { - ...disableVariables, - resourceId: 'c5', - closed: true, - }, + p2.update({ disabled: true, updatedAt: new Date().toISOString() }), + reportAgainstTrollingComment.relateTo(bobDerBaumeister, 'reviewed', { + ...disableVariables, + resourceId: 'c1', }), + trollingComment.update({ disabled: true, updatedAt: new Date().toISOString() }), ]) - // second review of resource and close claim - authenticatedUser = await peterLustig.toJson() - await Promise.all([ - mutate({ - mutation: reviewMutation, - variables: { - ...disableVariables, - resourceId: 'p2', - disable: false, - closed: true, - }, - }), - ]) - authenticatedUser = null - // report resource after closing of the claim - authenticatedUser = await bobDerBaumeister.toJson() + // second review of resource and close report await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'doxing', - reasonDescription: "That's my friends privat data!", - }, + reportAgainstDagobert.relateTo(peterLustig, 'reviewed', { + resourceId: 'u7', + disable: false, + closed: true, }), - ]) - // report resource second time after closing of the claim - authenticatedUser = await jennyRostock.toJson() - await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'doxing', - reasonDescription: 'I think it is my friends data!', - }, + dagobert.update({ disabled: false, updatedAt: new Date().toISOString(), closed: true }), + reportAgainstTrollingPost.relateTo(bobDerBaumeister, 'reviewed', { + resourceId: 'p2', + disable: true, + closed: true, }), + p2.update({ disabled: true, updatedAt: new Date().toISOString(), closed: true }), + reportAgainstTrollingComment.relateTo(peterLustig, 'reviewed', { + ...disableVariables, + resourceId: 'c1', + disable: true, + closed: true, + }), + trollingComment.update({ disabled: true, updatedAt: new Date().toISOString(), closed: true }), ]) - authenticatedUser = null - // third review of resource and close claim - authenticatedUser = await bobDerBaumeister.toJson() - await Promise.all([ - mutate({ - mutation: reviewMutation, - variables: { - ...disableVariables, - resourceId: 'p2', - disable: true, - closed: true, - }, - }), - ]) - authenticatedUser = null + // There is no error logged or the 'try' fails if this mutation is wrong. Why? + // const reportMutation = gql` + // mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { + // report( + // resourceId: $resourceId + // reasonCategory: $reasonCategory + // reasonDescription: $reasonDescription + // ) { + // type + // } + // } + // ` + // authenticatedUser = await huey.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p11', + // reasonCategory: 'discrimination_etc', + // reasonDescription: 'I am what I am !!!', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'c5', + // reasonCategory: 'doxing', + // reasonDescription: "This shouldn't be shown to anybody else! It's my privat thing!", + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'c1', + // reasonCategory: 'other', + // reasonDescription: 'This comment is bigoted', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p1', + // reasonCategory: 'discrimination_etc', + // reasonDescription: 'This post is bigoted', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'doxing', + // reasonDescription: 'OMG my data !!!', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'u1', + // reasonCategory: 'doxing', + // reasonDescription: 'This user is harassing me with bigoted remarks', + // }, + // }), + // ]) + // authenticatedUser = await dewey.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'c5', + // reasonCategory: 'doxing', + // reasonDescription: "That's my friends privat data!", + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'c1', + // reasonCategory: 'pornographic_content_links', + // reasonDescription: 'This comment is porno!!!', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p1', + // reasonCategory: 'intentional_intimidation_stalking_persecution', + // reasonDescription: '', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'intentional_intimidation_stalking_persecution', + // reasonDescription: '', + // }, + // }), + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'u1', + // reasonCategory: 'glorific_trivia_of_cruel_inhuman_acts', + // reasonDescription: 'murder', + // }, + // }), + // ]) + // authenticatedUser = null - // report resource after second closing of the claim - authenticatedUser = await huey.toJson() - await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'doxing', - reasonDescription: "That's my privat data!", - }, - }), - ]) - // report resource second time after second closing of the claim - authenticatedUser = await jennyRostock.toJson() - await Promise.all([ - mutate({ - mutation: reportMutation, - variables: { - resourceId: 'p2', - reasonCategory: 'doxing', - reasonDescription: 'I think it is my friends data again!', - }, - }), - ]) - authenticatedUser = null + // only review resource after report !!! + // const reviewMutation = gql` + // mutation($resourceId: ID!, $disable: Boolean, $closed: Boolean) { + // review(resourceId: $resourceId, disable: $disable, closed: $closed) { + // disable + // } + // } + // ` + // const disableVariables = { + // resourceId: 'undefined-resource', + // disable: true, + // closed: false, + // } + // authenticatedUser = await bobDerBaumeister.toJson() + // await Promise.all([ + // mutate({ + // mutation: reviewMutation, + // variables: { + // ...disableVariables, + // resourceId: 'p2', + // }, + // }), + // mutate({ + // mutation: reviewMutation, + // variables: { + // ...disableVariables, + // resourceId: 'p11', + // }, + // }), + // mutate({ + // mutation: reviewMutation, + // variables: { + // ...disableVariables, + // resourceId: 'c5', + // closed: true, + // }, + // }), + // ]) + // authenticatedUser = await peterLustig.toJson() + // await Promise.all([ + // mutate({ + // mutation: reviewMutation, + // variables: { + // ...disableVariables, + // resourceId: 'p2', + // disable: false, + // closed: true, + // }, + // }), + // ]) + // authenticatedUser = null + + // report resource after closing of the report + // authenticatedUser = await bobDerBaumeister.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'doxing', + // reasonDescription: "That's my friends privat data!", + // }, + // }), + // ]) + // // report resource second time after closing of the report + // authenticatedUser = await jennyRostock.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'doxing', + // reasonDescription: 'I think it is my friends data!', + // }, + // }), + // ]) + // authenticatedUser = null + + // // third review of resource and close report + // authenticatedUser = await bobDerBaumeister.toJson() + // await Promise.all([ + // mutate({ + // mutation: reviewMutation, + // variables: { + // ...disableVariables, + // resourceId: 'p2', + // disable: true, + // closed: true, + // }, + // }), + // ]) + // authenticatedUser = null + + // // report resource after second closing of the report + // authenticatedUser = await huey.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'doxing', + // reasonDescription: "That's my privat data!", + // }, + // }), + // ]) + // // report resource second time after second closing of the report + // authenticatedUser = await jennyRostock.toJson() + // await Promise.all([ + // mutate({ + // mutation: reportMutation, + // variables: { + // resourceId: 'p2', + // reasonCategory: 'doxing', + // reasonDescription: 'I think it is my friends data again!', + // }, + // }), + // ]) + // authenticatedUser = null await Promise.all( [...Array(30).keys()].map(i => { diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index 17481befe..5b0f96cb4 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -129,7 +129,7 @@ Given('somebody reported the following posts:', table => { .create('User', submitter) .authenticateAs(submitter) .mutate(`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { + fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { type } }`, { diff --git a/neo4j/change_disabled_relationship_to_claim_node.sh b/neo4j/change_disabled_relationship_to_claim_node.sh index 15d7ce470..9d587d906 100755 --- a/neo4j/change_disabled_relationship_to_claim_node.sh +++ b/neo4j/change_disabled_relationship_to_claim_node.sh @@ -16,23 +16,23 @@ do done echo " -// convert old DISABLED to new REVIEWED-Claim-BELONGS_TO structure +// convert old DISABLED to new REVIEWED-Report-BELONGS_TO structure MATCH (moderator:User)-[disabled:DISABLED]->(disabledResource) WHERE disabledResource:User OR disabledResource:Comment OR disabledResource:Post DELETE disabled -CREATE (moderator)-[review:REVIEWED]->(claim:Claim)-[:BELONGS_TO]->(disabledResource) +CREATE (moderator)-[review:REVIEWED]->(report:Report)-[:BELONGS_TO]->(disabledResource) SET review.createdAt = toString(datetime()), review.updatedAt = review.createdAt, review.disable = true -SET claim.id = randomUUID(), claim.createdAt = toString(datetime()), claim.updatedAt = claim.createdAt, claim.rule = 'latestReviewUpdatedAtRules', claim.disable = true, claim.closed = false +SET report.id = randomUUID(), report.createdAt = toString(datetime()), report.updatedAt = report.createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = true, report.closed = false // if disabledResource has no report, then create a moderators default report -WITH moderator, disabledResource, claim -OPTIONAL MATCH (disabledResourceReporter:User)-[existingReport:REPORTED]->(disabledResource) +WITH moderator, disabledResource, report +OPTIONAL MATCH (disabledResourceReporter:User)-[existingReport:FILED]->(disabledResource) FOREACH(disabledResource IN CASE WHEN existingReport IS NULL THEN [1] ELSE [] END | - CREATE (moderator)-[addModeratorReport:REPORTED]->(claim) + CREATE (moderator)-[addModeratorReport:FILED]->(report) SET addModeratorReport.createdAt = toString(datetime()), addModeratorReport.reasonCategory = 'other', addModeratorReport.reasonDescription = 'Old DISABLED relation had no now mandatory report !!! Created automatically to ensure database consistency! Creation date is when the database manipulation happened.' ) FOREACH(disabledResource IN CASE WHEN existingReport IS NOT NULL THEN [1] ELSE [] END | - CREATE (disabledResourceReporter)-[moveModeratorReport:REPORTED]->(claim) + CREATE (disabledResourceReporter)-[moveModeratorReport:FILED]->(report) SET moveModeratorReport = existingReport DELETE existingReport ) @@ -41,12 +41,12 @@ RETURN disabledResource {.id}; " | cypher-shell echo " -// for REPORTED resources without DISABLED relation which are handled above, create new REPORTED-Claim-BELONGS_TO structure -MATCH (reporter:User)-[oldReport:REPORTED]->(notDisabledResource) +// for FILED resources without DISABLED relation which are handled above, create new FILED-Report-BELONGS_TO structure +MATCH (reporter:User)-[oldReport:FILED]->(notDisabledResource) WHERE notDisabledResource:User OR notDisabledResource:Comment OR notDisabledResource:Post -MERGE (claim:Claim)-[:BELONGS_TO]->(notDisabledResource) -ON CREATE SET claim.id = randomUUID(), claim.createdAt = toString(datetime()), claim.updatedAt = claim.createdAt, claim.rule = 'latestReviewUpdatedAtRules', claim.disable = false, claim.closed = false -CREATE (reporter)-[report:REPORTED]->(claim) +MERGE (report:Report)-[:BELONGS_TO]->(notDisabledResource) +ON CREATE SET report.id = randomUUID(), report.createdAt = toString(datetime()), report.updatedAt = report.createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = false, report.closed = false +CREATE (reporter)-[report:FILED]->(report) SET report = oldReport DELETE oldReport diff --git a/neo4j/storeOldScriptsAsTemplates/change_report_node_to_relationship.sh b/neo4j/storeOldScriptsAsTemplates/change_report_node_to_relationship.sh index 8fb2ad4db..da3a1dad9 100644 --- a/neo4j/storeOldScriptsAsTemplates/change_report_node_to_relationship.sh +++ b/neo4j/storeOldScriptsAsTemplates/change_report_node_to_relationship.sh @@ -16,9 +16,9 @@ do done echo " -MATCH (submitter:User)-[:REPORTED]->(report:Report)-[:REPORTED]->(resource) +MATCH (submitter:User)-[:FILED]->(report:Report)-[:FILED]->(resource) DETACH DELETE report -CREATE (submitter)-[reported:REPORTED]->(resource) +CREATE (submitter)-[reported:FILED]->(resource) SET reported.createdAt = toString(datetime()) SET reported.reasonCategory = 'other' SET reported.reasonDescription = '!!! Created automatically to ensure database consistency! Creation date is when the database manipulation happened.' diff --git a/webapp/constants/modals.js b/webapp/constants/modals.js index f1d08fdc3..6011b8b88 100644 --- a/webapp/constants/modals.js +++ b/webapp/constants/modals.js @@ -1,4 +1,4 @@ -// this list equals to enums in GraphQL schema file "backend/src/schema/types/type/REPORTED.gql" +// this list equals to enums in GraphQL schema file "backend/src/schema/types/type/FILED.gql" export const valuesReasonCategoryOptions = [ 'discrimination_etc', 'pornographic_content_links', diff --git a/webapp/graphql/Moderation.js b/webapp/graphql/Moderation.js index 7e19241bc..ab6edccc2 100644 --- a/webapp/graphql/Moderation.js +++ b/webapp/graphql/Moderation.js @@ -8,7 +8,7 @@ export const reportListQuery = () => { createdAt reasonCategory reasonDescription - claim { + report { id createdAt updatedAt @@ -114,7 +114,7 @@ export const reportListQuery = () => { export const reportMutation = () => { return gql` mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { - report( + fileReport( resourceId: $resourceId reasonCategory: $reasonCategory reasonDescription: $reasonDescription diff --git a/webapp/pages/moderation/index.vue b/webapp/pages/moderation/index.vue index 4914c10e5..1c92610a5 100644 --- a/webapp/pages/moderation/index.vue +++ b/webapp/pages/moderation/index.vue @@ -238,84 +238,84 @@ export default { } }, }, - watch: { - reports: { - immediate: true, - handler(newReports) { - const newResourcesClaims = [] + // watch: { + // reports: { + // immediate: true, + // handler(newReports) { + // const newResourcesClaims = [] + // if (!newReports) return null + // newReports.forEach(report => { + // const resource = + // report.type === 'User' + // ? report.user + // : report.type === 'Post' + // ? report.post + // : report.type === 'Comment' + // ? report.comment + // : undefined + // let idxResource = newResourcesClaims.findIndex( + // resourceClaims => resourceClaims.resource.id === resource.id, + // ) + // // if resource is not in resource list, then add it + // if (idxResource === -1) { + // idxResource = newResourcesClaims.length + // newResourcesClaims.push({ + // type: report.type, + // resource, + // user: report.user, + // post: report.post, + // comment: report.comment, + // contentBelongsToUser: report.type === 'User' ? null : resource.author, + // claims: [], + // }) + // } + // let idxClaim = newResourcesClaims[idxResource].claims.findIndex( + // claim => claim.id === report.claim.id, + // ) + // // if claim is not in claim list, then add it + // if (idxClaim === -1) { + // idxClaim = newResourcesClaims[idxResource].claims.length + // newResourcesClaims[idxResource].claims.push({ + // // it is the same for all reports of a claim + // id: report.claim.id, + // createdAt: report.claim.createdAt, + // updatedAt: report.claim.updatedAt, + // disable: report.claim.disable, + // closed: report.claim.closed, + // reports: [], + // }) + // } + // newResourcesClaims[idxResource].claims[idxClaim].reports.push(report) + // }) - newReports.forEach(report => { - const resource = - report.type === 'User' - ? report.user - : report.type === 'Post' - ? report.post - : report.type === 'Comment' - ? report.comment - : undefined - let idxResource = newResourcesClaims.findIndex( - resourceClaims => resourceClaims.resource.id === resource.id, - ) - // if resource is not in resource list, then add it - if (idxResource === -1) { - idxResource = newResourcesClaims.length - newResourcesClaims.push({ - type: report.type, - resource, - user: report.user, - post: report.post, - comment: report.comment, - contentBelongsToUser: report.type === 'User' ? null : resource.author, - claims: [], - }) - } - let idxClaim = newResourcesClaims[idxResource].claims.findIndex( - claim => claim.id === report.claimId, - ) - // if claim is not in claim list, then add it - if (idxClaim === -1) { - idxClaim = newResourcesClaims[idxResource].claims.length - newResourcesClaims[idxResource].claims.push({ - // it is the same for all reports of a claim - id: report.claimId, - createdAt: report.claimCreatedAt, - updatedAt: report.claimUpdatedAt, - disable: report.claimDisable, - closed: report.claimClosed, - reports: [], - }) - } - newResourcesClaims[idxResource].claims[idxClaim].reports.push(report) - }) + // // sorting of resource claims and their reports + // newResourcesClaims.forEach(resourceClaims => { + // // latestClaim by updatedAt rules + // resourceClaims.claims.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)) + // resourceClaims.latestClaim = { + // id: resourceClaims.claims[0].id, + // createdAt: resourceClaims.claims[0].createdAt, + // updatedAt: resourceClaims.claims[0].updatedAt, + // disable: resourceClaims.claims[0].disable, + // closed: resourceClaims.claims[0].closed, + // } + // // display claims always by starting with latest createdAt + // resourceClaims.claims.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) - // sorting of resource claims and their reports - newResourcesClaims.forEach(resourceClaims => { - // latestClaim by updatedAt rules - resourceClaims.claims.sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)) - resourceClaims.latestClaim = { - id: resourceClaims.claims[0].id, - createdAt: resourceClaims.claims[0].createdAt, - updatedAt: resourceClaims.claims[0].updatedAt, - disable: resourceClaims.claims[0].disable, - closed: resourceClaims.claims[0].closed, - } - // display claims always by starting with latest createdAt - resourceClaims.claims.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) + // resourceClaims.claims.forEach(claim => { + // // display reports always by starting with latest createdAt + // claim.reports.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) + // }) + // }) + // // display resources by starting with claims by their latest createdAt + // newResourcesClaims.sort( + // (a, b) => new Date(b.claims[0].createdAt) - new Date(a.claims[0].createdAt), + // ) - resourceClaims.claims.forEach(claim => { - // display reports always by starting with latest createdAt - claim.reports.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)) - }) - }) - // display resources by starting with claims by their latest createdAt - newResourcesClaims.sort( - (a, b) => new Date(b.claims[0].createdAt) - new Date(a.claims[0].createdAt), - ) - - this.resourcesClaims = newResourcesClaims - }, - }, - }, + // this.resourcesClaims = newResourcesClaims + // }, + // }, + // }, methods: { confirm(resourceClaims) { this.openModal(resourceClaims) @@ -386,7 +386,8 @@ export default { return {} }, update({ reports }) { - return reports + console.log(reports) + // this.resourcesClaims = reports }, fetchPolicy: 'cache-and-network', },