From 09dcd1d5a76700511b39c89de3d2efa1a9c7722c Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 15 May 2023 23:55:16 +0200 Subject: [PATCH 01/19] update neo4j docker file --- neo4j/Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/neo4j/Dockerfile b/neo4j/Dockerfile index dc5a912f0..a88c16c09 100644 --- a/neo4j/Dockerfile +++ b/neo4j/Dockerfile @@ -1,7 +1,7 @@ ################################################################################## # COMMUNITY ###################################################################### ################################################################################## -FROM amd64/neo4j:3.5.14 as community +FROM amd64/neo4j:4.4-community as community # ENVs ## We Cannot do `$(date -u +'%Y-%m-%dT%H:%M:%SZ')` here so we use unix timestamp=0 @@ -31,15 +31,15 @@ LABEL maintainer="devops@ocelot.social" ## install: wget, htop (TODO: why do we need htop?) RUN apt-get update && apt-get -y install wget htop ## install: apoc plugin for neo4j -RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.4/apoc-3.5.0.4-all.jar -P plugins/ +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/4.4.0.17/apoc-4.4.0.17-all.jar -P plugins/ ################################################################################## # ENTERPRISE ##################################################################### ################################################################################## -FROM neo4j:3.5.14-enterprise as enterprise +FROM neo4j:4.4-enterprise as enterprise # Install Additional Software ## install: wget, htop (TODO: why do we need htop?) RUN apt-get update && apt-get -y install wget htop ## install: apoc plugin for neo4j -RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/3.5.0.4/apoc-3.5.0.4-all.jar -P plugins/ \ No newline at end of file +RUN wget https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases/download/4.4.0.17/apoc-4.4.0.17-all.jar -P plugins/ \ No newline at end of file From a9b06e6779e52e483f318d881c589107c2167bb0 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 15 May 2023 23:55:38 +0200 Subject: [PATCH 02/19] allow migration of neo4j database in docker --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index aeb26e4fd..759986d25 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,6 +111,9 @@ services: # TODO: This sounds scary for a production environment - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* + - NEO4J_dbms_connector_http_listen__address=:7474 + - NEO4J_dbms_allow__format__migration=true # TODO enable this in kubernetes setup + - NEO4J_dbms_allow__upgrade=true # TODO enable this in kubernetes setup # Uncomment following line for Neo4j Enterprise version instead of Community version # TODO: clarify if that is the only thing needed to unlock the Enterprise version # - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes From 3c023e877cd801031a6f8afcbdd2c887842019c8 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 15 May 2023 23:55:52 +0200 Subject: [PATCH 03/19] fix broken query due to outdated query format --- backend/src/schema/resolvers/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 1ce3b986f..8a7037397 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -319,7 +319,7 @@ export default { email: async (parent, params, context, resolveInfo) => { if (typeof parent.email !== 'undefined') return parent.email const { id } = parent - const statement = `MATCH(u:User {id: {id}})-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e` + const statement = `MATCH(u:User {id: $id})-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e` const result = await neode.cypher(statement, { id }) const [{ email }] = result.records.map((r) => r.get('e').properties) return email From 168aed6233fbd823aff76c24af53af8477449e1a Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 00:15:41 +0200 Subject: [PATCH 04/19] migrate kubernetes cluster(untested) --- deployment/src/kubernetes/templates/neo4j/ConfigMap.yml | 2 ++ docker-compose.yml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml b/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml index 9f0aa4bee..10edc50f7 100644 --- a/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml +++ b/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml @@ -18,4 +18,6 @@ data: NEO4J_dbms_memory_heap_max__size: "{{ .Values.NEO4J.DBMS_MEMORY_HEAP_MAX_SIZE }}" NEO4J_dbms_memory_pagecache_size: "{{ .Values.NEO4J.DBMS_MEMORY_PAGECACHE_SIZE }}" NEO4J_dbms_security_procedures_unrestricted: "{{ .Values.NEO4J.DBMS_SECURITY_PROCEDURES_UNRESTRICTED }}" + NEO4J_dbms_allow__format__migration: true + NEO4J_dbms_allow__upgrade: true NEO4J_apoc_import_file_enabled: "{{ .Values.NEO4J.APOC_IMPORT_FILE_ENABLED }}" \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 759986d25..1f4e4646f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -112,8 +112,8 @@ services: - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* - NEO4J_dbms_connector_http_listen__address=:7474 - - NEO4J_dbms_allow__format__migration=true # TODO enable this in kubernetes setup - - NEO4J_dbms_allow__upgrade=true # TODO enable this in kubernetes setup + - NEO4J_dbms_allow__format__migration=true + - NEO4J_dbms_allow__upgrade=true # Uncomment following line for Neo4j Enterprise version instead of Community version # TODO: clarify if that is the only thing needed to unlock the Enterprise version # - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes From a326b2777f7b6826d497bd1a5f4afbee98bb0dc9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 00:38:02 +0200 Subject: [PATCH 05/19] fix migrations --- ...te_fulltext_indices_and_unique_keys_for_groups.js | 12 ++++++------ .../20230320130345-fulltext-search-indexes.js | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js index b87e5632a..4c4c145f9 100644 --- a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js +++ b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js @@ -12,12 +12,12 @@ export async function up(next) { try { // Implement your migration here. - await transaction.run(` - CREATE CONSTRAINT ON ( group:Group ) ASSERT group.id IS UNIQUE - `) - await transaction.run(` - CREATE CONSTRAINT ON ( group:Group ) ASSERT group.slug IS UNIQUE - `) + //await transaction.run(` + // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.id IS UNIQUE + //`) + //await transaction.run(` + // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.slug IS UNIQUE + //`) await transaction.run(` CALL db.index.fulltext.createNodeIndex("group_fulltext_search",["Group"],["name", "slug", "about", "description"]) `) diff --git a/backend/src/db/migrations/20230320130345-fulltext-search-indexes.js b/backend/src/db/migrations/20230320130345-fulltext-search-indexes.js index 11029bea6..40ebc6c2e 100644 --- a/backend/src/db/migrations/20230320130345-fulltext-search-indexes.js +++ b/backend/src/db/migrations/20230320130345-fulltext-search-indexes.js @@ -10,7 +10,7 @@ export async function up(next) { try { // Drop indexes if they exist because due to legacy code they might be set already const indexesResponse = await transaction.run(`CALL db.indexes()`) - const indexes = indexesResponse.records.map((record) => record.get('indexName')) + const indexes = indexesResponse.records.map((record) => record.get('name')) if (indexes.indexOf('user_fulltext_search') > -1) { await transaction.run(`CALL db.index.fulltext.drop("user_fulltext_search")`) } From 44700f8a4192474deb9d0e03273836d0ceed1628 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 00:43:37 +0200 Subject: [PATCH 06/19] lint + comment --- ..._fulltext_indices_and_unique_keys_for_groups.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js index 4c4c145f9..63e40c72b 100644 --- a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js +++ b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.js @@ -11,13 +11,13 @@ export async function up(next) { const transaction = session.beginTransaction() try { - // Implement your migration here. - //await transaction.run(` - // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.id IS UNIQUE - //`) - //await transaction.run(` - // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.slug IS UNIQUE - //`) + // Those two indexes already exist + // await transaction.run(` + // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.id IS UNIQUE + // `) + // await transaction.run(` + // CREATE CONSTRAINT ON ( group:Group ) ASSERT group.slug IS UNIQUE + // `) await transaction.run(` CALL db.index.fulltext.createNodeIndex("group_fulltext_search",["Group"],["name", "slug", "about", "description"]) `) From 33b18a5431dae9dcfc0e7bb5db38aec37c288ca9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 11:53:40 +0200 Subject: [PATCH 07/19] fix searches --- backend/src/schema/resolvers/searches.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/src/schema/resolvers/searches.js b/backend/src/schema/resolvers/searches.js index a67abe90d..08825fad0 100644 --- a/backend/src/schema/resolvers/searches.js +++ b/backend/src/schema/resolvers/searches.js @@ -12,7 +12,7 @@ const cypherTemplate = (setup) => ` RETURN ${setup.returnClause} AS result - SKIP $skip + SKIP toInteger($skip) ${setup.limit} ` @@ -45,7 +45,7 @@ const searchPostsSetup = { clickedCount: toString(resource.clickedCount), viewedTeaserCount: toString(resource.viewedTeaserCount) }`, - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const searchUsersSetup = { @@ -54,7 +54,7 @@ const searchUsersSetup = { whereClause: simpleWhereClause, withClause: '', returnClause: 'resource {.*, __typename: labels(resource)[0]}', - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const searchHashtagsSetup = { @@ -63,7 +63,7 @@ const searchHashtagsSetup = { whereClause: simpleWhereClause, withClause: '', returnClause: 'resource {.*, __typename: labels(resource)[0]}', - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const searchGroupsSetup = { @@ -78,7 +78,7 @@ const searchGroupsSetup = { OR membership.role IN ['usual', 'admin', 'owner'])`, withClause: 'WITH resource, membership', returnClause: 'resource { .*, myRole: membership.role, __typename: labels(resource)[0] }', - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const countSetup = { From d86efa0a555144ab60f8e850b55704223da05d77 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 11:54:01 +0200 Subject: [PATCH 08/19] use write permissions for delete queries --- backend/src/schema/resolvers/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 8a7037397..513b1a28f 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -81,7 +81,7 @@ export default { muteUser: async (_parent, params, context, _resolveInfo) => { const { user: currentUser } = context if (currentUser.id === params.id) return null - await neode.cypher( + await neode.writeCypher( ` MATCH(u:User {id: $currentUser.id})-[previousRelationship:FOLLOWS]->(b:User {id: $params.id}) DELETE previousRelationship @@ -98,7 +98,7 @@ export default { unmuteUser: async (_parent, params, context, _resolveInfo) => { const { user: currentUser } = context if (currentUser.id === params.id) return null - await neode.cypher( + await neode.writeCypher( ` MATCH(u:User {id: $currentUser.id})-[previousRelationship:MUTED]->(b:User {id: $params.id}) DELETE previousRelationship From c2583bad0cba6ef66e42146aeff10200a95f9810 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 11:54:10 +0200 Subject: [PATCH 09/19] new query format --- backend/src/schema/resolvers/registration.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js index bfc6a5fa6..54e7f1ba7 100644 --- a/backend/src/schema/resolvers/registration.spec.js +++ b/backend/src/schema/resolvers/registration.spec.js @@ -251,7 +251,7 @@ describe('SignupVerification', () => { it('connects User with EmailAddress', async () => { const cypher = ` - MATCH(email:EmailAddress)-[:BELONGS_TO]->(u:User {name: {name}}) + MATCH(email:EmailAddress)-[:BELONGS_TO]->(u:User {name: $name}) RETURN email ` await mutate({ mutation, variables }) @@ -281,7 +281,7 @@ describe('SignupVerification', () => { it('marks the EmailAddress as primary', async () => { const cypher = ` - MATCH(email:EmailAddress)<-[:PRIMARY_EMAIL]-(u:User {name: {name}}) + MATCH(email:EmailAddress)<-[:PRIMARY_EMAIL]-(u:User {name: $name}) RETURN email ` await mutate({ mutation, variables }) From 46af4d80d01c76f177bcafa2f303545577cc29f8 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 11:54:22 +0200 Subject: [PATCH 10/19] new query format --- backend/src/schema/resolvers/follow.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/follow.spec.js b/backend/src/schema/resolvers/follow.spec.js index 0d9d524ff..c9d8dc1bf 100644 --- a/backend/src/schema/resolvers/follow.spec.js +++ b/backend/src/schema/resolvers/follow.spec.js @@ -147,7 +147,7 @@ describe('follow', () => { variables, }) const relation = await neode.cypher( - 'MATCH (user:User {id: {id}})-[relationship:FOLLOWS]->(followed:User) WHERE relationship.createdAt IS NOT NULL RETURN relationship', + 'MATCH (user:User {id: $id})-[relationship:FOLLOWS]->(followed:User) WHERE relationship.createdAt IS NOT NULL RETURN relationship', { id: 'u1' }, ) const relationshipProperties = relation.records.map( From 5e758328f1db735c842830d4f40a7ed1b29ab303 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 11:54:36 +0200 Subject: [PATCH 11/19] write query for delete operations --- backend/src/schema/resolvers/follow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/follow.js b/backend/src/schema/resolvers/follow.js index 80cce8400..6cf4938c7 100644 --- a/backend/src/schema/resolvers/follow.js +++ b/backend/src/schema/resolvers/follow.js @@ -29,7 +29,7 @@ export default { * It's suggested to use query builder feature (https://github.com/adam-cowley/neode/issues/67) * However, pure cypher query looks cleaner IMO */ - await neode.cypher( + await neode.writeCypher( `MATCH (user:User {id: $currentUser.id})-[relation:FOLLOWS]->(followedUser:User {id: $followedUserId}) DELETE relation RETURN COUNT(relation) > 0 as isFollowed`, From 4ce324cba23ca0ecd881cf90eb6d75d015de1d64 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Tue, 16 May 2023 12:11:21 +0200 Subject: [PATCH 12/19] corrected old query format --- backend/src/schema/resolvers/comments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/comments.js b/backend/src/schema/resolvers/comments.js index a3a0c7290..c6f07245c 100644 --- a/backend/src/schema/resolvers/comments.js +++ b/backend/src/schema/resolvers/comments.js @@ -21,7 +21,7 @@ export default { MATCH (post:Post {id: $postId}) MATCH (author:User {id: $userId}) WITH post, author - CREATE (comment:Comment {params}) + CREATE (comment:Comment $params) SET comment.createdAt = toString(datetime()) SET comment.updatedAt = toString(datetime()) MERGE (post)<-[:COMMENTS]-(comment)<-[:WROTE]-(author) From 144d39b35aea94a495ac29f0468cab2dcb0ca1ed Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 22 May 2023 15:58:19 +0200 Subject: [PATCH 13/19] fixed updatedAt field for fileReport --- backend/src/schema/resolvers/reports.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/reports.js b/backend/src/schema/resolvers/reports.js index da8d794c5..da61e6f10 100644 --- a/backend/src/schema/resolvers/reports.js +++ b/backend/src/schema/resolvers/reports.js @@ -13,7 +13,7 @@ export default { MATCH (resource {id: $resourceId}) WHERE resource:User OR resource:Post OR resource:Comment 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 CREATE SET report.id = randomUUID(), report.createdAt = $createdAt, report.updatedAt = $createdAt, report.rule = 'latestReviewUpdatedAtRules', report.disable = resource.disabled, report.closed = false WITH submitter, resource, report CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) From 2204b29c0a9459a1e4a92799064ea9c12522f92d Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 22 May 2023 16:08:50 +0200 Subject: [PATCH 14/19] fixed review updatedAt mutation --- backend/src/schema/resolvers/moderation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/schema/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js index c261d187e..97f48ec43 100644 --- a/backend/src/schema/resolvers/moderation.js +++ b/backend/src/schema/resolvers/moderation.js @@ -12,7 +12,7 @@ export default { MATCH (resource {id: $params.resourceId})<-[:BELONGS_TO]-(report:Report {closed: false}) WHERE resource:User OR resource:Post OR resource:Comment MERGE (report)<-[review:REVIEWED]-(moderator) - ON CREATE SET review.createdAt = $dateTime, review.updatedAt = review.createdAt + ON CREATE SET review.createdAt = $dateTime, review.updatedAt = $dateTime ON MATCH SET review.updatedAt = $dateTime SET review.disable = $params.disable SET report.updatedAt = $dateTime, report.disable = review.disable, report.closed = $params.closed From 8223024c308cc3ed785d9618270a5ab55d16bb03 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 22 May 2023 16:58:04 +0200 Subject: [PATCH 15/19] removed write rights from query where its not needed --- cypress/support/factories.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/support/factories.js b/cypress/support/factories.js index 2ca46c483..f8f86f9f7 100644 --- a/cypress/support/factories.js +++ b/cypress/support/factories.js @@ -9,7 +9,7 @@ const neo4jConfigs = { } const neodeInstance = getNeode(neo4jConfigs) -beforeEach(() => cy.then(() => neodeInstance.cypher('MATCH (everything) DETACH DELETE everything;'))) +beforeEach(() => cy.then(() => neodeInstance.writeCypher('MATCH (everything) DETACH DELETE everything;'))) Cypress.Commands.add('neode', () => { return neodeInstance From 0c4b789da1b956cd7cc1fb011575cd131d7ff96c Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Mon, 22 May 2023 16:58:19 +0200 Subject: [PATCH 16/19] remove write rights where its not needed --- backend/src/middleware/notifications/notificationsMiddleware.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/middleware/notifications/notificationsMiddleware.js b/backend/src/middleware/notifications/notificationsMiddleware.js index 1c97e9591..fd8629715 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.js @@ -15,7 +15,7 @@ const queryNotificationEmails = async (context, notificationUserIds) => { RETURN emailAddress {.email} ` const session = context.driver.session() - const writeTxResultPromise = session.writeTransaction(async (transaction) => { + const writeTxResultPromise = session.readTransaction(async (transaction) => { const emailAddressTransactionResponse = await transaction.run(userEmailCypher, { notificationUserIds, }) From eb6825b6e66e239877906ce81098fc0046a9e6b9 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Fri, 16 Jun 2023 15:14:27 +0200 Subject: [PATCH 17/19] remove listen address 7474 from docker since its default value --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1f4e4646f..41a03a7fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,7 +111,6 @@ services: # TODO: This sounds scary for a production environment - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* - - NEO4J_dbms_connector_http_listen__address=:7474 - NEO4J_dbms_allow__format__migration=true - NEO4J_dbms_allow__upgrade=true # Uncomment following line for Neo4j Enterprise version instead of Community version From df139c9937f8664e0952508bd7a09352d0651ba5 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Fri, 16 Jun 2023 15:34:27 +0200 Subject: [PATCH 18/19] use list comprehension instead of filter(not supported anymore in 4.4) --- .../notifications/notificationsMiddleware.ts | 2 +- .../middleware/validation/validationMiddleware.ts | 2 +- backend/src/schema/resolvers/moderation.ts | 2 +- backend/src/schema/resolvers/notifications.ts | 12 ++++++------ backend/src/schema/resolvers/posts.ts | 4 ++-- backend/src/schema/resolvers/reports.ts | 6 +++--- backend/src/schema/types/type/Post.gql | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/backend/src/middleware/notifications/notificationsMiddleware.ts b/backend/src/middleware/notifications/notificationsMiddleware.ts index 44accbc04..7922af90c 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.ts +++ b/backend/src/middleware/notifications/notificationsMiddleware.ts @@ -238,7 +238,7 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => { [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts WITH resource, user, notification, authors, posts, - resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0]} AS finalResource + resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0]} AS finalResource SET notification.read = FALSE SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime())) SET notification.updatedAt = toString(datetime()) diff --git a/backend/src/middleware/validation/validationMiddleware.ts b/backend/src/middleware/validation/validationMiddleware.ts index 9a56536e7..ff26f5ef1 100644 --- a/backend/src/middleware/validation/validationMiddleware.ts +++ b/backend/src/middleware/validation/validationMiddleware.ts @@ -64,7 +64,7 @@ const validateReview = async (resolve, root, args, context, info) => { WHERE resource:User OR resource:Post OR resource:Comment OPTIONAL MATCH (:User)-[filed:FILED]->(:Report {closed: false})-[:BELONGS_TO]->(resource) OPTIONAL MATCH (resource)<-[:WROTE]-(author:User) - RETURN filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0] AS label, author, filed + RETURN [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User']][0] AS label, author, filed `, { resourceId, diff --git a/backend/src/schema/resolvers/moderation.ts b/backend/src/schema/resolvers/moderation.ts index 4906aea90..a29a411aa 100644 --- a/backend/src/schema/resolvers/moderation.ts +++ b/backend/src/schema/resolvers/moderation.ts @@ -18,7 +18,7 @@ export default { SET report.updatedAt = $dateTime, report.disable = review.disable, report.closed = $params.closed SET resource.disabled = report.disable - WITH review, report, resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0]} AS finalResource + WITH review, report, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User']][0]} AS finalResource RETURN review {.*, report: properties(report), resource: properties(finalResource)} ` const reviewWriteTxResultPromise = session.writeTransaction(async (txc) => { diff --git a/backend/src/schema/resolvers/notifications.ts b/backend/src/schema/resolvers/notifications.ts index 83c4da11b..c443bc812 100644 --- a/backend/src/schema/resolvers/notifications.ts +++ b/backend/src/schema/resolvers/notifications.ts @@ -51,10 +51,10 @@ export default { OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(relatedUser) WITH user, notification, resource, membership, relatedUser, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts WITH resource, user, notification, authors, posts, relatedUser, membership, resource {.*, - __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], + __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource @@ -90,10 +90,10 @@ export default { SET notification.read = TRUE WITH user, notification, resource, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, - resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource + resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource RETURN notification {.*, from: finalResource, to: properties(user)} `, { resourceId: args.id, id: currentUser.id }, @@ -120,10 +120,10 @@ export default { SET notification.read = TRUE WITH user, notification, resource, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, - resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group'])[0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource + resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource RETURN notification {.*, from: finalResource, to: properties(user)} `, { id: currentUser.id }, diff --git a/backend/src/schema/resolvers/posts.ts b/backend/src/schema/resolvers/posts.ts index c9bfca053..b085b4b7c 100644 --- a/backend/src/schema/resolvers/posts.ts +++ b/backend/src/schema/resolvers/posts.ts @@ -146,7 +146,7 @@ export default { MERGE (post)<-[:WROTE]-(author) ${categoriesCypher} ${groupCypher} - RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post") } + RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = "Post"] } `, { userId: context.user.id, categoryIds, groupId, params }, ) @@ -214,7 +214,7 @@ export default { ` } - updatePostCypher += `RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post")}` + updatePostCypher += `RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = "Post"]}` const updatePostVariables = { categoryIds, params } try { const writeTxResultPromise = session.writeTransaction(async (transaction) => { diff --git a/backend/src/schema/resolvers/reports.ts b/backend/src/schema/resolvers/reports.ts index a09f52816..237d27dae 100644 --- a/backend/src/schema/resolvers/reports.ts +++ b/backend/src/schema/resolvers/reports.ts @@ -17,7 +17,7 @@ export default { WITH submitter, resource, report CREATE (report)<-[filed:FILED {createdAt: $createdAt, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription}]-(submitter) - WITH filed, report, resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0]} AS finalResource + WITH filed, report, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User']][0]} AS finalResource RETURN filed {.*, reportId: report.id, resource: properties(finalResource)} AS filedReport `, { @@ -92,8 +92,8 @@ export default { [(submitter:User)-[filed:FILED]->(report) | filed {.*, submitter: properties(submitter)} ] as filed, [(moderator:User)-[reviewed:REVIEWED]->(report) | reviewed {.*, moderator: properties(moderator)} ] as reviewed, [(resource)<-[:WROTE]-(author:User) | author {.*} ] as optionalAuthors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: filter(l IN labels(post) WHERE NOT l = "Post")} ] as optionalCommentedPosts, - resource {.*, __typename: filter(l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User'])[0] } as resourceWithType + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post")] ] as optionalCommentedPosts, + resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User']][0] } as resourceWithType WITH report, optionalAuthors, optionalCommentedPosts, reviewed, filed, resourceWithType {.*, post: optionalCommentedPosts[0], author: optionalAuthors[0] } as finalResource RETURN report {.*, resource: finalResource, filed: filed, reviewed: reviewed } diff --git a/backend/src/schema/types/type/Post.gql b/backend/src/schema/types/type/Post.gql index 7c93c0b73..0a7277515 100644 --- a/backend/src/schema/types/type/Post.gql +++ b/backend/src/schema/types/type/Post.gql @@ -178,7 +178,7 @@ type Post { group: Group @relation(name: "IN", direction: "OUT") postType: [PostType] - @cypher(statement: "RETURN filter(l IN labels(this) WHERE NOT l = 'Post')") + @cypher(statement: "RETURN [l IN labels(this) WHERE NOT l = 'Post']") eventLocationName: String eventLocation: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l") From 75bd7dbc3636ff9b2cb96db909c573a57bdfe597 Mon Sep 17 00:00:00 2001 From: Ulf Gebhardt Date: Fri, 16 Jun 2023 23:00:59 +0200 Subject: [PATCH 19/19] fixed report queries --- backend/src/schema/resolvers/notifications.ts | 6 +++--- backend/src/schema/resolvers/posts.ts | 4 ++-- backend/src/schema/resolvers/reports.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/backend/src/schema/resolvers/notifications.ts b/backend/src/schema/resolvers/notifications.ts index c443bc812..e427de227 100644 --- a/backend/src/schema/resolvers/notifications.ts +++ b/backend/src/schema/resolvers/notifications.ts @@ -51,7 +51,7 @@ export default { OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(relatedUser) WITH user, notification, resource, membership, relatedUser, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = 'Post']} ] AS posts WITH resource, user, notification, authors, posts, relatedUser, membership, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], @@ -90,7 +90,7 @@ export default { SET notification.read = TRUE WITH user, notification, resource, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = 'Post']} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0], myRole: membership.role } AS finalResource @@ -120,7 +120,7 @@ export default { SET notification.read = TRUE WITH user, notification, resource, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post"]} ] AS posts + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = 'Post']} ] AS posts OPTIONAL MATCH (resource)<-[membership:MEMBER_OF]-(user) WITH resource, user, notification, authors, posts, membership, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'Group']][0], author: authors[0], post: posts[0], myRole: membership.role} AS finalResource diff --git a/backend/src/schema/resolvers/posts.ts b/backend/src/schema/resolvers/posts.ts index b085b4b7c..0bd4507b5 100644 --- a/backend/src/schema/resolvers/posts.ts +++ b/backend/src/schema/resolvers/posts.ts @@ -146,7 +146,7 @@ export default { MERGE (post)<-[:WROTE]-(author) ${categoriesCypher} ${groupCypher} - RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = "Post"] } + RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = 'Post'] } `, { userId: context.user.id, categoryIds, groupId, params }, ) @@ -214,7 +214,7 @@ export default { ` } - updatePostCypher += `RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = "Post"]}` + updatePostCypher += `RETURN post {.*, postType: [l IN labels(post) WHERE NOT l = 'Post']}` const updatePostVariables = { categoryIds, params } try { const writeTxResultPromise = session.writeTransaction(async (transaction) => { diff --git a/backend/src/schema/resolvers/reports.ts b/backend/src/schema/resolvers/reports.ts index 237d27dae..f7945e060 100644 --- a/backend/src/schema/resolvers/reports.ts +++ b/backend/src/schema/resolvers/reports.ts @@ -92,7 +92,7 @@ export default { [(submitter:User)-[filed:FILED]->(report) | filed {.*, submitter: properties(submitter)} ] as filed, [(moderator:User)-[reviewed:REVIEWED]->(report) | reviewed {.*, moderator: properties(moderator)} ] as reviewed, [(resource)<-[:WROTE]-(author:User) | author {.*} ] as optionalAuthors, - [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = "Post")] ] as optionalCommentedPosts, + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post {.*, author: properties(author), postType: [l IN labels(post) WHERE NOT l = 'Post']} ] as optionalCommentedPosts, resource {.*, __typename: [l IN labels(resource) WHERE l IN ['Post', 'Comment', 'User']][0] } as resourceWithType WITH report, optionalAuthors, optionalCommentedPosts, reviewed, filed, resourceWithType {.*, post: optionalCommentedPosts[0], author: optionalAuthors[0] } as finalResource