diff --git a/backend/package.json b/backend/package.json index d4c9cee56..f236338bd 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,7 +13,7 @@ "start": "node build/", "build": "tsc && ./scripts/build.copy.files.sh", "dev": "nodemon --exec ts-node src/ -e js,ts,gql", - "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,gql", + "dev:debug": "nodemon --exec babel-node --inspect=0.0.0.0:9229 src/ -e js,ts,gql", "lint": "eslint src --config .eslintrc.js", "test": "cross-env NODE_ENV=test NODE_OPTIONS=--max-old-space-size=8192 jest --runInBand --coverage --forceExit --detectOpenHandles", "db:clean": "ts-node src/db/clean.ts", diff --git a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts index b87e5632a..63e40c72b 100644 --- a/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts +++ b/backend/src/db/migrations/20220803060819-create_fulltext_indices_and_unique_keys_for_groups.ts @@ -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"]) `) diff --git a/backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts b/backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts index 11029bea6..40ebc6c2e 100644 --- a/backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts +++ b/backend/src/db/migrations/20230320130345-fulltext-search-indexes.ts @@ -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")`) } diff --git a/backend/src/middleware/notifications/notificationsMiddleware.ts b/backend/src/middleware/notifications/notificationsMiddleware.ts index abb8abdc1..7922af90c 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.ts +++ b/backend/src/middleware/notifications/notificationsMiddleware.ts @@ -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, }) @@ -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/comments.ts b/backend/src/schema/resolvers/comments.ts index a3a0c7290..c6f07245c 100644 --- a/backend/src/schema/resolvers/comments.ts +++ b/backend/src/schema/resolvers/comments.ts @@ -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) diff --git a/backend/src/schema/resolvers/follow.spec.ts b/backend/src/schema/resolvers/follow.spec.ts index 0d9d524ff..c9d8dc1bf 100644 --- a/backend/src/schema/resolvers/follow.spec.ts +++ b/backend/src/schema/resolvers/follow.spec.ts @@ -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( diff --git a/backend/src/schema/resolvers/follow.ts b/backend/src/schema/resolvers/follow.ts index 80cce8400..6cf4938c7 100644 --- a/backend/src/schema/resolvers/follow.ts +++ b/backend/src/schema/resolvers/follow.ts @@ -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`, diff --git a/backend/src/schema/resolvers/index.ts b/backend/src/schema/resolvers/index.ts index 57a29a05a..1aeadbea2 100644 --- a/backend/src/schema/resolvers/index.ts +++ b/backend/src/schema/resolvers/index.ts @@ -1,5 +1,6 @@ import path from 'path' import { fileLoader, mergeResolvers } from 'merge-graphql-schemas' -const resolversArray = fileLoader(path.join(__dirname, './!(*.spec).ts')) +// the files must be correctly evaluated in built and dev state - therefore accept both js & ts files +const resolversArray = fileLoader(path.join(__dirname, './!(*.spec).(ts|js)')) export default mergeResolvers(resolversArray) diff --git a/backend/src/schema/resolvers/moderation.ts b/backend/src/schema/resolvers/moderation.ts index b0472070f..a29a411aa 100644 --- a/backend/src/schema/resolvers/moderation.ts +++ b/backend/src/schema/resolvers/moderation.ts @@ -12,13 +12,13 @@ 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 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..e427de227 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..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: 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/registration.spec.ts b/backend/src/schema/resolvers/registration.spec.ts index bfc6a5fa6..54e7f1ba7 100644 --- a/backend/src/schema/resolvers/registration.spec.ts +++ b/backend/src/schema/resolvers/registration.spec.ts @@ -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 }) diff --git a/backend/src/schema/resolvers/reports.ts b/backend/src/schema/resolvers/reports.ts index 414291acb..f7945e060 100644 --- a/backend/src/schema/resolvers/reports.ts +++ b/backend/src/schema/resolvers/reports.ts @@ -13,11 +13,11 @@ 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) - 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/resolvers/searches.ts b/backend/src/schema/resolvers/searches.ts index 83eeb1b2d..fba74ecc7 100644 --- a/backend/src/schema/resolvers/searches.ts +++ b/backend/src/schema/resolvers/searches.ts @@ -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: 'User'}`, - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const searchHashtagsSetup = { @@ -63,7 +63,7 @@ const searchHashtagsSetup = { whereClause: simpleWhereClause, withClause: '', returnClause: `resource {.*, __typename: 'Tag'}`, - 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: 'Group' }`, - limit: 'LIMIT $limit', + limit: 'LIMIT toInteger($limit)', } const countSetup = { diff --git a/backend/src/schema/resolvers/users.ts b/backend/src/schema/resolvers/users.ts index 1ce3b986f..513b1a28f 100644 --- a/backend/src/schema/resolvers/users.ts +++ b/backend/src/schema/resolvers/users.ts @@ -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 @@ -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 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") diff --git a/backend/test/features/support/steps.js b/backend/test/features/support/steps.ts similarity index 99% rename from backend/test/features/support/steps.js rename to backend/test/features/support/steps.ts index e15801f83..c62b286cd 100644 --- a/backend/test/features/support/steps.js +++ b/backend/test/features/support/steps.ts @@ -5,7 +5,7 @@ import { expect } from 'chai' import { GraphQLClient } from 'graphql-request' import Factory from '../../../src/db/factories' const debug = require('debug')('ea:test:steps') - +const host: any = null const client = new GraphQLClient(host) function createUser (slug) { diff --git a/backend/test/features/world.js b/backend/test/features/world.ts similarity index 94% rename from backend/test/features/world.js rename to backend/test/features/world.ts index be436b536..72e120dc7 100644 --- a/backend/test/features/world.js +++ b/backend/test/features/world.ts @@ -4,6 +4,11 @@ import request from 'request' const debug = require('debug')('ea:test:world') class CustomWorld { + lastResponses: any + lastContentType: any + lastInboxUrl: any + lastActivity: any + statusCode: any constructor () { // webFinger.feature this.lastResponses = [] diff --git a/cypress/support/factories.js b/cypress/support/factories.js index 1a55f43ed..825026346 100644 --- a/cypress/support/factories.js +++ b/cypress/support/factories.js @@ -3,7 +3,7 @@ import { getNeode } from '../../backend/build/db/neo4j' const neodeInstance = getNeode() -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 diff --git a/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml b/deployment/src/kubernetes/templates/neo4j/ConfigMap.yml index 9f0aa4bee..f71f11285 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 aeb26e4fd..41a03a7fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -111,6 +111,8 @@ services: # TODO: This sounds scary for a production environment - NEO4J_AUTH=none - NEO4J_dbms_security_procedures_unrestricted=algo.*,apoc.* + - 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 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 diff --git a/package.json b/package.json index b53319396..5a116bd13 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "release": "yarn version --no-git-tag-version --no-commit-hooks --no-commit && auto-changelog --latest-version $(node -p -e \"require('./package.json').version\") && cd backend && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../package.json').version\") && cd ../webapp/maintenance/source && yarn version --no-git-tag-version --no-commit-hooks --no-commit --new-version $(node -p -e \"require('./../../../package.json').version\")" }, "devDependencies": { - "@babel/core": "^7.21.8", + "@babel/core": "^7.22.5", "@babel/preset-env": "^7.22.4", "@babel/register": "^7.12.10", "@badeball/cypress-cucumber-preprocessor": "^15.1.4", @@ -32,7 +32,7 @@ "bcryptjs": "^2.4.3", "cross-env": "^7.0.3", "cucumber": "^6.0.5", - "cypress": "^12.6.0", + "cypress": "^12.14.0", "cypress-file-upload": "^3.5.3", "cypress-network-idle": "^1.14.2", "date-fns": "^2.25.0", diff --git a/webapp/Dockerfile.maintenance b/webapp/Dockerfile.maintenance index a6db9e612..91dc1c832 100644 --- a/webapp/Dockerfile.maintenance +++ b/webapp/Dockerfile.maintenance @@ -1,7 +1,7 @@ ################################################################################## # BASE ########################################################################### ################################################################################## -FROM node:20.2.0-alpine3.17 as base +FROM node:20.3.0-alpine3.17 as base # ENVs ## DOCKER_WORKDIR would be a classical ARG, but that is not multi layer persistent - shame diff --git a/yarn.lock b/yarn.lock index f23a6a189..be628e106 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,21 +10,14 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.22.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.0", "@babel/compat-data@^7.22.3": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.3": version "7.22.3" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.3.tgz#cd502a6a0b6e37d7ad72ce7e71a7160a3ae36f7e" integrity sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ== @@ -34,37 +27,27 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== -"@babel/core@^7.16.0", "@babel/core@^7.21.8": - version "7.22.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.1.tgz#5de51c5206f4c6f5533562838337a603c1033cfd" - integrity sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA== +"@babel/core@^7.16.0", "@babel/core@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" + integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.22.0" - "@babel/helper-compilation-targets" "^7.22.1" - "@babel/helper-module-transforms" "^7.22.1" - "@babel/helpers" "^7.22.0" - "@babel/parser" "^7.22.0" - "@babel/template" "^7.21.9" - "@babel/traverse" "^7.22.1" - "@babel/types" "^7.22.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helpers" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" semver "^6.3.0" -"@babel/generator@^7.22.0", "@babel/generator@^7.22.3": - version "7.22.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.3.tgz#0ff675d2edb93d7596c5f6728b52615cfc0df01e" - integrity sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A== - dependencies: - "@babel/types" "^7.22.3" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - "@babel/generator@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" @@ -103,18 +86,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.1": - version "7.22.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.1.tgz#bfcd6b7321ffebe33290d68550e2c9d7eb7c7a58" - integrity sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ== - dependencies: - "@babel/compat-data" "^7.22.0" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-compilation-targets@^7.22.5": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.1", "@babel/helper-compilation-targets@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== @@ -253,21 +225,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.1": - version "7.22.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.1.tgz#e0cad47fedcf3cae83c11021696376e2d5a50c63" - integrity sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.1" - "@babel/helper-module-imports" "^7.21.4" - "@babel/helper-simple-access" "^7.21.5" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.21.9" - "@babel/traverse" "^7.22.1" - "@babel/types" "^7.22.0" - -"@babel/helper-module-transforms@^7.22.5": +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.1", "@babel/helper-module-transforms@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== @@ -391,17 +349,12 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.21.5": - version "7.21.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd" - integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w== - "@babel/helper-string-parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": +"@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== @@ -441,23 +394,14 @@ "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/helpers@^7.22.0": - version "7.22.3" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.3.tgz#53b74351da9684ea2f694bf0877998da26dd830e" - integrity sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w== +"@babel/helpers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" + integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== dependencies: - "@babel/template" "^7.21.9" - "@babel/traverse" "^7.22.1" - "@babel/types" "^7.22.3" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.5" + "@babel/types" "^7.22.5" "@babel/highlight@^7.22.5": version "7.22.5" @@ -468,12 +412,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.18.8", "@babel/parser@^7.21.9", "@babel/parser@^7.22.0", "@babel/parser@^7.22.4": - version "7.22.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.4.tgz#a770e98fd785c231af9d93f6459d36770993fb32" - integrity sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA== - -"@babel/parser@^7.22.5": +"@babel/parser@^7.18.8", "@babel/parser@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== @@ -1747,16 +1686,7 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.21.9": - version "7.21.9" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.21.9.tgz#bf8dad2859130ae46088a99c1f265394877446fb" - integrity sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/parser" "^7.21.9" - "@babel/types" "^7.21.5" - -"@babel/template@^7.22.5": +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.21.9", "@babel/template@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== @@ -1765,23 +1695,7 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@^7.20.5", "@babel/traverse@^7.22.1": - version "7.22.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.4.tgz#c3cf96c5c290bd13b55e29d025274057727664c0" - integrity sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.22.3" - "@babel/helper-environment-visitor" "^7.22.1" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.22.4" - "@babel/types" "^7.22.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.22.5": +"@babel/traverse@^7.20.5", "@babel/traverse@^7.22.1", "@babel/traverse@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== @@ -1797,16 +1711,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.22.0", "@babel/types@^7.22.3", "@babel/types@^7.22.4", "@babel/types@^7.4.4": - version "7.22.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.4.tgz#56a2653ae7e7591365dabf20b76295410684c071" - integrity sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA== - dependencies: - "@babel/helper-string-parser" "^7.21.5" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@babel/types@^7.22.5": +"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.22.0", "@babel/types@^7.22.3", "@babel/types@^7.22.4", "@babel/types@^7.22.5", "@babel/types@^7.4.4": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== @@ -3259,10 +3164,10 @@ cypress-network-idle@^1.14.2: resolved "https://registry.yarnpkg.com/cypress-network-idle/-/cypress-network-idle-1.14.2.tgz#0837100861feeb5a18f4c2d9815be079f8590f4d" integrity sha512-xAdR8dH58KFPv8eCDWjviScITrJOcUpuMXYfYTc175nk2/NvnJ+I6ylSn1CM7yZmoV/gLbFa36QLiH5NfNEaLQ== -cypress@^12.6.0: - version "12.13.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.13.0.tgz#725b6617ea19e41e5c59cc509fc3e08097142b01" - integrity sha512-QJlSmdPk+53Zhy69woJMySZQJoWfEWun3X5OOenGsXjRPVfByVTHorxNehbzhZrEzH9RDUDqVcck0ahtlS+N/Q== +cypress@^12.14.0: + version "12.14.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.14.0.tgz#37a19b85f5e9d881995e9fee1ddf41b3d3a623dd" + integrity sha512-HiLIXKXZaIT1RT7sw1sVPt+qKtis3uYNm6KwC4qoYjabwLKaqZlyS/P+uVvvlBNcHIwL/BC6nQZajpbUd7hOgQ== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4"