diff --git a/backend/.env.template b/backend/.env.template
index abc62b2dc..e905d1eb6 100644
--- a/backend/.env.template
+++ b/backend/.env.template
@@ -4,7 +4,7 @@ NEO4J_PASSWORD=letmein
GRAPHQL_PORT=4000
GRAPHQL_URI=http://localhost:4000
CLIENT_URI=http://localhost:3000
-MOCK=false
+MOCKS=false
JWT_SECRET="b/&&7b78BF&fv/Vd"
MAPBOX_TOKEN="pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ"
diff --git a/backend/package.json b/backend/package.json
index d8d0408f4..d861f9b6c 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -11,7 +11,7 @@
"lint": "eslint src --config .eslintrc.js",
"test": "run-s test:jest test:cucumber",
"test:before:server": "cross-env GRAPHQL_URI=http://localhost:4123 GRAPHQL_PORT=4123 yarn run dev 2> /dev/null",
- "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DISABLED_MIDDLEWARES=permissions,activityPub yarn run dev 2> /dev/null",
+ "test:before:seeder": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DEBUG=true DISABLED_MIDDLEWARES=permissions,activityPub yarn run dev 2> /dev/null",
"test:jest:cmd": "wait-on tcp:4001 tcp:4123 && jest --forceExit --detectOpenHandles --runInBand",
"test:cucumber:cmd": "wait-on tcp:4001 tcp:4123 && cucumber-js --require-module @babel/register --exit test/",
"test:jest:cmd:debug": "wait-on tcp:4001 tcp:4123 && node --inspect-brk ./node_modules/.bin/jest -i --forceExit --detectOpenHandles --runInBand",
@@ -19,8 +19,8 @@
"test:cucumber": " cross-env CLIENT_URI=http://localhost:4123 run-p --race test:before:* 'test:cucumber:cmd {@}' --",
"test:jest:debug": "run-p --race test:before:* 'test:jest:cmd:debug {@}' --",
"db:script:seed": "wait-on tcp:4001 && babel-node src/seed/seed-db.js",
- "db:reset": "babel-node src/seed/reset-db.js",
- "db:seed": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DISABLED_MIDDLEWARES=permissions run-p --race dev db:script:seed"
+ "db:reset": "cross-env DEBUG=true babel-node src/seed/reset-db.js",
+ "db:seed": "cross-env GRAPHQL_URI=http://localhost:4001 GRAPHQL_PORT=4001 DEBUG=true DISABLED_MIDDLEWARES=permissions run-p --race dev db:script:seed"
},
"author": "Human Connection gGmbH",
"license": "MIT",
@@ -47,7 +47,7 @@
"apollo-client": "~2.5.1",
"apollo-link-context": "~1.0.14",
"apollo-link-http": "~1.5.14",
- "apollo-server": "~2.5.1",
+ "apollo-server": "~2.6.1",
"bcryptjs": "~2.4.3",
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
@@ -109,4 +109,4 @@
"prettier": "~1.17.1",
"supertest": "~4.0.2"
}
-}
+}
\ No newline at end of file
diff --git a/backend/src/activitypub/ActivityPub.js b/backend/src/activitypub/ActivityPub.js
index da1056362..12671f330 100644
--- a/backend/src/activitypub/ActivityPub.js
+++ b/backend/src/activitypub/ActivityPub.js
@@ -4,9 +4,9 @@ import request from 'request'
import as from 'activitystrea.ms'
import NitroDataSource from './NitroDataSource'
import router from './routes'
-import dotenv from 'dotenv'
import Collections from './Collections'
import uuid from 'uuid/v4'
+import CONFIG from '../config'
const debug = require('debug')('ea')
let activityPub = null
@@ -22,11 +22,7 @@ export default class ActivityPub {
static init(server) {
if (!activityPub) {
- dotenv.config()
- activityPub = new ActivityPub(
- process.env.CLIENT_URI || 'http://localhost:3000',
- process.env.GRAPHQL_URI || 'http://localhost:4000',
- )
+ activityPub = new ActivityPub(CONFIG.CLIENT_URI, CONFIG.GRAPHQL_URI)
// integrate into running graphql express server
server.express.set('ap', activityPub)
diff --git a/backend/src/activitypub/security/index.js b/backend/src/activitypub/security/index.js
index 7f619acbe..9b48b7ed9 100644
--- a/backend/src/activitypub/security/index.js
+++ b/backend/src/activitypub/security/index.js
@@ -1,13 +1,15 @@
-import dotenv from 'dotenv'
-import { resolve } from 'path'
+// import dotenv from 'dotenv'
+// import { resolve } from 'path'
import crypto from 'crypto'
import request from 'request'
+import CONFIG from './../../config'
const debug = require('debug')('ea:security')
-dotenv.config({ path: resolve('src', 'activitypub', '.env') })
+// TODO Does this reference a local config? Why?
+// dotenv.config({ path: resolve('src', 'activitypub', '.env') })
export function generateRsaKeyPair(options = {}) {
- const { passphrase = process.env.PRIVATE_KEY_PASSPHRASE } = options
+ const { passphrase = CONFIG.PRIVATE_KEY_PASSPHRASE } = options
return crypto.generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
@@ -31,7 +33,7 @@ export function createSignature(options) {
url,
headers = {},
algorithm = 'rsa-sha256',
- passphrase = process.env.PRIVATE_KEY_PASSPHRASE,
+ passphrase = CONFIG.PRIVATE_KEY_PASSPHRASE,
} = options
if (!SUPPORTED_HASH_ALGORITHMS.includes(algorithm)) {
throw Error(`SIGNING: Unsupported hashing algorithm = ${algorithm}`)
diff --git a/backend/src/activitypub/utils/index.js b/backend/src/activitypub/utils/index.js
index ee7ae2606..3927f4056 100644
--- a/backend/src/activitypub/utils/index.js
+++ b/backend/src/activitypub/utils/index.js
@@ -2,6 +2,7 @@ import { activityPub } from '../ActivityPub'
import gql from 'graphql-tag'
import { createSignature } from '../security'
import request from 'request'
+import CONFIG from './../../config'
const debug = require('debug')('ea:utils')
export function extractNameFromId(uri) {
@@ -38,7 +39,7 @@ export function throwErrorIfApolloErrorOccurred(result) {
export function signAndSend(activity, fromName, targetDomain, url) {
// fix for development: replace with http
url = url.indexOf('localhost') > -1 ? url.replace('https', 'http') : url
- debug(`passhprase = ${process.env.PRIVATE_KEY_PASSPHRASE}`)
+ debug(`passhprase = ${CONFIG.PRIVATE_KEY_PASSPHRASE}`)
return new Promise(async (resolve, reject) => {
debug('inside signAndSend')
// get the private key
diff --git a/backend/src/bootstrap/neo4j.js b/backend/src/bootstrap/neo4j.js
index 292983359..bfa68acf3 100644
--- a/backend/src/bootstrap/neo4j.js
+++ b/backend/src/bootstrap/neo4j.js
@@ -1,15 +1,13 @@
import { v1 as neo4j } from 'neo4j-driver'
-import dotenv from 'dotenv'
-
-dotenv.config()
+import CONFIG from './../config'
let driver
export function getDriver(options = {}) {
const {
- uri = process.env.NEO4J_URI || 'bolt://localhost:7687',
- username = process.env.NEO4J_USERNAME || 'neo4j',
- password = process.env.NEO4J_PASSWORD || 'neo4j',
+ uri = CONFIG.NEO4J_URI,
+ username = CONFIG.NEO4J_USERNAME,
+ password = CONFIG.NEO4J_PASSWORD,
} = options
if (!driver) {
driver = neo4j.driver(uri, neo4j.auth.basic(username, password))
diff --git a/backend/src/config/index.js b/backend/src/config/index.js
new file mode 100644
index 000000000..5cc455495
--- /dev/null
+++ b/backend/src/config/index.js
@@ -0,0 +1,34 @@
+import dotenv from 'dotenv'
+
+dotenv.config()
+
+export const requiredConfigs = {
+ MAPBOX_TOKEN: process.env.MAPBOX_TOKEN,
+ JWT_SECRET: process.env.JWT_SECRET,
+ PRIVATE_KEY_PASSPHRASE: process.env.PRIVATE_KEY_PASSPHRASE,
+}
+
+export const neo4jConfigs = {
+ NEO4J_URI: process.env.NEO4J_URI || 'bolt://localhost:7687',
+ NEO4J_USERNAME: process.env.NEO4J_USERNAME || 'neo4j',
+ NEO4J_PASSWORD: process.env.NEO4J_PASSWORD || 'neo4j',
+}
+
+export const serverConfigs = {
+ GRAPHQL_PORT: process.env.GRAPHQL_PORT || 4000,
+ CLIENT_URI: process.env.CLIENT_URI || 'http://localhost:3000',
+ GRAPHQL_URI: process.env.GRAPHQL_URI || 'http://localhost:4000',
+}
+
+export const developmentConfigs = {
+ DEBUG: process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true',
+ MOCKS: process.env.MOCKS === 'true',
+ DISABLED_MIDDLEWARES: process.env.DISABLED_MIDDLEWARES || '',
+}
+
+export default {
+ ...requiredConfigs,
+ ...neo4jConfigs,
+ ...serverConfigs,
+ ...developmentConfigs,
+}
diff --git a/backend/src/graphql-schema.js b/backend/src/graphql-schema.js
deleted file mode 100644
index 01b40dfc5..000000000
--- a/backend/src/graphql-schema.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as typeDefs } from './types'
-export { default as resolvers } from './resolvers'
diff --git a/backend/src/index.js b/backend/src/index.js
index 2095d171f..f28e58947 100644
--- a/backend/src/index.js
+++ b/backend/src/index.js
@@ -1,17 +1,18 @@
import createServer from './server'
import ActivityPub from './activitypub/ActivityPub'
+import CONFIG from './config'
const serverConfig = {
- port: process.env.GRAPHQL_PORT || 4000,
+ port: CONFIG.GRAPHQL_PORT,
// cors: {
// credentials: true,
- // origin: [process.env.CLIENT_URI] // your frontend url.
+ // origin: [CONFIG.CLIENT_URI] // your frontend url.
// }
}
const server = createServer()
server.start(serverConfig, options => {
/* eslint-disable-next-line no-console */
- console.log(`GraphQLServer ready at ${process.env.GRAPHQL_URI} đ`)
+ console.log(`GraphQLServer ready at ${CONFIG.GRAPHQL_URI} đ`)
ActivityPub.init(server)
})
diff --git a/backend/src/jwt/decode.js b/backend/src/jwt/decode.js
index d4485952d..b98357103 100644
--- a/backend/src/jwt/decode.js
+++ b/backend/src/jwt/decode.js
@@ -1,11 +1,12 @@
import jwt from 'jsonwebtoken'
+import CONFIG from './../config'
export default async (driver, authorizationHeader) => {
if (!authorizationHeader) return null
const token = authorizationHeader.replace('Bearer ', '')
let id = null
try {
- const decoded = await jwt.verify(token, process.env.JWT_SECRET)
+ const decoded = await jwt.verify(token, CONFIG.JWT_SECRET)
id = decoded.sub
} catch (err) {
return null
diff --git a/backend/src/jwt/encode.js b/backend/src/jwt/encode.js
index 49aa17bd0..97c6dcd66 100644
--- a/backend/src/jwt/encode.js
+++ b/backend/src/jwt/encode.js
@@ -1,15 +1,16 @@
import jwt from 'jsonwebtoken'
import ms from 'ms'
+import CONFIG from './../config'
// Generate an Access Token for the given User ID
export default function encode(user) {
- const token = jwt.sign(user, process.env.JWT_SECRET, {
+ const token = jwt.sign(user, CONFIG.JWT_SECRET, {
expiresIn: ms('1d'),
- issuer: process.env.GRAPHQL_URI,
- audience: process.env.CLIENT_URI,
+ issuer: CONFIG.GRAPHQL_URI,
+ audience: CONFIG.CLIENT_URI,
subject: user.id.toString(),
})
- // jwt.verifySignature(token, process.env.JWT_SECRET, (err, data) => {
+ // jwt.verifySignature(token, CONFIG.JWT_SECRET, (err, data) => {
// console.log('token verification:', err, data)
// })
return token
diff --git a/backend/src/middleware/activityPubMiddleware.js b/backend/src/middleware/activityPubMiddleware.js
index 43da21e26..f3ced42f9 100644
--- a/backend/src/middleware/activityPubMiddleware.js
+++ b/backend/src/middleware/activityPubMiddleware.js
@@ -1,10 +1,8 @@
import { generateRsaKeyPair } from '../activitypub/security'
import { activityPub } from '../activitypub/ActivityPub'
import as from 'activitystrea.ms'
-import dotenv from 'dotenv'
const debug = require('debug')('backend:schema')
-dotenv.config()
export default {
Mutation: {
diff --git a/backend/src/middleware/index.js b/backend/src/middleware/index.js
index bef6ceac9..754c59bbb 100644
--- a/backend/src/middleware/index.js
+++ b/backend/src/middleware/index.js
@@ -1,42 +1,63 @@
-import activityPubMiddleware from './activityPubMiddleware'
-import passwordMiddleware from './passwordMiddleware'
-import softDeleteMiddleware from './softDeleteMiddleware'
-import sluggifyMiddleware from './sluggifyMiddleware'
-import fixImageUrlsMiddleware from './fixImageUrlsMiddleware'
-import excerptMiddleware from './excerptMiddleware'
-import dateTimeMiddleware from './dateTimeMiddleware'
-import xssMiddleware from './xssMiddleware'
-import permissionsMiddleware from './permissionsMiddleware'
-import userMiddleware from './userMiddleware'
-import includedFieldsMiddleware from './includedFieldsMiddleware'
-import orderByMiddleware from './orderByMiddleware'
-import validationMiddleware from './validation'
-import notificationsMiddleware from './notifications'
+import CONFIG from './../config'
+import activityPub from './activityPubMiddleware'
+import password from './passwordMiddleware'
+import softDelete from './softDeleteMiddleware'
+import sluggify from './sluggifyMiddleware'
+import fixImageUrls from './fixImageUrlsMiddleware'
+import excerpt from './excerptMiddleware'
+import dateTime from './dateTimeMiddleware'
+import xss from './xssMiddleware'
+import permissions from './permissionsMiddleware'
+import user from './userMiddleware'
+import includedFields from './includedFieldsMiddleware'
+import orderBy from './orderByMiddleware'
+import validation from './validation'
+import notifications from './notifications'
export default schema => {
- let middleware = [
- passwordMiddleware,
- dateTimeMiddleware,
- validationMiddleware,
- sluggifyMiddleware,
- excerptMiddleware,
- notificationsMiddleware,
- xssMiddleware,
- fixImageUrlsMiddleware,
- softDeleteMiddleware,
- userMiddleware,
- includedFieldsMiddleware,
- orderByMiddleware,
+ const middlewares = {
+ permissions: permissions,
+ activityPub: activityPub,
+ password: password,
+ dateTime: dateTime,
+ validation: validation,
+ sluggify: sluggify,
+ excerpt: excerpt,
+ notifications: notifications,
+ xss: xss,
+ fixImageUrls: fixImageUrls,
+ softDelete: softDelete,
+ user: user,
+ includedFields: includedFields,
+ orderBy: orderBy,
+ }
+
+ let order = [
+ 'permissions',
+ 'activityPub',
+ 'password',
+ 'dateTime',
+ 'validation',
+ 'sluggify',
+ 'excerpt',
+ 'notifications',
+ 'xss',
+ 'fixImageUrls',
+ 'softDelete',
+ 'user',
+ 'includedFields',
+ 'orderBy',
]
// add permisions middleware at the first position (unless we're seeding)
- // NOTE: DO NOT SET THE PERMISSION FLAT YOUR SELF
- if (process.env.NODE_ENV !== 'production') {
- const DISABLED_MIDDLEWARES = process.env.DISABLED_MIDDLEWARES || ''
- const disabled = DISABLED_MIDDLEWARES.split(',')
- if (!disabled.includes('activityPub')) middleware.unshift(activityPubMiddleware)
- if (!disabled.includes('permissions'))
- middleware.unshift(permissionsMiddleware.generate(schema))
+ if (CONFIG.DEBUG) {
+ const disabledMiddlewares = CONFIG.DISABLED_MIDDLEWARES.split(',')
+ order = order.filter(key => {
+ return !disabledMiddlewares.includes(key)
+ })
+ /* eslint-disable-next-line no-console */
+ console.log(`Warning: "${disabledMiddlewares}" middlewares have been disabled.`)
}
- return middleware
+
+ return order.map(key => middlewares[key])
}
diff --git a/backend/src/middleware/nodes/locations.js b/backend/src/middleware/nodes/locations.js
index a0adeb57f..62d1e3a65 100644
--- a/backend/src/middleware/nodes/locations.js
+++ b/backend/src/middleware/nodes/locations.js
@@ -2,6 +2,7 @@ import request from 'request'
import { UserInputError } from 'apollo-server'
import isEmpty from 'lodash/isEmpty'
import asyncForEach from '../../helpers/asyncForEach'
+import CONFIG from './../../config'
const fetch = url => {
return new Promise((resolve, reject) => {
@@ -58,11 +59,12 @@ const createOrUpdateLocations = async (userId, locationName, driver) => {
if (isEmpty(locationName)) {
return
}
- const mapboxToken = process.env.MAPBOX_TOKEN
const res = await fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(
locationName,
- )}.json?access_token=${mapboxToken}&types=region,place,country&language=${locales.join(',')}`,
+ )}.json?access_token=${CONFIG.MAPBOX_TOKEN}&types=region,place,country&language=${locales.join(
+ ',',
+ )}`,
)
if (!res || !res.features || !res.features[0]) {
diff --git a/backend/src/middleware/orderByMiddleware.spec.js b/backend/src/middleware/orderByMiddleware.spec.js
index 658447160..450220cd6 100644
--- a/backend/src/middleware/orderByMiddleware.spec.js
+++ b/backend/src/middleware/orderByMiddleware.spec.js
@@ -1,6 +1,6 @@
+import { GraphQLClient } from 'graphql-request'
import Factory from '../seed/factories'
import { host } from '../jest/helpers'
-import { GraphQLClient } from 'graphql-request'
let client
let headers
diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js
index b1a08a14d..bc9b4c525 100644
--- a/backend/src/middleware/permissionsMiddleware.js
+++ b/backend/src/middleware/permissionsMiddleware.js
@@ -16,11 +16,15 @@ const isAdmin = rule()(async (parent, args, { user }, info) => {
return user && user.role === 'admin'
})
-const isMyOwn = rule({ cache: 'no_cache' })(async (parent, args, context, info) => {
+const isMyOwn = rule({
+ cache: 'no_cache',
+})(async (parent, args, context, info) => {
return context.user.id === parent.id
})
-const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
+const belongsToMe = rule({
+ cache: 'no_cache',
+})(async (_, args, context) => {
const {
driver,
user: { id: userId },
@@ -32,7 +36,10 @@ const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
MATCH (u:User {id: $userId})<-[:NOTIFIED]-(n:Notification {id: $notificationId})
RETURN n
`,
- { userId, notificationId },
+ {
+ userId,
+ notificationId,
+ },
)
const [notification] = result.records.map(record => {
return record.get('n')
@@ -41,21 +48,27 @@ const belongsToMe = rule({ cache: 'no_cache' })(async (_, args, context) => {
return Boolean(notification)
})
-const onlyEnabledContent = rule({ cache: 'strict' })(async (parent, args, ctx, info) => {
+const onlyEnabledContent = rule({
+ cache: 'strict',
+})(async (parent, args, ctx, info) => {
const { disabled, deleted } = args
return !(disabled || deleted)
})
-const isAuthor = rule({ cache: 'no_cache' })(async (parent, args, { user, driver }) => {
+const isAuthor = rule({
+ cache: 'no_cache',
+})(async (parent, args, { user, driver }) => {
if (!user) return false
const session = driver.session()
- const { id: postId } = args
+ const { id: resourceId } = args
const result = await session.run(
`
- MATCH (post:Post {id: $postId})<-[:WROTE]-(author)
+ MATCH (resource {id: $resourceId})<-[:WROTE]-(author)
RETURN author
`,
- { postId },
+ {
+ resourceId,
+ },
)
const [author] = result.records.map(record => {
return record.get('author')
@@ -100,6 +113,7 @@ const permissions = shield({
enable: isModerator,
disable: isModerator,
CreateComment: isAuthenticated,
+ DeleteComment: isAuthor,
// CreateUser: allow,
},
User: {
diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.js
index fc1815631..6cf9dc302 100644
--- a/backend/src/middleware/permissionsMiddleware.spec.js
+++ b/backend/src/middleware/permissionsMiddleware.spec.js
@@ -1,6 +1,6 @@
+import { GraphQLClient } from 'graphql-request'
import Factory from '../seed/factories'
import { host, login } from '../jest/helpers'
-import { GraphQLClient } from 'graphql-request'
const factory = Factory()
diff --git a/backend/src/middleware/slugifyMiddleware.spec.js b/backend/src/middleware/slugifyMiddleware.spec.js
index 7ca4ec193..79bba0a5d 100644
--- a/backend/src/middleware/slugifyMiddleware.spec.js
+++ b/backend/src/middleware/slugifyMiddleware.spec.js
@@ -1,6 +1,6 @@
+import { GraphQLClient } from 'graphql-request'
import Factory from '../seed/factories'
import { host, login } from '../jest/helpers'
-import { GraphQLClient } from 'graphql-request'
let authenticatedClient
let headers
diff --git a/backend/src/middleware/softDeleteMiddleware.spec.js b/backend/src/middleware/softDeleteMiddleware.spec.js
index 4265599dd..388f44a3c 100644
--- a/backend/src/middleware/softDeleteMiddleware.spec.js
+++ b/backend/src/middleware/softDeleteMiddleware.spec.js
@@ -1,6 +1,6 @@
+import { GraphQLClient } from 'graphql-request'
import Factory from '../seed/factories'
import { host, login } from '../jest/helpers'
-import { GraphQLClient } from 'graphql-request'
const factory = Factory()
let client
diff --git a/backend/src/middleware/userMiddleware.js b/backend/src/middleware/userMiddleware.js
index 079ba310a..29e512ebd 100644
--- a/backend/src/middleware/userMiddleware.js
+++ b/backend/src/middleware/userMiddleware.js
@@ -1,9 +1,5 @@
-import dotenv from 'dotenv'
-
import createOrUpdateLocations from './nodes/locations'
-dotenv.config()
-
export default {
Mutation: {
CreateUser: async (resolve, root, args, context, info) => {
diff --git a/backend/src/schema/index.js b/backend/src/schema/index.js
new file mode 100644
index 000000000..d294d8aba
--- /dev/null
+++ b/backend/src/schema/index.js
@@ -0,0 +1,24 @@
+import { makeAugmentedSchema } from 'neo4j-graphql-js'
+import CONFIG from './../config'
+import applyScalars from './../bootstrap/scalars'
+import applyDirectives from './../bootstrap/directives'
+import typeDefs from './types'
+import resolvers from './resolvers'
+
+export default applyScalars(
+ applyDirectives(
+ makeAugmentedSchema({
+ typeDefs,
+ resolvers,
+ config: {
+ query: {
+ exclude: ['Notfication', 'Statistics', 'LoggedInUser'],
+ },
+ mutation: {
+ exclude: ['Notfication', 'Statistics', 'LoggedInUser'],
+ },
+ debug: CONFIG.DEBUG,
+ },
+ }),
+ ),
+)
diff --git a/backend/src/resolvers/badges.spec.js b/backend/src/schema/resolvers/badges.spec.js
similarity index 98%
rename from backend/src/resolvers/badges.spec.js
rename to backend/src/schema/resolvers/badges.spec.js
index 8383d9838..a0dbafe00 100644
--- a/backend/src/resolvers/badges.spec.js
+++ b/backend/src/schema/resolvers/badges.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
diff --git a/backend/src/resolvers/comments.js b/backend/src/schema/resolvers/comments.js
similarity index 90%
rename from backend/src/resolvers/comments.js
rename to backend/src/schema/resolvers/comments.js
index 949b77041..7f3b11da4 100644
--- a/backend/src/resolvers/comments.js
+++ b/backend/src/schema/resolvers/comments.js
@@ -53,6 +53,11 @@ export default {
)
session.close()
+ return comment
+ },
+ DeleteComment: async (object, params, context, resolveInfo) => {
+ const comment = await neo4jgraphql(object, params, context, resolveInfo, false)
+
return comment
},
},
diff --git a/backend/src/resolvers/comments.spec.js b/backend/src/schema/resolvers/comments.spec.js
similarity index 62%
rename from backend/src/resolvers/comments.spec.js
rename to backend/src/schema/resolvers/comments.spec.js
index 451c559f1..55b946bb9 100644
--- a/backend/src/resolvers/comments.spec.js
+++ b/backend/src/schema/resolvers/comments.spec.js
@@ -1,6 +1,7 @@
-import Factory from '../seed/factories'
+import gql from 'graphql-tag'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
@@ -21,22 +22,22 @@ afterEach(async () => {
})
describe('CreateComment', () => {
- const createCommentMutation = `
- mutation($postId: ID, $content: String!) {
- CreateComment(postId: $postId, content: $content) {
- id
- content
+ const createCommentMutation = gql`
+ mutation($postId: ID, $content: String!) {
+ CreateComment(postId: $postId, content: $content) {
+ id
+ content
+ }
}
- }
`
- const createPostMutation = `
- mutation($id: ID!, $title: String!, $content: String!) {
- CreatePost(id: $id, title: $title, content: $content) {
- id
+ const createPostMutation = gql`
+ mutation($id: ID!, $title: String!, $content: String!) {
+ CreatePost(id: $id, title: $title, content: $content) {
+ id
+ }
}
- }
`
- const commentQueryForPostId = `
+ const commentQueryForPostId = gql`
query($content: String) {
Comment(content: $content) {
postId
@@ -59,8 +60,13 @@ describe('CreateComment', () => {
describe('authenticated', () => {
let headers
beforeEach(async () => {
- headers = await login({ email: 'test@example.org', password: '1234' })
- client = new GraphQLClient(host, { headers })
+ headers = await login({
+ email: 'test@example.org',
+ password: '1234',
+ })
+ client = new GraphQLClient(host, {
+ headers,
+ })
createCommentVariables = {
postId: 'p1',
content: "I'm authorised to comment",
@@ -88,15 +94,25 @@ describe('CreateComment', () => {
it('assigns the authenticated user as author', async () => {
await client.request(createCommentMutation, createCommentVariables)
- const { User } = await client.request(`{
+ const { User } = await client.request(gql`
+ {
User(email: "test@example.org") {
comments {
content
}
}
- }`)
+ }
+ `)
- expect(User).toEqual([{ comments: [{ content: "I'm authorised to comment" }] }])
+ expect(User).toEqual([
+ {
+ comments: [
+ {
+ content: "I'm authorised to comment",
+ },
+ ],
+ },
+ ])
})
it('throw an error if an empty string is sent from the editor as content', async () => {
@@ -186,7 +202,98 @@ describe('CreateComment', () => {
commentQueryForPostId,
commentQueryVariablesByContent,
)
- expect(Comment).toEqual([{ postId: null }])
+ expect(Comment).toEqual([
+ {
+ postId: null,
+ },
+ ])
+ })
+ })
+})
+
+describe('DeleteComment', () => {
+ const deleteCommentMutation = gql`
+ mutation($id: ID!) {
+ DeleteComment(id: $id) {
+ id
+ }
+ }
+ `
+
+ let deleteCommentVariables = {
+ id: 'c1',
+ }
+
+ beforeEach(async () => {
+ const asAuthor = Factory()
+ await asAuthor.create('User', {
+ email: 'author@example.org',
+ password: '1234',
+ })
+ await asAuthor.authenticateAs({
+ email: 'author@example.org',
+ password: '1234',
+ })
+ await asAuthor.create('Post', {
+ id: 'p1',
+ content: 'Post to be commented',
+ })
+ await asAuthor.create('Comment', {
+ id: 'c1',
+ postId: 'p1',
+ content: 'Comment to be deleted',
+ })
+ })
+
+ describe('unauthenticated', () => {
+ it('throws authorization error', async () => {
+ client = new GraphQLClient(host)
+ await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow(
+ 'Not Authorised',
+ )
+ })
+ })
+
+ describe('authenticated but not the author', () => {
+ beforeEach(async () => {
+ let headers
+ headers = await login({
+ email: 'test@example.org',
+ password: '1234',
+ })
+ client = new GraphQLClient(host, {
+ headers,
+ })
+ })
+
+ it('throws authorization error', async () => {
+ await expect(client.request(deleteCommentMutation, deleteCommentVariables)).rejects.toThrow(
+ 'Not Authorised',
+ )
+ })
+ })
+
+ describe('authenticated as author', () => {
+ beforeEach(async () => {
+ let headers
+ headers = await login({
+ email: 'author@example.org',
+ password: '1234',
+ })
+ client = new GraphQLClient(host, {
+ headers,
+ })
+ })
+
+ it('deletes the comment', async () => {
+ const expected = {
+ DeleteComment: {
+ id: 'c1',
+ },
+ }
+ await expect(client.request(deleteCommentMutation, deleteCommentVariables)).resolves.toEqual(
+ expected,
+ )
})
})
})
diff --git a/backend/src/resolvers/fileUpload/index.js b/backend/src/schema/resolvers/fileUpload/index.js
similarity index 100%
rename from backend/src/resolvers/fileUpload/index.js
rename to backend/src/schema/resolvers/fileUpload/index.js
diff --git a/backend/src/resolvers/fileUpload/spec.js b/backend/src/schema/resolvers/fileUpload/spec.js
similarity index 100%
rename from backend/src/resolvers/fileUpload/spec.js
rename to backend/src/schema/resolvers/fileUpload/spec.js
diff --git a/backend/src/resolvers/follow.js b/backend/src/schema/resolvers/follow.js
similarity index 100%
rename from backend/src/resolvers/follow.js
rename to backend/src/schema/resolvers/follow.js
diff --git a/backend/src/resolvers/follow.spec.js b/backend/src/schema/resolvers/follow.spec.js
similarity index 97%
rename from backend/src/resolvers/follow.spec.js
rename to backend/src/schema/resolvers/follow.spec.js
index 4a361b03d..d29e17938 100644
--- a/backend/src/resolvers/follow.spec.js
+++ b/backend/src/schema/resolvers/follow.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let clientUser1
diff --git a/backend/src/resolvers/index.js b/backend/src/schema/resolvers/index.js
similarity index 100%
rename from backend/src/resolvers/index.js
rename to backend/src/schema/resolvers/index.js
diff --git a/backend/src/resolvers/moderation.js b/backend/src/schema/resolvers/moderation.js
similarity index 100%
rename from backend/src/resolvers/moderation.js
rename to backend/src/schema/resolvers/moderation.js
diff --git a/backend/src/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js
similarity index 99%
rename from backend/src/resolvers/moderation.spec.js
rename to backend/src/schema/resolvers/moderation.spec.js
index 835e9e535..b1dec603b 100644
--- a/backend/src/resolvers/moderation.spec.js
+++ b/backend/src/schema/resolvers/moderation.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
diff --git a/backend/src/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.js
similarity index 100%
rename from backend/src/resolvers/notifications.js
rename to backend/src/schema/resolvers/notifications.js
diff --git a/backend/src/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js
similarity index 98%
rename from backend/src/resolvers/notifications.spec.js
rename to backend/src/schema/resolvers/notifications.spec.js
index 37d8c83ff..3876a4be3 100644
--- a/backend/src/resolvers/notifications.spec.js
+++ b/backend/src/schema/resolvers/notifications.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
diff --git a/backend/src/resolvers/posts.js b/backend/src/schema/resolvers/posts.js
similarity index 100%
rename from backend/src/resolvers/posts.js
rename to backend/src/schema/resolvers/posts.js
diff --git a/backend/src/resolvers/posts.spec.js b/backend/src/schema/resolvers/posts.spec.js
similarity index 98%
rename from backend/src/resolvers/posts.spec.js
rename to backend/src/schema/resolvers/posts.spec.js
index e4175ff09..9e2ec70a2 100644
--- a/backend/src/resolvers/posts.spec.js
+++ b/backend/src/schema/resolvers/posts.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let client
diff --git a/backend/src/resolvers/reports.js b/backend/src/schema/resolvers/reports.js
similarity index 100%
rename from backend/src/resolvers/reports.js
rename to backend/src/schema/resolvers/reports.js
diff --git a/backend/src/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.js
similarity index 98%
rename from backend/src/resolvers/reports.spec.js
rename to backend/src/schema/resolvers/reports.spec.js
index 19b5e6f9e..6b996b016 100644
--- a/backend/src/resolvers/reports.spec.js
+++ b/backend/src/schema/resolvers/reports.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
diff --git a/backend/src/resolvers/rewards.js b/backend/src/schema/resolvers/rewards.js
similarity index 100%
rename from backend/src/resolvers/rewards.js
rename to backend/src/schema/resolvers/rewards.js
diff --git a/backend/src/resolvers/rewards.spec.js b/backend/src/schema/resolvers/rewards.spec.js
similarity index 98%
rename from backend/src/resolvers/rewards.spec.js
rename to backend/src/schema/resolvers/rewards.spec.js
index e2b67b25d..2bdd9a39b 100644
--- a/backend/src/resolvers/rewards.spec.js
+++ b/backend/src/schema/resolvers/rewards.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
diff --git a/backend/src/resolvers/shout.js b/backend/src/schema/resolvers/shout.js
similarity index 100%
rename from backend/src/resolvers/shout.js
rename to backend/src/schema/resolvers/shout.js
diff --git a/backend/src/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js
similarity index 97%
rename from backend/src/resolvers/shout.spec.js
rename to backend/src/schema/resolvers/shout.spec.js
index 46570efa0..a94f7ca0b 100644
--- a/backend/src/resolvers/shout.spec.js
+++ b/backend/src/schema/resolvers/shout.spec.js
@@ -1,6 +1,6 @@
-import Factory from '../seed/factories'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
let clientUser1, clientUser2
diff --git a/backend/src/resolvers/socialMedia.js b/backend/src/schema/resolvers/socialMedia.js
similarity index 100%
rename from backend/src/resolvers/socialMedia.js
rename to backend/src/schema/resolvers/socialMedia.js
diff --git a/backend/src/resolvers/socialMedia.spec.js b/backend/src/schema/resolvers/socialMedia.spec.js
similarity index 73%
rename from backend/src/resolvers/socialMedia.spec.js
rename to backend/src/schema/resolvers/socialMedia.spec.js
index 5143587b1..38850761c 100644
--- a/backend/src/resolvers/socialMedia.spec.js
+++ b/backend/src/schema/resolvers/socialMedia.spec.js
@@ -1,13 +1,14 @@
-import Factory from '../seed/factories'
+import gql from 'graphql-tag'
import { GraphQLClient } from 'graphql-request'
-import { host, login } from '../jest/helpers'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
-describe('CreateSocialMedia', () => {
+describe('SocialMedia', () => {
let client
let headers
- const mutationC = `
+ const mutationC = gql`
mutation($url: String!) {
CreateSocialMedia(url: $url) {
id
@@ -15,7 +16,7 @@ describe('CreateSocialMedia', () => {
}
}
`
- const mutationD = `
+ const mutationD = gql`
mutation($id: ID!) {
DeleteSocialMedia(id: $id) {
id
@@ -42,19 +43,28 @@ describe('CreateSocialMedia', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
- const variables = { url: 'http://nsosp.org' }
+ const variables = {
+ url: 'http://nsosp.org',
+ }
await expect(client.request(mutationC, variables)).rejects.toThrow('Not Authorised')
})
})
describe('authenticated', () => {
beforeEach(async () => {
- headers = await login({ email: 'test@example.org', password: '1234' })
- client = new GraphQLClient(host, { headers })
+ headers = await login({
+ email: 'test@example.org',
+ password: '1234',
+ })
+ client = new GraphQLClient(host, {
+ headers,
+ })
})
it('creates social media with correct URL', async () => {
- const variables = { url: 'http://nsosp.org' }
+ const variables = {
+ url: 'http://nsosp.org',
+ }
await expect(client.request(mutationC, variables)).resolves.toEqual(
expect.objectContaining({
CreateSocialMedia: {
@@ -66,11 +76,15 @@ describe('CreateSocialMedia', () => {
})
it('deletes social media', async () => {
- const creationVariables = { url: 'http://nsosp.org' }
+ const creationVariables = {
+ url: 'http://nsosp.org',
+ }
const { CreateSocialMedia } = await client.request(mutationC, creationVariables)
const { id } = CreateSocialMedia
- const deletionVariables = { id }
+ const deletionVariables = {
+ id,
+ }
const expected = {
DeleteSocialMedia: {
id: id,
@@ -81,12 +95,16 @@ describe('CreateSocialMedia', () => {
})
it('rejects empty string', async () => {
- const variables = { url: '' }
+ const variables = {
+ url: '',
+ }
await expect(client.request(mutationC, variables)).rejects.toThrow('Input is not a URL')
})
it('validates URLs', async () => {
- const variables = { url: 'not-a-url' }
+ const variables = {
+ url: 'not-a-url',
+ }
await expect(client.request(mutationC, variables)).rejects.toThrow('Input is not a URL')
})
})
diff --git a/backend/src/resolvers/statistics.js b/backend/src/schema/resolvers/statistics.js
similarity index 100%
rename from backend/src/resolvers/statistics.js
rename to backend/src/schema/resolvers/statistics.js
diff --git a/backend/src/resolvers/user_management.js b/backend/src/schema/resolvers/user_management.js
similarity index 98%
rename from backend/src/resolvers/user_management.js
rename to backend/src/schema/resolvers/user_management.js
index e2fd5acf1..eb07a07b3 100644
--- a/backend/src/resolvers/user_management.js
+++ b/backend/src/schema/resolvers/user_management.js
@@ -1,4 +1,4 @@
-import encode from '../jwt/encode'
+import encode from '../../jwt/encode'
import bcrypt from 'bcryptjs'
import { AuthenticationError } from 'apollo-server'
import { neo4jgraphql } from 'neo4j-graphql-js'
diff --git a/backend/src/resolvers/user_management.spec.js b/backend/src/schema/resolvers/user_management.spec.js
similarity index 98%
rename from backend/src/resolvers/user_management.spec.js
rename to backend/src/schema/resolvers/user_management.spec.js
index 9dff9e388..cf648a6bd 100644
--- a/backend/src/resolvers/user_management.spec.js
+++ b/backend/src/schema/resolvers/user_management.spec.js
@@ -1,8 +1,9 @@
import gql from 'graphql-tag'
-import Factory from '../seed/factories'
import { GraphQLClient, request } from 'graphql-request'
import jwt from 'jsonwebtoken'
-import { host, login } from '../jest/helpers'
+import CONFIG from './../../config'
+import Factory from '../../seed/factories'
+import { host, login } from '../../jest/helpers'
const factory = Factory()
@@ -185,7 +186,7 @@ describe('login', () => {
}),
)
const token = data.login
- jwt.verify(token, process.env.JWT_SECRET, (err, data) => {
+ jwt.verify(token, CONFIG.JWT_SECRET, (err, data) => {
expect(data.email).toEqual('test@example.org')
expect(err).toBeNull()
})
diff --git a/backend/src/resolvers/users.js b/backend/src/schema/resolvers/users.js
similarity index 100%
rename from backend/src/resolvers/users.js
rename to backend/src/schema/resolvers/users.js
diff --git a/backend/src/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.js
similarity index 95%
rename from backend/src/resolvers/users.spec.js
rename to backend/src/schema/resolvers/users.spec.js
index 22096b6c8..a5c50f4f9 100644
--- a/backend/src/resolvers/users.spec.js
+++ b/backend/src/schema/resolvers/users.spec.js
@@ -1,6 +1,6 @@
import { GraphQLClient } from 'graphql-request'
-import { host } from '../jest/helpers'
-import Factory from '../seed/factories'
+import { host } from '../../jest/helpers'
+import Factory from '../../seed/factories'
const factory = Factory()
let client
diff --git a/backend/src/types/enum/BadgeStatus.gql b/backend/src/schema/types/enum/BadgeStatus.gql
similarity index 100%
rename from backend/src/types/enum/BadgeStatus.gql
rename to backend/src/schema/types/enum/BadgeStatus.gql
diff --git a/backend/src/types/enum/BadgeType.gql b/backend/src/schema/types/enum/BadgeType.gql
similarity index 100%
rename from backend/src/types/enum/BadgeType.gql
rename to backend/src/schema/types/enum/BadgeType.gql
diff --git a/backend/src/types/enum/UserGroup.gql b/backend/src/schema/types/enum/UserGroup.gql
similarity index 100%
rename from backend/src/types/enum/UserGroup.gql
rename to backend/src/schema/types/enum/UserGroup.gql
diff --git a/backend/src/types/enum/Visibility.gql b/backend/src/schema/types/enum/Visibility.gql
similarity index 100%
rename from backend/src/types/enum/Visibility.gql
rename to backend/src/schema/types/enum/Visibility.gql
diff --git a/backend/src/types/index.js b/backend/src/schema/types/index.js
similarity index 100%
rename from backend/src/types/index.js
rename to backend/src/schema/types/index.js
diff --git a/backend/src/types/scalar/Date.gql_ b/backend/src/schema/types/scalar/Date.gql_
similarity index 100%
rename from backend/src/types/scalar/Date.gql_
rename to backend/src/schema/types/scalar/Date.gql_
diff --git a/backend/src/types/scalar/DateTime.gql_ b/backend/src/schema/types/scalar/DateTime.gql_
similarity index 100%
rename from backend/src/types/scalar/DateTime.gql_
rename to backend/src/schema/types/scalar/DateTime.gql_
diff --git a/backend/src/types/scalar/Time.gql_ b/backend/src/schema/types/scalar/Time.gql_
similarity index 100%
rename from backend/src/types/scalar/Time.gql_
rename to backend/src/schema/types/scalar/Time.gql_
diff --git a/backend/src/types/scalar/Upload.gql b/backend/src/schema/types/scalar/Upload.gql
similarity index 100%
rename from backend/src/types/scalar/Upload.gql
rename to backend/src/schema/types/scalar/Upload.gql
diff --git a/backend/src/types/schema.gql b/backend/src/schema/types/schema.gql
similarity index 100%
rename from backend/src/types/schema.gql
rename to backend/src/schema/types/schema.gql
diff --git a/backend/src/types/schema_full.gql_ b/backend/src/schema/types/schema_full.gql_
similarity index 100%
rename from backend/src/types/schema_full.gql_
rename to backend/src/schema/types/schema_full.gql_
diff --git a/backend/src/types/type/Badge.gql b/backend/src/schema/types/type/Badge.gql
similarity index 100%
rename from backend/src/types/type/Badge.gql
rename to backend/src/schema/types/type/Badge.gql
diff --git a/backend/src/types/type/Category.gql b/backend/src/schema/types/type/Category.gql
similarity index 100%
rename from backend/src/types/type/Category.gql
rename to backend/src/schema/types/type/Category.gql
diff --git a/backend/src/types/type/Comment.gql b/backend/src/schema/types/type/Comment.gql
similarity index 100%
rename from backend/src/types/type/Comment.gql
rename to backend/src/schema/types/type/Comment.gql
diff --git a/backend/src/types/type/Post.gql b/backend/src/schema/types/type/Post.gql
similarity index 100%
rename from backend/src/types/type/Post.gql
rename to backend/src/schema/types/type/Post.gql
diff --git a/backend/src/types/type/Tag.gql b/backend/src/schema/types/type/Tag.gql
similarity index 100%
rename from backend/src/types/type/Tag.gql
rename to backend/src/schema/types/type/Tag.gql
diff --git a/backend/src/types/type/User.gql b/backend/src/schema/types/type/User.gql
similarity index 100%
rename from backend/src/types/type/User.gql
rename to backend/src/schema/types/type/User.gql
diff --git a/backend/src/seed/reset-db.js b/backend/src/seed/reset-db.js
index 3197a6e18..5f4319f73 100644
--- a/backend/src/seed/reset-db.js
+++ b/backend/src/seed/reset-db.js
@@ -1,10 +1,8 @@
import { cleanDatabase } from './factories'
-import dotenv from 'dotenv'
+import CONFIG from './../config'
-dotenv.config()
-
-if (process.env.NODE_ENV === 'production') {
- throw new Error(`YOU CAN'T CLEAN THE DATABASE WITH NODE_ENV=${process.env.NODE_ENV}`)
+if (!CONFIG.DEBUG) {
+ throw new Error(`YOU CAN'T CLEAN THE DATABASE WITH DEBUG=${CONFIG.DEBUG}`)
}
;(async function() {
diff --git a/backend/src/server.js b/backend/src/server.js
index 59261302f..7692f0d2c 100644
--- a/backend/src/server.js
+++ b/backend/src/server.js
@@ -1,48 +1,27 @@
-import { GraphQLServer } from 'graphql-yoga'
-import { makeAugmentedSchema } from 'neo4j-graphql-js'
-import { typeDefs, resolvers } from './graphql-schema'
import express from 'express'
-import dotenv from 'dotenv'
+import helmet from 'helmet'
+import { GraphQLServer } from 'graphql-yoga'
+import CONFIG, { requiredConfigs } from './config'
import mocks from './mocks'
import middleware from './middleware'
-import applyDirectives from './bootstrap/directives'
-import applyScalars from './bootstrap/scalars'
import { getDriver } from './bootstrap/neo4j'
-import helmet from 'helmet'
import decode from './jwt/decode'
+import schema from './schema'
-dotenv.config()
-// check env and warn
-const requiredEnvVars = ['MAPBOX_TOKEN', 'JWT_SECRET', 'PRIVATE_KEY_PASSPHRASE']
-requiredEnvVars.forEach(env => {
- if (!process.env[env]) {
- throw new Error(`ERROR: "${env}" env variable is missing.`)
+// check required configs and throw error
+// TODO check this directly in config file - currently not possible due to testsetup
+Object.entries(requiredConfigs).map(entry => {
+ if (!entry[1]) {
+ throw new Error(`ERROR: "${entry[0]}" env variable is missing.`)
}
})
const driver = getDriver()
-const debug = process.env.NODE_ENV !== 'production' && process.env.DEBUG === 'true'
-
-let schema = makeAugmentedSchema({
- typeDefs,
- resolvers,
- config: {
- query: {
- exclude: ['Notfication', 'Statistics', 'LoggedInUser'],
- },
- mutation: {
- exclude: ['Notfication', 'Statistics', 'LoggedInUser'],
- },
- debug: debug,
- },
-})
-schema = applyScalars(applyDirectives(schema))
const createServer = options => {
const defaults = {
context: async ({ request }) => {
- const authorizationHeader = request.headers.authorization || ''
- const user = await decode(driver, authorizationHeader)
+ const user = await decode(driver, request.headers.authorization)
return {
driver,
user,
@@ -52,11 +31,11 @@ const createServer = options => {
},
}
},
- schema: schema,
- debug: debug,
- tracing: debug,
+ schema,
+ debug: CONFIG.DEBUG,
+ tracing: CONFIG.DEBUG,
middlewares: middleware(schema),
- mocks: process.env.MOCK === 'true' ? mocks : false,
+ mocks: CONFIG.MOCKS ? mocks : false,
}
const server = new GraphQLServer(Object.assign({}, defaults, options))
diff --git a/backend/yarn.lock b/backend/yarn.lock
index f4a968e16..d56871d83 100644
--- a/backend/yarn.lock
+++ b/backend/yarn.lock
@@ -9,13 +9,6 @@
dependencies:
apollo-env "0.5.1"
-"@apollographql/apollo-tools@^0.3.6-alpha.1":
- version "0.3.6-alpha.1"
- resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.3.6-alpha.1.tgz#5199b36c65c2fddc4f8bc8bb97642f74e9fb00c5"
- integrity sha512-fq74In3Vw9OmtKHze0L5/Ns/pdTZOqUeFVC6Um9NRgziVehXz/qswsh2r3+dsn82uqoa/AlvckHtd6aPPPYj9g==
- dependencies:
- apollo-env "0.4.1-alpha.1"
-
"@apollographql/graphql-playground-html@1.6.20":
version "1.6.20"
resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.20.tgz#bf9f2acdf319c0959fad8ec1239741dd2ead4e8d"
@@ -1288,14 +1281,6 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-apollo-cache-control@0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.6.1.tgz#c73ff521fe606faf18edcbd3463c421a966f3e5d"
- integrity sha512-M3cDeQDXtRxYPQ/sL4pu3IVE5Q/9jpBlENB2IjwxTDir+WFZbJV1CAnvVwyJdL1DvS6ESR35DFOurJH4Ws/OPA==
- dependencies:
- apollo-server-env "2.3.0"
- graphql-extensions "0.6.1"
-
apollo-cache-control@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.7.1.tgz#3d4fba232f561f096f61051e103bf58ee4bf8b54"
@@ -1353,14 +1338,6 @@ apollo-client@~2.5.1:
tslib "^1.9.3"
zen-observable "^0.8.0"
-apollo-datasource@0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.4.0.tgz#f042641fd2593fa5f4f002fc30d1fb1a20284df8"
- integrity sha512-6QkgnLYwQrW0qv+yXIf617DojJbGmza2XJXUlgnzrGGhxzfAynzEjaLyYkc8rYS1m82vjrl9EOmLHTcnVkvZAQ==
- dependencies:
- apollo-server-caching "0.4.0"
- apollo-server-env "2.3.0"
-
apollo-datasource@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.5.0.tgz#7a8c97e23da7b9c15cb65103d63178ab19eca5e9"
@@ -1376,18 +1353,6 @@ apollo-engine-reporting-protobuf@0.3.0:
dependencies:
protobufjs "^6.8.6"
-apollo-engine-reporting@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.1.1.tgz#f5a3240bc5c5afb210ff8c45d72995de7b0d2a13"
- integrity sha512-K7BDsj99jr8ftd9NIuHL4oF/S7CBFcgMGjL0ChhfxpkgUv80FPxJ+9Fs+9ZkKIVylV3PCi2WnihpDeEO10eZAw==
- dependencies:
- apollo-engine-reporting-protobuf "0.3.0"
- apollo-graphql "^0.2.1-alpha.1"
- apollo-server-core "2.5.1"
- apollo-server-env "2.3.0"
- async-retry "^1.2.1"
- graphql-extensions "0.6.1"
-
apollo-engine-reporting@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.2.1.tgz#0b77fad2e9221d62f4a29b8b4fab8f7f47dcc1d6"
@@ -1400,15 +1365,6 @@ apollo-engine-reporting@1.2.1:
async-retry "^1.2.1"
graphql-extensions "0.7.1"
-apollo-env@0.4.1-alpha.1:
- version "0.4.1-alpha.1"
- resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.4.1-alpha.1.tgz#10d3ea508b8f3ba03939ef4e6ec4b2b5db77e8f1"
- integrity sha512-4qWiaUKWh92jvKxxRsiZSjmW9YH9GWSG1W6X+S1BcC1uqtPiHsem7ExG9MMTt+UrzHsbpQLctj12xk8lI4lgCg==
- dependencies:
- core-js "3.0.0-beta.13"
- node-fetch "^2.2.0"
- sha.js "^2.4.11"
-
apollo-env@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.5.1.tgz#b9b0195c16feadf0fe9fd5563edb0b9b7d9e97d3"
@@ -1426,14 +1382,6 @@ apollo-errors@^1.9.0:
assert "^1.4.1"
extendable-error "^0.1.5"
-apollo-graphql@^0.2.1-alpha.1:
- version "0.2.1-alpha.1"
- resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.2.1-alpha.1.tgz#a0cc0bd65e03c7e887c96c9f53421f3c6dd7b599"
- integrity sha512-kObCSpYRHEf4IozJV+TZAXEL2Yni2DpzQckohJNYXg5/KRAF20jJ7lHxuJz+kMQrc7QO4wYGSa29HuFZH2AtQA==
- dependencies:
- apollo-env "0.4.1-alpha.1"
- lodash.sortby "^4.7.0"
-
apollo-graphql@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.3.1.tgz#d13b80cc0cae3fe7066b81b80914c6f983fac8d7"
@@ -1492,32 +1440,6 @@ apollo-server-caching@0.4.0:
dependencies:
lru-cache "^5.0.0"
-apollo-server-core@2.5.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.5.1.tgz#0fdb6cfca56a0f5b5b3aecffb48db17b3c8e1d71"
- integrity sha512-4QNrW1AUM3M/p0+hbBX/MsjSjZTy+2rt7JpiKKkG9RmeEIzd/VG7hwwwloAZSLjYx3twz0+BnASJ9y+rGEPC8A==
- dependencies:
- "@apollographql/apollo-tools" "^0.3.6"
- "@apollographql/graphql-playground-html" "1.6.20"
- "@types/ws" "^6.0.0"
- apollo-cache-control "0.6.1"
- apollo-datasource "0.4.0"
- apollo-engine-reporting "1.1.1"
- apollo-server-caching "0.4.0"
- apollo-server-env "2.3.0"
- apollo-server-errors "2.3.0"
- apollo-server-plugin-base "0.4.1"
- apollo-tracing "0.6.1"
- fast-json-stable-stringify "^2.0.0"
- graphql-extensions "0.6.1"
- graphql-subscriptions "^1.0.0"
- graphql-tag "^2.9.2"
- graphql-tools "^4.0.0"
- graphql-upload "^8.0.2"
- sha.js "^2.4.11"
- subscriptions-transport-ws "^0.9.11"
- ws "^6.0.0"
-
apollo-server-core@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.1.tgz#d0d878b0a4959b6c661fc43300ce45b29996176a"
@@ -1553,14 +1475,6 @@ apollo-server-core@^1.3.6, apollo-server-core@^1.4.0:
apollo-tracing "^0.1.0"
graphql-extensions "^0.0.x"
-apollo-server-env@2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.3.0.tgz#f0bf4484a6cc331a8c13763ded56e91beb16ba17"
- integrity sha512-WIwlkCM/gir0CkoYWPMTCH8uGCCKB/aM074U1bKayvkFOBVO2VgG5x2kgsfkyF05IMQq2/GOTsKhNY7RnUEhTA==
- dependencies:
- node-fetch "^2.1.2"
- util.promisify "^1.0.0"
-
apollo-server-env@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.4.0.tgz#6611556c6b627a1636eed31317d4f7ea30705872"
@@ -1574,10 +1488,10 @@ apollo-server-errors@2.3.0:
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.0.tgz#700622b66a16dffcad3b017e4796749814edc061"
integrity sha512-rUvzwMo2ZQgzzPh2kcJyfbRSfVKRMhfIlhY7BzUfM4x6ZT0aijlgsf714Ll3Mbf5Fxii32kD0A/DmKsTecpccw==
-apollo-server-express@2.5.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.5.1.tgz#b112d9795f2fb39076d9cbc109f5eeb7835bed6b"
- integrity sha512-528wDQnOMIenDaICkYPFWQykdXQZwpygxd+Ar0PmZiaST042NSVExV4iRWI09p1THqfsuyHygqpkK+K94bUtBA==
+apollo-server-express@2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.6.1.tgz#1e2649d3fd38c0c0a2c830090fd41e086b259c9f"
+ integrity sha512-TVu68LVp+COMGOXuxc0OFeCUQiPApxy7Isv2Vk85nikZV4t4FXlODB6PrRKf5rfvP31dvGsfE6GHPJTLLbKfyg==
dependencies:
"@apollographql/graphql-playground-html" "1.6.20"
"@types/accepts" "^1.3.5"
@@ -1585,7 +1499,7 @@ apollo-server-express@2.5.1:
"@types/cors" "^2.8.4"
"@types/express" "4.16.1"
accepts "^1.3.5"
- apollo-server-core "2.5.1"
+ apollo-server-core "2.6.1"
body-parser "^1.18.3"
cors "^2.8.4"
graphql-subscriptions "^1.0.0"
@@ -1613,11 +1527,6 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0:
resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec"
integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA==
-apollo-server-plugin-base@0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.4.1.tgz#be380b28d71ad3b6b146d0d6a8f7ebf5675b07ff"
- integrity sha512-D2G6Ca/KBdQgEbmSfYqZqYbdVJnk/rrSv7Vj2NntwjfL7WJf0TjufxYJlrTH5jF6xCbsszDNGqfmt2Nm8x/o4g==
-
apollo-server-plugin-base@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.1.tgz#b81056666763879bdc98d8d58f3c4c43cbb30da6"
@@ -1630,25 +1539,17 @@ apollo-server-testing@~2.6.1:
dependencies:
apollo-server-core "2.6.1"
-apollo-server@~2.5.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.5.1.tgz#bfcfbebc123f692c0e6d85b0c56739646bd1bb7e"
- integrity sha512-eH3ubq300xhpFAxek28kb+5WZINXpWcwzyNqBQDbuasTlW8qSsqY7xrV6IIz6WUYKdX+ET0mx+Ta1DdaYQPrqw==
+apollo-server@~2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.6.1.tgz#1b1fc6020b75c0913550da5fa0f2005c62f1bc53"
+ integrity sha512-Ed0zZjluRYPMC3Yr6oXQjcR11izu86nkjiS2MhjJA1mF8IXJfxbPp2hnX4Jf4vXPSkOP2e5ZHw0cdaIcu9GnRw==
dependencies:
- apollo-server-core "2.5.1"
- apollo-server-express "2.5.1"
+ apollo-server-core "2.6.1"
+ apollo-server-express "2.6.1"
express "^4.0.0"
graphql-subscriptions "^1.0.0"
graphql-tools "^4.0.0"
-apollo-tracing@0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.6.1.tgz#48a6d6040f9b2f2b4365a890c2e97cb763eb2392"
- integrity sha512-rrDBgTHa9GDA3wY8O7rDsFwC6ePIVzRGxpUsThgmLvIVkkCr0KS4wJJ4C01c+v4xsOXNuQwx0IyYhxZt4twwcA==
- dependencies:
- apollo-server-env "2.3.0"
- graphql-extensions "0.6.1"
-
apollo-tracing@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.7.1.tgz#6a7356b619f3aa0ca22c623b5d8bb1af5ca1c74c"
@@ -2524,11 +2425,6 @@ core-js-pure@3.1.2:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.2.tgz#62fc435f35b7374b9b782013cdcb2f97e9f6dffa"
integrity sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w==
-core-js@3.0.0-beta.13:
- version "3.0.0-beta.13"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.13.tgz#7732c69be5e4758887917235fe7c0352c4cb42a1"
- integrity sha512-16Q43c/3LT9NyePUJKL8nRIQgYWjcBhjJSMWg96PVSxoS0PeE0NHitPI3opBrs9MGGHjte1KoEVr9W63YKlTXQ==
-
core-js@^2.4.0, core-js@^2.5.3, core-js@^2.5.7:
version "2.6.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.2.tgz#267988d7268323b349e20b4588211655f0e83944"
@@ -3832,13 +3728,6 @@ graphql-deduplicator@^2.0.1:
resolved "https://registry.yarnpkg.com/graphql-deduplicator/-/graphql-deduplicator-2.0.2.tgz#d8608161cf6be97725e178df0c41f6a1f9f778f3"
integrity sha512-0CGmTmQh4UvJfsaTPppJAcHwHln8Ayat7yXXxdnuWT+Mb1dBzkbErabCWzjXyKh/RefqlGTTA7EQOZHofMaKJA==
-graphql-extensions@0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.6.1.tgz#e61c4cb901e336dc5993a61093a8678a021dda59"
- integrity sha512-vB2WNQJn99pncHfvxgcdyVoazmG3cD8XzkgcaDrHTvV+xJGJEBP6056EWi0mNt1d6ukYyRS2zexdekmMCjcq0w==
- dependencies:
- "@apollographql/apollo-tools" "^0.3.6-alpha.1"
-
graphql-extensions@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.1.tgz#f55b01ac8ddf09a215e21f34caeee3ae66a88f21"
diff --git a/deployment/human-connection/templates/configmap.template.yaml b/deployment/human-connection/templates/configmap.template.yaml
index baf41661a..87b51a7d3 100644
--- a/deployment/human-connection/templates/configmap.template.yaml
+++ b/deployment/human-connection/templates/configmap.template.yaml
@@ -4,7 +4,7 @@
data:
GRAPHQL_PORT: "4000"
GRAPHQL_URI: "http://nitro-backend.human-connection:4000"
- MOCK: "false"
+ MOCKS: "false"
NEO4J_URI: "bolt://nitro-neo4j.human-connection:7687"
NEO4J_USER: "neo4j"
NEO4J_AUTH: "none"
diff --git a/deployment/legacy-migration/maintenance-worker/migration/mongo/.env b/deployment/legacy-migration/maintenance-worker/migration/mongo/.env
index 602f51fc4..4c5f9e18c 100644
--- a/deployment/legacy-migration/maintenance-worker/migration/mongo/.env
+++ b/deployment/legacy-migration/maintenance-worker/migration/mongo/.env
@@ -12,5 +12,6 @@
# On Windows this resolves to C:\Users\dornhoeschen\AppData\Local\Temp\mongo-export (MinGW)
EXPORT_PATH='/tmp/mongo-export/'
EXPORT_MONGOEXPORT_BIN='mongoexport'
+MONGO_EXPORT_SPLIT_SIZE=100
# On Windows use something like this
-# EXPORT_MONGOEXPORT_BIN='C:\Program Files\MongoDB\Server\3.6\bin\mongoexport.exe'
\ No newline at end of file
+# EXPORT_MONGOEXPORT_BIN='C:\Program Files\MongoDB\Server\3.6\bin\mongoexport.exe'
diff --git a/deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh b/deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh
index 257bc4c61..abed9b0f5 100755
--- a/deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh
+++ b/deployment/legacy-migration/maintenance-worker/migration/mongo/export.sh
@@ -10,7 +10,7 @@ set +o allexport
function export_collection () {
"${EXPORT_MONGOEXPORT_BIN}" --db ${MONGODB_DATABASE} --host localhost -d ${MONGODB_DATABASE} --port 27018 --username ${MONGODB_USERNAME} --password ${MONGODB_PASSWORD} --authenticationDatabase ${MONGODB_AUTH_DB} --collection $1 --collection $1 --out "${EXPORT_PATH}$1.json"
mkdir -p ${EXPORT_PATH}splits/$1/
- split -l 1000 -a 3 ${EXPORT_PATH}$1.json ${EXPORT_PATH}splits/$1/
+ split -l ${MONGO_EXPORT_SPLIT_SIZE} -a 3 ${EXPORT_PATH}$1.json ${EXPORT_PATH}splits/$1/
}
# Delete old export & ensure directory
diff --git a/deployment/legacy-migration/maintenance-worker/migration/neo4j/import.sh b/deployment/legacy-migration/maintenance-worker/migration/neo4j/import.sh
index 08c05c8cc..ac256e3f0 100755
--- a/deployment/legacy-migration/maintenance-worker/migration/neo4j/import.sh
+++ b/deployment/legacy-migration/maintenance-worker/migration/neo4j/import.sh
@@ -83,17 +83,17 @@ import_collection "contributions"
import_collection "shouts"
import_collection "comments"
-import_collection "emotions"
-import_collection "invites"
-import_collection "notifications"
-import_collection "organizations"
-import_collection "pages"
-import_collection "projects"
-import_collection "settings"
-import_collection "status"
-import_collection "systemnotifications"
-import_collection "userscandos"
-import_collection "usersettings"
+# import_collection "emotions"
+# import_collection "invites"
+# import_collection "notifications"
+# import_collection "organizations"
+# import_collection "pages"
+# import_collection "projects"
+# import_collection "settings"
+# import_collection "status"
+# import_collection "systemnotifications"
+# import_collection "userscandos"
+# import_collection "usersettings"
echo "DONE"
diff --git a/docker-compose.maintenance.yml b/docker-compose.maintenance.yml
index 113b4492c..e536b1157 100644
--- a/docker-compose.maintenance.yml
+++ b/docker-compose.maintenance.yml
@@ -19,7 +19,7 @@ services:
- GRAPHQL_URI=http://localhost:4000
- CLIENT_URI=http://localhost:3000
- JWT_SECRET=b/&&7b78BF&fv/Vd
- - MOCK=false
+ - MOCKS=false
- MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ
- PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78
- NEO4J_apoc_import_file_enabled=true
@@ -30,6 +30,7 @@ services:
- "MONGODB_AUTH_DB=${MONGODB_AUTH_DB}"
- "MONGODB_DATABASE=${MONGODB_DATABASE}"
- "UPLOADS_DIRECTORY=${UPLOADS_DIRECTORY}"
+ - "MONGO_EXPORT_SPLIT_SIZE=${MONGO_EXPORT_SPLIT_SIZE}"
ports:
- 7687:7687
- 7474:7474
diff --git a/docker-compose.yml b/docker-compose.yml
index 896d1bef9..ca66217c2 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -32,7 +32,7 @@ services:
- GRAPHQL_URI=http://localhost:4000
- CLIENT_URI=http://localhost:3000
- JWT_SECRET=b/&&7b78BF&fv/Vd
- - MOCK=false
+ - MOCKS=false
- MAPBOX_TOKEN=pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ
- PRIVATE_KEY_PASSPHRASE=a7dsf78sadg87ad87sfagsadg78
neo4j:
diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh
index 1f627cf1a..9aa9a8e2a 100755
--- a/scripts/docker_push.sh
+++ b/scripts/docker_push.sh
@@ -2,5 +2,7 @@
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-backend:latest $TRAVIS_BUILD_DIR/backend
docker build --build-arg BUILD_COMMIT=$TRAVIS_COMMIT --target production -t humanconnection/nitro-web:latest $TRAVIS_BUILD_DIR/webapp
+docker build -t humanconnection/nitro-maintenance-worker:latest $TRAVIS_BUILD_DIR/deployment/legacy-migration/maintenance-worker
docker push humanconnection/nitro-backend:latest
docker push humanconnection/nitro-web:latest
+docker push humanconnection/nitro-maintenance-worker:latest
diff --git a/webapp/components/Comment.spec.js b/webapp/components/Comment.spec.js
index ebb9b8bf8..e899a05e1 100644
--- a/webapp/components/Comment.spec.js
+++ b/webapp/components/Comment.spec.js
@@ -14,11 +14,20 @@ describe('Comment.vue', () => {
let propsData
let mocks
let getters
+ let wrapper
+ let Wrapper
beforeEach(() => {
propsData = {}
mocks = {
$t: jest.fn(),
+ $toast: {
+ success: jest.fn(),
+ error: jest.fn(),
+ },
+ $apollo: {
+ mutate: jest.fn().mockResolvedValue(),
+ },
}
getters = {
'auth/user': () => {
@@ -29,11 +38,16 @@ describe('Comment.vue', () => {
})
describe('shallowMount', () => {
- const Wrapper = () => {
+ Wrapper = () => {
const store = new Vuex.Store({
getters,
})
- return shallowMount(Comment, { store, propsData, mocks, localVue })
+ return shallowMount(Comment, {
+ store,
+ propsData,
+ mocks,
+ localVue,
+ })
}
describe('given a comment', () => {
@@ -45,7 +59,7 @@ describe('Comment.vue', () => {
})
it('renders content', () => {
- const wrapper = Wrapper()
+ wrapper = Wrapper()
expect(wrapper.text()).toMatch('Hello I am a comment content')
})
@@ -55,17 +69,17 @@ describe('Comment.vue', () => {
})
it('renders no comment data', () => {
- const wrapper = Wrapper()
+ wrapper = Wrapper()
expect(wrapper.text()).not.toMatch('comment content')
})
it('has no "disabled-content" css class', () => {
- const wrapper = Wrapper()
+ wrapper = Wrapper()
expect(wrapper.classes()).not.toContain('disabled-content')
})
it('translates a placeholder', () => {
- /* const wrapper = */ Wrapper()
+ wrapper = Wrapper()
const calls = mocks.$t.mock.calls
const expected = [['comment.content.unavailable-placeholder']]
expect(calls).toEqual(expect.arrayContaining(expected))
@@ -77,16 +91,46 @@ describe('Comment.vue', () => {
})
it('renders comment data', () => {
- const wrapper = Wrapper()
+ wrapper = Wrapper()
expect(wrapper.text()).toMatch('comment content')
})
it('has a "disabled-content" css class', () => {
- const wrapper = Wrapper()
+ wrapper = Wrapper()
expect(wrapper.classes()).toContain('disabled-content')
})
})
})
+
+ beforeEach(jest.useFakeTimers)
+
+ describe('test callbacks', () => {
+ beforeEach(() => {
+ wrapper = Wrapper()
+ })
+
+ describe('deletion of Comment from List by invoking "deleteCommentCallback()"', () => {
+ beforeEach(() => {
+ wrapper.vm.deleteCommentCallback()
+ })
+
+ describe('after timeout', () => {
+ beforeEach(jest.runAllTimers)
+
+ it('emits "deleteComment"', () => {
+ expect(wrapper.emitted().deleteComment.length).toBe(1)
+ })
+
+ it('does call mutation', () => {
+ expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1)
+ })
+
+ it('mutation is successful', () => {
+ expect(mocks.$toast.success).toHaveBeenCalledTimes(1)
+ })
+ })
+ })
+ })
})
})
})
diff --git a/webapp/components/Comment.vue b/webapp/components/Comment.vue
index 5bce3d480..4796dd783 100644
--- a/webapp/components/Comment.vue
+++ b/webapp/components/Comment.vue
@@ -14,6 +14,7 @@
placement="bottom-end"
resource-type="comment"
:resource="comment"
+ :callbacks="{ confirm: deleteCommentCallback, cancel: null }"
style="float-right"
:is-owner="isAuthor(author.id)"
/>
@@ -27,6 +28,7 @@
diff --git a/webapp/components/ContentMenu.vue b/webapp/components/ContentMenu.vue
index 6e5bca4c0..69289cb6d 100644
--- a/webapp/components/ContentMenu.vue
+++ b/webapp/components/ContentMenu.vue
@@ -28,6 +28,7 @@
import Dropdown from '~/components/Dropdown'
export default {
+ name: 'ContentMenu',
components: {
Dropdown,
},
@@ -42,6 +43,7 @@ export default {
return value.match(/(contribution|comment|organization|user)/)
},
},
+ callbacks: { type: Object, required: true },
},
computed: {
routes() {
@@ -49,7 +51,7 @@ export default {
if (this.isOwner && this.resourceType === 'contribution') {
routes.push({
- name: this.$t(`contribution.edit`),
+ name: this.$t(`post.menu.edit`),
path: this.$router.resolve({
name: 'post-edit-id',
params: {
@@ -59,21 +61,29 @@ export default {
icon: 'edit',
})
routes.push({
- name: this.$t(`post.delete.title`),
+ name: this.$t(`post.menu.delete`),
callback: () => {
this.openModal('delete')
},
icon: 'trash',
})
}
+
if (this.isOwner && this.resourceType === 'comment') {
+ // routes.push({
+ // name: this.$t(`comment.menu.edit`),
+ // callback: () => {
+ // /* eslint-disable-next-line no-console */
+ // console.log('EDIT COMMENT')
+ // },
+ // icon: 'edit'
+ // })
routes.push({
- name: this.$t(`comment.edit`),
+ name: this.$t(`comment.menu.delete`),
callback: () => {
- /* eslint-disable-next-line no-console */
- console.log('EDIT COMMENT')
+ this.openModal('delete')
},
- icon: 'edit',
+ icon: 'trash',
})
}
@@ -125,6 +135,7 @@ export default {
data: {
type: this.resourceType,
resource: this.resource,
+ callbacks: this.callbacks,
},
})
},
diff --git a/webapp/components/Modal.spec.js b/webapp/components/Modal.spec.js
index 52d13c4a0..0e2158e96 100644
--- a/webapp/components/Modal.spec.js
+++ b/webapp/components/Modal.spec.js
@@ -1,5 +1,6 @@
import { shallowMount, createLocalVue } from '@vue/test-utils'
import Modal from './Modal.vue'
+import DeleteModal from './Modal/DeleteModal.vue'
import DisableModal from './Modal/DisableModal.vue'
import ReportModal from './Modal/ReportModal.vue'
import Vuex from 'vuex'
@@ -29,7 +30,11 @@ describe('Modal.vue', () => {
'modal/SET_OPEN': mutations.SET_OPEN,
},
})
- return mountMethod(Modal, { store, mocks, localVue })
+ return mountMethod(Modal, {
+ store,
+ mocks,
+ localVue,
+ })
}
}
@@ -55,6 +60,7 @@ describe('Modal.vue', () => {
it('initially empty', () => {
wrapper = Wrapper()
+ expect(wrapper.contains(DeleteModal)).toBe(false)
expect(wrapper.contains(DisableModal)).toBe(false)
expect(wrapper.contains(ReportModal)).toBe(false)
})
@@ -69,6 +75,10 @@ describe('Modal.vue', () => {
id: 'c456',
title: 'some title',
},
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
},
}
wrapper = Wrapper()
@@ -83,6 +93,10 @@ describe('Modal.vue', () => {
type: 'contribution',
name: 'some title',
id: 'c456',
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
})
})
@@ -97,23 +111,49 @@ describe('Modal.vue', () => {
it('passes author name to disable modal', () => {
state.data = {
type: 'comment',
- resource: { id: 'c456', author: { name: 'Author name' } },
+ resource: {
+ id: 'c456',
+ author: {
+ name: 'Author name',
+ },
+ },
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
}
wrapper = Wrapper()
expect(wrapper.find(DisableModal).props()).toEqual({
type: 'comment',
name: 'Author name',
id: 'c456',
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
})
})
it('does not crash if author is undefined', () => {
- state.data = { type: 'comment', resource: { id: 'c456' } }
+ state.data = {
+ type: 'comment',
+ resource: {
+ id: 'c456',
+ },
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
+ }
wrapper = Wrapper()
expect(wrapper.find(DisableModal).props()).toEqual({
type: 'comment',
name: '',
id: 'c456',
+ callbacks: {
+ confirm: null,
+ cancel: null,
+ },
})
})
})
diff --git a/webapp/components/Modal.vue b/webapp/components/Modal.vue
index 88b89d407..efe1b8ab6 100644
--- a/webapp/components/Modal.vue
+++ b/webapp/components/Modal.vue
@@ -1,10 +1,12 @@
+