mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2026-01-20 20:01:22 +00:00
Merge branch 'master' of https://github.com/Human-Connection/Human-Connection into 1455-fix-update-comment-list
# Conflicts: # webapp/components/Comment.vue # webapp/components/CommentForm/CommentForm.spec.js # webapp/components/CommentForm/CommentForm.vue # webapp/components/EditCommentForm/EditCommentForm.vue # webapp/store/editor.js
This commit is contained in:
commit
379f7d1ed7
@ -46,8 +46,8 @@
|
||||
"activitystrea.ms": "~2.1.3",
|
||||
"apollo-cache-inmemory": "~1.6.3",
|
||||
"apollo-client": "~2.6.4",
|
||||
"apollo-link-context": "~1.0.18",
|
||||
"apollo-link-http": "~1.5.15",
|
||||
"apollo-link-context": "~1.0.19",
|
||||
"apollo-link-http": "~1.5.16",
|
||||
"apollo-server": "~2.9.3",
|
||||
"apollo-server-express": "^2.9.0",
|
||||
"babel-plugin-transform-runtime": "^6.23.0",
|
||||
@ -55,7 +55,7 @@
|
||||
"cheerio": "~1.0.0-rc.3",
|
||||
"cors": "~2.8.5",
|
||||
"cross-env": "~5.2.1",
|
||||
"date-fns": "2.0.1",
|
||||
"date-fns": "2.1.0",
|
||||
"debug": "~4.1.1",
|
||||
"dotenv": "~8.1.0",
|
||||
"express": "^4.17.1",
|
||||
@ -65,7 +65,7 @@
|
||||
"graphql-iso-date": "~3.6.1",
|
||||
"graphql-middleware": "~3.0.5",
|
||||
"graphql-middleware-sentry": "^3.2.0",
|
||||
"graphql-shield": "~6.0.6",
|
||||
"graphql-shield": "~6.1.0",
|
||||
"graphql-tag": "~2.10.1",
|
||||
"helmet": "~3.21.0",
|
||||
"jsonwebtoken": "~8.5.1",
|
||||
@ -91,7 +91,7 @@
|
||||
"minimatch": "^3.0.4",
|
||||
"neo4j-driver": "~1.7.6",
|
||||
"neo4j-graphql-js": "^2.7.2",
|
||||
"neode": "^0.3.2",
|
||||
"neode": "^0.3.3",
|
||||
"node-fetch": "~2.6.0",
|
||||
"nodemailer": "^6.3.0",
|
||||
"npm-run-all": "~4.1.5",
|
||||
@ -104,12 +104,12 @@
|
||||
"wait-on": "~3.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "~7.5.5",
|
||||
"@babel/core": "~7.5.5",
|
||||
"@babel/node": "~7.5.5",
|
||||
"@babel/cli": "~7.6.0",
|
||||
"@babel/core": "~7.6.0",
|
||||
"@babel/node": "~7.6.1",
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
|
||||
"@babel/preset-env": "~7.5.5",
|
||||
"@babel/register": "~7.5.5",
|
||||
"@babel/preset-env": "~7.6.0",
|
||||
"@babel/register": "~7.6.0",
|
||||
"apollo-server-testing": "~2.9.3",
|
||||
"babel-core": "~7.0.0-0",
|
||||
"babel-eslint": "~10.0.3",
|
||||
|
||||
@ -3,6 +3,22 @@ import nodemailer from 'nodemailer'
|
||||
import { resetPasswordMail, wrongAccountMail } from './templates/passwordReset'
|
||||
import { signupTemplate } from './templates/signup'
|
||||
|
||||
let sendMail
|
||||
if (CONFIG.SMTP_HOST && CONFIG.SMTP_PORT) {
|
||||
sendMail = async templateArgs => {
|
||||
await transporter().sendMail({
|
||||
from: '"Human Connection" <info@human-connection.org>',
|
||||
...templateArgs,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
sendMail = () => {}
|
||||
if (process.env.NODE_ENV !== 'test') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Warning: Email middleware will not try to send mails.')
|
||||
}
|
||||
}
|
||||
|
||||
const transporter = () => {
|
||||
const configs = {
|
||||
host: CONFIG.SMTP_HOST,
|
||||
@ -17,41 +33,24 @@ const transporter = () => {
|
||||
return nodemailer.createTransport(configs)
|
||||
}
|
||||
|
||||
const returnResponse = async (resolve, root, args, context, resolveInfo) => {
|
||||
const { response } = await resolve(root, args, context, resolveInfo)
|
||||
delete response.nonce
|
||||
return response
|
||||
}
|
||||
|
||||
const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
|
||||
const { email } = args
|
||||
const { response, nonce } = await resolve(root, args, context, resolveInfo)
|
||||
const response = await resolve(root, args, context, resolveInfo)
|
||||
const { email, nonce } = response
|
||||
await sendMail(signupTemplate({ email, nonce }))
|
||||
delete response.nonce
|
||||
await transporter().sendMail(signupTemplate({ email, nonce }))
|
||||
return response
|
||||
}
|
||||
|
||||
export default function({ isEnabled }) {
|
||||
if (!isEnabled)
|
||||
return {
|
||||
Mutation: {
|
||||
requestPasswordReset: returnResponse,
|
||||
Signup: returnResponse,
|
||||
SignupByInvitation: returnResponse,
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
Mutation: {
|
||||
requestPasswordReset: async (resolve, root, args, context, resolveInfo) => {
|
||||
const { email } = args
|
||||
const { response, user, code, name } = await resolve(root, args, context, resolveInfo)
|
||||
const mailTemplate = user ? resetPasswordMail : wrongAccountMail
|
||||
await transporter().sendMail(mailTemplate({ email, code, name }))
|
||||
return response
|
||||
},
|
||||
Signup: sendSignupMail,
|
||||
SignupByInvitation: sendSignupMail,
|
||||
export default {
|
||||
Mutation: {
|
||||
requestPasswordReset: async (resolve, root, args, context, resolveInfo) => {
|
||||
const { email } = args
|
||||
const { email: emailFound, nonce, name } = await resolve(root, args, context, resolveInfo)
|
||||
const mailTemplate = emailFound ? resetPasswordMail : wrongAccountMail
|
||||
await sendMail(mailTemplate({ email, nonce, name }))
|
||||
return true
|
||||
},
|
||||
}
|
||||
Signup: sendSignupMail,
|
||||
SignupByInvitation: sendSignupMail,
|
||||
},
|
||||
}
|
||||
|
||||
@ -1,17 +1,15 @@
|
||||
import CONFIG from '../../../config'
|
||||
|
||||
export const from = '"Human Connection" <info@human-connection.org>'
|
||||
|
||||
export const resetPasswordMail = options => {
|
||||
const {
|
||||
name,
|
||||
email,
|
||||
code,
|
||||
nonce,
|
||||
subject = 'Use this link to reset your password. The link is only valid for 24 hours.',
|
||||
supportUrl = 'https://human-connection.org/en/contact/',
|
||||
} = options
|
||||
const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI)
|
||||
actionUrl.searchParams.set('code', code)
|
||||
actionUrl.searchParams.set('nonce', nonce)
|
||||
actionUrl.searchParams.set('email', email)
|
||||
|
||||
return {
|
||||
@ -37,7 +35,7 @@ The Human Connection Team
|
||||
If you're having trouble with the link above, you can manually copy and
|
||||
paste the following code into your browser window:
|
||||
|
||||
${code}
|
||||
${nonce}
|
||||
|
||||
Human Connection gemeinnützige GmbH
|
||||
Bahnhofstr. 11
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import CONFIG from '../../../config'
|
||||
|
||||
export const from = '"Human Connection" <info@human-connection.org>'
|
||||
|
||||
export const signupTemplate = options => {
|
||||
const {
|
||||
email,
|
||||
nonce,
|
||||
subject = 'Signup link',
|
||||
subject = 'Welcome to Human Connection! Here is your signup link.',
|
||||
supportUrl = 'https://human-connection.org/en/contact/',
|
||||
} = options
|
||||
const actionUrl = new URL('/registration/create-user-account', CONFIG.CLIENT_URI)
|
||||
@ -17,12 +15,33 @@ export const signupTemplate = options => {
|
||||
to: email,
|
||||
subject,
|
||||
text: `
|
||||
Willkommen bei Human Connection! Klick auf diesen Link, um den
|
||||
Registrierungsprozess abzuschließen und um ein Benutzerkonto zu erstellen!
|
||||
|
||||
${actionUrl}
|
||||
|
||||
Alternativ kannst du diesen Code auch kopieren und im Browserfenster einfügen:
|
||||
|
||||
${nonce}
|
||||
|
||||
Bitte ignoriere diese Mail, falls du dich nicht bei Human Connection angemeldet
|
||||
hast. Bei Fragen kontaktiere gerne unseren Support:
|
||||
|
||||
${supportUrl}
|
||||
|
||||
Danke,
|
||||
Das Human Connection Team
|
||||
|
||||
|
||||
English Version
|
||||
===============
|
||||
|
||||
Welcome to Human Connection! Use this link to complete the registration process
|
||||
and create a user account:
|
||||
|
||||
${actionUrl}
|
||||
|
||||
You can also copy+paste this verification code in your browser window:
|
||||
You can also copy+paste this verification nonce in your browser window:
|
||||
|
||||
${nonce}
|
||||
|
||||
|
||||
@ -33,9 +33,7 @@ export default schema => {
|
||||
user,
|
||||
includedFields,
|
||||
orderBy,
|
||||
email: email({
|
||||
isEnabled: CONFIG.SMTP_HOST && CONFIG.SMTP_PORT,
|
||||
}),
|
||||
email,
|
||||
}
|
||||
|
||||
let order = [
|
||||
|
||||
@ -1,62 +1,81 @@
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
import Factory from '../seed/factories'
|
||||
import { host, login, gql } from '../jest/helpers'
|
||||
import { neode } from '../bootstrap/neo4j'
|
||||
import { gql } from '../jest/helpers'
|
||||
import { neode as getNeode, getDriver } from '../bootstrap/neo4j'
|
||||
import createServer from '../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
let authenticatedClient
|
||||
let headers
|
||||
const factory = Factory()
|
||||
const instance = neode()
|
||||
const categoryIds = ['cat9']
|
||||
const createPostMutation = gql`
|
||||
mutation($title: String!, $content: String!, $categoryIds: [ID]!, $slug: String) {
|
||||
CreatePost(title: $title, content: $content, categoryIds: $categoryIds, slug: $slug) {
|
||||
slug
|
||||
}
|
||||
}
|
||||
`
|
||||
let createPostVariables = {
|
||||
title: 'I am a brand new post',
|
||||
content: 'Some content',
|
||||
categoryIds,
|
||||
}
|
||||
|
||||
let mutate
|
||||
let authenticatedUser
|
||||
let variables
|
||||
|
||||
const driver = getDriver()
|
||||
const neode = getNeode()
|
||||
|
||||
beforeAll(() => {
|
||||
const { server } = createServer({
|
||||
context: () => {
|
||||
return {
|
||||
driver,
|
||||
neode,
|
||||
user: authenticatedUser,
|
||||
}
|
||||
},
|
||||
})
|
||||
mutate = createTestClient(server).mutate
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
const adminParams = { role: 'admin', email: 'admin@example.org', password: '1234' }
|
||||
await factory.create('User', adminParams)
|
||||
variables = {}
|
||||
const admin = await factory.create('User', { role: 'admin' })
|
||||
await factory.create('User', {
|
||||
email: 'someone@example.org',
|
||||
password: '1234',
|
||||
})
|
||||
await instance.create('Category', {
|
||||
await factory.create('Category', {
|
||||
id: 'cat9',
|
||||
name: 'Democracy & Politics',
|
||||
icon: 'university',
|
||||
})
|
||||
// we need to be an admin, otherwise we're not authorized to create a user
|
||||
headers = await login(adminParams)
|
||||
authenticatedClient = new GraphQLClient(host, { headers })
|
||||
authenticatedUser = await admin.toJson()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await factory.cleanDatabase()
|
||||
})
|
||||
|
||||
describe('slugify', () => {
|
||||
describe('slugifyMiddleware', () => {
|
||||
describe('CreatePost', () => {
|
||||
const categoryIds = ['cat9']
|
||||
const createPostMutation = gql`
|
||||
mutation($title: String!, $content: String!, $categoryIds: [ID]!, $slug: String) {
|
||||
CreatePost(title: $title, content: $content, categoryIds: $categoryIds, slug: $slug) {
|
||||
slug
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
beforeEach(() => {
|
||||
variables = {
|
||||
...variables,
|
||||
title: 'I am a brand new post',
|
||||
content: 'Some content',
|
||||
categoryIds,
|
||||
}
|
||||
})
|
||||
|
||||
it('generates a slug based on title', async () => {
|
||||
const response = await authenticatedClient.request(createPostMutation, createPostVariables)
|
||||
expect(response).toEqual({
|
||||
CreatePost: { slug: 'i-am-a-brand-new-post' },
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
CreatePost: { slug: 'i-am-a-brand-new-post' },
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('if slug exists', () => {
|
||||
beforeEach(async () => {
|
||||
const asSomeoneElse = await Factory().authenticateAs({
|
||||
email: 'someone@example.org',
|
||||
password: '1234',
|
||||
})
|
||||
await asSomeoneElse.create('Post', {
|
||||
await factory.create('Post', {
|
||||
title: 'Pre-existing post',
|
||||
slug: 'pre-existing-post',
|
||||
content: 'as Someone else content',
|
||||
@ -65,72 +84,110 @@ describe('slugify', () => {
|
||||
})
|
||||
|
||||
it('chooses another slug', async () => {
|
||||
createPostVariables = { title: 'Pre-existing post', content: 'Some content', categoryIds }
|
||||
const response = await authenticatedClient.request(createPostMutation, createPostVariables)
|
||||
expect(response).toEqual({
|
||||
CreatePost: { slug: 'pre-existing-post-1' },
|
||||
variables = {
|
||||
...variables,
|
||||
title: 'Pre-existing post',
|
||||
content: 'Some content',
|
||||
categoryIds,
|
||||
}
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject({
|
||||
data: { CreatePost: { slug: 'pre-existing-post-1' } },
|
||||
})
|
||||
})
|
||||
|
||||
describe('but if the client specifies a slug', () => {
|
||||
it('rejects CreatePost', async () => {
|
||||
createPostVariables = {
|
||||
variables = {
|
||||
...variables,
|
||||
title: 'Pre-existing post',
|
||||
content: 'Some content',
|
||||
slug: 'pre-existing-post',
|
||||
categoryIds,
|
||||
}
|
||||
await expect(
|
||||
authenticatedClient.request(createPostMutation, createPostVariables),
|
||||
).rejects.toThrow('already exists')
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject({
|
||||
errors: [{ message: 'Post with this slug already exists!' }],
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('SignupVerification', () => {
|
||||
const mutation = `mutation($password: String!, $email: String!, $name: String!, $slug: String, $nonce: String!, $termsAndConditionsAgreedVersion: String!) {
|
||||
SignupVerification(email: $email, password: $password, name: $name, slug: $slug, nonce: $nonce, termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion) {
|
||||
slug
|
||||
const mutation = gql`
|
||||
mutation(
|
||||
$password: String!
|
||||
$email: String!
|
||||
$name: String!
|
||||
$slug: String
|
||||
$nonce: String!
|
||||
$termsAndConditionsAgreedVersion: String!
|
||||
) {
|
||||
SignupVerification(
|
||||
email: $email
|
||||
password: $password
|
||||
name: $name
|
||||
slug: $slug
|
||||
nonce: $nonce
|
||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||
) {
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const action = async variables => {
|
||||
// required for SignupVerification
|
||||
await instance.create('EmailAddress', { email: '123@example.org', nonce: '123456' })
|
||||
|
||||
const defaultVariables = {
|
||||
beforeEach(() => {
|
||||
variables = {
|
||||
...variables,
|
||||
name: 'I am a user',
|
||||
nonce: '123456',
|
||||
password: 'yo',
|
||||
email: '123@example.org',
|
||||
termsAndConditionsAgreedVersion: '0.0.1',
|
||||
}
|
||||
return authenticatedClient.request(mutation, { ...defaultVariables, ...variables })
|
||||
}
|
||||
|
||||
it('generates a slug based on name', async () => {
|
||||
await expect(action({ name: 'I am a user' })).resolves.toEqual({
|
||||
SignupVerification: { slug: 'i-am-a-user' },
|
||||
})
|
||||
})
|
||||
|
||||
describe('if slug exists', () => {
|
||||
describe('given a user has signed up with their email address', () => {
|
||||
beforeEach(async () => {
|
||||
await factory.create('User', { name: 'pre-existing user', slug: 'pre-existing-user' })
|
||||
})
|
||||
|
||||
it('chooses another slug', async () => {
|
||||
await expect(action({ name: 'pre-existing-user' })).resolves.toEqual({
|
||||
SignupVerification: { slug: 'pre-existing-user-1' },
|
||||
await factory.create('EmailAddress', {
|
||||
email: '123@example.org',
|
||||
nonce: '123456',
|
||||
verifiedAt: null,
|
||||
})
|
||||
})
|
||||
|
||||
describe('but if the client specifies a slug', () => {
|
||||
it('rejects SignupVerification', async () => {
|
||||
await expect(
|
||||
action({ name: 'Pre-existing user', slug: 'pre-existing-user' }),
|
||||
).rejects.toThrow('already exists')
|
||||
it('generates a slug based on name', async () => {
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { SignupVerification: { slug: 'i-am-a-user' } },
|
||||
})
|
||||
})
|
||||
|
||||
describe('if slug exists', () => {
|
||||
beforeEach(async () => {
|
||||
await factory.create('User', { name: 'I am a user', slug: 'i-am-a-user' })
|
||||
})
|
||||
|
||||
it('chooses another slug', async () => {
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: {
|
||||
SignupVerification: { slug: 'i-am-a-user-1' },
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('but if the client specifies a slug', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, slug: 'i-am-a-user' }
|
||||
})
|
||||
|
||||
it('rejects SignupVerification', async () => {
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'User with this slug already exists!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -2,39 +2,47 @@ import uuid from 'uuid/v4'
|
||||
import bcrypt from 'bcryptjs'
|
||||
|
||||
export async function createPasswordReset(options) {
|
||||
const { driver, code, email, issuedAt = new Date() } = options
|
||||
const { driver, nonce, email, issuedAt = new Date() } = options
|
||||
const session = driver.session()
|
||||
const cypher = `
|
||||
let response = {}
|
||||
try {
|
||||
const cypher = `
|
||||
MATCH (u:User)-[:PRIMARY_EMAIL]->(e:EmailAddress {email:$email})
|
||||
CREATE(pr:PasswordReset {code: $code, issuedAt: datetime($issuedAt), usedAt: NULL})
|
||||
CREATE(pr:PasswordReset {nonce: $nonce, issuedAt: datetime($issuedAt), usedAt: NULL})
|
||||
MERGE (u)-[:REQUESTED]->(pr)
|
||||
RETURN u
|
||||
RETURN e, pr, u
|
||||
`
|
||||
const transactionRes = await session.run(cypher, {
|
||||
issuedAt: issuedAt.toISOString(),
|
||||
code,
|
||||
email,
|
||||
})
|
||||
const users = transactionRes.records.map(record => record.get('u'))
|
||||
session.close()
|
||||
return users
|
||||
const transactionRes = await session.run(cypher, {
|
||||
issuedAt: issuedAt.toISOString(),
|
||||
nonce,
|
||||
email,
|
||||
})
|
||||
const records = transactionRes.records.map(record => {
|
||||
const { email } = record.get('e').properties
|
||||
const { nonce } = record.get('pr').properties
|
||||
const { name } = record.get('u').properties
|
||||
return { email, nonce, name }
|
||||
})
|
||||
response = records[0] || {}
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
requestPasswordReset: async (_, { email }, { driver }) => {
|
||||
const code = uuid().substring(0, 6)
|
||||
const [user] = await createPasswordReset({ driver, code, email })
|
||||
const name = (user && user.name) || ''
|
||||
return { user, code, name, response: true }
|
||||
requestPasswordReset: async (_parent, { email }, { driver }) => {
|
||||
const nonce = uuid().substring(0, 6)
|
||||
return createPasswordReset({ driver, nonce, email })
|
||||
},
|
||||
resetPassword: async (_, { email, code, newPassword }, { driver }) => {
|
||||
resetPassword: async (_parent, { email, nonce, newPassword }, { driver }) => {
|
||||
const session = driver.session()
|
||||
const stillValid = new Date()
|
||||
stillValid.setDate(stillValid.getDate() - 1)
|
||||
const encryptedNewPassword = await bcrypt.hashSync(newPassword, 10)
|
||||
const cypher = `
|
||||
MATCH (pr:PasswordReset {code: $code})
|
||||
MATCH (pr:PasswordReset {nonce: $nonce})
|
||||
MATCH (e:EmailAddress {email: $email})<-[:PRIMARY_EMAIL]-(u:User)-[:REQUESTED]->(pr)
|
||||
WHERE duration.between(pr.issuedAt, datetime()).days <= 0 AND pr.usedAt IS NULL
|
||||
SET pr.usedAt = datetime()
|
||||
@ -44,13 +52,13 @@ export default {
|
||||
const transactionRes = await session.run(cypher, {
|
||||
stillValid,
|
||||
email,
|
||||
code,
|
||||
nonce,
|
||||
encryptedNewPassword,
|
||||
})
|
||||
const [reset] = transactionRes.records.map(record => record.get('pr'))
|
||||
const result = !!(reset && reset.properties.usedAt)
|
||||
const response = !!(reset && reset.properties.usedAt)
|
||||
session.close()
|
||||
return result
|
||||
return response
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1,12 +1,17 @@
|
||||
import { GraphQLClient } from 'graphql-request'
|
||||
import Factory from '../../seed/factories'
|
||||
import { host } from '../../jest/helpers'
|
||||
import { getDriver } from '../../bootstrap/neo4j'
|
||||
import { gql } from '../../jest/helpers'
|
||||
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
|
||||
import { createPasswordReset } from './passwordReset'
|
||||
import createServer from '../../server'
|
||||
import { createTestClient } from 'apollo-server-testing'
|
||||
|
||||
const factory = Factory()
|
||||
let client
|
||||
const neode = getNeode()
|
||||
const driver = getDriver()
|
||||
const factory = Factory()
|
||||
|
||||
let mutate
|
||||
let authenticatedUser
|
||||
let variables
|
||||
|
||||
const getAllPasswordResets = async () => {
|
||||
const session = driver.session()
|
||||
@ -16,120 +21,167 @@ const getAllPasswordResets = async () => {
|
||||
return resets
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
variables = {}
|
||||
})
|
||||
|
||||
beforeAll(() => {
|
||||
const { server } = createServer({
|
||||
context: () => {
|
||||
return {
|
||||
driver,
|
||||
neode,
|
||||
user: authenticatedUser,
|
||||
}
|
||||
},
|
||||
})
|
||||
mutate = createTestClient(server).mutate
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await factory.cleanDatabase()
|
||||
})
|
||||
|
||||
describe('passwordReset', () => {
|
||||
beforeEach(async () => {
|
||||
client = new GraphQLClient(host)
|
||||
await factory.create('User', {
|
||||
email: 'user@example.org',
|
||||
role: 'user',
|
||||
password: '1234',
|
||||
describe('given a user', () => {
|
||||
beforeEach(async () => {
|
||||
await factory.create('User', {
|
||||
email: 'user@example.org',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await factory.cleanDatabase()
|
||||
})
|
||||
describe('requestPasswordReset', () => {
|
||||
const mutation = gql`
|
||||
mutation($email: String!) {
|
||||
requestPasswordReset(email: $email)
|
||||
}
|
||||
`
|
||||
|
||||
describe('requestPasswordReset', () => {
|
||||
const mutation = `mutation($email: String!) { requestPasswordReset(email: $email) }`
|
||||
describe('with invalid email', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, email: 'non-existent@example.org' }
|
||||
})
|
||||
|
||||
describe('with invalid email', () => {
|
||||
const variables = { email: 'non-existent@example.org' }
|
||||
it('resolves anyways', async () => {
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { requestPasswordReset: true },
|
||||
})
|
||||
})
|
||||
|
||||
it('resolves anyways', async () => {
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({
|
||||
requestPasswordReset: true,
|
||||
it('creates no node', async () => {
|
||||
await mutate({ mutation, variables })
|
||||
const resets = await getAllPasswordResets()
|
||||
expect(resets).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('creates no node', async () => {
|
||||
await client.request(mutation, variables)
|
||||
const resets = await getAllPasswordResets()
|
||||
expect(resets).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a valid email', () => {
|
||||
const variables = { email: 'user@example.org' }
|
||||
|
||||
it('resolves', async () => {
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({
|
||||
requestPasswordReset: true,
|
||||
describe('with a valid email', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, email: 'user@example.org' }
|
||||
})
|
||||
})
|
||||
|
||||
it('creates node with label `PasswordReset`', async () => {
|
||||
await client.request(mutation, variables)
|
||||
const resets = await getAllPasswordResets()
|
||||
expect(resets).toHaveLength(1)
|
||||
})
|
||||
it('resolves', async () => {
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { requestPasswordReset: true },
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a reset code', async () => {
|
||||
await client.request(mutation, variables)
|
||||
const resets = await getAllPasswordResets()
|
||||
const [reset] = resets
|
||||
const { code } = reset.properties
|
||||
expect(code).toHaveLength(6)
|
||||
it('creates node with label `PasswordReset`', async () => {
|
||||
let resets = await getAllPasswordResets()
|
||||
expect(resets).toHaveLength(0)
|
||||
await mutate({ mutation, variables })
|
||||
resets = await getAllPasswordResets()
|
||||
expect(resets).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('creates a reset nonce', async () => {
|
||||
await mutate({ mutation, variables })
|
||||
const resets = await getAllPasswordResets()
|
||||
const [reset] = resets
|
||||
const { nonce } = reset.properties
|
||||
expect(nonce).toHaveLength(6)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('resetPassword', () => {
|
||||
const setup = async (options = {}) => {
|
||||
const { email = 'user@example.org', issuedAt = new Date(), code = 'abcdef' } = options
|
||||
describe('resetPassword', () => {
|
||||
const setup = async (options = {}) => {
|
||||
const { email = 'user@example.org', issuedAt = new Date(), nonce = 'abcdef' } = options
|
||||
|
||||
const session = driver.session()
|
||||
await createPasswordReset({ driver, email, issuedAt, code })
|
||||
session.close()
|
||||
const session = driver.session()
|
||||
await createPasswordReset({ driver, email, issuedAt, nonce })
|
||||
session.close()
|
||||
}
|
||||
|
||||
const mutation = gql`
|
||||
mutation($nonce: String!, $email: String!, $newPassword: String!) {
|
||||
resetPassword(nonce: $nonce, email: $email, newPassword: $newPassword)
|
||||
}
|
||||
`
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, newPassword: 'supersecret' }
|
||||
})
|
||||
|
||||
const mutation = `mutation($code: String!, $email: String!, $newPassword: String!) { resetPassword(code: $code, email: $email, newPassword: $newPassword) }`
|
||||
const email = 'user@example.org'
|
||||
const code = 'abcdef'
|
||||
const newPassword = 'supersecret'
|
||||
let variables
|
||||
describe('given a user', () => {
|
||||
beforeEach(async () => {
|
||||
await factory.create('User', {
|
||||
email: 'user@example.org',
|
||||
role: 'user',
|
||||
password: '1234',
|
||||
})
|
||||
})
|
||||
|
||||
describe('invalid email', () => {
|
||||
it('resolves to false', async () => {
|
||||
await setup()
|
||||
variables = { newPassword, email: 'non-existent@example.org', code }
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({ resetPassword: false })
|
||||
variables = { ...variables, email: 'non-existent@example.org', nonce: 'abcdef' }
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { resetPassword: false },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid email', () => {
|
||||
describe('but invalid code', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, email: 'user@example.org' }
|
||||
})
|
||||
|
||||
describe('but invalid nonce', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, nonce: 'slkdjf' }
|
||||
})
|
||||
|
||||
it('resolves to false', async () => {
|
||||
await setup()
|
||||
variables = { newPassword, email, code: 'slkdjf' }
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({
|
||||
resetPassword: false,
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { resetPassword: false },
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('and valid code', () => {
|
||||
describe('and valid nonce', () => {
|
||||
beforeEach(() => {
|
||||
variables = {
|
||||
newPassword,
|
||||
email: 'user@example.org',
|
||||
code: 'abcdef',
|
||||
...variables,
|
||||
nonce: 'abcdef',
|
||||
}
|
||||
})
|
||||
|
||||
describe('and code not expired', () => {
|
||||
describe('and nonce not expired', () => {
|
||||
beforeEach(async () => {
|
||||
await setup()
|
||||
})
|
||||
|
||||
it('resolves to true', async () => {
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({
|
||||
resetPassword: true,
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { resetPassword: true },
|
||||
})
|
||||
})
|
||||
|
||||
it('updates PasswordReset `usedAt` property', async () => {
|
||||
await client.request(mutation, variables)
|
||||
await mutate({ mutation, variables })
|
||||
const requests = await getAllPasswordResets()
|
||||
const [request] = requests
|
||||
const { usedAt } = request.properties
|
||||
@ -137,23 +189,20 @@ describe('passwordReset', () => {
|
||||
})
|
||||
|
||||
it('updates password of the user', async () => {
|
||||
await client.request(mutation, variables)
|
||||
const checkLoginMutation = `
|
||||
mutation($email: String!, $password: String!) {
|
||||
login(email: $email, password: $password)
|
||||
}
|
||||
await mutate({ mutation, variables })
|
||||
const checkLoginMutation = gql`
|
||||
mutation($email: String!, $password: String!) {
|
||||
login(email: $email, password: $password)
|
||||
}
|
||||
`
|
||||
const expected = expect.objectContaining({ login: expect.any(String) })
|
||||
variables = { ...variables, email: 'user@example.org', password: 'supersecret' }
|
||||
await expect(
|
||||
client.request(checkLoginMutation, {
|
||||
email: 'user@example.org',
|
||||
password: 'supersecret',
|
||||
}),
|
||||
).resolves.toEqual(expected)
|
||||
mutate({ mutation: checkLoginMutation, variables }),
|
||||
).resolves.toMatchObject({ data: { login: expect.any(String) } })
|
||||
})
|
||||
})
|
||||
|
||||
describe('but expired code', () => {
|
||||
describe('but expired nonce', () => {
|
||||
beforeEach(async () => {
|
||||
const issuedAt = new Date()
|
||||
issuedAt.setDate(issuedAt.getDate() - 1)
|
||||
@ -161,13 +210,13 @@ describe('passwordReset', () => {
|
||||
})
|
||||
|
||||
it('resolves to false', async () => {
|
||||
await expect(client.request(mutation, variables)).resolves.toEqual({
|
||||
resetPassword: false,
|
||||
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
|
||||
data: { resetPassword: false },
|
||||
})
|
||||
})
|
||||
|
||||
it('does not update PasswordReset `usedAt` property', async () => {
|
||||
await client.request(mutation, variables)
|
||||
await mutate({ mutation, variables })
|
||||
const requests = await getAllPasswordResets()
|
||||
const [request] = requests
|
||||
const { usedAt } = request.properties
|
||||
|
||||
@ -3,6 +3,7 @@ import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||
import fileUpload from './fileUpload'
|
||||
import { getBlockedUsers, getBlockedByUsers } from './users.js'
|
||||
import { mergeWith, isArray } from 'lodash'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
import Resolver from './helpers/Resolver'
|
||||
|
||||
const filterForBlockedUsers = async (params, context) => {
|
||||
@ -78,6 +79,7 @@ export default {
|
||||
delete params.categoryIds
|
||||
params = await fileUpload(params, { file: 'imageUpload', url: 'image' })
|
||||
params.id = params.id || uuid()
|
||||
let post
|
||||
|
||||
const createPostCypher = `CREATE (post:Post {params})
|
||||
WITH post
|
||||
@ -92,15 +94,21 @@ export default {
|
||||
const createPostVariables = { userId: context.user.id, categoryIds, params }
|
||||
|
||||
const session = context.driver.session()
|
||||
const transactionRes = await session.run(createPostCypher, createPostVariables)
|
||||
try {
|
||||
const transactionRes = await session.run(createPostCypher, createPostVariables)
|
||||
const posts = transactionRes.records.map(record => {
|
||||
return record.get('post').properties
|
||||
})
|
||||
post = posts[0]
|
||||
} catch (e) {
|
||||
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||
throw new UserInputError('Post with this slug already exists!')
|
||||
throw new Error(e)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
|
||||
const [post] = transactionRes.records.map(record => {
|
||||
return record.get('post')
|
||||
})
|
||||
|
||||
session.close()
|
||||
|
||||
return post.properties
|
||||
return post
|
||||
},
|
||||
UpdatePost: async (object, params, context, resolveInfo) => {
|
||||
const { categoryIds } = params
|
||||
|
||||
@ -91,7 +91,7 @@ afterEach(async () => {
|
||||
})
|
||||
|
||||
describe('Post', () => {
|
||||
const postQuery = gql`
|
||||
const postQueryFilteredByCategories = gql`
|
||||
query Post($filter: _PostFilter) {
|
||||
Post(filter: $filter) {
|
||||
id
|
||||
@ -102,13 +102,28 @@ describe('Post', () => {
|
||||
}
|
||||
`
|
||||
|
||||
const postQueryFilteredByEmotions = gql`
|
||||
query Post($filter: _PostFilter) {
|
||||
Post(filter: $filter) {
|
||||
id
|
||||
emotions {
|
||||
emotion
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
describe('can be filtered', () => {
|
||||
it('by categories', async () => {
|
||||
await Promise.all([
|
||||
let post31, post32
|
||||
beforeEach(async () => {
|
||||
;[post31, post32] = await Promise.all([
|
||||
factory.create('Post', { id: 'p31', categoryIds: ['cat4'] }),
|
||||
factory.create('Post', { id: 'p32', categoryIds: ['cat15'] }),
|
||||
factory.create('Post', { id: 'p33', categoryIds: ['cat9'] }),
|
||||
])
|
||||
})
|
||||
|
||||
it('by categories', async () => {
|
||||
const expected = {
|
||||
data: {
|
||||
Post: [
|
||||
@ -120,7 +135,50 @@ describe('Post', () => {
|
||||
},
|
||||
}
|
||||
variables = { ...variables, filter: { categories_some: { id_in: ['cat9'] } } }
|
||||
await expect(query({ query: postQuery, variables })).resolves.toMatchObject(expected)
|
||||
await expect(
|
||||
query({ query: postQueryFilteredByCategories, variables }),
|
||||
).resolves.toMatchObject(expected)
|
||||
})
|
||||
|
||||
it('by emotions', async () => {
|
||||
const expected = {
|
||||
data: {
|
||||
Post: [
|
||||
{
|
||||
id: 'p31',
|
||||
emotions: [{ emotion: 'happy' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
await user.relateTo(post31, 'emoted', { emotion: 'happy' })
|
||||
variables = { ...variables, filter: { emotions_some: { emotion_in: ['happy'] } } }
|
||||
await expect(query({ query: postQueryFilteredByEmotions, variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
})
|
||||
|
||||
it('supports filtering by multiple emotions', async () => {
|
||||
const expected = [
|
||||
{
|
||||
id: 'p31',
|
||||
emotions: [{ emotion: 'happy' }],
|
||||
},
|
||||
{
|
||||
id: 'p32',
|
||||
emotions: [{ emotion: 'cry' }],
|
||||
},
|
||||
]
|
||||
await user.relateTo(post31, 'emoted', { emotion: 'happy' })
|
||||
await user.relateTo(post32, 'emoted', { emotion: 'cry' })
|
||||
variables = { ...variables, filter: { emotions_some: { emotion_in: ['happy', 'cry'] } } }
|
||||
await expect(query({ query: postQueryFilteredByEmotions, variables })).resolves.toMatchObject(
|
||||
{
|
||||
data: {
|
||||
Post: expect.arrayContaining(expected),
|
||||
},
|
||||
},
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ForbiddenError, UserInputError } from 'apollo-server'
|
||||
import { UserInputError } from 'apollo-server'
|
||||
import uuid from 'uuid/v4'
|
||||
import { neode } from '../../bootstrap/neo4j'
|
||||
import fileUpload from './fileUpload'
|
||||
@ -18,7 +18,7 @@ const checkEmailDoesNotExist = async ({ email }) => {
|
||||
|
||||
export default {
|
||||
Mutation: {
|
||||
CreateInvitationCode: async (parent, args, context, resolveInfo) => {
|
||||
CreateInvitationCode: async (_parent, args, context, _resolveInfo) => {
|
||||
args.token = uuid().substring(0, 6)
|
||||
const {
|
||||
user: { id: userId },
|
||||
@ -37,18 +37,18 @@ export default {
|
||||
}
|
||||
return response
|
||||
},
|
||||
Signup: async (parent, args, context, resolveInfo) => {
|
||||
Signup: async (_parent, args, _context, _resolveInfo) => {
|
||||
const nonce = uuid().substring(0, 6)
|
||||
args.nonce = nonce
|
||||
await checkEmailDoesNotExist({ email: args.email })
|
||||
try {
|
||||
const emailAddress = await instance.create('EmailAddress', args)
|
||||
return { response: emailAddress.toJson(), nonce }
|
||||
return emailAddress.toJson()
|
||||
} catch (e) {
|
||||
throw new UserInputError(e.message)
|
||||
}
|
||||
},
|
||||
SignupByInvitation: async (parent, args, context, resolveInfo) => {
|
||||
SignupByInvitation: async (_parent, args, _context, _resolveInfo) => {
|
||||
const { token } = args
|
||||
const nonce = uuid().substring(0, 6)
|
||||
args.nonce = nonce
|
||||
@ -71,16 +71,16 @@ export default {
|
||||
throw new UserInputError('Invitation code already used or does not exist.')
|
||||
const emailAddress = await instance.create('EmailAddress', args)
|
||||
await validInvitationCode.relateTo(emailAddress, 'activated')
|
||||
return { response: emailAddress.toJson(), nonce }
|
||||
return emailAddress.toJson()
|
||||
} catch (e) {
|
||||
throw new UserInputError(e)
|
||||
}
|
||||
},
|
||||
SignupVerification: async (object, args, context, resolveInfo) => {
|
||||
SignupVerification: async (_parent, args, _context, _resolveInfo) => {
|
||||
const { termsAndConditionsAgreedVersion } = args
|
||||
const regEx = new RegExp(/^[0-9]+\.[0-9]+\.[0-9]+$/g)
|
||||
if (!regEx.test(termsAndConditionsAgreedVersion)) {
|
||||
throw new ForbiddenError('Invalid version format!')
|
||||
throw new UserInputError('Invalid version format!')
|
||||
}
|
||||
|
||||
let { nonce, email } = args
|
||||
@ -106,6 +106,8 @@ export default {
|
||||
])
|
||||
return user.toJson()
|
||||
} catch (e) {
|
||||
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||
throw new UserInputError('User with this slug already exists!')
|
||||
throw new UserInputError(e.message)
|
||||
}
|
||||
},
|
||||
|
||||
@ -327,6 +327,7 @@ describe('SignupVerification', () => {
|
||||
$password: String!
|
||||
$email: String!
|
||||
$nonce: String!
|
||||
$about: String
|
||||
$termsAndConditionsAgreedVersion: String!
|
||||
) {
|
||||
SignupVerification(
|
||||
@ -334,6 +335,7 @@ describe('SignupVerification', () => {
|
||||
password: $password
|
||||
email: $email
|
||||
nonce: $nonce
|
||||
about: $about
|
||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||
) {
|
||||
id
|
||||
@ -423,6 +425,15 @@ describe('SignupVerification', () => {
|
||||
expect(emails).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('sets `about` attribute of User', async () => {
|
||||
variables = { ...variables, about: 'Find this description in the user profile' }
|
||||
await mutate({ mutation, variables })
|
||||
const user = await neode.first('User', { name: 'John Doe' })
|
||||
await expect(user.toJson()).resolves.toMatchObject({
|
||||
about: 'Find this description in the user profile',
|
||||
})
|
||||
})
|
||||
|
||||
it('marks the EmailAddress as primary', async () => {
|
||||
const cypher = `
|
||||
MATCH(email:EmailAddress)<-[:PRIMARY_EMAIL]-(u:User {name: {name}})
|
||||
|
||||
@ -23,7 +23,7 @@ type Mutation {
|
||||
login(email: String!, password: String!): String!
|
||||
changePassword(oldPassword: String!, newPassword: String!): String!
|
||||
requestPasswordReset(email: String!): Boolean!
|
||||
resetPassword(email: String!, code: String!, newPassword: String!): Boolean!
|
||||
resetPassword(email: String!, nonce: String!, newPassword: String!): Boolean!
|
||||
report(id: ID!, description: String): Report
|
||||
disable(id: ID!): ID
|
||||
enable(id: ID!): ID
|
||||
|
||||
@ -3,8 +3,8 @@ type EMOTED @relation(name: "EMOTED") {
|
||||
to: Post
|
||||
|
||||
emotion: Emotion
|
||||
#createdAt: DateTime
|
||||
#updatedAt: DateTime
|
||||
# createdAt: DateTime
|
||||
# updatedAt: DateTime
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
}
|
||||
@ -15,6 +15,12 @@ input _EMOTEDInput {
|
||||
updatedAt: String
|
||||
}
|
||||
|
||||
input _PostEMOTEDFilter {
|
||||
emotion_in: [Emotion]
|
||||
createdAt: String
|
||||
updatedAt: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
|
||||
RemovePostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
|
||||
|
||||
17
backend/src/seed/factories/emailAddresses.js
Normal file
17
backend/src/seed/factories/emailAddresses.js
Normal file
@ -0,0 +1,17 @@
|
||||
import faker from 'faker'
|
||||
|
||||
export default function create() {
|
||||
return {
|
||||
factory: async ({ args, neodeInstance }) => {
|
||||
const defaults = {
|
||||
email: faker.internet.email(),
|
||||
verifiedAt: new Date().toISOString(),
|
||||
}
|
||||
args = {
|
||||
...defaults,
|
||||
...args,
|
||||
}
|
||||
return neodeInstance.create('EmailAddress', args)
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import createCategory from './categories.js'
|
||||
import createTag from './tags.js'
|
||||
import createSocialMedia from './socialMedia.js'
|
||||
import createLocation from './locations.js'
|
||||
import createEmailAddress from './emailAddresses.js'
|
||||
|
||||
export const seedServerHost = 'http://127.0.0.1:4001'
|
||||
|
||||
@ -30,6 +31,7 @@ const factories = {
|
||||
Tag: createTag,
|
||||
SocialMedia: createSocialMedia,
|
||||
Location: createLocation,
|
||||
EmailAddress: createEmailAddress,
|
||||
}
|
||||
|
||||
export const cleanDatabase = async (options = {}) => {
|
||||
|
||||
@ -30,7 +30,7 @@ export default function create() {
|
||||
let { categories, categoryIds } = args
|
||||
delete args.categories
|
||||
delete args.categoryIds
|
||||
if (categories && categoryIds) throw new Error('You provided both category and categoryIds')
|
||||
if (categories && categoryIds) throw new Error('You provided both categories and categoryIds')
|
||||
if (categoryIds)
|
||||
categories = await Promise.all(categoryIds.map(id => neodeInstance.find('Category', id)))
|
||||
categories = categories || (await Promise.all([factoryInstance.create('Category')]))
|
||||
|
||||
@ -5,7 +5,7 @@ import slugify from 'slug'
|
||||
|
||||
export default function create() {
|
||||
return {
|
||||
factory: async ({ args, neodeInstance }) => {
|
||||
factory: async ({ args, neodeInstance, factoryInstance }) => {
|
||||
const defaults = {
|
||||
id: uuid(),
|
||||
name: faker.name.findName(),
|
||||
@ -24,7 +24,7 @@ export default function create() {
|
||||
}
|
||||
args = await encryptPassword(args)
|
||||
const user = await neodeInstance.create('User', args)
|
||||
const email = await neodeInstance.create('EmailAddress', { email: args.email })
|
||||
const email = await factoryInstance.create('EmailAddress', { email: args.email })
|
||||
await user.relateTo(email, 'primaryEmail')
|
||||
await email.relateTo(user, 'belongsTo')
|
||||
return user
|
||||
|
||||
@ -14,10 +14,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz#3ce939cb127fb8aaa3ffc1e90dff9b8af9f2e3dc"
|
||||
integrity sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ==
|
||||
|
||||
"@babel/cli@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.5.5.tgz#bdb6d9169e93e241a08f5f7b0265195bf38ef5ec"
|
||||
integrity sha512-UHI+7pHv/tk9g6WXQKYz+kmXTI77YtuY3vqC59KIqcoWEjsJJSG6rAxKaLsgj3LDyadsPrCB929gVOKM6Hui0w==
|
||||
"@babel/cli@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.6.0.tgz#1470a04394eaf37862989ea4912adf440fa6ff8d"
|
||||
integrity sha512-1CTDyGUjQqW3Mz4gfKZ04KGOckyyaNmKneAMlABPS+ZyuxWv3FrVEVz7Ag08kNIztVx8VaJ8YgvYLSNlMKAT5Q==
|
||||
dependencies:
|
||||
commander "^2.8.1"
|
||||
convert-source-map "^1.1.0"
|
||||
@ -29,7 +29,7 @@
|
||||
slash "^2.0.0"
|
||||
source-map "^0.5.0"
|
||||
optionalDependencies:
|
||||
chokidar "^2.0.4"
|
||||
chokidar "^2.1.8"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5":
|
||||
version "7.5.5"
|
||||
@ -38,18 +38,18 @@
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.0.0"
|
||||
|
||||
"@babel/core@^7.1.0", "@babel/core@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30"
|
||||
integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==
|
||||
"@babel/core@^7.1.0", "@babel/core@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48"
|
||||
integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.5.5"
|
||||
"@babel/generator" "^7.5.5"
|
||||
"@babel/helpers" "^7.5.5"
|
||||
"@babel/parser" "^7.5.5"
|
||||
"@babel/template" "^7.4.4"
|
||||
"@babel/traverse" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/generator" "^7.6.0"
|
||||
"@babel/helpers" "^7.6.0"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/template" "^7.6.0"
|
||||
"@babel/traverse" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
convert-source-map "^1.1.0"
|
||||
debug "^4.1.0"
|
||||
json5 "^2.1.0"
|
||||
@ -58,12 +58,12 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.4.0", "@babel/generator@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf"
|
||||
integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==
|
||||
"@babel/generator@^7.4.0", "@babel/generator@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56"
|
||||
integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/types" "^7.6.0"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
@ -224,14 +224,14 @@
|
||||
"@babel/traverse" "^7.1.0"
|
||||
"@babel/types" "^7.2.0"
|
||||
|
||||
"@babel/helpers@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e"
|
||||
integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==
|
||||
"@babel/helpers@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e"
|
||||
integrity sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==
|
||||
dependencies:
|
||||
"@babel/template" "^7.4.4"
|
||||
"@babel/traverse" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/template" "^7.6.0"
|
||||
"@babel/traverse" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
|
||||
"@babel/highlight@^7.0.0":
|
||||
version "7.5.0"
|
||||
@ -242,22 +242,22 @@
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/node@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.5.5.tgz#5db48a3bcee64d9eda6474f2a0a55b235d0438b5"
|
||||
integrity sha512-xsW6il+yY+lzXMsQuvIJNA7tU8ix/f4G6bDt4DrnCkVpsR6clk9XgEbp7QF+xGNDdoD7M7QYokCH83pm+UjD0w==
|
||||
"@babel/node@~7.6.1":
|
||||
version "7.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/node/-/node-7.6.1.tgz#84f8f4f1d86647d99537a681f32e65e70bb59f19"
|
||||
integrity sha512-q2sJw+7aES/5wwjccECJfOuIgM1XIbZcn7b63JZM6VpaZwvOq913jL+tXRIn41Eg/Hr+BeIGWnvnjLTuT579pA==
|
||||
dependencies:
|
||||
"@babel/polyfill" "^7.0.0"
|
||||
"@babel/register" "^7.5.5"
|
||||
"@babel/polyfill" "^7.6.0"
|
||||
"@babel/register" "^7.6.0"
|
||||
commander "^2.8.1"
|
||||
lodash "^4.17.13"
|
||||
node-environment-flags "^1.0.5"
|
||||
v8flags "^3.1.1"
|
||||
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
|
||||
integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b"
|
||||
integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==
|
||||
|
||||
"@babel/plugin-proposal-async-generator-functions@^7.2.0":
|
||||
version "7.2.0"
|
||||
@ -382,10 +382,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-block-scoping@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce"
|
||||
integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==
|
||||
"@babel/plugin-transform-block-scoping@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc"
|
||||
integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
lodash "^4.17.13"
|
||||
@ -411,10 +411,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-destructuring@^7.5.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a"
|
||||
integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==
|
||||
"@babel/plugin-transform-destructuring@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6"
|
||||
integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
@ -480,10 +480,10 @@
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
babel-plugin-dynamic-import-node "^2.3.0"
|
||||
|
||||
"@babel/plugin-transform-modules-commonjs@^7.5.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
|
||||
integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
|
||||
"@babel/plugin-transform-modules-commonjs@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486"
|
||||
integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms" "^7.4.4"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
@ -507,12 +507,12 @@
|
||||
"@babel/helper-module-transforms" "^7.1.0"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5":
|
||||
version "7.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106"
|
||||
integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz#1e6e663097813bb4f53d42df0750cf28ad3bb3f1"
|
||||
integrity sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==
|
||||
dependencies:
|
||||
regexp-tree "^0.1.6"
|
||||
regexp-tree "^0.1.13"
|
||||
|
||||
"@babel/plugin-transform-new-target@^7.4.4":
|
||||
version "7.4.4"
|
||||
@ -605,18 +605,18 @@
|
||||
"@babel/helper-regex" "^7.4.4"
|
||||
regexpu-core "^4.5.4"
|
||||
|
||||
"@babel/polyfill@^7.0.0", "@babel/polyfill@^7.2.3":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.4.4.tgz#78801cf3dbe657844eeabf31c1cae3828051e893"
|
||||
integrity sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==
|
||||
"@babel/polyfill@^7.2.3", "@babel/polyfill@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.6.0.tgz#6d89203f8b6cd323e8d946e47774ea35dc0619cc"
|
||||
integrity sha512-q5BZJI0n/B10VaQQvln1IlDK3BTBJFbADx7tv+oXDPIDZuTo37H5Adb9jhlXm/fEN4Y7/64qD9mnrJJG7rmaTw==
|
||||
dependencies:
|
||||
core-js "^2.6.5"
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/preset-env@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a"
|
||||
integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==
|
||||
"@babel/preset-env@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.0.tgz#aae4141c506100bb2bfaa4ac2a5c12b395619e50"
|
||||
integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
@ -634,10 +634,10 @@
|
||||
"@babel/plugin-transform-arrow-functions" "^7.2.0"
|
||||
"@babel/plugin-transform-async-to-generator" "^7.5.0"
|
||||
"@babel/plugin-transform-block-scoped-functions" "^7.2.0"
|
||||
"@babel/plugin-transform-block-scoping" "^7.5.5"
|
||||
"@babel/plugin-transform-block-scoping" "^7.6.0"
|
||||
"@babel/plugin-transform-classes" "^7.5.5"
|
||||
"@babel/plugin-transform-computed-properties" "^7.2.0"
|
||||
"@babel/plugin-transform-destructuring" "^7.5.0"
|
||||
"@babel/plugin-transform-destructuring" "^7.6.0"
|
||||
"@babel/plugin-transform-dotall-regex" "^7.4.4"
|
||||
"@babel/plugin-transform-duplicate-keys" "^7.5.0"
|
||||
"@babel/plugin-transform-exponentiation-operator" "^7.2.0"
|
||||
@ -646,10 +646,10 @@
|
||||
"@babel/plugin-transform-literals" "^7.2.0"
|
||||
"@babel/plugin-transform-member-expression-literals" "^7.2.0"
|
||||
"@babel/plugin-transform-modules-amd" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.6.0"
|
||||
"@babel/plugin-transform-modules-systemjs" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-umd" "^7.2.0"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0"
|
||||
"@babel/plugin-transform-new-target" "^7.4.4"
|
||||
"@babel/plugin-transform-object-super" "^7.5.5"
|
||||
"@babel/plugin-transform-parameters" "^7.4.4"
|
||||
@ -662,19 +662,18 @@
|
||||
"@babel/plugin-transform-template-literals" "^7.4.4"
|
||||
"@babel/plugin-transform-typeof-symbol" "^7.2.0"
|
||||
"@babel/plugin-transform-unicode-regex" "^7.4.4"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/types" "^7.6.0"
|
||||
browserslist "^4.6.0"
|
||||
core-js-compat "^3.1.1"
|
||||
invariant "^2.2.2"
|
||||
js-levenshtein "^1.1.3"
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/register@^7.5.5", "@babel/register@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.5.5.tgz#40fe0d474c8c8587b28d6ae18a03eddad3dac3c1"
|
||||
integrity sha512-pdd5nNR+g2qDkXZlW1yRCWFlNrAn2PPdnZUB72zjX4l1Vv4fMRRLwyf+n/idFCLI1UgVGboUU8oVziwTBiyNKQ==
|
||||
"@babel/register@^7.6.0", "@babel/register@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.6.0.tgz#76b6f466714680f4becafd45beeb2a7b87431abf"
|
||||
integrity sha512-78BomdN8el+x/nkup9KwtjJXuptW5oXMFmP11WoM2VJBjxrKv4grC3qjpLL8RGGUYUGsm57xnjYFM2uom+jWUQ==
|
||||
dependencies:
|
||||
core-js "^3.0.0"
|
||||
find-cache-dir "^2.0.0"
|
||||
lodash "^4.17.13"
|
||||
mkdirp "^0.5.1"
|
||||
@ -696,34 +695,34 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
|
||||
integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6"
|
||||
integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"@babel/parser" "^7.4.4"
|
||||
"@babel/types" "^7.4.4"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb"
|
||||
integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516"
|
||||
integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.5.5"
|
||||
"@babel/generator" "^7.5.5"
|
||||
"@babel/generator" "^7.6.0"
|
||||
"@babel/helper-function-name" "^7.1.0"
|
||||
"@babel/helper-split-export-declaration" "^7.4.4"
|
||||
"@babel/parser" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a"
|
||||
integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0":
|
||||
version "7.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648"
|
||||
integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.13"
|
||||
@ -1632,41 +1631,41 @@ apollo-graphql@^0.3.3:
|
||||
apollo-env "0.5.1"
|
||||
lodash.sortby "^4.7.0"
|
||||
|
||||
apollo-link-context@~1.0.18:
|
||||
version "1.0.18"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.18.tgz#9e700e3314da8ded50057fee0a18af2bfcedbfc3"
|
||||
integrity sha512-aG5cbUp1zqOHHQjAJXG7n/izeMQ6LApd/whEF5z6qZp5ATvcyfSNkCfy3KRJMMZZ3iNfVTs6jF+IUA8Zvf+zeg==
|
||||
apollo-link-context@~1.0.19:
|
||||
version "1.0.19"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-context/-/apollo-link-context-1.0.19.tgz#3c9ba5bf75ed5428567ce057b8837ef874a58987"
|
||||
integrity sha512-TUi5TyufU84hEiGkpt+5gdH5HkB3Gx46npNfoxR4of3DKBCMuItGERt36RCaryGcU/C3u2zsICU3tJ+Z9LjFoQ==
|
||||
dependencies:
|
||||
apollo-link "^1.2.12"
|
||||
apollo-link "^1.2.13"
|
||||
tslib "^1.9.3"
|
||||
|
||||
apollo-link-http-common@^0.2.14:
|
||||
version "0.2.14"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.14.tgz#d3a195c12e00f4e311c417f121181dcc31f7d0c8"
|
||||
integrity sha512-v6mRU1oN6XuX8beVIRB6OpF4q1ULhSnmy7ScnHnuo1qV6GaFmDcbdvXqxIkAV1Q8SQCo2lsv4HeqJOWhFfApOg==
|
||||
apollo-link-http-common@^0.2.15:
|
||||
version "0.2.15"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.15.tgz#304e67705122bf69a9abaded4351b10bc5efd6d9"
|
||||
integrity sha512-+Heey4S2IPsPyTf8Ag3PugUupASJMW894iVps6hXbvwtg1aHSNMXUYO5VG7iRHkPzqpuzT4HMBanCTXPjtGzxg==
|
||||
dependencies:
|
||||
apollo-link "^1.2.12"
|
||||
apollo-link "^1.2.13"
|
||||
ts-invariant "^0.4.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
apollo-link-http@~1.5.15:
|
||||
version "1.5.15"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.15.tgz#106ab23bb8997bd55965d05855736d33119652cf"
|
||||
integrity sha512-epZFhCKDjD7+oNTVK3P39pqWGn4LEhShAoA1Q9e2tDrBjItNfviiE33RmcLcCURDYyW5JA6SMgdODNI4Is8tvQ==
|
||||
apollo-link-http@~1.5.16:
|
||||
version "1.5.16"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.16.tgz#44fe760bcc2803b8a7f57fc9269173afb00f3814"
|
||||
integrity sha512-IA3xA/OcrOzINRZEECI6IdhRp/Twom5X5L9jMehfzEo2AXdeRwAMlH5LuvTZHgKD8V1MBnXdM6YXawXkTDSmJw==
|
||||
dependencies:
|
||||
apollo-link "^1.2.12"
|
||||
apollo-link-http-common "^0.2.14"
|
||||
apollo-link "^1.2.13"
|
||||
apollo-link-http-common "^0.2.15"
|
||||
tslib "^1.9.3"
|
||||
|
||||
apollo-link@^1.0.0, apollo-link@^1.2.12, apollo-link@^1.2.3:
|
||||
version "1.2.12"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.12.tgz#014b514fba95f1945c38ad4c216f31bcfee68429"
|
||||
integrity sha512-fsgIAXPKThyMVEMWQsUN22AoQI+J/pVXcjRGAShtk97h7D8O+SPskFinCGEkxPeQpE83uKaqafB2IyWdjN+J3Q==
|
||||
apollo-link@^1.0.0, apollo-link@^1.2.13, apollo-link@^1.2.3:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.13.tgz#dff00fbf19dfcd90fddbc14b6a3f9a771acac6c4"
|
||||
integrity sha512-+iBMcYeevMm1JpYgwDEIDt/y0BB7VWyvlm/7x+TIPNLHCTCMgcEgDuW5kH86iQZWo0I7mNwQiTOz+/3ShPFmBw==
|
||||
dependencies:
|
||||
apollo-utilities "^1.3.0"
|
||||
ts-invariant "^0.4.0"
|
||||
tslib "^1.9.3"
|
||||
zen-observable-ts "^0.8.19"
|
||||
zen-observable-ts "^0.8.20"
|
||||
|
||||
apollo-server-caching@^0.5.0:
|
||||
version "0.5.0"
|
||||
@ -2383,7 +2382,7 @@ cheerio@~1.0.0-rc.2, cheerio@~1.0.0-rc.3:
|
||||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
chokidar@^2.0.4, chokidar@^2.1.5:
|
||||
chokidar@^2.1.5, chokidar@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
|
||||
integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==
|
||||
@ -2663,7 +2662,7 @@ core-js@^2.4.0, core-js@^2.6.5:
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2"
|
||||
integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==
|
||||
|
||||
core-js@^3.0.0, core-js@^3.0.1:
|
||||
core-js@^3.0.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.2.1.tgz#cd41f38534da6cc59f7db050fe67307de9868b09"
|
||||
integrity sha512-Qa5XSVefSVPRxy2XfUC13WbvqkxhkwB3ve+pgCQveNgYzbM/UxZeu1dcOX/xr4UmfUd+muuvsaxilQzCyUurMw==
|
||||
@ -2839,10 +2838,10 @@ data-urls@^1.0.0:
|
||||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-fns@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.1.tgz#c5f30e31d3294918e6b6a82753a4e719120e203d"
|
||||
integrity sha512-C14oTzTZy8DH1Eq8N78owrCWvf3+cnJw88BTK/N3DYWVxDJuJzPaNdplzYxDYuuXXGvqBcO4Vy5SOrwAooXSWw==
|
||||
date-fns@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.1.0.tgz#0d7e806c3cefe14a943532dbf968995ccfd46bd9"
|
||||
integrity sha512-eKeLk3sLCnxB/0PN4t1+zqDtSs4jb4mXRSTZ2okmx/myfWyDqeO4r5nnmA5LClJiCwpuTMeK2v5UQPuE4uMaxA==
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
@ -4118,10 +4117,10 @@ graphql-request@~1.8.2:
|
||||
dependencies:
|
||||
cross-fetch "2.2.2"
|
||||
|
||||
graphql-shield@~6.0.6:
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-6.0.6.tgz#ef8c53f1dd972c2d1828ffd45ce9b1f877576534"
|
||||
integrity sha512-rwhno5ZvEBbedQ8mEOi/Lk71J5CrpQCOcyuDIO+qb1hqm7cvWLtLVyZFrhVp7vN/vULV9oX30j0clC/1d05LpQ==
|
||||
graphql-shield@~6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-6.1.0.tgz#7298af72167e7c9fd19a36fac9b425b94025a393"
|
||||
integrity sha512-dIZ6ABnUn3XQtIzw9/9f8wFmZoY5XZlsHgkxSKF+N/oXmKvQoi11J5/y/jxJTBmKYi/2JZ12C1JjDn5TOopn+w==
|
||||
dependencies:
|
||||
"@types/yup" "0.26.23"
|
||||
lightercollective "^0.3.0"
|
||||
@ -6196,10 +6195,10 @@ neo4j-graphql-js@^2.7.2:
|
||||
lodash "^4.17.15"
|
||||
neo4j-driver "^1.7.3"
|
||||
|
||||
neode@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/neode/-/neode-0.3.2.tgz#ced277e1daba26a77c48f5857c30af054f11c7df"
|
||||
integrity sha512-Bm4GBXdXunv8cqUUkJtksIGHDnYdBJf4UHwzFgXbJiDKBAdqfjhzwAPAhf1PrvlFmR4vJva2Bh/XvIghYOiKrA==
|
||||
neode@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/neode/-/neode-0.3.3.tgz#a539830cce6f6e4825462f6cb03f2969a0003f1b"
|
||||
integrity sha512-pArHG1hD2kVwrzLlz6B1+IgdOJRQj/BgR6KzH6DlVzSA6geoZRe68fbpvmOJtzyPU7iuUYxXVk87PpPM1A7dlg==
|
||||
dependencies:
|
||||
"@hapi/joi" "^15.1.0"
|
||||
dotenv "^4.0.0"
|
||||
@ -7231,10 +7230,10 @@ regex-not@^1.0.0, regex-not@^1.0.2:
|
||||
extend-shallow "^3.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
regexp-tree@^0.1.6:
|
||||
version "0.1.11"
|
||||
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.11.tgz#c9c7f00fcf722e0a56c7390983a7a63dd6c272f3"
|
||||
integrity sha512-7/l/DgapVVDzZobwMCCgMlqiqyLFJ0cduo/j+3BcDJIB+yJdsYCfKuI3l/04NV+H/rfNRdPIDbXNZHM9XvQatg==
|
||||
regexp-tree@^0.1.13:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.13.tgz#5b19ab9377edc68bc3679256840bb29afc158d7f"
|
||||
integrity sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==
|
||||
|
||||
regexpp@^2.0.1:
|
||||
version "2.0.1"
|
||||
@ -8930,10 +8929,10 @@ yup@^0.27.0:
|
||||
synchronous-promise "^2.0.6"
|
||||
toposort "^2.0.2"
|
||||
|
||||
zen-observable-ts@^0.8.19:
|
||||
version "0.8.19"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.19.tgz#c094cd20e83ddb02a11144a6e2a89706946b5694"
|
||||
integrity sha512-u1a2rpE13G+jSzrg3aiCqXU5tN2kw41b+cBZGmnc+30YimdkKiDj9bTowcB41eL77/17RF/h+393AuVgShyheQ==
|
||||
zen-observable-ts@^0.8.20:
|
||||
version "0.8.20"
|
||||
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz#44091e335d3fcbc97f6497e63e7f57d5b516b163"
|
||||
integrity sha512-2rkjiPALhOtRaDX6pWyNqK1fnP5KkJJybYebopNSn6wDG1lxBoFs2+nwwXKoA6glHIrtwrfBBy6da0stkKtTAA==
|
||||
dependencies:
|
||||
tslib "^1.9.3"
|
||||
zen-observable "^0.8.0"
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
"faker": "Marak/faker.js#master",
|
||||
"graphql-request": "^1.8.2",
|
||||
"neo4j-driver": "^1.7.6",
|
||||
"neode": "^0.3.2",
|
||||
"neode": "^0.3.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"slug": "^1.1.0"
|
||||
}
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils'
|
||||
import CommentForm from './CommentForm'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
import Vuex from 'vuex'
|
||||
import MutationObserver from 'mutation-observer'
|
||||
|
||||
global.MutationObserver = MutationObserver
|
||||
|
||||
const localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
localVue.use(Styleguide)
|
||||
|
||||
describe('CommentForm.vue', () => {
|
||||
@ -53,20 +51,11 @@ describe('CommentForm.vue', () => {
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const getters = {
|
||||
'editor/placeholder': () => {
|
||||
return 'some cool placeholder'
|
||||
},
|
||||
}
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
})
|
||||
const Wrapper = () => {
|
||||
return mount(CommentForm, {
|
||||
mocks,
|
||||
localVue,
|
||||
propsData,
|
||||
store,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils'
|
||||
import Editor from './Editor'
|
||||
import Vuex from 'vuex'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
import MutationObserver from 'mutation-observer'
|
||||
import Vue from 'vue'
|
||||
@ -8,19 +7,14 @@ import Vue from 'vue'
|
||||
global.MutationObserver = MutationObserver
|
||||
|
||||
const localVue = createLocalVue()
|
||||
localVue.use(Vuex)
|
||||
localVue.use(Styleguide)
|
||||
|
||||
describe('Editor.vue', () => {
|
||||
let wrapper
|
||||
let propsData
|
||||
let mocks
|
||||
let getters
|
||||
|
||||
const Wrapper = () => {
|
||||
const store = new Vuex.Store({
|
||||
getters,
|
||||
})
|
||||
return (wrapper = mount(Editor, {
|
||||
mocks,
|
||||
propsData,
|
||||
@ -29,19 +23,13 @@ describe('Editor.vue', () => {
|
||||
stubs: {
|
||||
transition: false,
|
||||
},
|
||||
store,
|
||||
}))
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
propsData = {}
|
||||
mocks = {
|
||||
$t: () => {},
|
||||
}
|
||||
getters = {
|
||||
'editor/placeholder': () => {
|
||||
return 'some cool placeholder'
|
||||
},
|
||||
$t: () => 'some cool placeholder',
|
||||
}
|
||||
wrapper = Wrapper()
|
||||
})
|
||||
@ -64,12 +52,10 @@ describe('Editor.vue', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('uses the placeholder', () => {
|
||||
it('from the store', () => {
|
||||
expect(wrapper.vm.editor.extensions.options.placeholder.emptyNodeText).toEqual(
|
||||
'some cool placeholder',
|
||||
)
|
||||
})
|
||||
it('translates the placeholder', () => {
|
||||
expect(wrapper.vm.editor.extensions.options.placeholder.emptyNodeText).toEqual(
|
||||
'some cool placeholder',
|
||||
)
|
||||
})
|
||||
|
||||
describe('optional extensions', () => {
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { Editor, EditorContent } from 'tiptap'
|
||||
import { History } from 'tiptap-extensions'
|
||||
import linkify from 'linkify-it'
|
||||
@ -70,7 +69,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({ placeholder: 'editor/placeholder' }),
|
||||
placeholder() {
|
||||
return this.$t('editor.placeholder')
|
||||
},
|
||||
optionalExtensions() {
|
||||
const extensions = []
|
||||
// Don't change the following line. The functionallity is in danger!
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<ds-container>
|
||||
<ds-space />
|
||||
<ds-space margin-top="large">
|
||||
<ds-flex id="filter-posts-header">
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.categories.header') }}</ds-heading>
|
||||
<ds-space margin-bottom="large" />
|
||||
@ -57,65 +56,22 @@
|
||||
</ds-flex>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-space />
|
||||
<ds-flex id="filter-posts-by-followers-header">
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.general.header') }}</ds-heading>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
<ds-flex>
|
||||
<ds-flex-item
|
||||
:width="{ base: '100%', sm: '100%', md: '100%', lg: '10%' }"
|
||||
class="categories-menu-item"
|
||||
>
|
||||
<ds-flex>
|
||||
<ds-flex-item width="10%" />
|
||||
<ds-flex-item width="100%">
|
||||
<div class="follow-button">
|
||||
<ds-button
|
||||
v-tooltip="{
|
||||
content: this.$t('contribution.filterFollow'),
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
name="filter-by-followed-authors-only"
|
||||
icon="user-plus"
|
||||
:primary="filteredByUsersFollowed"
|
||||
@click="toggleFilteredByFollowed(user.id)"
|
||||
/>
|
||||
<ds-flex-item>
|
||||
<label class="follow-label">{{ $t('filter-posts.followers.label') }}</label>
|
||||
</ds-flex-item>
|
||||
<ds-space />
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-flex-item>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
</ds-container>
|
||||
</ds-space>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
user: { type: Object, required: true },
|
||||
chunk: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filter: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
filteredCategoryIds: 'postsFilter/filteredCategoryIds',
|
||||
filteredByUsersFollowed: 'postsFilter/filteredByUsersFollowed',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
toggleFilteredByFollowed: 'postsFilter/TOGGLE_FILTER_BY_FOLLOWED',
|
||||
resetCategories: 'postsFilter/RESET_CATEGORIES',
|
||||
toggleCategory: 'postsFilter/TOGGLE_CATEGORY',
|
||||
}),
|
||||
@ -123,14 +79,6 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
#filter-posts-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#filter-posts-by-followers-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.categories-menu-item {
|
||||
text-align: center;
|
||||
}
|
||||
@ -150,13 +98,4 @@ export default {
|
||||
margin: 9px 0px 40px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
#filter-posts-header {
|
||||
text-align: center;
|
||||
}
|
||||
.follow-button {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -19,6 +19,7 @@ describe('FilterPosts.vue', () => {
|
||||
let allCategoriesButton
|
||||
let environmentAndNatureButton
|
||||
let democracyAndPoliticsButton
|
||||
let happyEmotionButton
|
||||
|
||||
beforeEach(() => {
|
||||
mocks = {
|
||||
@ -52,6 +53,7 @@ describe('FilterPosts.vue', () => {
|
||||
'postsFilter/TOGGLE_FILTER_BY_FOLLOWED': jest.fn(),
|
||||
'postsFilter/RESET_CATEGORIES': jest.fn(),
|
||||
'postsFilter/TOGGLE_CATEGORY': jest.fn(),
|
||||
'postsFilter/TOGGLE_EMOTION': jest.fn(),
|
||||
}
|
||||
getters = {
|
||||
'postsFilter/isActive': () => false,
|
||||
@ -61,6 +63,7 @@ describe('FilterPosts.vue', () => {
|
||||
},
|
||||
'postsFilter/filteredCategoryIds': jest.fn(() => []),
|
||||
'postsFilter/filteredByUsersFollowed': jest.fn(),
|
||||
'postsFilter/filteredByEmotions': jest.fn(() => []),
|
||||
}
|
||||
const openFilterPosts = () => {
|
||||
const store = new Vuex.Store({ mutations, getters })
|
||||
@ -120,5 +123,22 @@ describe('FilterPosts.vue', () => {
|
||||
expect(mutations['postsFilter/TOGGLE_FILTER_BY_FOLLOWED']).toHaveBeenCalledWith({}, 'u34')
|
||||
})
|
||||
})
|
||||
|
||||
describe('click on an "emotions-buttons" button', () => {
|
||||
it('calls TOGGLE_EMOTION when clicked', () => {
|
||||
const wrapper = openFilterPosts()
|
||||
happyEmotionButton = wrapper.findAll('button.emotions-buttons').at(1)
|
||||
happyEmotionButton.trigger('click')
|
||||
expect(mutations['postsFilter/TOGGLE_EMOTION']).toHaveBeenCalledWith({}, 'happy')
|
||||
})
|
||||
|
||||
it('sets the attribute `src` to colorized image', () => {
|
||||
getters['postsFilter/filteredByEmotions'] = jest.fn(() => ['happy'])
|
||||
const wrapper = openFilterPosts()
|
||||
happyEmotionButton = wrapper.findAll('button.emotions-buttons').at(1)
|
||||
const happyEmotionButtonImage = happyEmotionButton.find('img')
|
||||
expect(happyEmotionButtonImage.attributes().src).toEqual('/img/svg/emoji/happy_color.svg')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -11,20 +11,25 @@
|
||||
<ds-icon size="xx-small" name="angle-down" />
|
||||
</ds-button>
|
||||
<template slot="popover">
|
||||
<filter-posts-menu-items :chunk="chunk" :user="currentUser" />
|
||||
<ds-container>
|
||||
<categories-filter-menu-items :chunk="chunk" />
|
||||
<general-filter-menu-items :user="currentUser" />
|
||||
</ds-container>
|
||||
</template>
|
||||
</dropdown>
|
||||
</template>
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { chunk } from 'lodash'
|
||||
import Dropdown from '~/components/Dropdown'
|
||||
import { mapGetters } from 'vuex'
|
||||
import FilterPostsMenuItems from '~/components/FilterPosts/FilterPostsMenuItems'
|
||||
import CategoriesFilterMenuItems from './CategoriesFilterMenuItems'
|
||||
import GeneralFilterMenuItems from './GeneralFilterMenuItems'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Dropdown,
|
||||
FilterPostsMenuItems,
|
||||
CategoriesFilterMenuItems,
|
||||
GeneralFilterMenuItems,
|
||||
},
|
||||
props: {
|
||||
placement: { type: String },
|
||||
@ -37,7 +42,7 @@ export default {
|
||||
filterActive: 'postsFilter/isActive',
|
||||
}),
|
||||
chunk() {
|
||||
return _.chunk(this.categories, 2)
|
||||
return chunk(this.categories, 2)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
110
webapp/components/FilterPosts/GeneralFilterMenuItems.vue
Normal file
110
webapp/components/FilterPosts/GeneralFilterMenuItems.vue
Normal file
@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<ds-space>
|
||||
<ds-flex id="filter-posts-by-followers-header">
|
||||
<ds-heading tag="h4">{{ $t('filter-posts.general.header') }}</ds-heading>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
<ds-flex :gutter="{ lg: 'large' }">
|
||||
<ds-flex-item
|
||||
:width="{ base: '100%', sm: '100%', md: '100%', lg: '10%' }"
|
||||
class="categories-menu-item"
|
||||
>
|
||||
<ds-flex>
|
||||
<ds-flex-item width="10%" />
|
||||
<ds-space margin-bottom="xx-small" />
|
||||
<ds-flex-item width="100%">
|
||||
<div class="follow-button">
|
||||
<ds-button
|
||||
v-tooltip="{
|
||||
content: this.$t('contribution.filterFollow'),
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
name="filter-by-followed-authors-only"
|
||||
icon="user-plus"
|
||||
:primary="filteredByUsersFollowed"
|
||||
@click="toggleFilteredByFollowed(user.id)"
|
||||
/>
|
||||
<ds-space margin-bottom="x-small" />
|
||||
<ds-flex-item>
|
||||
<label class="follow-label">{{ $t('filter-posts.followers.label') }}</label>
|
||||
</ds-flex-item>
|
||||
<ds-space />
|
||||
</div>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</ds-flex-item>
|
||||
<div v-for="emotion in emotionsArray" :key="emotion">
|
||||
<ds-flex-item :width="{ lg: '100%' }">
|
||||
<ds-button
|
||||
size="large"
|
||||
ghost
|
||||
@click="toogleFilteredByEmotions(emotion)"
|
||||
class="emotions-buttons"
|
||||
>
|
||||
<img :src="iconPath(emotion)" width="40" />
|
||||
</ds-button>
|
||||
<ds-space margin-bottom="x-small" />
|
||||
<ds-flex-item class="emotions-mobile-space text-center">
|
||||
<label class="emotions-label">{{ $t(`contribution.emotions-label.${emotion}`) }}</label>
|
||||
</ds-flex-item>
|
||||
</ds-flex-item>
|
||||
</div>
|
||||
<ds-space margin-bottom="large" />
|
||||
</ds-flex>
|
||||
</ds-space>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
user: { type: Object, required: true },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
emotionsArray: ['funny', 'happy', 'surprised', 'cry', 'angry'],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
filteredByUsersFollowed: 'postsFilter/filteredByUsersFollowed',
|
||||
filteredByEmotions: 'postsFilter/filteredByEmotions',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
toggleFilteredByFollowed: 'postsFilter/TOGGLE_FILTER_BY_FOLLOWED',
|
||||
toogleFilteredByEmotions: 'postsFilter/TOGGLE_EMOTION',
|
||||
}),
|
||||
iconPath(emotion) {
|
||||
if (this.filteredByEmotions.includes(emotion)) {
|
||||
return `/img/svg/emoji/${emotion}_color.svg`
|
||||
}
|
||||
return `/img/svg/emoji/${emotion}.svg`
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
#filter-posts-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#filter-posts-by-followers-header {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
#filter-posts-header {
|
||||
text-align: center;
|
||||
}
|
||||
.follow-button {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@ -1,13 +1,10 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
import Vuex from 'vuex'
|
||||
import VTooltip from 'v-tooltip'
|
||||
import LocaleSwitch from './LocaleSwitch.vue'
|
||||
import { mutations } from '~/store/editor'
|
||||
|
||||
const localVue = createLocalVue()
|
||||
|
||||
localVue.use(Vuex)
|
||||
localVue.use(Styleguide)
|
||||
localVue.use(VTooltip)
|
||||
|
||||
@ -46,13 +43,8 @@ describe('LocaleSwitch.vue', () => {
|
||||
})
|
||||
|
||||
describe('mount', () => {
|
||||
const store = new Vuex.Store({
|
||||
mutations: {
|
||||
'editor/SET_PLACEHOLDER_TEXT': mutations.SET_PLACEHOLDER_TEXT,
|
||||
},
|
||||
})
|
||||
const Wrapper = () => {
|
||||
return mount(LocaleSwitch, { mocks, localVue, store, computed })
|
||||
return mount(LocaleSwitch, { mocks, localVue, computed })
|
||||
}
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
import Dropdown from '~/components/Dropdown'
|
||||
import find from 'lodash/find'
|
||||
import orderBy from 'lodash/orderBy'
|
||||
import { mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -66,11 +65,9 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({ setPlaceholderText: 'editor/SET_PLACEHOLDER_TEXT' }),
|
||||
changeLanguage(locale, toggleMenu) {
|
||||
this.$i18n.set(locale)
|
||||
toggleMenu()
|
||||
this.setPlaceholderText(this.$t('editor.placeholder'))
|
||||
},
|
||||
matcher(locale) {
|
||||
return locale === this.$i18n.locale()
|
||||
|
||||
@ -39,10 +39,10 @@ describe('ChangePassword ', () => {
|
||||
})
|
||||
}
|
||||
|
||||
describe('given email and verification code', () => {
|
||||
describe('given email and verification nonce', () => {
|
||||
beforeEach(() => {
|
||||
propsData.email = 'mail@example.org'
|
||||
propsData.code = '123456'
|
||||
propsData.nonce = '123456'
|
||||
})
|
||||
|
||||
describe('submitting new password', () => {
|
||||
@ -59,14 +59,14 @@ describe('ChangePassword ', () => {
|
||||
|
||||
it('delivers new password to backend', () => {
|
||||
const expected = expect.objectContaining({
|
||||
variables: { code: '123456', email: 'mail@example.org', password: 'supersecret' },
|
||||
variables: { nonce: '123456', email: 'mail@example.org', password: 'supersecret' },
|
||||
})
|
||||
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
|
||||
})
|
||||
|
||||
describe('password reset successful', () => {
|
||||
it('displays success message', () => {
|
||||
const expected = 'verify-code.form.change-password.success'
|
||||
const expected = 'verify-nonce.form.change-password.success'
|
||||
expect(mocks.$t).toHaveBeenCalledWith(expected)
|
||||
})
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ds-card class="verify-code">
|
||||
<ds-card class="verify-nonce">
|
||||
<ds-space margin="large">
|
||||
<ds-form
|
||||
v-if="!changePasswordResult"
|
||||
@ -35,14 +35,14 @@
|
||||
<template v-if="changePasswordResult === 'success'">
|
||||
<sweetalert-icon icon="success" />
|
||||
<ds-text>
|
||||
{{ $t(`verify-code.form.change-password.success`) }}
|
||||
{{ $t(`verify-nonce.form.change-password.success`) }}
|
||||
</ds-text>
|
||||
</template>
|
||||
<template v-else>
|
||||
<sweetalert-icon icon="error" />
|
||||
<ds-text align="left">
|
||||
{{ $t(`verify-code.form.change-password.error`) }}
|
||||
{{ $t('verify-code.form.change-password.help') }}
|
||||
{{ $t(`verify-nonce.form.change-password.error`) }}
|
||||
{{ $t('verify-nonce.form.change-password.help') }}
|
||||
</ds-text>
|
||||
<a href="mailto:support@human-connection.org">support@human-connection.org</a>
|
||||
</template>
|
||||
@ -64,7 +64,7 @@ export default {
|
||||
},
|
||||
props: {
|
||||
email: { type: String, required: true },
|
||||
code: { type: String, required: true },
|
||||
nonce: { type: String, required: true },
|
||||
},
|
||||
data() {
|
||||
const passwordForm = PasswordForm({ translate: this.$t })
|
||||
@ -82,13 +82,13 @@ export default {
|
||||
methods: {
|
||||
async handleSubmitPassword() {
|
||||
const mutation = gql`
|
||||
mutation($code: String!, $email: String!, $password: String!) {
|
||||
resetPassword(code: $code, email: $email, newPassword: $password)
|
||||
mutation($nonce: String!, $email: String!, $password: String!) {
|
||||
resetPassword(nonce: $nonce, email: $email, newPassword: $password)
|
||||
}
|
||||
`
|
||||
const { password } = this.formData
|
||||
const { email, code } = this
|
||||
const variables = { password, email, code }
|
||||
const { email, nonce } = this
|
||||
const variables = { password, email, nonce }
|
||||
try {
|
||||
const {
|
||||
data: { resetPassword },
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils'
|
||||
import VerifyCode from './VerifyCode'
|
||||
import VerifyNonce from './VerifyNonce.vue'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
|
||||
const localVue = createLocalVue()
|
||||
|
||||
localVue.use(Styleguide)
|
||||
|
||||
describe('VerifyCode ', () => {
|
||||
describe('VerifyNonce ', () => {
|
||||
let wrapper
|
||||
let Wrapper
|
||||
let mocks
|
||||
@ -25,27 +25,27 @@ describe('VerifyCode ', () => {
|
||||
beforeEach(jest.useFakeTimers)
|
||||
|
||||
Wrapper = () => {
|
||||
return mount(VerifyCode, {
|
||||
return mount(VerifyNonce, {
|
||||
mocks,
|
||||
localVue,
|
||||
propsData,
|
||||
})
|
||||
}
|
||||
|
||||
it('renders a verify code form', () => {
|
||||
it('renders a verify nonce form', () => {
|
||||
wrapper = Wrapper()
|
||||
expect(wrapper.find('.verify-code').exists()).toBe(true)
|
||||
expect(wrapper.find('.verify-nonce').exists()).toBe(true)
|
||||
})
|
||||
|
||||
describe('after verification code given', () => {
|
||||
describe('after verification nonce given', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = Wrapper()
|
||||
wrapper.find('input#code').setValue('123456')
|
||||
wrapper.find('input#nonce').setValue('123456')
|
||||
wrapper.find('form').trigger('submit')
|
||||
})
|
||||
|
||||
it('emits `verifyCode`', () => {
|
||||
const expected = [[{ code: '123456', email: 'mail@example.org' }]]
|
||||
it('emits `verification`', () => {
|
||||
const expected = [[{ nonce: '123456', email: 'mail@example.org' }]]
|
||||
expect(wrapper.emitted('verification')).toEqual(expected)
|
||||
})
|
||||
})
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<ds-card class="verify-code">
|
||||
<ds-card class="verify-nonce">
|
||||
<ds-space margin="large">
|
||||
<ds-form
|
||||
v-model="formData"
|
||||
@ -9,19 +9,19 @@
|
||||
@input-valid="handleInputValid"
|
||||
>
|
||||
<ds-input
|
||||
:placeholder="$t('verify-code.form.code')"
|
||||
model="code"
|
||||
name="code"
|
||||
id="code"
|
||||
:placeholder="$t('verify-nonce.form.nonce')"
|
||||
model="nonce"
|
||||
name="nonce"
|
||||
id="nonce"
|
||||
icon="question-circle"
|
||||
/>
|
||||
<ds-space margin-botton="large">
|
||||
<ds-text>
|
||||
{{ $t('verify-code.form.description') }}
|
||||
{{ $t('verify-nonce.form.description') }}
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
<ds-button :disabled="disabled" primary fullwidth name="submit" type="submit">
|
||||
{{ $t('verify-code.form.next') }}
|
||||
{{ $t('verify-nonce.form.next') }}
|
||||
</ds-button>
|
||||
</ds-form>
|
||||
</ds-space>
|
||||
@ -36,15 +36,15 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
code: '',
|
||||
nonce: '',
|
||||
},
|
||||
formSchema: {
|
||||
code: {
|
||||
nonce: {
|
||||
type: 'string',
|
||||
min: 6,
|
||||
max: 6,
|
||||
required: true,
|
||||
message: this.$t('common.validations.verification-code'),
|
||||
message: this.$t('common.validations.verification-nonce'),
|
||||
},
|
||||
},
|
||||
disabled: true,
|
||||
@ -58,9 +58,9 @@ export default {
|
||||
this.disabled = false
|
||||
},
|
||||
handleSubmitVerify() {
|
||||
const { code } = this.formData
|
||||
const { nonce } = this.formData
|
||||
const email = this.email
|
||||
this.$emit('verification', { email, code })
|
||||
this.$emit('verification', { email, nonce })
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import { config, mount, createLocalVue } from '@vue/test-utils'
|
||||
import CreateUserAccount, { SignupVerificationMutation } from './CreateUserAccount'
|
||||
import CreateUserAccount from './CreateUserAccount'
|
||||
import { SignupVerificationMutation } from '~/graphql/Registration.js'
|
||||
import Styleguide from '@human-connection/styleguide'
|
||||
|
||||
const localVue = createLocalVue()
|
||||
@ -55,6 +56,7 @@ describe('CreateUserAccount', () => {
|
||||
wrapper = Wrapper()
|
||||
wrapper.find('input#name').setValue('John Doe')
|
||||
wrapper.find('input#password').setValue('hellopassword')
|
||||
wrapper.find('textarea#about').setValue('Hello I am the `about` attribute')
|
||||
wrapper.find('input#passwordConfirmation').setValue('hellopassword')
|
||||
wrapper.find('input#checkbox').setChecked()
|
||||
await wrapper.find('form').trigger('submit')
|
||||
@ -72,7 +74,7 @@ describe('CreateUserAccount', () => {
|
||||
await action()
|
||||
const expected = expect.objectContaining({
|
||||
variables: {
|
||||
about: '',
|
||||
about: 'Hello I am the `about` attribute',
|
||||
name: 'John Doe',
|
||||
email: 'sixseven@example.org',
|
||||
nonce: '666777',
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
:placeholder="$t('settings.data.namePlaceholder')"
|
||||
/>
|
||||
<ds-input
|
||||
id="bio"
|
||||
id="about"
|
||||
model="about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
@ -83,34 +83,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import PasswordStrength from '../Password/Strength'
|
||||
import { SweetalertIcon } from 'vue-sweetalert-icons'
|
||||
import PasswordForm from '~/components/utils/PasswordFormHelper'
|
||||
import { VERSION } from '~/constants/terms-and-conditions-version.js'
|
||||
import { SignupVerificationMutation } from '~/graphql/Registration.js'
|
||||
|
||||
/* TODO: hier muss die version rein */
|
||||
export const SignupVerificationMutation = gql`
|
||||
mutation(
|
||||
$nonce: String!
|
||||
$name: String!
|
||||
$email: String!
|
||||
$password: String!
|
||||
$termsAndConditionsAgreedVersion: String!
|
||||
) {
|
||||
SignupVerification(
|
||||
nonce: $nonce
|
||||
email: $email
|
||||
name: $name
|
||||
password: $password
|
||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||
) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
`
|
||||
export default {
|
||||
components: {
|
||||
PasswordStrength,
|
||||
|
||||
24
webapp/graphql/Registration.js
Normal file
24
webapp/graphql/Registration.js
Normal file
@ -0,0 +1,24 @@
|
||||
import gql from 'graphql-tag'
|
||||
export const SignupVerificationMutation = gql`
|
||||
mutation(
|
||||
$nonce: String!
|
||||
$name: String!
|
||||
$email: String!
|
||||
$password: String!
|
||||
$about: String
|
||||
$termsAndConditionsAgreedVersion: String!
|
||||
) {
|
||||
SignupVerification(
|
||||
nonce: $nonce
|
||||
email: $email
|
||||
name: $name
|
||||
password: $password
|
||||
about: $about
|
||||
termsAndConditionsAgreedVersion: $termsAndConditionsAgreedVersion
|
||||
) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -82,9 +82,9 @@
|
||||
"success": "Dein Benutzerkonto wurde erstellt!"
|
||||
}
|
||||
},
|
||||
"verify-code": {
|
||||
"verify-nonce": {
|
||||
"form": {
|
||||
"code": "Code eingeben",
|
||||
"nonce": "Code eingeben",
|
||||
"description": "Öffne dein E-Mail Postfach und gib den Code ein, den wir geschickt haben.",
|
||||
"next": "Weiter",
|
||||
"change-password": {
|
||||
@ -342,7 +342,7 @@
|
||||
"validations": {
|
||||
"email": "muss eine gültige E-Mail Adresse sein",
|
||||
"url": "muss eine gültige URL sein",
|
||||
"verification-code": "muss genau 6 Buchstaben lang sein"
|
||||
"verification-nonce": "muss genau 6 Buchstaben lang sein"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
|
||||
@ -82,9 +82,9 @@
|
||||
"success": "Your account has been created!"
|
||||
}
|
||||
},
|
||||
"verify-code": {
|
||||
"verify-nonce": {
|
||||
"form": {
|
||||
"code": "Enter your code",
|
||||
"nonce": "Enter your code",
|
||||
"description": "Open your inbox and enter the code that we've sent to you.",
|
||||
"next": "Continue",
|
||||
"change-password": {
|
||||
@ -342,7 +342,7 @@
|
||||
"validations": {
|
||||
"email": "must be a valid email address",
|
||||
"url": "must be a valid URL",
|
||||
"verification-code": "must be 6 characters long"
|
||||
"verification-nonce": "must be 6 characters long"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
|
||||
@ -37,9 +37,9 @@
|
||||
"submitted": "Na adres <b>{email}</b> została wysłana wiadomość z dalszymi instrukcjami."
|
||||
}
|
||||
},
|
||||
"verify-code": {
|
||||
"verify-nonce": {
|
||||
"form": {
|
||||
"code": "Wprowadź swój kod",
|
||||
"nonce": "Wprowadź swój kod",
|
||||
"description": "Otwórz swoją skrzynkę odbiorczą i wpisz kod, który do Ciebie wysłaliśmy.",
|
||||
"next": "Kontynuuj",
|
||||
"change-password": {
|
||||
@ -237,7 +237,7 @@
|
||||
"reportContent": "Sprawozdanie",
|
||||
"validations": {
|
||||
"email": "musi być ważny adres e-mail.",
|
||||
"verification-code": "musi mieć długość 6 znaków."
|
||||
"verification-nonce": "musi mieć długość 6 znaków."
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
|
||||
@ -35,11 +35,11 @@ module.exports = {
|
||||
'login',
|
||||
'logout',
|
||||
'password-reset-request',
|
||||
'password-reset-verify-code',
|
||||
'password-reset-verify-nonce',
|
||||
'password-reset-change-password',
|
||||
// 'registration-signup', TODO: uncomment to open public registration
|
||||
'registration-signup-by-invitation-code',
|
||||
'registration-verify-code',
|
||||
// 'registration-signup', TODO: implement to open public registration
|
||||
// 'registration-signup-by-invitation-code',
|
||||
// 'registration-verify-nonce',
|
||||
'registration-create-user-account',
|
||||
'pages-slug',
|
||||
'imprint',
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@human-connection/styleguide": "0.5.19",
|
||||
"@human-connection/styleguide": "0.5.21",
|
||||
"@nuxtjs/apollo": "^4.0.0-rc12",
|
||||
"@nuxtjs/axios": "~5.6.0",
|
||||
"@nuxtjs/dotenv": "~1.4.0",
|
||||
@ -61,7 +61,7 @@
|
||||
"apollo-client": "~2.6.4",
|
||||
"cookie-universal-nuxt": "~2.0.17",
|
||||
"cross-env": "~5.2.1",
|
||||
"date-fns": "2.0.1",
|
||||
"date-fns": "2.1.0",
|
||||
"express": "~4.17.1",
|
||||
"graphql": "~14.5.4",
|
||||
"isemail": "^3.2.0",
|
||||
@ -85,9 +85,9 @@
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "~7.5.5",
|
||||
"@babel/core": "~7.6.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/preset-env": "~7.5.5",
|
||||
"@babel/preset-env": "~7.6.0",
|
||||
"@storybook/addon-a11y": "^5.1.11",
|
||||
"@storybook/addon-actions": "^5.1.11",
|
||||
"@storybook/vue": "~5.1.11",
|
||||
@ -124,7 +124,7 @@
|
||||
"style-loader": "~0.23.1",
|
||||
"style-resources-loader": "~1.2.1",
|
||||
"tippy.js": "^4.3.5",
|
||||
"vue-jest": "~3.0.4",
|
||||
"vue-jest": "~3.0.5",
|
||||
"vue-loader": "~15.7.0",
|
||||
"vue-svg-loader": "~0.12.0",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
|
||||
@ -27,12 +27,8 @@
|
||||
<template v-else>
|
||||
<ds-grid-item :row-span="2" column-span="fullWidth">
|
||||
<hc-empty icon="docs" />
|
||||
<ds-text align="center">
|
||||
{{ $t('index.no-results') }}
|
||||
</ds-text>
|
||||
<ds-text align="center">
|
||||
{{ $t('index.change-filter-settings') }}
|
||||
</ds-text>
|
||||
<ds-text align="center">{{ $t('index.no-results') }}</ds-text>
|
||||
<ds-text align="center">{{ $t('index.change-filter-settings') }}</ds-text>
|
||||
</ds-grid-item>
|
||||
</template>
|
||||
</masonry-grid>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<change-password
|
||||
:email="email"
|
||||
:code="code"
|
||||
:nonce="nonce"
|
||||
@passwordResetResponse="handlePasswordResetResponse"
|
||||
/>
|
||||
</template>
|
||||
@ -11,8 +11,8 @@ import ChangePassword from '~/components/PasswordReset/ChangePassword'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
const { email = '', code = '' } = this.$route.query
|
||||
return { email, code }
|
||||
const { email = '', nonce = '' } = this.$route.query
|
||||
return { email, nonce }
|
||||
},
|
||||
components: {
|
||||
ChangePassword,
|
||||
|
||||
@ -11,7 +11,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handlePasswordResetRequested({ email }) {
|
||||
this.$router.push({ path: 'verify-code', query: { email } })
|
||||
this.$router.push({ path: 'verify-nonce', query: { email } })
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<verify-code :email="email" @verification="handleVerification" />
|
||||
<verify-nonce :email="email" @verification="handleVerification" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VerifyCode from '~/components/PasswordReset/VerifyCode'
|
||||
import VerifyNonce from '~/components/PasswordReset/VerifyNonce'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VerifyCode,
|
||||
VerifyNonce,
|
||||
},
|
||||
data() {
|
||||
const { email = '' } = this.$route.query
|
||||
return { email }
|
||||
},
|
||||
methods: {
|
||||
handleVerification({ email, code }) {
|
||||
this.$router.push({ path: 'change-password', query: { email, code } })
|
||||
handleVerification({ email, nonce }) {
|
||||
this.$router.push({ path: 'change-password', query: { email, nonce } })
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
export const state = () => {
|
||||
return {
|
||||
placeholder: null,
|
||||
}
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
placeholder(state) {
|
||||
return state.placeholder
|
||||
},
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
SET_PLACEHOLDER_TEXT(state, text) {
|
||||
state.placeholder = text
|
||||
},
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
import { getters, mutations } from './editor.js'
|
||||
|
||||
let state
|
||||
|
||||
describe('getters', () => {
|
||||
describe('placeholder', () => {
|
||||
it('return the value in state', () => {
|
||||
state = { placeholder: null }
|
||||
expect(getters.placeholder(state)).toBe(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('mutations', () => {
|
||||
it('SET_PLACEHOLDER_TEXT', () => {
|
||||
state = { placeholder: null }
|
||||
mutations.SET_PLACEHOLDER_TEXT(state, 'new placeholder')
|
||||
expect(getters.placeholder(state)).toBe('new placeholder')
|
||||
})
|
||||
})
|
||||
@ -40,6 +40,12 @@ export const mutations = {
|
||||
if (isEmpty(get(filter, 'categories_some.id_in'))) delete filter.categories_some
|
||||
state.filter = filter
|
||||
},
|
||||
TOGGLE_EMOTION(state, emotion) {
|
||||
const filter = clone(state.filter)
|
||||
update(filter, 'emotions_some.emotion_in', emotions => xor(emotions, [emotion]))
|
||||
if (isEmpty(get(filter, 'emotions_some.emotion_in'))) delete filter.emotions_some
|
||||
state.filter = filter
|
||||
},
|
||||
}
|
||||
|
||||
export const getters = {
|
||||
@ -55,4 +61,7 @@ export const getters = {
|
||||
filteredByUsersFollowed(state) {
|
||||
return !!get(state.filter, 'author.followedBy_some.id')
|
||||
},
|
||||
filteredByEmotions(state) {
|
||||
return get(state.filter, 'emotions_some.emotion_in') || []
|
||||
},
|
||||
}
|
||||
|
||||
@ -43,6 +43,30 @@ describe('getters', () => {
|
||||
expect(getters.filteredByUsersFollowed(state)).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('filteredByEmotions', () => {
|
||||
it('returns an emotions array if filter is set', () => {
|
||||
state = { filter: { emotions_some: { emotion_in: ['sad'] } } }
|
||||
expect(getters.filteredByEmotions(state)).toEqual(['sad'])
|
||||
})
|
||||
|
||||
it('returns an emotions array even when other filters are set', () => {
|
||||
state = {
|
||||
filter: { emotions_some: { emotion_in: ['sad'] }, categories_some: { id_in: [23] } },
|
||||
}
|
||||
expect(getters.filteredByEmotions(state)).toEqual(['sad'])
|
||||
})
|
||||
|
||||
it('returns empty array if filter is not set', () => {
|
||||
state = { filter: {} }
|
||||
expect(getters.filteredByEmotions(state)).toEqual([])
|
||||
})
|
||||
|
||||
it('returns empty array if another filter is set, but not emotions', () => {
|
||||
state = { filter: { categories_some: { id_in: [23] } } }
|
||||
expect(getters.filteredByEmotions(state)).toEqual([])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('mutations', () => {
|
||||
|
||||
201
webapp/yarn.lock
201
webapp/yarn.lock
@ -56,18 +56,18 @@
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.0.0"
|
||||
|
||||
"@babel/core@^7.1.0", "@babel/core@^7.5.5", "@babel/core@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30"
|
||||
integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==
|
||||
"@babel/core@^7.1.0", "@babel/core@^7.5.5", "@babel/core@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.0.tgz#9b00f73554edd67bebc86df8303ef678be3d7b48"
|
||||
integrity sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.5.5"
|
||||
"@babel/generator" "^7.5.5"
|
||||
"@babel/helpers" "^7.5.5"
|
||||
"@babel/parser" "^7.5.5"
|
||||
"@babel/template" "^7.4.4"
|
||||
"@babel/traverse" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/generator" "^7.6.0"
|
||||
"@babel/helpers" "^7.6.0"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/template" "^7.6.0"
|
||||
"@babel/traverse" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
convert-source-map "^1.1.0"
|
||||
debug "^4.1.0"
|
||||
json5 "^2.1.0"
|
||||
@ -76,7 +76,7 @@
|
||||
semver "^5.4.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@7.5.5", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5":
|
||||
"@babel/generator@7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.5.5.tgz#873a7f936a3c89491b43536d12245b626664e3cf"
|
||||
integrity sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==
|
||||
@ -87,6 +87,17 @@
|
||||
source-map "^0.5.0"
|
||||
trim-right "^1.0.1"
|
||||
|
||||
"@babel/generator@^7.4.0", "@babel/generator@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.0.tgz#e2c21efbfd3293ad819a2359b448f002bfdfda56"
|
||||
integrity sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.6.0"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
trim-right "^1.0.1"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32"
|
||||
@ -283,14 +294,14 @@
|
||||
"@babel/traverse" "^7.1.0"
|
||||
"@babel/types" "^7.2.0"
|
||||
|
||||
"@babel/helpers@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e"
|
||||
integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==
|
||||
"@babel/helpers@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.0.tgz#21961d16c6a3c3ab597325c34c465c0887d31c6e"
|
||||
integrity sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==
|
||||
dependencies:
|
||||
"@babel/template" "^7.4.4"
|
||||
"@babel/traverse" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/template" "^7.6.0"
|
||||
"@babel/traverse" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
|
||||
"@babel/highlight@^7.0.0":
|
||||
version "7.0.0"
|
||||
@ -301,10 +312,10 @@
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
|
||||
integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
|
||||
"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.0.tgz#3e05d0647432a8326cb28d0de03895ae5a57f39b"
|
||||
integrity sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==
|
||||
|
||||
"@babel/plugin-proposal-async-generator-functions@^7.2.0":
|
||||
version "7.2.0"
|
||||
@ -445,10 +456,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-block-scoping@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce"
|
||||
integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg==
|
||||
"@babel/plugin-transform-block-scoping@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz#c49e21228c4bbd4068a35667e6d951c75439b1dc"
|
||||
integrity sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
lodash "^4.17.13"
|
||||
@ -474,10 +485,10 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-destructuring@^7.5.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a"
|
||||
integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==
|
||||
"@babel/plugin-transform-destructuring@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.6.0.tgz#44bbe08b57f4480094d57d9ffbcd96d309075ba6"
|
||||
integrity sha512-2bGIS5P1v4+sWTCnKNDZDxbGvEqi0ijeqM/YqHtVGrvG2y0ySgnEEhXErvE9dA0bnIzY9bIzdFK0jFA46ASIIQ==
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
@ -543,10 +554,10 @@
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
babel-plugin-dynamic-import-node "^2.3.0"
|
||||
|
||||
"@babel/plugin-transform-modules-commonjs@^7.5.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74"
|
||||
integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==
|
||||
"@babel/plugin-transform-modules-commonjs@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.6.0.tgz#39dfe957de4420445f1fcf88b68a2e4aa4515486"
|
||||
integrity sha512-Ma93Ix95PNSEngqomy5LSBMAQvYKVe3dy+JlVJSHEXZR5ASL9lQBedMiCyVtmTLraIDVRE3ZjTZvmXXD2Ozw3g==
|
||||
dependencies:
|
||||
"@babel/helper-module-transforms" "^7.4.4"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
@ -570,12 +581,12 @@
|
||||
"@babel/helper-module-transforms" "^7.1.0"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5":
|
||||
version "7.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106"
|
||||
integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==
|
||||
"@babel/plugin-transform-named-capturing-groups-regex@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz#1e6e663097813bb4f53d42df0750cf28ad3bb3f1"
|
||||
integrity sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==
|
||||
dependencies:
|
||||
regexp-tree "^0.1.6"
|
||||
regexp-tree "^0.1.13"
|
||||
|
||||
"@babel/plugin-transform-new-target@^7.4.4":
|
||||
version "7.4.4"
|
||||
@ -686,10 +697,10 @@
|
||||
"@babel/helper-regex" "^7.4.4"
|
||||
regexpu-core "^4.5.4"
|
||||
|
||||
"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5", "@babel/preset-env@~7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a"
|
||||
integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A==
|
||||
"@babel/preset-env@^7.4.5", "@babel/preset-env@^7.5.5", "@babel/preset-env@~7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.0.tgz#aae4141c506100bb2bfaa4ac2a5c12b395619e50"
|
||||
integrity sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.0.0"
|
||||
"@babel/helper-plugin-utils" "^7.0.0"
|
||||
@ -707,10 +718,10 @@
|
||||
"@babel/plugin-transform-arrow-functions" "^7.2.0"
|
||||
"@babel/plugin-transform-async-to-generator" "^7.5.0"
|
||||
"@babel/plugin-transform-block-scoped-functions" "^7.2.0"
|
||||
"@babel/plugin-transform-block-scoping" "^7.5.5"
|
||||
"@babel/plugin-transform-block-scoping" "^7.6.0"
|
||||
"@babel/plugin-transform-classes" "^7.5.5"
|
||||
"@babel/plugin-transform-computed-properties" "^7.2.0"
|
||||
"@babel/plugin-transform-destructuring" "^7.5.0"
|
||||
"@babel/plugin-transform-destructuring" "^7.6.0"
|
||||
"@babel/plugin-transform-dotall-regex" "^7.4.4"
|
||||
"@babel/plugin-transform-duplicate-keys" "^7.5.0"
|
||||
"@babel/plugin-transform-exponentiation-operator" "^7.2.0"
|
||||
@ -719,10 +730,10 @@
|
||||
"@babel/plugin-transform-literals" "^7.2.0"
|
||||
"@babel/plugin-transform-member-expression-literals" "^7.2.0"
|
||||
"@babel/plugin-transform-modules-amd" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-commonjs" "^7.6.0"
|
||||
"@babel/plugin-transform-modules-systemjs" "^7.5.0"
|
||||
"@babel/plugin-transform-modules-umd" "^7.2.0"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.4.5"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.6.0"
|
||||
"@babel/plugin-transform-new-target" "^7.4.4"
|
||||
"@babel/plugin-transform-object-super" "^7.5.5"
|
||||
"@babel/plugin-transform-parameters" "^7.4.4"
|
||||
@ -735,7 +746,7 @@
|
||||
"@babel/plugin-transform-template-literals" "^7.4.4"
|
||||
"@babel/plugin-transform-typeof-symbol" "^7.2.0"
|
||||
"@babel/plugin-transform-unicode-regex" "^7.4.4"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/types" "^7.6.0"
|
||||
browserslist "^4.6.0"
|
||||
core-js-compat "^3.1.1"
|
||||
invariant "^2.2.2"
|
||||
@ -771,31 +782,31 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
|
||||
integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
|
||||
"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6"
|
||||
integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
"@babel/parser" "^7.4.4"
|
||||
"@babel/types" "^7.4.4"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb"
|
||||
integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==
|
||||
"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.5.5", "@babel/traverse@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.0.tgz#389391d510f79be7ce2ddd6717be66d3fed4b516"
|
||||
integrity sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.5.5"
|
||||
"@babel/generator" "^7.5.5"
|
||||
"@babel/generator" "^7.6.0"
|
||||
"@babel/helper-function-name" "^7.1.0"
|
||||
"@babel/helper-split-export-declaration" "^7.4.4"
|
||||
"@babel/parser" "^7.5.5"
|
||||
"@babel/types" "^7.5.5"
|
||||
"@babel/parser" "^7.6.0"
|
||||
"@babel/types" "^7.6.0"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/types@7.5.5", "@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5":
|
||||
"@babel/types@7.5.5":
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.5.5.tgz#97b9f728e182785909aa4ab56264f090a028d18a"
|
||||
integrity sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==
|
||||
@ -804,6 +815,15 @@
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.6.0":
|
||||
version "7.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.1.tgz#53abf3308add3ac2a2884d539151c57c4b3ac648"
|
||||
integrity sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@cnakazawa/watch@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
|
||||
@ -966,10 +986,10 @@
|
||||
supports-color "^5.5.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@human-connection/styleguide@0.5.19":
|
||||
version "0.5.19"
|
||||
resolved "https://registry.yarnpkg.com/@human-connection/styleguide/-/styleguide-0.5.19.tgz#ab5df5e421bb8e8259747c0f48b1f324ad013c43"
|
||||
integrity sha512-UrmHtIvJ+bi0s4Q2Xjh0lIcBYcGiiOeIp34XT16CO4Oe/ziZZ/bFph5kTgrYtrIz42qucmNHZ8TxN5gYRD1MoQ==
|
||||
"@human-connection/styleguide@0.5.21":
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/@human-connection/styleguide/-/styleguide-0.5.21.tgz#ef577325bef8577d2846f3b29567ca15856f2e39"
|
||||
integrity sha512-psGiIfrDRfwsZ5UtFGDiq2uB/nLkfPsNpAv5c2RAI3QpK+YOp5c3W1MuHASij7Z9iFaxZ0qkuzXiOg+mVAZbdg==
|
||||
dependencies:
|
||||
vue "^2.6.10"
|
||||
|
||||
@ -4295,16 +4315,7 @@ browserslist@4.5.4:
|
||||
electron-to-chromium "^1.3.122"
|
||||
node-releases "^1.1.13"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.5.4, browserslist@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.0.tgz#5274028c26f4d933d5b1323307c1d1da5084c9ff"
|
||||
integrity sha512-Jk0YFwXBuMOOol8n6FhgkDzn3mY9PYLYGk29zybF05SbRTsMgPqmTNeQQhOghCxq5oFqAXE3u4sYddr4C0uRhg==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30000967"
|
||||
electron-to-chromium "^1.3.133"
|
||||
node-releases "^1.1.19"
|
||||
|
||||
browserslist@^4.6.3, browserslist@^4.6.4:
|
||||
browserslist@^4.0.0, browserslist@^4.5.4, browserslist@^4.6.0, browserslist@^4.6.3, browserslist@^4.6.4:
|
||||
version "4.6.6"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453"
|
||||
integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==
|
||||
@ -4537,7 +4548,7 @@ caniuse-api@^3.0.0:
|
||||
lodash.memoize "^4.1.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000957, caniuse-lite@^1.0.30000967:
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000957:
|
||||
version "1.0.30000967"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000967.tgz#a5039577806fccee80a04aaafb2c0890b1ee2f73"
|
||||
integrity sha512-rUBIbap+VJfxTzrM4akJ00lkvVb5/n5v3EGXfWzSH5zT8aJmGzjA8HWhJ4U6kCpzxozUSnB+yvAYDRPY6mRpgQ==
|
||||
@ -5701,10 +5712,10 @@ data-urls@^1.0.0:
|
||||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-fns@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.0.1.tgz#c5f30e31d3294918e6b6a82753a4e719120e203d"
|
||||
integrity sha512-C14oTzTZy8DH1Eq8N78owrCWvf3+cnJw88BTK/N3DYWVxDJuJzPaNdplzYxDYuuXXGvqBcO4Vy5SOrwAooXSWw==
|
||||
date-fns@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.1.0.tgz#0d7e806c3cefe14a943532dbf968995ccfd46bd9"
|
||||
integrity sha512-eKeLk3sLCnxB/0PN4t1+zqDtSs4jb4mXRSTZ2okmx/myfWyDqeO4r5nnmA5LClJiCwpuTMeK2v5UQPuE4uMaxA==
|
||||
|
||||
date-fns@^1.27.2:
|
||||
version "1.30.1"
|
||||
@ -6133,11 +6144,6 @@ electron-to-chromium@^1.3.122:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.211.tgz#0c39d17316bf342d1971fed68e754fa1775918f7"
|
||||
integrity sha512-GZAiK3oHrs0K+LwH+HD+bdjZ17v40oQQdXbbd3dgrwgbENvazrGpcuIADSAREWnxzo9gADB1evuizrbXsnoU2Q==
|
||||
|
||||
electron-to-chromium@^1.3.133:
|
||||
version "1.3.137"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.137.tgz#ba7c88024984c038a5c5c434529aabcea7b42944"
|
||||
integrity sha512-kGi32g42a8vS/WnYE7ELJyejRT7hbr3UeOOu0WeuYuQ29gCpg9Lrf6RdcTQVXSt/v0bjCfnlb/EWOOsiKpTmkw==
|
||||
|
||||
electron-to-chromium@^1.3.191:
|
||||
version "1.3.237"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.237.tgz#39c5d1da59d6fd16ff705b97e772bb3b5dfda7e4"
|
||||
@ -10511,13 +10517,6 @@ node-releases@^1.1.13:
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
node-releases@^1.1.19:
|
||||
version "1.1.21"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.21.tgz#46c86f9adaceae4d63c75d3c2f2e6eee618e55f3"
|
||||
integrity sha512-TwnURTCjc8a+ElJUjmDqU6+12jhli1Q61xOQmdZ7ECZVBZuQpN/1UnembiIHDM1wCcfLvh5wrWXUF5H6ufX64Q==
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
node-releases@^1.1.25:
|
||||
version "1.1.27"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.27.tgz#b19ec8add2afe9a826a99dceccc516104c1edaf4"
|
||||
@ -12975,10 +12974,10 @@ regex-not@^1.0.0, regex-not@^1.0.2:
|
||||
extend-shallow "^3.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
regexp-tree@^0.1.6:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.10.tgz#d837816a039c7af8a8d64d7a7c3cf6a1d93450bc"
|
||||
integrity sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==
|
||||
regexp-tree@^0.1.13:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.13.tgz#5b19ab9377edc68bc3679256840bb29afc158d7f"
|
||||
integrity sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==
|
||||
|
||||
regexp.prototype.flags@^1.2.0:
|
||||
version "1.2.0"
|
||||
@ -15171,10 +15170,10 @@ vue-izitoast@^1.2.1:
|
||||
dependencies:
|
||||
izitoast "^1.4.0"
|
||||
|
||||
vue-jest@~3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-3.0.4.tgz#b6a2b0d874968f26fa775ac901903fece531e08b"
|
||||
integrity sha512-PY9Rwt4OyaVlA+KDJJ0614CbEvNOkffDI9g9moLQC/2DDoo0YrqZm7dHi13Q10uoK5Nt5WCYFdeAheOExPah0w==
|
||||
vue-jest@~3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/vue-jest/-/vue-jest-3.0.5.tgz#d6f124b542dcbff207bf9296c19413f4c40b70c9"
|
||||
integrity sha512-xWDxde91pDqYBGDlODENZ3ezPgw+IQFoVDtf+5Awlg466w3KvMSqWzs8PxcTeTr+wmAHi0j+a+Lm3R7aUJa1jA==
|
||||
dependencies:
|
||||
babel-plugin-transform-es2015-modules-commonjs "^6.26.0"
|
||||
chalk "^2.1.0"
|
||||
|
||||
@ -3471,10 +3471,10 @@ neo4j-driver@^1.7.5, neo4j-driver@^1.7.6:
|
||||
text-encoding-utf-8 "^1.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
neode@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/neode/-/neode-0.3.2.tgz#ced277e1daba26a77c48f5857c30af054f11c7df"
|
||||
integrity sha512-Bm4GBXdXunv8cqUUkJtksIGHDnYdBJf4UHwzFgXbJiDKBAdqfjhzwAPAhf1PrvlFmR4vJva2Bh/XvIghYOiKrA==
|
||||
neode@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/neode/-/neode-0.3.3.tgz#a539830cce6f6e4825462f6cb03f2969a0003f1b"
|
||||
integrity sha512-pArHG1hD2kVwrzLlz6B1+IgdOJRQj/BgR6KzH6DlVzSA6geoZRe68fbpvmOJtzyPU7iuUYxXVk87PpPM1A7dlg==
|
||||
dependencies:
|
||||
"@hapi/joi" "^15.1.0"
|
||||
dotenv "^4.0.0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user