Merge branch 'master' of github.com:Human-Connection/Human-Connection into 3054-add-e2e-tests-image-uploader

This commit is contained in:
mattwr18 2020-02-17 18:38:09 +01:00
commit 3398c2c12a
26 changed files with 532 additions and 413 deletions

View File

@ -1,8 +1,8 @@
--- ---
name: :boom: DevOps ticket name: 💥 DevOps ticket
about: Help us manage our deployed App. about: Help us manage our deployed App.
labels: devops labels: devops
title: :boom: [DevOps] title: 💥 [DevOps]
--- ---
## :fire: DevOps ticket ## :fire: DevOps ticket

View File

@ -60,9 +60,11 @@
"graphql-iso-date": "~3.6.1", "graphql-iso-date": "~3.6.1",
"graphql-middleware": "~4.0.2", "graphql-middleware": "~4.0.2",
"graphql-middleware-sentry": "^3.2.1", "graphql-middleware-sentry": "^3.2.1",
"graphql-redis-subscriptions": "^2.1.2",
"graphql-shield": "~7.0.11", "graphql-shield": "~7.0.11",
"graphql-tag": "~2.10.3", "graphql-tag": "~2.10.3",
"helmet": "~3.21.2", "helmet": "~3.21.2",
"ioredis": "^4.14.1",
"jsonwebtoken": "~8.5.1", "jsonwebtoken": "~8.5.1",
"linkifyjs": "~2.1.8", "linkifyjs": "~2.1.8",
"lodash": "~4.17.14", "lodash": "~4.17.14",
@ -73,7 +75,7 @@
"metascraper-clearbit-logo": "^5.3.0", "metascraper-clearbit-logo": "^5.3.0",
"metascraper-date": "^5.10.7", "metascraper-date": "^5.10.7",
"metascraper-description": "^5.11.0", "metascraper-description": "^5.11.0",
"metascraper-image": "^5.10.7", "metascraper-image": "^5.11.1",
"metascraper-lang": "^5.10.7", "metascraper-lang": "^5.10.7",
"metascraper-lang-detector": "^4.10.2", "metascraper-lang-detector": "^4.10.2",
"metascraper-logo": "^5.10.7", "metascraper-logo": "^5.10.7",
@ -96,6 +98,7 @@
"request": "~2.88.2", "request": "~2.88.2",
"sanitize-html": "~1.21.1", "sanitize-html": "~1.21.1",
"slug": "~2.1.1", "slug": "~2.1.1",
"subscriptions-transport-ws": "^0.9.16",
"trunc-html": "~1.1.2", "trunc-html": "~1.1.2",
"uuid": "~3.4.0", "uuid": "~3.4.0",
"validator": "^12.2.0", "validator": "^12.2.0",
@ -119,7 +122,7 @@
"eslint-config-prettier": "~6.10.0", "eslint-config-prettier": "~6.10.0",
"eslint-config-standard": "~14.1.0", "eslint-config-standard": "~14.1.0",
"eslint-plugin-import": "~2.20.1", "eslint-plugin-import": "~2.20.1",
"eslint-plugin-jest": "~23.6.0", "eslint-plugin-jest": "~23.7.0",
"eslint-plugin-node": "~11.0.0", "eslint-plugin-node": "~11.0.0",
"eslint-plugin-prettier": "~3.1.2", "eslint-plugin-prettier": "~3.1.2",
"eslint-plugin-promise": "~4.2.1", "eslint-plugin-promise": "~4.2.1",

View File

@ -23,6 +23,9 @@ const {
NEO4J_PASSWORD = 'neo4j', NEO4J_PASSWORD = 'neo4j',
CLIENT_URI = 'http://localhost:3000', CLIENT_URI = 'http://localhost:3000',
GRAPHQL_URI = 'http://localhost:4000', GRAPHQL_URI = 'http://localhost:4000',
REDIS_DOMAIN,
REDIS_PORT,
REDIS_PASSWORD,
} = env } = env
export const requiredConfigs = { export const requiredConfigs = {
@ -61,7 +64,7 @@ export const developmentConfigs = {
} }
export const sentryConfigs = { SENTRY_DSN_BACKEND, COMMIT } export const sentryConfigs = { SENTRY_DSN_BACKEND, COMMIT }
export const redisConfiig = { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD }
export default { export default {
...requiredConfigs, ...requiredConfigs,
...smtpConfigs, ...smtpConfigs,
@ -69,4 +72,5 @@ export default {
...serverConfigs, ...serverConfigs,
...developmentConfigs, ...developmentConfigs,
...sentryConfigs, ...sentryConfigs,
...redisConfiig,
} }

View File

@ -1,9 +1,11 @@
import createServer from './server' import createServer from './server'
import CONFIG from './config' import CONFIG from './config'
const { app } = createServer() const { server, httpServer } = createServer()
const url = new URL(CONFIG.GRAPHQL_URI) const url = new URL(CONFIG.GRAPHQL_URI)
app.listen({ port: url.port }, () => { httpServer.listen({ port: url.port }, () => {
/* eslint-disable-next-line no-console */ /* eslint-disable-next-line no-console */
console.log(`GraphQLServer ready at ${CONFIG.GRAPHQL_URI} 🚀`) console.log(`🚀 Server ready at http://localhost:${url.port}${server.graphqlPath}`)
/* eslint-disable-next-line no-console */
console.log(`🚀 Subscriptions ready at ws://localhost:${url.port}${server.subscriptionsPath}`)
}) })

View File

@ -1,5 +1,6 @@
import extractMentionedUsers from './mentions/extractMentionedUsers' import extractMentionedUsers from './mentions/extractMentionedUsers'
import { validateNotifyUsers } from '../validation/validationMiddleware' import { validateNotifyUsers } from '../validation/validationMiddleware'
import { pubsub, NOTIFICATION_ADDED } from '../../server'
const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => { const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => {
const idsOfUsers = extractMentionedUsers(args.content) const idsOfUsers = extractMentionedUsers(args.content)
@ -52,34 +53,48 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => {
WHERE user.id in $idsOfUsers WHERE user.id in $idsOfUsers
AND NOT (user)-[:BLOCKED]-(author) AND NOT (user)-[:BLOCKED]-(author)
MERGE (post)-[notification:NOTIFIED {reason: $reason}]->(user) MERGE (post)-[notification:NOTIFIED {reason: $reason}]->(user)
WITH post AS resource, notification, user
` `
break break
} }
case 'mentioned_in_comment': { case 'mentioned_in_comment': {
mentionedCypher = ` mentionedCypher = `
MATCH (postAuthor: User)-[:WROTE]->(post: Post)<-[:COMMENTS]-(comment: Comment { id: $id })<-[:WROTE]-(author: User) MATCH (postAuthor: User)-[:WROTE]->(post: Post)<-[:COMMENTS]-(comment: Comment { id: $id })<-[:WROTE]-(commenter: User)
MATCH (user: User) MATCH (user: User)
WHERE user.id in $idsOfUsers WHERE user.id in $idsOfUsers
AND NOT (user)-[:BLOCKED]-(author) AND NOT (user)-[:BLOCKED]-(commenter)
AND NOT (user)-[:BLOCKED]-(postAuthor) AND NOT (user)-[:BLOCKED]-(postAuthor)
MERGE (comment)-[notification:NOTIFIED {reason: $reason}]->(user) MERGE (comment)-[notification:NOTIFIED {reason: $reason}]->(user)
WITH comment AS resource, notification, user
` `
break break
} }
} }
mentionedCypher += ` mentionedCypher += `
WITH notification, user, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
WITH resource, user, notification, authors, posts,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource
SET notification.read = FALSE SET notification.read = FALSE
SET ( SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime()))
CASE
WHEN notification.createdAt IS NULL
THEN notification END ).createdAt = toString(datetime())
SET notification.updatedAt = toString(datetime()) SET notification.updatedAt = toString(datetime())
RETURN notification {.*, from: finalResource, to: properties(user)}
` `
const session = context.driver.session() const session = context.driver.session()
try { const writeTxResultPromise = session.writeTransaction(async transaction => {
await session.writeTransaction(transaction => { const notificationTransactionResponse = await transaction.run(mentionedCypher, {
return transaction.run(mentionedCypher, { id, idsOfUsers, reason }) id,
idsOfUsers,
reason,
}) })
return notificationTransactionResponse.records.map(record => record.get('notification'))
})
try {
const [notification] = await writeTxResultPromise
return pubsub.publish(NOTIFICATION_ADDED, { notificationAdded: notification })
} catch (error) {
throw new Error(error)
} finally { } finally {
session.close() session.close()
} }
@ -88,24 +103,26 @@ const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => {
const notifyUsersOfComment = async (label, commentId, postAuthorId, reason, context) => { const notifyUsersOfComment = async (label, commentId, postAuthorId, reason, context) => {
await validateNotifyUsers(label, reason) await validateNotifyUsers(label, reason)
const session = context.driver.session() const session = context.driver.session()
const writeTxResultPromise = await session.writeTransaction(async transaction => {
const notificationTransactionResponse = await transaction.run(
`
MATCH (postAuthor:User {id: $postAuthorId})-[:WROTE]->(post:Post)<-[:COMMENTS]-(comment:Comment { id: $commentId })<-[:WROTE]-(commenter:User)
WHERE NOT (postAuthor)-[:BLOCKED]-(commenter)
MERGE (comment)-[notification:NOTIFIED {reason: $reason}]->(postAuthor)
SET notification.read = FALSE
SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime()))
SET notification.updatedAt = toString(datetime())
WITH notification, postAuthor, post,
comment {.*, __typename: labels(comment)[0], author: properties(commenter), post: post {.*, author: properties(postAuthor) } } AS finalResource
RETURN notification {.*, from: finalResource, to: properties(postAuthor)}
`,
{ commentId, postAuthorId, reason },
)
return notificationTransactionResponse.records.map(record => record.get('notification'))
})
try { try {
await session.writeTransaction(async transaction => { const [notification] = await writeTxResultPromise
await transaction.run( return pubsub.publish(NOTIFICATION_ADDED, { notificationAdded: notification })
`
MATCH (postAuthor:User {id: $postAuthorId})-[:WROTE]->(post:Post)<-[:COMMENTS]-(comment:Comment { id: $commentId })<-[:WROTE]-(commenter:User)
WHERE NOT (postAuthor)-[:BLOCKED]-(commenter)
MERGE (comment)-[notification:NOTIFIED {reason: $reason}]->(postAuthor)
SET notification.read = FALSE
SET (
CASE
WHEN notification.createdAt IS NULL
THEN notification END ).createdAt = toString(datetime())
SET notification.updatedAt = toString(datetime())
`,
{ commentId, postAuthorId, reason },
)
})
} finally { } finally {
session.close() session.close()
} }

View File

@ -1,21 +1,18 @@
import log from './helpers/databaseLogger' import log from './helpers/databaseLogger'
import { withFilter } from 'graphql-subscriptions'
const resourceTypes = ['Post', 'Comment'] import { pubsub, NOTIFICATION_ADDED } from '../../server'
const transformReturnType = record => {
return {
...record.get('notification').properties,
from: {
__typename: record.get('resource').labels.find(l => resourceTypes.includes(l)),
...record.get('resource').properties,
},
to: {
...record.get('user').properties,
},
}
}
export default { export default {
Subscription: {
notificationAdded: {
subscribe: withFilter(
() => pubsub.asyncIterator(NOTIFICATION_ADDED),
(payload, variables) => {
return payload.notificationAdded.to.id === variables.userId
},
),
},
},
Query: { Query: {
notifications: async (_parent, args, context, _resolveInfo) => { notifications: async (_parent, args, context, _resolveInfo) => {
const { user: currentUser } = context const { user: currentUser } = context
@ -51,10 +48,10 @@ export default {
MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id}) MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id})
${whereClause} ${whereClause}
WITH user, notification, resource, WITH user, notification, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] as authors, [(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] as posts [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
WITH resource, user, notification, authors, posts, WITH resource, user, notification, authors, posts,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} as finalResource resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource
RETURN notification {.*, from: finalResource, to: properties(user)} RETURN notification {.*, from: finalResource, to: properties(user)}
${orderByClause} ${orderByClause}
${offset} ${limit} ${offset} ${limit}
@ -81,12 +78,19 @@ export default {
` `
MATCH (resource {id: $resourceId})-[notification:NOTIFIED {read: FALSE}]->(user:User {id:$id}) MATCH (resource {id: $resourceId})-[notification:NOTIFIED {read: FALSE}]->(user:User {id:$id})
SET notification.read = TRUE SET notification.read = TRUE
RETURN resource, notification, user WITH user, notification, resource,
[(resource)<-[:WROTE]-(author:User) | author {.*}] AS authors,
[(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] AS posts
WITH resource, user, notification, authors, posts,
resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} AS finalResource
RETURN notification {.*, from: finalResource, to: properties(user)}
`, `,
{ resourceId: args.id, id: currentUser.id }, { resourceId: args.id, id: currentUser.id },
) )
log(markNotificationAsReadTransactionResponse) log(markNotificationAsReadTransactionResponse)
return markNotificationAsReadTransactionResponse.records.map(transformReturnType) return markNotificationAsReadTransactionResponse.records.map(record =>
record.get('notification'),
)
}) })
try { try {
const [notifications] = await writeTxResultPromise const [notifications] = await writeTxResultPromise

View File

@ -30,3 +30,7 @@ type Query {
type Mutation { type Mutation {
markAsRead(id: ID!): NOTIFIED markAsRead(id: ID!): NOTIFIED
} }
type Subscription {
notificationAdded(userId: ID!): NOTIFIED
}

View File

@ -1,4 +1,5 @@
import express from 'express' import express from 'express'
import http from 'http'
import helmet from 'helmet' import helmet from 'helmet'
import { ApolloServer } from 'apollo-server-express' import { ApolloServer } from 'apollo-server-express'
import CONFIG from './config' import CONFIG from './config'
@ -7,12 +8,35 @@ import { getNeode, getDriver } from './db/neo4j'
import decode from './jwt/decode' import decode from './jwt/decode'
import schema from './schema' import schema from './schema'
import webfinger from './activitypub/routes/webfinger' import webfinger from './activitypub/routes/webfinger'
import { RedisPubSub } from 'graphql-redis-subscriptions'
import { PubSub } from 'graphql-subscriptions'
import Redis from 'ioredis'
import bodyParser from 'body-parser' import bodyParser from 'body-parser'
export const NOTIFICATION_ADDED = 'NOTIFICATION_ADDED'
const { REDIS_DOMAIN, REDIS_PORT, REDIS_PASSWORD } = CONFIG
let prodPubsub, devPubsub
const options = {
host: REDIS_DOMAIN,
port: REDIS_PORT,
password: REDIS_PASSWORD,
retryStrategy: times => {
return Math.min(times * 50, 2000)
},
}
if (options.host && options.port && options.password) {
prodPubsub = new RedisPubSub({
publisher: new Redis(options),
subscriber: new Redis(options),
})
} else {
devPubsub = new PubSub()
}
export const pubsub = prodPubsub || devPubsub
const driver = getDriver() const driver = getDriver()
const neode = getNeode() const neode = getNeode()
export const context = async ({ req }) => { const getContext = async req => {
const user = await decode(driver, req.headers.authorization) const user = await decode(driver, req.headers.authorization)
return { return {
driver, driver,
@ -24,11 +48,24 @@ export const context = async ({ req }) => {
}, },
} }
} }
export const context = async options => {
const { connection, req } = options
if (connection) {
return connection.context
} else {
return getContext(req)
}
}
const createServer = options => { const createServer = options => {
const defaults = { const defaults = {
context, context,
schema: middleware(schema), schema: middleware(schema),
subscriptions: {
onConnect: (connectionParams, webSocket) => {
return getContext(connectionParams)
},
},
debug: !!CONFIG.DEBUG, debug: !!CONFIG.DEBUG,
tracing: !!CONFIG.DEBUG, tracing: !!CONFIG.DEBUG,
formatError: error => { formatError: error => {
@ -49,8 +86,10 @@ const createServer = options => {
app.use(bodyParser.json({ limit: '10mb' })) app.use(bodyParser.json({ limit: '10mb' }))
app.use(bodyParser.urlencoded({ limit: '10mb', extended: true })) app.use(bodyParser.urlencoded({ limit: '10mb', extended: true }))
server.applyMiddleware({ app, path: '/' }) server.applyMiddleware({ app, path: '/' })
const httpServer = http.createServer(app)
server.installSubscriptionHandlers(httpServer)
return { server, app } return { server, httpServer, app }
} }
export default createServer export default createServer

View File

@ -1175,13 +1175,13 @@
url-regex "~4.1.1" url-regex "~4.1.1"
video-extensions "~1.1.0" video-extensions "~1.1.0"
"@metascraper/helpers@^5.10.7": "@metascraper/helpers@^5.10.7", "@metascraper/helpers@^5.11.1":
version "5.10.7" version "5.11.1"
resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.10.7.tgz#4d330204372ce5c1afedfc3ac891fb373f72c085" resolved "https://registry.yarnpkg.com/@metascraper/helpers/-/helpers-5.11.1.tgz#227fdd0caf1d33f4b24a85298a355ce7ebb451df"
integrity sha512-YkL4vTF4grgNTFhe9t4qsD0c5aEjxWoC0cpvMICs6JriRtedwjVfiwWhaGiTbU3pGFhmLgE9fV42wXOXGUGjMQ== integrity sha512-oES/e6bwKBlT7WGa2ni3xbJMDx2rbFxSzbUhRX8D+Kylb8H2ThP07c7f+VXMPXWx5CPrNMai/Oyp5IczCf3v8g==
dependencies: dependencies:
audio-extensions "0.0.0" audio-extensions "0.0.0"
chrono-node "~1.4.2" chrono-node "~1.4.3"
condense-whitespace "~2.0.0" condense-whitespace "~2.0.0"
entities "~2.0.0" entities "~2.0.0"
file-extension "~4.0.5" file-extension "~4.0.5"
@ -2691,10 +2691,10 @@ chrono-node@~1.3.11:
dependencies: dependencies:
moment "2.21.0" moment "2.21.0"
chrono-node@~1.4.2: chrono-node@~1.4.3:
version "1.4.2" version "1.4.3"
resolved "https://registry.yarnpkg.com/chrono-node/-/chrono-node-1.4.2.tgz#0c7fc1f264e60a660c2b2dab753a3f285dbfd8c9" resolved "https://registry.yarnpkg.com/chrono-node/-/chrono-node-1.4.3.tgz#4c8e24643ec5e576f6f8fe0429370c3b554491b4"
integrity sha512-fsb82wPDHVZl3xtche8k4ZZtNwf81/ZMueil2ANpSfogUAEa3BuzZAar7ObLXi1ptMjBzdzA6ys/bFq1oBjO8w== integrity sha512-ZyKcnTcr8i7Mt9p4+ixMHEuR6+eMTrjYCL9Rm9TZHviLleCtcZoVzmr2uSc+Vg8MX1YbNCnPbEd4rfV8WvzLcw==
dependencies: dependencies:
dayjs "^1.8.19" dayjs "^1.8.19"
@ -2774,6 +2774,11 @@ clone-response@^1.0.2:
dependencies: dependencies:
mimic-response "^1.0.0" mimic-response "^1.0.0"
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==
co@^4.6.0: co@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
@ -3254,6 +3259,11 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
denque@^1.1.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf"
integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==
depd@2.0.0: depd@2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@ -3643,13 +3653,12 @@ eslint-plugin-import@~2.20.1:
read-pkg-up "^2.0.0" read-pkg-up "^2.0.0"
resolve "^1.12.0" resolve "^1.12.0"
eslint-plugin-jest@~23.6.0: eslint-plugin-jest@~23.7.0:
version "23.6.0" version "23.7.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.6.0.tgz#508b32f80d44058c8c01257c0ee718cfbd521e9d" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.7.0.tgz#84d5603b6e745b59898cb6750df6a44782a39b04"
integrity sha512-GH8AhcFXspOLqak7fqnddLXEJsrFyvgO8Bm60SexvKSn1+3rWYESnCiWUOCUcBTprNSDSE4CtAZdM4EyV6gPPw== integrity sha512-zkiyGlvJeHNjAEz8FaIxTXNblJJ/zj3waNbYbgflK7K6uy0cpE5zJBt/JpJtOBGM/UGkC6BqsQ4n0y7kQ2HA8w==
dependencies: dependencies:
"@typescript-eslint/experimental-utils" "^2.5.0" "@typescript-eslint/experimental-utils" "^2.5.0"
micromatch "^4.0.2"
eslint-plugin-node@~11.0.0: eslint-plugin-node@~11.0.0:
version "11.0.0" version "11.0.0"
@ -4476,6 +4485,15 @@ graphql-middleware@~4.0.2:
dependencies: dependencies:
graphql-tools "^4.0.5" graphql-tools "^4.0.5"
graphql-redis-subscriptions@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/graphql-redis-subscriptions/-/graphql-redis-subscriptions-2.1.2.tgz#9c1b744bace0c6ba99dd0ebafe0148cad1df3301"
integrity sha512-l69KbGxyYfVHxvE+Dzv9/hXg/q+Xnjfx1JsrJD6ikePuSsNaCSNxr+MubSTNF3Gt3C/+JZs4FaWImFeK/+X2og==
dependencies:
iterall "^1.2.2"
optionalDependencies:
ioredis "^4.6.3"
graphql-shield@~7.0.11: graphql-shield@~7.0.11:
version "7.0.11" version "7.0.11"
resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-7.0.11.tgz#78d49f346326be71090d35d8f5843da9ee8136e2" resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-7.0.11.tgz#78d49f346326be71090d35d8f5843da9ee8136e2"
@ -4920,6 +4938,21 @@ invariant@^2.2.2, invariant@^2.2.4:
dependencies: dependencies:
loose-envify "^1.0.0" loose-envify "^1.0.0"
ioredis@^4.14.1, ioredis@^4.6.3:
version "4.14.1"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.14.1.tgz#b73ded95fcf220f106d33125a92ef6213aa31318"
integrity sha512-94W+X//GHM+1GJvDk6JPc+8qlM7Dul+9K+lg3/aHixPN7ZGkW6qlvX0DG6At9hWtH2v3B32myfZqWoANUJYGJA==
dependencies:
cluster-key-slot "^1.1.0"
debug "^4.1.1"
denque "^1.1.0"
lodash.defaults "^4.2.0"
lodash.flatten "^4.4.0"
redis-commands "1.5.0"
redis-errors "^1.2.0"
redis-parser "^3.0.0"
standard-as-callback "^2.0.1"
ip-regex@^1.0.1: ip-regex@^1.0.1:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
@ -5960,11 +5993,21 @@ lodash.clonedeep@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
lodash.escaperegexp@^4.1.2: lodash.escaperegexp@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347" resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c= integrity sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
lodash.includes@^4.3.0: lodash.includes@^4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@ -6190,12 +6233,12 @@ metascraper-description@^5.11.0:
dependencies: dependencies:
"@metascraper/helpers" "^5.10.7" "@metascraper/helpers" "^5.10.7"
metascraper-image@^5.10.7: metascraper-image@^5.11.1:
version "5.10.7" version "5.11.1"
resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.10.7.tgz#9b1da02f2e748fd388dea6394d29b6e43c367924" resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.11.1.tgz#e63e9ff045441783f9aa8c684e04927cac289e44"
integrity sha512-xrR4Rl8UNwwyzMfrKH3RtaC775aHDXVT0TQEzn5p5uYfd4evLI2O+jr1CIBIl1d3CXqVxWCQWBY3gA7RtcjgWQ== integrity sha512-Nz2ZTecj2V0KgK2QE390dOSedppaG2PtUBrTz/oaFLMZEReBtMVrcygYm9VuuTpa6XwkubvuBaouCRah12zdfg==
dependencies: dependencies:
"@metascraper/helpers" "^5.10.7" "@metascraper/helpers" "^5.11.1"
metascraper-lang-detector@^4.10.2: metascraper-lang-detector@^4.10.2:
version "4.10.2" version "4.10.2"
@ -7489,6 +7532,23 @@ realpath-native@^1.1.0:
dependencies: dependencies:
util.promisify "^1.0.0" util.promisify "^1.0.0"
redis-commands@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.5.0.tgz#80d2e20698fe688f227127ff9e5164a7dd17e785"
integrity sha512-6KxamqpZ468MeQC3bkWmCB1fp56XL64D4Kf0zJSwDZbVLLm7KFkoIcHrgRvQ+sk8dnhySs7+yBg94yIkAK7aJg==
redis-errors@^1.0.0, redis-errors@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60=
redis-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ=
dependencies:
redis-errors "^1.0.0"
referrer-policy@1.2.0: referrer-policy@1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.2.0.tgz#b99cfb8b57090dc454895ef897a4cc35ef67a98e" resolved "https://registry.yarnpkg.com/referrer-policy/-/referrer-policy-1.2.0.tgz#b99cfb8b57090dc454895ef897a4cc35ef67a98e"
@ -8196,6 +8256,11 @@ stacktrace-js@^2.0.0:
stack-generator "^2.0.1" stack-generator "^2.0.1"
stacktrace-gps "^3.0.1" stacktrace-gps "^3.0.1"
standard-as-callback@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.0.1.tgz#ed8bb25648e15831759b6023bdb87e6b60b38126"
integrity sha512-NQOxSeB8gOI5WjSaxjBgog2QFw55FV8TkS6Y07BiB3VJ8xNTvUYm0wl0s8ObgQ5NhdpnNfigMIKjgPESzgr4tg==
static-extend@^0.1.1: static-extend@^0.1.1:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"

View File

@ -14,9 +14,8 @@ Feature: Tags and Categories
looking at the popularity of a tag. looking at the popularity of a tag.
Background: Background:
Given my user account has the role "admin" Given I am logged in with a "admin" role
And we have a selection of tags and categories as well as posts And we have a selection of tags and categories as well as posts
And I am logged in
Scenario: See an overview of categories Scenario: See an overview of categories
When I navigate to the administration dashboard When I navigate to the administration dashboard

View File

@ -32,15 +32,20 @@ Given("I see David Irving's post on the post page", page => {
Given('I am logged in with a {string} role', role => { Given('I am logged in with a {string} role', role => {
cy.factory().build('user', { cy.factory().build('user', {
termsAndConditionsAgreedVersion: VERSION, termsAndConditionsAgreedVersion: VERSION,
role role,
name: `${role} is my name`
}, { }, {
email: `${role}@example.org`, email: `${role}@example.org`,
password: '1234', password: '1234',
}) })
cy.login({ cy.neode()
email: `${role}@example.org`, .first("User", {
password: '1234' name: `${role} is my name`,
}) })
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
}) })
When('I click on "Report Post" from the content menu of the post', () => { When('I click on "Report Post" from the content menu of the post', () => {

View File

@ -35,13 +35,38 @@ const annoyingParams = {
}; };
Given("I am logged in", () => { Given("I am logged in", () => {
cy.login(loginCredentials); cy.neode()
.first("User", {
name: narratorParams.name
})
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
}); });
Given("I log in as {string}", name => {
cy.neode()
.first("User", {
name
})
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
})
Given("the {string} user searches for {string}", (_, postTitle) => { Given("the {string} user searches for {string}", (_, postTitle) => {
cy.logout() cy.logout()
.login({ email: annoyingParams.email, password: '1234' }) cy.neode()
.get(".searchable-input .ds-select-search") .first("User", {
id: "annoying-user"
})
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
cy.get(".searchable-input .ds-select-search")
.focus() .focus()
.type(postTitle); .type(postTitle);
}); });
@ -113,8 +138,15 @@ When("I visit the {string} page", page => {
When("a blocked user visits the post page of one of my authored posts", () => { When("a blocked user visits the post page of one of my authored posts", () => {
cy.logout() cy.logout()
.login({ email: annoyingParams.email, password: annoyingParams.password }) cy.neode()
.openPage('/post/previously-created-post') .first("User", {
name: 'Harassing User'
})
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
cy.openPage('post/previously-created-post')
}) })
Given("I am on the {string} page", page => { Given("I am on the {string} page", page => {
@ -122,7 +154,7 @@ Given("I am on the {string} page", page => {
}); });
When("I fill in my email and password combination and click submit", () => { When("I fill in my email and password combination and click submit", () => {
cy.login(loginCredentials); cy.manualLogin(loginCredentials);
}); });
When(/(?:when )?I refresh the page/, () => { When(/(?:when )?I refresh the page/, () => {
@ -306,12 +338,21 @@ Then(
} }
); );
Given("my user account has the following login credentials:", table => { Given("I am logged in with these credentials:", table => {
loginCredentials = table.hashes()[0]; loginCredentials = table.hashes()[0];
cy.debug(); cy.debug();
cy.factory().build("user", { cy.factory().build("user", {
...termsAndConditionsAgreedVersion, ...termsAndConditionsAgreedVersion,
name: loginCredentials.email,
}, loginCredentials); }, loginCredentials);
cy.neode()
.first("User", {
name: loginCredentials.email,
})
.then(async user => {
const userJson = await user.toJson()
cy.login(userJson)
})
}); });
When("I fill the password form with:", table => { When("I fill the password form with:", table => {
@ -330,45 +371,16 @@ When("submit the form", () => {
Then("I cannot login anymore with password {string}", password => { Then("I cannot login anymore with password {string}", password => {
cy.reload(); cy.reload();
const { const { email } = loginCredentials
email cy.manualLogin({ email, password })
} = loginCredentials; .get(".iziToast-wrapper").should("contain", "Incorrect email address or password.");
cy.visit(`/login`);
cy.get("input[name=email]")
.trigger("focus")
.type(email);
cy.get("input[name=password]")
.trigger("focus")
.type(password);
cy.get("button[name=submit]")
.as("submitButton")
.click();
cy.get(".iziToast-wrapper").should(
"contain",
"Incorrect email address or password."
);
}); });
Then("I can login successfully with password {string}", password => { Then("I can login successfully with password {string}", password => {
cy.reload(); cy.reload();
cy.login({ const { email } = loginCredentials
...loginCredentials, cy.manualLogin({ email, password })
...{ .get(".iziToast-wrapper").should("contain", "You are logged in!");
password
}
});
cy.get(".iziToast-wrapper").should("contain", "You are logged in!");
});
When("I log in with the following credentials:", table => {
const {
email,
password
} = table.hashes()[0];
cy.login({
email,
password
});
}); });
When("open the notification menu and click on the first item", () => { When("open the notification menu and click on the first item", () => {
@ -440,15 +452,15 @@ Given("there is an annoying user who has muted me", () => {
}); });
Given("I am on the profile page of the annoying user", name => { Given("I am on the profile page of the annoying user", name => {
cy.openPage("/profile/annoying-user/spammy-spammer"); cy.openPage("profile/annoying-user/spammy-spammer");
}); });
When("I visit the profile page of the annoying user", name => { When("I visit the profile page of the annoying user", name => {
cy.openPage("/profile/annoying-user"); cy.openPage("profile/annoying-user");
}); });
When("I ", name => { When("I ", name => {
cy.openPage("/profile/annoying-user"); cy.openPage("profile/annoying-user");
}); });
When( When(
@ -559,18 +571,6 @@ When("a user has blocked me", () => {
}); });
}); });
When("I log in with:", table => {
const [firstRow] = table.hashes();
const {
Email,
Password
} = firstRow;
cy.login({
email: Email,
password: Password
});
});
Then("I see only one post with the title {string}", title => { Then("I see only one post with the title {string}", title => {
cy.get(".main-container") cy.get(".main-container")
.find(".post-link") .find(".post-link")

View File

@ -62,9 +62,8 @@ Feature: Report and Moderate
Given somebody reported the following posts: Given somebody reported the following posts:
| submitterEmail | resourceId | reasonCategory | reasonDescription | | submitterEmail | resourceId | reasonCategory | reasonDescription |
| p2.submitter@example.org | p2 | other | Offensive content | | p2.submitter@example.org | p2 | other | Offensive content |
And my user account has the role "moderator" And I am logged in with a "moderator" role
And there is an annoying user who has muted me And there is an annoying user who has muted me
And I am logged in
When I click on the avatar menu in the top right corner When I click on the avatar menu in the top right corner
And I click on "Moderation" And I click on "Moderation"
Then I see all the reported posts including from the user who muted me Then I see all the reported posts including from the user who muted me

View File

@ -11,9 +11,7 @@ Feature: Notification for a mention
| Matt Rider | matt-rider | matt@example.org | 4321 | | Matt Rider | matt-rider | matt@example.org | 4321 |
Scenario: Mention another user, re-login as this user and see notifications Scenario: Mention another user, re-login as this user and see notifications
Given I log in with the following credentials: Given I log in as "Wolle aus Hamburg"
| email | password |
| wolle@example.org | 1234 |
And I start to write a new post with the title "Hey Matt" beginning with: And I start to write a new post with the title "Hey Matt" beginning with:
""" """
Big shout to our fellow contributor Big shout to our fellow contributor
@ -23,9 +21,7 @@ Feature: Notification for a mention
And I choose "en" as the language for the post And I choose "en" as the language for the post
And I click on "Save" And I click on "Save"
When I log out When I log out
And I log in with the following credentials: And I log in as "Matt Rider"
| email | password |
| matt@example.org | 4321 |
And see 1 unread notifications in the top menu And see 1 unread notifications in the top menu
And open the notification menu and click on the first item And open the notification menu and click on the first item
Then I get to the post page of ".../hey-matt" Then I get to the post page of ".../hey-matt"

View File

@ -9,10 +9,9 @@ Feature: Change password
password or just out of an good habit, you want to change your password. password or just out of an good habit, you want to change your password.
Background: Background:
Given my user account has the following login credentials: Given I am logged in with these credentials:
| email | password | | email | password |
| user@example.org | exposed | | user@example.org | exposed |
And I am logged in
Scenario: Change my password Scenario: Change my password
Given I am on the "settings" page Given I am on the "settings" page

View File

@ -7,7 +7,7 @@ Feature: Authentication
Given I have a user account Given I have a user account
Scenario: Log in Scenario: Log in
When I visit the "/login" page When I visit the "login" page
And I fill in my email and password combination and click submit And I fill in my email and password combination and click submit
Then I can click on my profile picture in the top right corner Then I can click on my profile picture in the top right corner
And I can see my name "Peter Lustig" in the dropdown menu And I can see my name "Peter Lustig" in the dropdown menu

View File

@ -23,7 +23,7 @@ module.exports = (on, config) => {
config.env.NEO4J_URI = parsed.NEO4J_URI config.env.NEO4J_URI = parsed.NEO4J_URI
config.env.NEO4J_USERNAME = parsed.NEO4J_USERNAME config.env.NEO4J_USERNAME = parsed.NEO4J_USERNAME
config.env.NEO4J_PASSWORD = parsed.NEO4J_PASSWORD config.env.NEO4J_PASSWORD = parsed.NEO4J_PASSWORD
config.env.JWT_SECRET = parsed.JWT_SECRET
on('file:preprocessor', cucumber()) on('file:preprocessor', cucumber())
return config return config
} }

View File

@ -18,6 +18,7 @@ import helpers from "./helpers";
import { GraphQLClient, request } from 'graphql-request' import { GraphQLClient, request } from 'graphql-request'
import { gql } from '../../backend/src/helpers/jest' import { gql } from '../../backend/src/helpers/jest'
import config from '../../backend/src/config' import config from '../../backend/src/config'
import encode from '../../backend/src/jwt/encode'
const switchLang = name => { const switchLang = name => {
cy.get(".locale-menu").click(); cy.get(".locale-menu").click();
@ -47,7 +48,13 @@ Cypress.Commands.add("switchLanguage", (name, force) => {
} }
}); });
Cypress.Commands.add("login", ({ email, password }) => { Cypress.Commands.add("login", user => {
const token = encode(user)
cy.setCookie('human-connection-token', token)
.visit("/")
});
Cypress.Commands.add("manualLogin", ({ email, password }) => {
cy.visit(`/login`); cy.visit(`/login`);
cy.get("input[name=email]") cy.get("input[name=email]")
.trigger("focus") .trigger("focus")
@ -58,11 +65,9 @@ Cypress.Commands.add("login", ({ email, password }) => {
cy.get("button[name=submit]") cy.get("button[name=submit]")
.as("submitButton") .as("submitButton")
.click(); .click();
cy.get(".iziToast-message").should("contain", "You are logged in!");
cy.location("pathname").should("eq", "/");
}); });
Cypress.Commands.add("logout", (email, password) => { Cypress.Commands.add("logout", () => {
cy.visit(`/logout`); cy.visit(`/logout`);
cy.location("pathname").should("contain", "/login"); // we're out cy.location("pathname").should("contain", "/login"); // we're out
}); });

View File

@ -43,6 +43,7 @@
"expect": "^25.1.0", "expect": "^25.1.0",
"faker": "Marak/faker.js#master", "faker": "Marak/faker.js#master",
"graphql-request": "^1.8.2", "graphql-request": "^1.8.2",
"jsonwebtoken": "^8.5.1",
"neo4j-driver": "^4.0.1", "neo4j-driver": "^4.0.1",
"neode": "^0.3.7", "neode": "^0.3.7",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",

View File

@ -22,10 +22,9 @@
</template> </template>
<script> <script>
import { NOTIFICATIONS_POLL_INTERVAL } from '~/constants/notifications' import { mapGetters } from 'vuex'
import { notificationQuery, markAsReadMutation } from '~/graphql/User'
import unionBy from 'lodash/unionBy' import unionBy from 'lodash/unionBy'
import { notificationQuery, markAsReadMutation, notificationAdded } from '~/graphql/User'
import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon' import CounterIcon from '~/components/_new/generic/CounterIcon/CounterIcon'
import Dropdown from '~/components/Dropdown' import Dropdown from '~/components/Dropdown'
import NotificationList from '../NotificationList/NotificationList' import NotificationList from '../NotificationList/NotificationList'
@ -59,6 +58,9 @@ export default {
}, },
}, },
computed: { computed: {
...mapGetters({
user: 'auth/user',
}),
unreadNotificationsCount() { unreadNotificationsCount() {
const result = this.notifications.reduce((count, notification) => { const result = this.notifications.reduce((count, notification) => {
return notification.read ? count : count + 1 return notification.read ? count : count + 1
@ -77,11 +79,25 @@ export default {
orderBy: 'updatedAt_desc', orderBy: 'updatedAt_desc',
} }
}, },
pollInterval: NOTIFICATIONS_POLL_INTERVAL, subscribeToMore: {
update({ notifications }) { document: notificationAdded(),
return unionBy(notifications, this.notifications, notification => notification.id).sort( variables() {
(a, b) => new Date(b.createdAt) - new Date(a.createdAt), return {
) userId: this.user.id,
}
},
updateQuery: (previousResult, { subscriptionData }) => {
const {
data: { notificationAdded: newNotification },
} = subscriptionData
return {
notifications: unionBy(
[newNotification],
previousResult.notifications,
notification => notification.id,
).sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)),
}
},
}, },
error(error) { error(error) {
this.$toast.error(error.message) this.$toast.error(error.message)

View File

@ -1 +0,0 @@
export const NOTIFICATIONS_POLL_INTERVAL = 60000

View File

@ -71,6 +71,7 @@ export const notificationQuery = i18n => {
read read
reason reason
createdAt createdAt
updatedAt
from { from {
__typename __typename
... on Post { ... on Post {
@ -109,6 +110,7 @@ export const markAsReadMutation = i18n => {
read read
reason reason
createdAt createdAt
updatedAt
from { from {
__typename __typename
... on Post { ... on Post {
@ -132,6 +134,44 @@ export const markAsReadMutation = i18n => {
` `
} }
export const notificationAdded = () => {
return gql`
${userFragment}
${commentFragment}
${postFragment}
subscription notifications($userId: ID!) {
notificationAdded(userId: $userId) {
id
read
reason
createdAt
updatedAt
from {
__typename
... on Post {
...post
author {
...user
}
}
... on Comment {
...comment
author {
...user
}
post {
...post
author {
...user
}
}
}
}
}
}
`
}
export const followUserMutation = i18n => { export const followUserMutation = i18n => {
return gql` return gql`
${userFragment} ${userFragment}

View File

@ -62,12 +62,12 @@
"@nuxtjs/axios": "~5.9.5", "@nuxtjs/axios": "~5.9.5",
"@nuxtjs/dotenv": "~1.4.1", "@nuxtjs/dotenv": "~1.4.1",
"@nuxtjs/pwa": "^3.0.0-beta.20", "@nuxtjs/pwa": "^3.0.0-beta.20",
"@nuxtjs/sentry": "^3.2.2", "@nuxtjs/sentry": "^3.2.3",
"@nuxtjs/style-resources": "~1.0.0", "@nuxtjs/style-resources": "~1.0.0",
"accounting": "~0.4.1", "accounting": "~0.4.1",
"apollo-cache-inmemory": "~1.6.5", "apollo-cache-inmemory": "~1.6.5",
"apollo-client": "~2.6.8", "apollo-client": "~2.6.8",
"cookie-universal-nuxt": "~2.1.1", "cookie-universal-nuxt": "~2.1.2",
"cropperjs": "^1.5.5", "cropperjs": "^1.5.5",
"cross-env": "~7.0.0", "cross-env": "~7.0.0",
"date-fns": "2.9.0", "date-fns": "2.9.0",
@ -100,7 +100,7 @@
"@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/preset-env": "~7.8.4", "@babel/preset-env": "~7.8.4",
"@storybook/addon-a11y": "^5.3.13", "@storybook/addon-a11y": "^5.3.13",
"@storybook/addon-actions": "^5.3.12", "@storybook/addon-actions": "^5.3.13",
"@storybook/addon-notes": "^5.3.13", "@storybook/addon-notes": "^5.3.13",
"@storybook/vue": "~5.3.13", "@storybook/vue": "~5.3.13",
"@vue/cli-shared-utils": "~4.2.2", "@vue/cli-shared-utils": "~4.2.2",
@ -141,7 +141,7 @@
"style-loader": "~0.23.1", "style-loader": "~0.23.1",
"style-resources-loader": "~1.3.3", "style-resources-loader": "~1.3.3",
"vue-jest": "~3.0.5", "vue-jest": "~3.0.5",
"vue-loader": "~15.8.3", "vue-loader": "~15.9.0",
"vue-svg-loader": "~0.16.0", "vue-svg-loader": "~0.16.0",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"
} }

View File

@ -9,6 +9,7 @@ export default ({ app }) => {
const backendUrl = process.env.GRAPHQL_URI || 'http://localhost:4000' const backendUrl = process.env.GRAPHQL_URI || 'http://localhost:4000'
return { return {
wsEndpoint: process.env.WEBSOCKETS_URI || 'ws://localhost:4000/graphql',
httpEndpoint: process.server ? backendUrl : '/api', httpEndpoint: process.server ? backendUrl : '/api',
httpLinkOptions: { httpLinkOptions: {
credentials: 'same-origin', credentials: 'same-origin',

View File

@ -1721,15 +1721,15 @@
jimp-compact "^0.8.0" jimp-compact "^0.8.0"
workbox-cdn "^4.3.1" workbox-cdn "^4.3.1"
"@nuxtjs/sentry@^3.2.2": "@nuxtjs/sentry@^3.2.3":
version "3.2.2" version "3.2.3"
resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-3.2.2.tgz#ee0add861b18844f8367e1e30d5c7bac1e5f5c91" resolved "https://registry.yarnpkg.com/@nuxtjs/sentry/-/sentry-3.2.3.tgz#ac102faeb9b1d6ad65d14abdb9705173108dc6c2"
integrity sha512-eoHSoN9+QiHwIBY8aa8sVgZnh9X73BqlZy0qtO3LthM2awROFEYJ3sqIGkhrucgTrRM8na6LAFNEvd64QI9sCw== integrity sha512-3dTH9y2Of70h7JSk73kuxRMd9zxidwMsZp/OJJlb66b73rKR9dZtBCkH6J7z1vh+32b5IZh9vLP1LfWZaHnd0Q==
dependencies: dependencies:
"@sentry/browser" "^5.11.2" "@sentry/browser" "^5.12.1"
"@sentry/integrations" "^5.11.1" "@sentry/integrations" "^5.12.0"
"@sentry/node" "^5.11.2" "@sentry/node" "^5.12.3"
"@sentry/webpack-plugin" "^1.9.3" "@sentry/webpack-plugin" "^1.10.0"
consola "^2.11.3" consola "^2.11.3"
deepmerge "^4.2.2" deepmerge "^4.2.2"
@ -1989,26 +1989,26 @@
dependencies: dependencies:
any-observable "^0.3.0" any-observable "^0.3.0"
"@sentry/apm@5.11.2": "@sentry/apm@5.12.3":
version "5.11.2" version "5.12.3"
resolved "https://registry.yarnpkg.com/@sentry/apm/-/apm-5.11.2.tgz#35961b9d2319ad21ae91f1b697998a8c523f1919" resolved "https://registry.yarnpkg.com/@sentry/apm/-/apm-5.12.3.tgz#23a5e9c771a8748f59426a1d0f8b1fbb9b72a717"
integrity sha512-qn4HiSZ+6b1Gg+DlXdHVpiPPEbRu4IicGSbI8HTJLzrlsjoaBQPPkDwtuQUBVq21tU3RYXnTwrl9m45KuX6alA== integrity sha512-OSGEeo4b1Gsu/TUcWMx9vmgSnQvR+zM+1Iwq5xFQAK2ET3Y4gBFqZ1iRt2hxlzr8KCQmQTQc1mao1X0tmidFQg==
dependencies: dependencies:
"@sentry/browser" "5.11.2" "@sentry/browser" "5.12.1"
"@sentry/hub" "5.11.2" "@sentry/hub" "5.12.0"
"@sentry/minimal" "5.11.2" "@sentry/minimal" "5.12.0"
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/browser@5.11.2", "@sentry/browser@^5.11.2": "@sentry/browser@5.12.1", "@sentry/browser@^5.12.1":
version "5.11.2" version "5.12.1"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.11.2.tgz#f0b19bd97e9f09a20e9f93a9835339ed9ab1f5a4" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.12.1.tgz#dc1f268595269fb7277f55eb625c7e92d76dc01b"
integrity sha512-ls6ARX5m+23ld8OsuoPnR+kehjR5ketYWRcDYlmJDX2VOq5K4EzprujAo8waDB0o5a92yLXQ0ZSoK/zzAV2VoA== integrity sha512-Zl7VdppUxctyaoqMSEhnDJp2rrupx8n8N2n3PSooH74yhB2Z91nt84mouczprBsw3JU1iggGyUw9seRFzDI1hw==
dependencies: dependencies:
"@sentry/core" "5.11.2" "@sentry/core" "5.12.0"
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/cli@^1.49.0": "@sentry/cli@^1.49.0":
@ -2023,76 +2023,76 @@
progress "2.0.0" progress "2.0.0"
proxy-from-env "^1.0.0" proxy-from-env "^1.0.0"
"@sentry/core@5.11.2": "@sentry/core@5.12.0":
version "5.11.2" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.11.2.tgz#f2d9d37940d291dbcb9a9e4a012f76919474bdf6" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.12.0.tgz#d6380c4ef7beee5f418ac1d0e5be86a2de2af449"
integrity sha512-IFCXGy7ebqIq/Kb8RVryCo/SjwhPcrfBmOjkicr4+DxN1UybLre2N3p9bejQMPIteOfDVHlySLYeipjTf+mxZw== integrity sha512-wY4rsoX71QsGpcs9tF+OxKgDPKzIFMRvFiSRcJoPMfhFsTilQ/CBMn/c3bDtWQd9Bnr/ReQIL6NbnIjUsPHA4Q==
dependencies: dependencies:
"@sentry/hub" "5.11.2" "@sentry/hub" "5.12.0"
"@sentry/minimal" "5.11.2" "@sentry/minimal" "5.12.0"
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/hub@5.11.2": "@sentry/hub@5.12.0":
version "5.11.2" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.11.2.tgz#a3b7ec27cd4cea2cddd75c372fbf1b4bc04c6aae" resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.12.0.tgz#5e8c8f249f5bdbeb8cc4ec02c2ccc53a67f2cc02"
integrity sha512-5BiDin6ZPsaiTm29rCC41MAjP1vOaKniqfjtXHVPm7FeOBA2bpHm95ncjLkshKGJTPfPZHXTpX/1IZsHrfGVEA== integrity sha512-3k7yE8BEVJsKx8mR4LcI4IN0O8pngmq44OcJ/fRUUBAPqsT38jsJdP2CaWhdlM1jiNUzUDB1ktBv6/lY+VgcoQ==
dependencies: dependencies:
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/integrations@^5.11.1": "@sentry/integrations@^5.12.0":
version "5.11.1" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-5.11.1.tgz#6612efc620c187ba85a57c6e70e69d9474af7fb6" resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-5.12.0.tgz#4d735abf2989049ef860e3eaad0883b63d8274e6"
integrity sha512-zubOE9zQ4qSutS0ZTnAteDnzbVcHSI2bXD/0nTD3t3ljY+OWgcluBXYCAeAp8vOv2qCoef5ySdQa1DBCW7NQ3Q== integrity sha512-4G/TvCEP9M6xgY61r46UE4ruSgF42rZnvO0ZfIBI/240DNYMTpHLvjU3Xvrv3wDl3emCvy4QgAIceI/zj8nPjw==
dependencies: dependencies:
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/minimal@5.11.2": "@sentry/minimal@5.12.0":
version "5.11.2" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.11.2.tgz#ae417699342266ecd109a97e53cd9519c0893b21" resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.12.0.tgz#2611e2aa520c1edb7999e6de51bd65ec66341757"
integrity sha512-oNuJuz3EZhVtamzABmPdr6lcYo06XHLWb2LvgnoNaYcMD1ExUSvhepOSyZ2h5STCMbmVgGVfXBNPV9RUTp8GZg== integrity sha512-fk73meyz4k4jCg9yzbma+WkggsfEIQWI2e2TWfYsRGcrV3RnlSrXyM4D91/A8Bjx10SNezHPUFHjasjlHXOkyA==
dependencies: dependencies:
"@sentry/hub" "5.11.2" "@sentry/hub" "5.12.0"
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/node@^5.11.2": "@sentry/node@^5.12.3":
version "5.11.2" version "5.12.3"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.11.2.tgz#575c320b624c218d2155183f6bbe82b732bfb1f2" resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.12.3.tgz#4a4934b04c5163fc340312eaf0d152990aa7140f"
integrity sha512-jYq9u76BdAbOKPuYg39Xh/+797MevzjMkCIC9cw/bQxAm6nHc3FXeKqd79O33jO4Jag0JL+Bz/0JidgrKgKgXg== integrity sha512-QwqN+i6IC3/YrNq7kqxH7YiXtZYY8tBuJqFi84WbiMHF7MAqxMSPNQJGfX2GJuMHKHwn6IZdgSE8+FkfN9zGLQ==
dependencies: dependencies:
"@sentry/apm" "5.11.2" "@sentry/apm" "5.12.3"
"@sentry/core" "5.11.2" "@sentry/core" "5.12.0"
"@sentry/hub" "5.11.2" "@sentry/hub" "5.12.0"
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
"@sentry/utils" "5.11.1" "@sentry/utils" "5.12.0"
cookie "^0.3.1" cookie "^0.3.1"
https-proxy-agent "^4.0.0" https-proxy-agent "^4.0.0"
lru_map "^0.3.3" lru_map "^0.3.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/types@5.11.0": "@sentry/types@5.12.0":
version "5.11.0" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.11.0.tgz#40f0f3174362928e033ddd9725d55e7c5cb7c5b6" resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.12.0.tgz#5367e53c74261beea01502e3f7b6f3d822682a31"
integrity sha512-1Uhycpmeo1ZK2GLvrtwZhTwIodJHcyIS6bn+t4IMkN9MFoo6ktbAfhvexBDW/IDtdLlCGJbfm8nIZerxy0QUpg== integrity sha512-aZbBouBLrKB8wXlztriIagZNmsB+wegk1Jkl6eprqRW/w24Sl/47tiwH8c5S4jYTxdAiJk+SAR10AAuYmIN3zg==
"@sentry/utils@5.11.1": "@sentry/utils@5.12.0":
version "5.11.1" version "5.12.0"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.11.1.tgz#aa19fcc234cf632257b2281261651d2fac967607" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.12.0.tgz#62967f934a3ee6d21472eac0219084e37225933e"
integrity sha512-O0Zl4R2JJh8cTkQ8ZL2cDqGCmQdpA5VeXpuBbEl1v78LQPkBDISi35wH4mKmLwMsLBtTVpx2UeUHBj0KO5aLlA== integrity sha512-fYUadGLbfTCbs4OG5hKCOtv2jrNE4/8LHNABy9DwNJ/t5DVtGqWAZBnxsC+FG6a3nVqCpxjFI9AHlYsJ2wsf7Q==
dependencies: dependencies:
"@sentry/types" "5.11.0" "@sentry/types" "5.12.0"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/webpack-plugin@^1.9.3": "@sentry/webpack-plugin@^1.10.0":
version "1.9.3" version "1.10.0"
resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.9.3.tgz#bf29bf16ae82863140639063ffa620a80452303b" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.10.0.tgz#7f7727b18dbdd3eaeb0998102be89d8733ddbca5"
integrity sha512-b0ZExcvde15jSm7N5LjeosCcWFZFjZbGHEsXdNramm5B0TL+kwWA4thyW4v8rSrAEA2jxXDW2aop5cwBHCI2wg== integrity sha512-keT6cH8732bFjdH/v+C/UwbJu6byZ5L8t7QRLjgj+fqDyc/RlVEw9VzIQSJGUtd2XgImpdduWzgxythLkwKJjg==
dependencies: dependencies:
"@sentry/cli" "^1.49.0" "@sentry/cli" "^1.49.0"
@ -2125,17 +2125,17 @@
ts-dedent "^1.1.0" ts-dedent "^1.1.0"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
"@storybook/addon-actions@^5.3.12": "@storybook/addon-actions@^5.3.13":
version "5.3.12" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.12.tgz#024678ddd207f050e42c5f8e20b5064cf9839a38" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-5.3.13.tgz#faf57ca14a46ce0c69168c631fbfc3d79d294b38"
integrity sha512-3j6ZJROcH4bm8vpaM2RU/sRdoOLF9DpVWiE6uutlrVEV6eWuexrUAYwSzuF4Pjr1LUWDSDIT9pEES+tHdn9Rww== integrity sha512-NoKTI/7Zf/IpbfeIFPWQT3eN0As1yICLcSklj9BjHq7itSssaqZzvP/vxmeAvdagIBcPM58GaN9XXXLQIn5HLg==
dependencies: dependencies:
"@storybook/addons" "5.3.12" "@storybook/addons" "5.3.13"
"@storybook/api" "5.3.12" "@storybook/api" "5.3.13"
"@storybook/client-api" "5.3.12" "@storybook/client-api" "5.3.13"
"@storybook/components" "5.3.12" "@storybook/components" "5.3.13"
"@storybook/core-events" "5.3.12" "@storybook/core-events" "5.3.13"
"@storybook/theming" "5.3.12" "@storybook/theming" "5.3.13"
core-js "^3.0.1" core-js "^3.0.1"
fast-deep-equal "^2.0.1" fast-deep-equal "^2.0.1"
global "^4.3.2" global "^4.3.2"
@ -2177,19 +2177,6 @@
global "^4.3.2" global "^4.3.2"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
"@storybook/addons@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.12.tgz#77fb0e0d3ac9eb70414bff4b03c12bbccfe31716"
integrity sha512-5jVns+wq95ZismEQ5ByDhrEFzDH8OIEj2BLSPT7VTbik7iLC+h7H2toWKAwIYZCxAuq0OTy6ZpIyhU/R2YuO4w==
dependencies:
"@storybook/api" "5.3.12"
"@storybook/channels" "5.3.12"
"@storybook/client-logger" "5.3.12"
"@storybook/core-events" "5.3.12"
core-js "^3.0.1"
global "^4.3.2"
util-deprecate "^1.0.2"
"@storybook/addons@5.3.13": "@storybook/addons@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.13.tgz#8c16fbab1142e2cd4bdfb93ffcb35a883dac2866" resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-5.3.13.tgz#8c16fbab1142e2cd4bdfb93ffcb35a883dac2866"
@ -2226,32 +2213,6 @@
telejson "^3.0.2" telejson "^3.0.2"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
"@storybook/api@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.12.tgz#7d1ca7a487fb9b6604d26cae756e291015908d35"
integrity sha512-wYsr97vqARwmOordlPY17MJ9PrHSCsSM9JRC/zh698kXQGwYnse1nErzAiwj8YxuItfWGzE06kqjZBccnfSxPQ==
dependencies:
"@reach/router" "^1.2.1"
"@storybook/channels" "5.3.12"
"@storybook/client-logger" "5.3.12"
"@storybook/core-events" "5.3.12"
"@storybook/csf" "0.0.1"
"@storybook/router" "5.3.12"
"@storybook/theming" "5.3.12"
"@types/reach__router" "^1.2.3"
core-js "^3.0.1"
fast-deep-equal "^2.0.1"
global "^4.3.2"
lodash "^4.17.15"
memoizerific "^1.11.3"
prop-types "^15.6.2"
react "^16.8.3"
semver "^6.0.0"
shallow-equal "^1.1.0"
store2 "^2.7.1"
telejson "^3.2.0"
util-deprecate "^1.0.2"
"@storybook/api@5.3.13": "@storybook/api@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.13.tgz#51cbdb461ff2ee8468a3c54411f42f07aa307f5d" resolved "https://registry.yarnpkg.com/@storybook/api/-/api-5.3.13.tgz#51cbdb461ff2ee8468a3c54411f42f07aa307f5d"
@ -2278,17 +2239,6 @@
telejson "^3.2.0" telejson "^3.2.0"
util-deprecate "^1.0.2" util-deprecate "^1.0.2"
"@storybook/channel-postmessage@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.12.tgz#945c9702f335018f6224af3159bf4d33c66a131e"
integrity sha512-yQZ6Ef0KnxI7vxJrcJaBYeZpxhl/18WEFtAO9MphvYvtd1dudqKNqdx9B/30PIXb7c/SptvGJR/EZhsRNr4Oug==
dependencies:
"@storybook/channels" "5.3.12"
"@storybook/client-logger" "5.3.12"
core-js "^3.0.1"
global "^4.3.2"
telejson "^3.2.0"
"@storybook/channel-postmessage@5.3.13": "@storybook/channel-postmessage@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.13.tgz#80cf8136bf4b96b2f9b291d3cc81e5d02abecc98" resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-5.3.13.tgz#80cf8136bf4b96b2f9b291d3cc81e5d02abecc98"
@ -2307,13 +2257,6 @@
dependencies: dependencies:
core-js "^3.0.1" core-js "^3.0.1"
"@storybook/channels@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.12.tgz#dd2e111377f0eaafa0e66746cb6628322615ade9"
integrity sha512-sfSHIRUusjZ69WhfPp8BrfmlGg80PYTNCBSE+1apK/WkgzYJyGgQmJgRAW6HTFqjawD7T+utAtarsqS30jo9jQ==
dependencies:
core-js "^3.0.1"
"@storybook/channels@5.3.13": "@storybook/channels@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.13.tgz#2adf4595988e2586f1a360cf4760f16338ffec26" resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-5.3.13.tgz#2adf4595988e2586f1a360cf4760f16338ffec26"
@ -2321,29 +2264,6 @@
dependencies: dependencies:
core-js "^3.0.1" core-js "^3.0.1"
"@storybook/client-api@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.12.tgz#7c18921d0290b30b020ad7d41fbda170009780bd"
integrity sha512-Qzi+pS9FwqrArnG1VMV4QJxEdvw7KVc2ufgax7jCvK8JtDlSVe1/qpbJn7U3o1z4TPY/u3m6PbBLJDoSWTVonw==
dependencies:
"@storybook/addons" "5.3.12"
"@storybook/channel-postmessage" "5.3.12"
"@storybook/channels" "5.3.12"
"@storybook/client-logger" "5.3.12"
"@storybook/core-events" "5.3.12"
"@storybook/csf" "0.0.1"
"@types/webpack-env" "^1.15.0"
core-js "^3.0.1"
eventemitter3 "^4.0.0"
global "^4.3.2"
is-plain-object "^3.0.0"
lodash "^4.17.15"
memoizerific "^1.11.3"
qs "^6.6.0"
stable "^0.1.8"
ts-dedent "^1.1.0"
util-deprecate "^1.0.2"
"@storybook/client-api@5.3.13": "@storybook/client-api@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.13.tgz#0d41ae3846a6ae2ebbbeef0ca945c3ee6448ba2e" resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-5.3.13.tgz#0d41ae3846a6ae2ebbbeef0ca945c3ee6448ba2e"
@ -2374,13 +2294,6 @@
dependencies: dependencies:
core-js "^3.0.1" core-js "^3.0.1"
"@storybook/client-logger@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.12.tgz#64033dd647b6ce6971977e4f5ce2908de21526eb"
integrity sha512-LsKDW4ijGJjyRg3GetS/OtVS+8ESxydVG55jvAlExHehUcVRvrPew5MsW63CRTQDpZsoh1aT9oV1yr8eYu1HZg==
dependencies:
core-js "^3.0.1"
"@storybook/client-logger@5.3.13": "@storybook/client-logger@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.13.tgz#1c2abf0fc53009cf159eb76e30cf32ce2b9327b1" resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-5.3.13.tgz#1c2abf0fc53009cf159eb76e30cf32ce2b9327b1"
@ -2413,33 +2326,6 @@
react-textarea-autosize "^7.1.0" react-textarea-autosize "^7.1.0"
simplebar-react "^1.0.0-alpha.6" simplebar-react "^1.0.0-alpha.6"
"@storybook/components@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.12.tgz#0d930343624d459f46cd55b140be979709ee5a29"
integrity sha512-Ma67yaSJHaNqLjp2csOZvHdu1Sk1eMke29WVEWjPYUBzzaZK7ZlmGiXzN0roYJVGaqHkl2f7xxRfPfWQp9NCIw==
dependencies:
"@storybook/client-logger" "5.3.12"
"@storybook/theming" "5.3.12"
"@types/react-syntax-highlighter" "11.0.2"
"@types/react-textarea-autosize" "^4.3.3"
core-js "^3.0.1"
global "^4.3.2"
lodash "^4.17.15"
markdown-to-jsx "^6.9.1"
memoizerific "^1.11.3"
polished "^3.3.1"
popper.js "^1.14.7"
prop-types "^15.7.2"
react "^16.8.3"
react-dom "^16.8.3"
react-focus-lock "^2.1.0"
react-helmet-async "^1.0.2"
react-popper-tooltip "^2.8.3"
react-syntax-highlighter "^11.0.2"
react-textarea-autosize "^7.1.0"
simplebar-react "^1.0.0-alpha.6"
ts-dedent "^1.1.0"
"@storybook/components@5.3.13": "@storybook/components@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.13.tgz#646f8347ffa38298e3f9c1d15866c2167f577027" resolved "https://registry.yarnpkg.com/@storybook/components/-/components-5.3.13.tgz#646f8347ffa38298e3f9c1d15866c2167f577027"
@ -2474,13 +2360,6 @@
dependencies: dependencies:
core-js "^3.0.1" core-js "^3.0.1"
"@storybook/core-events@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.12.tgz#188526c9003884104cce4fcd20448ca34d14d9f7"
integrity sha512-qUX0xvADM8LBUtzeTi8r803eeikyzooH8HwnUg6GP238NRnR13BK/tSnBx6XpJubGL5gv9a1jZJQWxP25KPHfA==
dependencies:
core-js "^3.0.1"
"@storybook/core-events@5.3.13": "@storybook/core-events@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.13.tgz#df74d2ffe29a1924557dc67e46d5d399893b2b11" resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-5.3.13.tgz#df74d2ffe29a1924557dc67e46d5d399893b2b11"
@ -2599,21 +2478,6 @@
memoizerific "^1.11.3" memoizerific "^1.11.3"
qs "^6.6.0" qs "^6.6.0"
"@storybook/router@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.12.tgz#f08d75793790aacc5543c55e62d08d3bb00188fd"
integrity sha512-IuI/MMFb27XGFaFjaUCYUgK+P4jeGLBDI4cCn6Fezb5RRgpdOf2DobDIUZtujSmvPnEF8C+SJE/v1dXihRO1Xg==
dependencies:
"@reach/router" "^1.2.1"
"@storybook/csf" "0.0.1"
"@types/reach__router" "^1.2.3"
core-js "^3.0.1"
global "^4.3.2"
lodash "^4.17.15"
memoizerific "^1.11.3"
qs "^6.6.0"
util-deprecate "^1.0.2"
"@storybook/router@5.3.13": "@storybook/router@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.13.tgz#1ef971488036083ee284323fe8814b8795f94626" resolved "https://registry.yarnpkg.com/@storybook/router/-/router-5.3.13.tgz#1ef971488036083ee284323fe8814b8795f94626"
@ -2647,24 +2511,6 @@
prop-types "^15.7.2" prop-types "^15.7.2"
resolve-from "^5.0.0" resolve-from "^5.0.0"
"@storybook/theming@5.3.12":
version "5.3.12"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.12.tgz#70908dc23c0635765256fc4dbb7cd6d318886dfe"
integrity sha512-LwyFBbxYtm2rr86mA0d+oYisIpW2GrDqmv0ZGEmx9EqKK1JwG3N99VSK7iHig6vpNu42LHLakuaqK55H2Q7YcA==
dependencies:
"@emotion/core" "^10.0.20"
"@emotion/styled" "^10.0.17"
"@storybook/client-logger" "5.3.12"
core-js "^3.0.1"
deep-object-diff "^1.1.0"
emotion-theming "^10.0.19"
global "^4.3.2"
memoizerific "^1.11.3"
polished "^3.3.1"
prop-types "^15.7.2"
resolve-from "^5.0.0"
ts-dedent "^1.1.0"
"@storybook/theming@5.3.13": "@storybook/theming@5.3.13":
version "5.3.13" version "5.3.13"
resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.13.tgz#17e8101e2d3ad3fb6245b2cb15b07e9f2a9881cd" resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-5.3.13.tgz#17e8101e2d3ad3fb6245b2cb15b07e9f2a9881cd"
@ -6098,10 +5944,10 @@ cookie-signature@1.0.6:
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
cookie-universal-nuxt@~2.1.1: cookie-universal-nuxt@~2.1.2:
version "2.1.1" version "2.1.2"
resolved "https://registry.yarnpkg.com/cookie-universal-nuxt/-/cookie-universal-nuxt-2.1.1.tgz#883b28d699b69f3b56de437253978e43c4e4d672" resolved "https://registry.yarnpkg.com/cookie-universal-nuxt/-/cookie-universal-nuxt-2.1.2.tgz#790a6fc72e5f34b4cf7cf77d92bf2ee63e207901"
integrity sha512-ACKtgwafdIE3Kr18pv8JJiEUvOEygKeD7dVowytlbpEuPKrMh288XEkPsTSjgsRY35vRkSorifePo4uv+YQsNw== integrity sha512-UEE8uglIlTq+SYhOv6LhdZ/ByDk+f3mQPrUEkJFXU81Ck56ox5UR5CdHmeFtfpibpD8DvWHh4nnCHOpA22gRnQ==
dependencies: dependencies:
"@types/cookie" "^0.3.3" "@types/cookie" "^0.3.3"
cookie-universal "^2.1.1" cookie-universal "^2.1.1"
@ -16646,10 +16492,10 @@ vue-jest@~3.0.5:
tsconfig "^7.0.0" tsconfig "^7.0.0"
vue-template-es2015-compiler "^1.6.0" vue-template-es2015-compiler "^1.6.0"
vue-loader@^15.8.3, vue-loader@~15.8.3: vue-loader@^15.8.3, vue-loader@~15.9.0:
version "15.8.3" version "15.9.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.8.3.tgz#857cb9e30eb5fc25e66db48dce7e4f768602a23c" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.0.tgz#5d4b0378a4606188fc83e587ed23c94bc3a10998"
integrity sha512-yFksTFbhp+lxlm92DrKdpVIWMpranXnTEuGSc0oW+Gk43M9LWaAmBTnfj5+FCdve715mTHvo78IdaXf5TbiTJg== integrity sha512-FeDHvTSpwyLeF7LIV1PYkvqUQgTJ8UmOxhSlCyRSxaXCKk+M6NF4tDQsLsPPNeDPyR7TfRQ8MLg6v+8PsDV9xQ==
dependencies: dependencies:
"@vue/component-compiler-utils" "^3.1.0" "@vue/component-compiler-utils" "^3.1.0"
hash-sum "^1.0.2" hash-sum "^1.0.2"

View File

@ -1763,6 +1763,11 @@ buffer-crc32@~0.2.3:
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer-from@^1.0.0: buffer-from@^1.0.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@ -2927,6 +2932,13 @@ ecc-jsbn@~0.1.1:
jsbn "~0.1.0" jsbn "~0.1.0"
safer-buffer "^2.1.0" safer-buffer "^2.1.0"
ecdsa-sig-formatter@1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
dependencies:
safe-buffer "^5.0.1"
electron-to-chromium@^1.3.341: electron-to-chromium@^1.3.341:
version "1.3.344" version "1.3.344"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz#f1397a633c35e726730c24be1084cd25c3ee8148" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz#f1397a633c35e726730c24be1084cd25c3ee8148"
@ -4336,6 +4348,22 @@ jsonparse@^1.2.0:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
jsonwebtoken@^8.5.1:
version "8.5.1"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
dependencies:
jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
ms "^2.1.1"
semver "^5.6.0"
jsprim@^1.2.2: jsprim@^1.2.2:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -4346,6 +4374,23 @@ jsprim@^1.2.2:
json-schema "0.2.3" json-schema "0.2.3"
verror "1.10.0" verror "1.10.0"
jwa@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
dependencies:
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
jws@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
dependencies:
jwa "^1.4.1"
safe-buffer "^5.0.1"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2" version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@ -4508,17 +4553,47 @@ lodash.clonedeep@4.5.0:
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
lodash.ismatch@^4.4.0: lodash.ismatch@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37"
integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=
lodash.isnumber@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.memoize@~3.0.3: lodash.memoize@~3.0.3:
version "3.0.4" version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8= integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=
lodash.once@^4.1.1: lodash.once@^4.0.0, lodash.once@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=