Merge branch 'master' of github.com:Human-Connection/Human-Connection into 967-filter-post-by-category

This commit is contained in:
Matt Rider 2019-07-10 07:09:58 -03:00
commit 0113751003
44 changed files with 1397 additions and 409 deletions

View File

@ -48,7 +48,7 @@
"apollo-client": "~2.6.3",
"apollo-link-context": "~1.0.18",
"apollo-link-http": "~1.5.15",
"apollo-server": "~2.6.6",
"apollo-server": "~2.6.8",
"bcryptjs": "~2.4.3",
"cheerio": "~1.0.0-rc.3",
"cors": "~2.8.5",
@ -68,7 +68,7 @@
"helmet": "~3.18.0",
"jsonwebtoken": "~8.5.1",
"linkifyjs": "~2.1.8",
"lodash": "~4.17.11",
"lodash": "~4.17.13",
"merge-graphql-schemas": "^1.5.8",
"neo4j-driver": "~1.7.4",
"neo4j-graphql-js": "^2.6.3",
@ -85,12 +85,12 @@
},
"devDependencies": {
"@babel/cli": "~7.5.0",
"@babel/core": "~7.5.0",
"@babel/core": "~7.5.4",
"@babel/node": "~7.5.0",
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/preset-env": "~7.5.2",
"@babel/preset-env": "~7.5.4",
"@babel/register": "~7.4.4",
"apollo-server-testing": "~2.6.7",
"apollo-server-testing": "~2.6.8",
"babel-core": "~7.0.0-0",
"babel-eslint": "~10.0.2",
"babel-jest": "~24.8.0",

View File

@ -1,88 +1,9 @@
import Neode from 'neode'
import uuid from 'uuid/v4'
import models from '../models'
export default function setupNeode(options) {
const { uri, username, password } = options
const neodeInstance = new Neode(uri, username, password)
neodeInstance.model('InvitationCode', {
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
token: { type: 'string', primary: true, token: true },
generatedBy: {
type: 'relationship',
relationship: 'GENERATED',
target: 'User',
direction: 'in',
},
activated: {
type: 'relationship',
relationship: 'ACTIVATED',
target: 'EmailAddress',
direction: 'out',
},
})
neodeInstance.model('EmailAddress', {
email: { type: 'string', primary: true, lowercase: true, email: true },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
verifiedAt: { type: 'string', isoDate: true },
nonce: { type: 'string', token: true },
belongsTo: {
type: 'relationship',
relationship: 'BELONGS_TO',
target: 'User',
direction: 'out',
},
})
neodeInstance.model('User', {
id: { type: 'string', primary: true, default: uuid }, // TODO: should be type: 'uuid' but simplified for our tests
actorId: { type: 'string', allow: [null] },
name: { type: 'string', min: 3 },
email: { type: 'string', lowercase: true, email: true },
slug: 'string',
encryptedPassword: 'string',
avatar: { type: 'string', allow: [null] },
coverImg: { type: 'string', allow: [null] },
deleted: { type: 'boolean', default: false },
disabled: { type: 'boolean', default: false },
role: 'string',
publicKey: 'string',
privateKey: 'string',
wasInvited: 'boolean',
wasSeeded: 'boolean',
locationName: { type: 'string', allow: [null] },
about: { type: 'string', allow: [null] },
primaryEmail: {
type: 'relationship',
relationship: 'PRIMARY_EMAIL',
target: 'EmailAddress',
direction: 'out',
},
following: {
type: 'relationship',
relationship: 'FOLLOWS',
target: 'User',
direction: 'out',
},
followedBy: {
type: 'relationship',
relationship: 'FOLLOWS',
target: 'User',
direction: 'in',
},
friends: { type: 'relationship', relationship: 'FRIENDS', target: 'User', direction: 'both' },
disabledBy: {
type: 'relationship',
relationship: 'DISABLED',
target: 'User',
direction: 'in',
},
invitedBy: { type: 'relationship', relationship: 'INVITED', target: 'User', direction: 'in' },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
updatedAt: {
type: 'string',
isoDate: true,
required: true,
default: () => new Date().toISOString(),
},
})
neodeInstance.with(models)
return neodeInstance
}

View File

@ -0,0 +1,12 @@
module.exports = {
email: { type: 'string', primary: true, lowercase: true, email: true },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
verifiedAt: { type: 'string', isoDate: true },
nonce: { type: 'string', token: true },
belongsTo: {
type: 'relationship',
relationship: 'BELONGS_TO',
target: 'User',
direction: 'out',
},
}

View File

@ -0,0 +1,16 @@
module.exports = {
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
token: { type: 'string', primary: true, token: true },
generatedBy: {
type: 'relationship',
relationship: 'GENERATED',
target: 'User',
direction: 'in',
},
activated: {
type: 'relationship',
relationship: 'ACTIVATED',
target: 'EmailAddress',
direction: 'out',
},
}

View File

@ -0,0 +1,54 @@
import uuid from 'uuid/v4'
module.exports = {
id: { type: 'string', primary: true, default: uuid }, // TODO: should be type: 'uuid' but simplified for our tests
actorId: { type: 'string', allow: [null] },
name: { type: 'string', min: 3 },
email: { type: 'string', lowercase: true, email: true },
slug: 'string',
encryptedPassword: 'string',
avatar: { type: 'string', allow: [null] },
coverImg: { type: 'string', allow: [null] },
deleted: { type: 'boolean', default: false },
disabled: { type: 'boolean', default: false },
role: { type: 'string', default: 'user' },
publicKey: 'string',
privateKey: 'string',
wasInvited: 'boolean',
wasSeeded: 'boolean',
locationName: { type: 'string', allow: [null] },
about: { type: 'string', allow: [null] },
primaryEmail: {
type: 'relationship',
relationship: 'PRIMARY_EMAIL',
target: 'EmailAddress',
direction: 'out',
},
following: {
type: 'relationship',
relationship: 'FOLLOWS',
target: 'User',
direction: 'out',
},
followedBy: {
type: 'relationship',
relationship: 'FOLLOWS',
target: 'User',
direction: 'in',
},
friends: { type: 'relationship', relationship: 'FRIENDS', target: 'User', direction: 'both' },
disabledBy: {
type: 'relationship',
relationship: 'DISABLED',
target: 'User',
direction: 'in',
},
invitedBy: { type: 'relationship', relationship: 'INVITED', target: 'User', direction: 'in' },
createdAt: { type: 'string', isoDate: true, default: () => new Date().toISOString() },
updatedAt: {
type: 'string',
isoDate: true,
required: true,
default: () => new Date().toISOString(),
},
}

View File

@ -0,0 +1,20 @@
import Factory from '../seed/factories'
import { neode } from '../bootstrap/neo4j'
const factory = Factory()
const instance = neode()
afterEach(async () => {
await factory.cleanDatabase()
})
describe('role', () => {
it('defaults to `user`', async () => {
const user = await instance.create('User', { name: 'John' })
await expect(user.toJson()).resolves.toEqual(
expect.objectContaining({
role: 'user',
}),
)
})
})

View File

@ -0,0 +1,7 @@
// NOTE: We cannot use `fs` here to clean up the code. Cypress breaks on any npm
// module that is not browser-compatible. Node's `fs` module is server-side only
export default {
User: require('./User.js'),
InvitationCode: require('./InvitationCode.js'),
EmailAddress: require('./EmailAddress.js'),
}

View File

@ -9,7 +9,7 @@ type User {
deleted: Boolean
disabled: Boolean
disabledBy: User @relation(name: "DISABLED", direction: "IN")
role: UserGroup
role: UserGroup!
publicKey: String
invitedBy: User @relation(name: "INVITED", direction: "IN")
invited: [User] @relation(name: "INVITED", direction: "OUT")

View File

@ -38,14 +38,14 @@
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/core@^7.1.0", "@babel/core@~7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.0.tgz#6ed6a2881ad48a732c5433096d96d1b0ee5eb734"
integrity sha512-6Isr4X98pwXqHvtigw71CKgmhL1etZjPs5A67jL/w0TkLM9eqmFR40YrnJvEc1WnMZFsskjsmid8bHZyxKEAnw==
"@babel/core@^7.1.0", "@babel/core@~7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd"
integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/generator" "^7.5.0"
"@babel/helpers" "^7.5.0"
"@babel/helpers" "^7.5.4"
"@babel/parser" "^7.5.0"
"@babel/template" "^7.4.4"
"@babel/traverse" "^7.5.0"
@ -260,10 +260,10 @@
"@babel/traverse" "^7.1.0"
"@babel/types" "^7.2.0"
"@babel/helpers@^7.5.0":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.2.tgz#97424dc82fc0041f4c751119b4d2b1ec68cdb5ba"
integrity sha512-NDkkTqDvgFUeo8djXBOiwO/mFjownznOWvmP9hvNdfiFUmx0nwNOqxuaTTbxjH744eQsD9M5ubC7gdANBvIWPw==
"@babel/helpers@^7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0"
integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==
dependencies:
"@babel/template" "^7.4.4"
"@babel/traverse" "^7.5.0"
@ -320,10 +320,10 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread@^7.5.2":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.2.tgz#ec92b0c6419074ea7af77c78b7c5d42041f2f5a9"
integrity sha512-C/JU3YOx5J4d9s0GGlJlYXVwsbd5JmqQ0AvB7cIDAx7nN57aDTnlJEsZJPuSskeBtMGFWSWU5Q+piTiDe0s7FQ==
"@babel/plugin-proposal-object-rest-spread@^7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331"
integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
@ -649,17 +649,17 @@
core-js "^2.5.7"
regenerator-runtime "^0.12.0"
"@babel/preset-env@~7.5.2":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.2.tgz#34a46f01aed617b174b8dbaf8fed9239300343d0"
integrity sha512-7rRJLaUqJhQ+8xGrWtMROAgOi/+udIzyK2ES9NHhDIUvR2zfx/ON5lRR8ACUGehIYst8KVbl4vpkgOqn08gBxA==
"@babel/preset-env@~7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.4.tgz#64bc15041a3cbb0798930319917e70fcca57713d"
integrity sha512-hFnFnouyRNiH1rL8YkX1ANCNAUVC8Djwdqfev8i1415tnAG+7hlA5zhZ0Q/3Q5gkop4HioIPbCEWAalqcbxRoQ==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-async-generator-functions" "^7.2.0"
"@babel/plugin-proposal-dynamic-import" "^7.5.0"
"@babel/plugin-proposal-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread" "^7.5.2"
"@babel/plugin-proposal-object-rest-spread" "^7.5.4"
"@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
"@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
"@babel/plugin-syntax-async-generators" "^7.2.0"
@ -1406,18 +1406,6 @@ apollo-engine-reporting-protobuf@0.3.1:
dependencies:
protobufjs "^6.8.6"
apollo-engine-reporting@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.3.4.tgz#65e12f94221d80b3b1740c26e82ce9bb6bdfb7ee"
integrity sha512-DJdYghyUBzT0/LcPLwuQNXDCw06r1RfxkVfNTGKoTv6a+leVvjhDJmXvc+jSuBPwaNsc+RYRnfyQ2qUn9fmfyA==
dependencies:
apollo-engine-reporting-protobuf "0.3.1"
apollo-graphql "^0.3.2"
apollo-server-core "2.6.6"
apollo-server-env "2.4.0"
async-retry "^1.2.1"
graphql-extensions "0.7.5"
apollo-engine-reporting@1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-1.3.5.tgz#075424d39dfe77a20f96e8e33b7ae52d58c38e1e"
@ -1447,14 +1435,6 @@ apollo-errors@^1.9.0:
assert "^1.4.1"
extendable-error "^0.1.5"
apollo-graphql@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.3.2.tgz#8881a87f1d5fcf80837b34dba90737e664eabe9a"
integrity sha512-YbzYGR14GV0023m//EU66vOzZ3i7c04V/SF8Qk+60vf1sOWyKgO6mxZJ4BKhw10qWUayirhSDxq3frYE+qSG0A==
dependencies:
apollo-env "0.5.1"
lodash.sortby "^4.7.0"
apollo-graphql@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/apollo-graphql/-/apollo-graphql-0.3.3.tgz#ce1df194f6e547ad3ce1e35b42f9c211766e1658"
@ -1506,32 +1486,6 @@ apollo-server-caching@0.4.0:
dependencies:
lru-cache "^5.0.0"
apollo-server-core@2.6.6:
version "2.6.6"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.6.tgz#55fea7980a943948c49dea20d81b9bbfc0e04f87"
integrity sha512-PFSjJbqkV1eetfFJxu11gzklQYC8BrF0RZfvC1d1mhvtxAOKl25uhPHxltN0Omyjp7LW4YeoC6zwl9rLWuhZFQ==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
"@apollographql/graphql-playground-html" "1.6.20"
"@types/ws" "^6.0.0"
apollo-cache-control "0.7.4"
apollo-datasource "0.5.0"
apollo-engine-reporting "1.3.4"
apollo-server-caching "0.4.0"
apollo-server-env "2.4.0"
apollo-server-errors "2.3.0"
apollo-server-plugin-base "0.5.5"
apollo-tracing "0.7.3"
fast-json-stable-stringify "^2.0.0"
graphql-extensions "0.7.5"
graphql-subscriptions "^1.0.0"
graphql-tag "^2.9.2"
graphql-tools "^4.0.0"
graphql-upload "^8.0.2"
sha.js "^2.4.11"
subscriptions-transport-ws "^0.9.11"
ws "^6.0.0"
apollo-server-core@2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.7.tgz#85b0310f40cfec43a702569c73af16d88776a6f0"
@ -1558,6 +1512,32 @@ apollo-server-core@2.6.7:
subscriptions-transport-ws "^0.9.11"
ws "^6.0.0"
apollo-server-core@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.6.8.tgz#c8758b5f26b5f3b9fef51b911265b80a9ce5251d"
integrity sha512-Jxw+6R/2I2LiZ6kjRFTzPpdjw7HfuVLfNU+svgNlxioLducxBH/wqUs3qYTf4eVUUtWy+nSS/BUf/Ullo+Ur0Q==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
"@apollographql/graphql-playground-html" "1.6.20"
"@types/ws" "^6.0.0"
apollo-cache-control "0.7.4"
apollo-datasource "0.5.0"
apollo-engine-reporting "1.3.5"
apollo-server-caching "0.4.0"
apollo-server-env "2.4.0"
apollo-server-errors "2.3.0"
apollo-server-plugin-base "0.5.7"
apollo-tracing "0.7.3"
fast-json-stable-stringify "^2.0.0"
graphql-extensions "0.7.6"
graphql-subscriptions "^1.0.0"
graphql-tag "^2.9.2"
graphql-tools "^4.0.0"
graphql-upload "^8.0.2"
sha.js "^2.4.11"
subscriptions-transport-ws "^0.9.11"
ws "^6.0.0"
apollo-server-core@^1.3.6, apollo-server-core@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-1.4.0.tgz#4faff7f110bfdd6c3f47008302ae24140f94c592"
@ -1580,10 +1560,10 @@ apollo-server-errors@2.3.0:
resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.3.0.tgz#700622b66a16dffcad3b017e4796749814edc061"
integrity sha512-rUvzwMo2ZQgzzPh2kcJyfbRSfVKRMhfIlhY7BzUfM4x6ZT0aijlgsf714Ll3Mbf5Fxii32kD0A/DmKsTecpccw==
apollo-server-express@2.6.6:
version "2.6.6"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.6.6.tgz#ec2b955354d7dd4d12fe01ea7e983d302071d5b9"
integrity sha512-bY/xrr9lZH+hsjchiQuSXpW3ivXfL1h81M5VE9Ppus1PVwwEIar/irBN+PFp97WxERZPDjVZzrRKa+lRHjtJsA==
apollo-server-express@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-express/-/apollo-server-express-2.6.8.tgz#9f3e29f7087af669f05d75dfd335b4a9383ba48e"
integrity sha512-LQzVHknQDkHWffc2qK9dr/qNxQ/WecSKiye5/w10tXrOy3aruTFe67ysG/vMnFZ/puroqiZ2njHzhHZztqQ4sA==
dependencies:
"@apollographql/graphql-playground-html" "1.6.20"
"@types/accepts" "^1.3.5"
@ -1591,7 +1571,7 @@ apollo-server-express@2.6.6:
"@types/cors" "^2.8.4"
"@types/express" "4.17.0"
accepts "^1.3.5"
apollo-server-core "2.6.6"
apollo-server-core "2.6.8"
body-parser "^1.18.3"
cors "^2.8.4"
graphql-subscriptions "^1.0.0"
@ -1619,30 +1599,30 @@ apollo-server-module-graphiql@^1.3.4, apollo-server-module-graphiql@^1.4.0:
resolved "https://registry.yarnpkg.com/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.4.0.tgz#c559efa285578820709f1769bb85d3b3eed3d8ec"
integrity sha512-GmkOcb5he2x5gat+TuiTvabnBf1m4jzdecal3XbXBh/Jg+kx4hcvO3TTDFQ9CuTprtzdcVyA11iqG7iOMOt7vA==
apollo-server-plugin-base@0.5.5:
version "0.5.5"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.5.tgz#364e4a2fca4d95ddeb9fd3e78940ed1da58865c2"
integrity sha512-agiuhknyu3lnnEsqUh99tzxwPCGp+TuDK+TSRTkXU1RUG6lY4C3uJp0JGJw03cP+M6ze73TbRjMA4E68g/ks5A==
apollo-server-plugin-base@0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.6.tgz#3a7128437a0f845e7d873fa43ef091ff7bf27975"
integrity sha512-wJvcPqfm/kiBwY5JZT85t2A4pcHv24xdQIpWMNt1zsnx77lIZqJmhsc22eSUSrlnYqUMXC4XMVgSUfAO4oI9wg==
apollo-server-testing@~2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.6.7.tgz#cfc6366921eb99fd0cbc5d02552a8a5b268787d5"
integrity sha512-lqgZuSqBd5hkRILeVEleo2ScJjukR/E71Mv67vPBUs01s0gEHNnjSRnuOJJOM3cAFBQOdKPc42cHGANzf2ZZTw==
dependencies:
apollo-server-core "2.6.7"
apollo-server-plugin-base@0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.5.7.tgz#267faeb5c2de7fa8d3be469cb99f82f601be7aed"
integrity sha512-HeEwEZ92c2XYRV+0CFLbstW3vUJ4idCxR9E9Q3wwvhXrq8gaGzqyDoC8EzAzRxCJUKcEn7xQOpT/AUTC/KtkRA==
apollo-server@~2.6.6:
version "2.6.6"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.6.6.tgz#0570fce4a682eb1de8bc1b86dbe2543de440cd4e"
integrity sha512-7Bulb3RnOO4/SGA66LXu3ZHCXIK8MYMrsxy4yti1/adDIUmcniolDqJwOYUGoTmv1AQjRxgJb4TVZ0Dk9nrrYg==
apollo-server-testing@~2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server-testing/-/apollo-server-testing-2.6.8.tgz#e75364df7fdc2d6a11023f8a0f72a14309b90800"
integrity sha512-pch2I+8QhdXBMnGDctVth4BcZ5hocwY/ogtBMoQuv7H2HBnlDOz7dCM9BH4TW3+Tk6cFgvLTaDtLJ+NxMCtyVA==
dependencies:
apollo-server-core "2.6.6"
apollo-server-express "2.6.6"
apollo-server-core "2.6.8"
apollo-server@~2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/apollo-server/-/apollo-server-2.6.8.tgz#5f3cf5cf4f2feccbded0cb03fa37dcd8260e5c6a"
integrity sha512-BxwaGxnD3GPuZAAqsexVHFvDlF/s2X8pILgYQ4x+VhUkMeQ12DHQtKPuxn2v2GYwH0U/GDXNohkgwxF/5eTDsQ==
dependencies:
apollo-server-core "2.6.8"
apollo-server-express "2.6.8"
express "^4.0.0"
graphql-subscriptions "^1.0.0"
graphql-tools "^4.0.0"
@ -3854,13 +3834,6 @@ graphql-extensions@0.7.4:
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
graphql-extensions@0.7.5:
version "0.7.5"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.5.tgz#fab2b9e53cf6014952e6547456d50680ff0ea579"
integrity sha512-B1m+/WEJa3IYKWqBPS9W/7OasfPmlHOSz5hpEAq2Jbn6T0FQ/d2YWFf2HBETHR3RR2qfT+55VMiYovl2ga3qcg==
dependencies:
"@apollographql/apollo-tools" "^0.3.6"
graphql-extensions@0.7.6:
version "0.7.6"
resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.7.6.tgz#80cdddf08b0af12525529d1922ee2ea0d0cc8ecf"
@ -5428,10 +5401,10 @@ lodash@=3.10.1:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.11:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.13:
version "4.17.13"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93"
integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==
long@^4.0.0:
version "4.0.0"

View File

@ -276,9 +276,9 @@ When("I fill the password form with:", table => {
table = table.rowsHash();
cy.get("input[id=oldPassword]")
.type(table["Your old password"])
.get("input[id=newPassword]")
.get("input[id=password]")
.type(table["Your new passsword"])
.get("input[id=confirmPassword]")
.get("input[id=passwordConfirmation]")
.type(table["Confirm new password"]);
});

View File

@ -22,7 +22,7 @@
"bcryptjs": "^2.4.3",
"codecov": "^3.5.0",
"cross-env": "^5.2.0",
"cypress": "^3.3.2",
"cypress": "^3.4.0",
"cypress-cucumber-preprocessor": "^1.12.0",
"cypress-file-upload": "^3.2.0",
"cypress-plugin-retries": "^1.2.2",

View File

@ -66,7 +66,8 @@ blockquote {
border-left: 3px dotted $color-neutral-70;
&::before {
content: '\201C'; /*Unicode for Left Double Quote*/
content: '\201C';
/*Unicode for Left Double Quote*/
/*Font*/
font-size: $font-size-xxxx-large;

View File

@ -54,7 +54,7 @@ describe('ChangePassword.vue', () => {
describe('match', () => {
beforeEach(() => {
wrapper.find('input#oldPassword').setValue('some secret')
wrapper.find('input#newPassword').setValue('some secret')
wrapper.find('input#password').setValue('some secret')
})
it('invalid', () => {
@ -90,8 +90,8 @@ describe('ChangePassword.vue', () => {
describe('given valid input', () => {
beforeEach(() => {
wrapper.find('input#oldPassword').setValue('supersecret')
wrapper.find('input#newPassword').setValue('superdupersecret')
wrapper.find('input#confirmPassword').setValue('superdupersecret')
wrapper.find('input#password').setValue('superdupersecret')
wrapper.find('input#passwordConfirmation').setValue('superdupersecret')
})
describe('submit form', () => {
@ -109,8 +109,8 @@ describe('ChangePassword.vue', () => {
expect.objectContaining({
variables: {
oldPassword: 'supersecret',
newPassword: 'superdupersecret',
confirmPassword: 'superdupersecret',
password: 'superdupersecret',
passwordConfirmation: 'superdupersecret',
},
}),
)
@ -135,8 +135,8 @@ describe('ChangePassword.vue', () => {
/* describe('mutation rejects', () => {
beforeEach(async () => {
await wrapper.find('input#oldPassword').setValue('supersecret')
await wrapper.find('input#newPassword').setValue('supersecret')
await wrapper.find('input#confirmPassword').setValue('supersecret')
await wrapper.find('input#password').setValue('supersecret')
await wrapper.find('input#passwordConfirmation').setValue('supersecret')
})
it('displays error message', async () => {

View File

@ -1,12 +1,6 @@
<template>
<ds-form
v-model="formData"
:schema="formSchema"
@submit="handleSubmit"
@input="handleInput"
@input-valid="handleInputValid"
>
<template>
<ds-form v-model="formData" :schema="formSchema" @submit="handleSubmit">
<template slot-scope="{ errors }">
<ds-input
id="oldPassword"
model="oldPassword"
@ -15,22 +9,22 @@
:label="$t('settings.security.change-password.label-old-password')"
/>
<ds-input
id="newPassword"
model="newPassword"
id="password"
model="password"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')"
/>
<ds-input
id="confirmPassword"
model="confirmPassword"
id="passwordConfirmation"
model="passwordConfirmation"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')"
/>
<password-strength :password="formData.newPassword" />
<password-strength :password="formData.password" />
<ds-space margin-top="base">
<ds-button :loading="loading" :disabled="disabled" primary>
<ds-button :loading="loading" :disabled="errors" primary>
{{ $t('settings.security.change-password.button') }}
</ds-button>
</ds-space>
@ -41,6 +35,7 @@
<script>
import gql from 'graphql-tag'
import PasswordStrength from './Strength'
import PasswordForm from '~/components/utils/PasswordFormHelper'
export default {
name: 'ChangePassword',
@ -48,11 +43,11 @@ export default {
PasswordStrength,
},
data() {
const passwordForm = PasswordForm({ translate: this.$t })
return {
formData: {
oldPassword: '',
newPassword: '',
confirmPassword: '',
...passwordForm.formData,
},
formSchema: {
oldPassword: {
@ -60,38 +55,18 @@ export default {
required: true,
message: this.$t('settings.security.change-password.message-old-password-required'),
},
newPassword: {
type: 'string',
required: true,
message: this.$t('settings.security.change-password.message-new-password-required'),
},
confirmPassword: [
{ validator: this.matchPassword },
{
type: 'string',
required: true,
message: this.$t(
'settings.security.change-password.message-new-password-confirm-required',
),
},
],
...passwordForm.formSchema,
},
loading: false,
disabled: true,
}
},
methods: {
async handleInput(data) {
this.disabled = true
},
async handleInputValid(data) {
this.disabled = false
},
async handleSubmit(data) {
this.loading = true
const mutation = gql`
mutation($oldPassword: String!, $newPassword: String!) {
changePassword(oldPassword: $oldPassword, newPassword: $newPassword)
mutation($oldPassword: String!, $password: String!) {
changePassword(oldPassword: $oldPassword, newPassword: $password)
}
`
const variables = this.formData
@ -102,8 +77,8 @@ export default {
this.$toast.success(this.$t('settings.security.change-password.success'))
this.formData = {
oldPassword: '',
newPassword: '',
confirmPassword: '',
password: '',
passwordConfirmation: '',
}
} catch (err) {
this.$toast.error(err.message)
@ -111,15 +86,6 @@ export default {
this.loading = false
}
},
matchPassword(rule, value, callback, source, options) {
var errors = []
if (this.formData.newPassword !== value) {
errors.push(
new Error(this.$t('settings.security.change-password.message-new-password-missmatch')),
)
}
callback(errors)
},
},
}
</script>

View File

@ -47,8 +47,8 @@ describe('ChangePassword ', () => {
describe('submitting new password', () => {
beforeEach(() => {
wrapper = Wrapper()
wrapper.find('input#newPassword').setValue('supersecret')
wrapper.find('input#confirmPassword').setValue('supersecret')
wrapper.find('input#password').setValue('supersecret')
wrapper.find('input#passwordConfirmation').setValue('supersecret')
wrapper.find('form').trigger('submit')
})
@ -58,7 +58,7 @@ describe('ChangePassword ', () => {
it('delivers new password to backend', () => {
const expected = expect.objectContaining({
variables: { code: '123456', email: 'mail@example.org', newPassword: 'supersecret' },
variables: { code: '123456', email: 'mail@example.org', password: 'supersecret' },
})
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})

View File

@ -1,54 +1,52 @@
<template>
<ds-card class="verify-code">
<ds-space margin="large">
<template>
<ds-form
v-if="!changePasswordResult"
v-model="formData"
:schema="formSchema"
@submit="handleSubmitPassword"
@input="handleInput"
@input-valid="handleInputValid"
class="change-password"
>
<ds-form
v-if="!changePasswordResult"
v-model="formData"
:schema="formSchema"
@submit="handleSubmitPassword"
class="change-password"
>
<template slot-scope="{ errors }">
<ds-input
id="newPassword"
model="newPassword"
id="password"
model="password"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')"
/>
<ds-input
id="confirmPassword"
model="confirmPassword"
id="passwordConfirmation"
model="passwordConfirmation"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')"
/>
<password-strength :password="formData.newPassword" />
<password-strength :password="formData.password" />
<ds-space margin-top="base">
<ds-button :loading="$apollo.loading" :disabled="disabled" primary>
<ds-button :loading="$apollo.loading" :disabled="errors" primary>
{{ $t('settings.security.change-password.button') }}
</ds-button>
</ds-space>
</ds-form>
<ds-text v-else>
<template v-if="changePasswordResult === 'success'">
<sweetalert-icon icon="success" />
<ds-text>
{{ $t(`verify-code.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') }}
</ds-text>
<a href="mailto:support@human-connection.org">support@human-connection.org</a>
</template>
</ds-text>
</template>
</template>
</ds-form>
<ds-text v-else>
<template v-if="changePasswordResult === 'success'">
<sweetalert-icon icon="success" />
<ds-text>
{{ $t(`verify-code.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') }}
</ds-text>
<a href="mailto:support@human-connection.org">support@human-connection.org</a>
</template>
</ds-text>
</ds-space>
</ds-card>
</template>
@ -57,6 +55,7 @@
import PasswordStrength from '../Password/Strength'
import gql from 'graphql-tag'
import { SweetalertIcon } from 'vue-sweetalert-icons'
import PasswordForm from '~/components/utils/PasswordFormHelper'
export default {
components: {
@ -68,48 +67,28 @@ export default {
code: { type: String, required: true },
},
data() {
const passwordForm = PasswordForm({ translate: this.$t })
return {
formData: {
newPassword: '',
confirmPassword: '',
...passwordForm.formData,
},
formSchema: {
newPassword: {
type: 'string',
required: true,
message: this.$t('settings.security.change-password.message-new-password-required'),
},
confirmPassword: [
{ validator: this.matchPassword },
{
type: 'string',
required: true,
message: this.$t(
'settings.security.change-password.message-new-password-confirm-required',
),
},
],
...passwordForm.formSchema,
},
disabled: true,
changePasswordResult: null,
}
},
methods: {
async handleInput() {
this.disabled = true
},
async handleInputValid() {
this.disabled = false
},
async handleSubmitPassword() {
const mutation = gql`
mutation($code: String!, $email: String!, $newPassword: String!) {
resetPassword(code: $code, email: $email, newPassword: $newPassword)
mutation($code: String!, $email: String!, $password: String!) {
resetPassword(code: $code, email: $email, newPassword: $password)
}
`
const { newPassword } = this.formData
const { password } = this.formData
const { email, code } = this
const variables = { newPassword, email, code }
const variables = { password, email, code }
try {
const {
data: { resetPassword },
@ -119,22 +98,13 @@ export default {
this.$emit('passwordResetResponse', this.changePasswordResult)
}, 3000)
this.formData = {
newPassword: '',
confirmPassword: '',
password: '',
passwordConfirmation: '',
}
} catch (err) {
this.$toast.error(err.message)
}
},
matchPassword(rule, value, callback, source, options) {
var errors = []
if (this.formData.newPassword !== value) {
errors.push(
new Error(this.$t('settings.security.change-password.message-new-password-missmatch')),
)
}
callback(errors)
},
},
}
</script>

View File

@ -128,6 +128,15 @@ export default {
</script>
<style lang="scss">
.ds-card-image img {
width: 100%;
max-height: 300px;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: center;
object-position: center;
}
.post-card {
cursor: pointer;
position: relative;

View File

@ -0,0 +1,132 @@
import { mount, createLocalVue } from '@vue/test-utils'
import CreateUserAccount, { SignupVerificationMutation } from './CreateUserAccount'
import Styleguide from '@human-connection/styleguide'
const localVue = createLocalVue()
localVue.use(Styleguide)
describe('CreateUserAccount', () => {
let wrapper
let Wrapper
let mocks
let propsData
beforeEach(() => {
mocks = {
$toast: {
success: jest.fn(),
error: jest.fn(),
},
$t: jest.fn(),
$apollo: {
loading: false,
mutate: jest.fn(),
},
}
propsData = {}
})
describe('mount', () => {
Wrapper = () => {
return mount(CreateUserAccount, {
mocks,
propsData,
localVue,
})
}
describe('given email and nonce', () => {
beforeEach(() => {
propsData.nonce = '666777'
propsData.email = 'sixseven@example.org'
})
it('renders a form to create a new user', () => {
wrapper = Wrapper()
expect(wrapper.find('.create-user-account').exists()).toBe(true)
})
describe('submit', () => {
let action
beforeEach(() => {
action = async () => {
wrapper = Wrapper()
wrapper.find('input#name').setValue('John Doe')
wrapper.find('input#password').setValue('hellopassword')
wrapper.find('input#passwordConfirmation').setValue('hellopassword')
await wrapper.find('form').trigger('submit')
await wrapper.html()
}
})
it('calls CreateUserAccount graphql mutation', async () => {
await action()
const expected = expect.objectContaining({ mutation: SignupVerificationMutation })
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
it('delivers data to backend', async () => {
await action()
const expected = expect.objectContaining({
variables: {
about: '',
name: 'John Doe',
email: 'sixseven@example.org',
nonce: '666777',
password: 'hellopassword',
},
})
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
describe('in case mutation resolves', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest.fn().mockResolvedValue({
data: {
SignupVerification: {
id: 'u1',
name: 'John Doe',
slug: 'john-doe',
},
},
})
})
it('displays success', async () => {
await action()
expect(mocks.$t).toHaveBeenCalledWith('registration.create-user-account.success')
})
describe('after timeout', () => {
beforeEach(jest.useFakeTimers)
it('emits `userCreated` with { password, email }', async () => {
await action()
jest.runAllTimers()
expect(wrapper.emitted('userCreated')).toEqual([
[
{
email: 'sixseven@example.org',
password: 'hellopassword',
},
],
])
})
})
})
describe('in case mutation rejects', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest.fn().mockRejectedValue(new Error('Invalid nonce'))
})
it('displays form errors', async () => {
await action()
expect(wrapper.find('.backendErrors').text()).toContain('Invalid nonce')
})
})
})
})
})
})

View File

@ -0,0 +1,142 @@
<template>
<ds-card v-if="success" class="success">
<ds-space>
<sweetalert-icon icon="success" />
<ds-text align="center" bold color="success">
{{ $t('registration.create-user-account.success') }}
</ds-text>
</ds-space>
</ds-card>
<ds-form
v-else
class="create-user-account"
v-model="formData"
:schema="formSchema"
@submit="submit"
>
<template slot-scope="{ errors }">
<ds-card :header="$t('registration.create-user-account.title')">
<ds-input
id="name"
model="name"
icon="user"
:label="$t('settings.data.labelName')"
:placeholder="$t('settings.data.namePlaceholder')"
/>
<ds-input
id="bio"
model="about"
type="textarea"
rows="3"
:label="$t('settings.data.labelBio')"
:placeholder="$t('settings.data.labelBio')"
/>
<ds-input
id="password"
model="password"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password')"
/>
<ds-input
id="passwordConfirmation"
model="passwordConfirmation"
type="password"
autocomplete="off"
:label="$t('settings.security.change-password.label-new-password-confirm')"
/>
<password-strength :password="formData.password" />
<template slot="footer">
<ds-space class="backendErrors" v-if="backendErrors">
<ds-text align="center" bold color="danger">
{{ backendErrors.message }}
</ds-text>
</ds-space>
<ds-button
style="float: right;"
icon="check"
type="submit"
:loading="$apollo.loading"
:disabled="errors"
primary
>
{{ $t('actions.save') }}
</ds-button>
</template>
</ds-card>
</template>
</ds-form>
</template>
<script>
import gql from 'graphql-tag'
import PasswordStrength from '../Password/Strength'
import { SweetalertIcon } from 'vue-sweetalert-icons'
import PasswordForm from '~/components/utils/PasswordFormHelper'
export const SignupVerificationMutation = gql`
mutation($nonce: String!, $name: String!, $email: String!, $password: String!) {
SignupVerification(nonce: $nonce, email: $email, name: $name, password: $password) {
id
name
slug
}
}
`
export default {
components: {
PasswordStrength,
SweetalertIcon,
},
data() {
const passwordForm = PasswordForm({ translate: this.$t })
return {
formData: {
name: '',
about: '',
...passwordForm.formData,
},
formSchema: {
name: {
type: 'string',
required: true,
min: 3,
},
about: {
type: 'string',
required: false,
},
...passwordForm.formSchema,
},
disabled: true,
success: null,
backendErrors: null,
}
},
props: {
nonce: { type: String, required: true },
email: { type: String, required: true },
},
methods: {
async submit() {
const { name, password, about } = this.formData
const { email, nonce } = this
try {
await this.$apollo.mutate({
mutation: SignupVerificationMutation,
variables: { name, password, about, email, nonce },
})
this.success = true
setTimeout(() => {
this.$emit('userCreated', {
email,
password,
})
}, 3000)
} catch (err) {
this.backendErrors = err
}
},
},
}
</script>

View File

@ -0,0 +1,146 @@
import { mount, createLocalVue } from '@vue/test-utils'
import Signup, { SignupMutation, SignupByInvitationMutation } from './Signup'
import Styleguide from '@human-connection/styleguide'
const localVue = createLocalVue()
localVue.use(Styleguide)
describe('Signup', () => {
let wrapper
let Wrapper
let mocks
let propsData
beforeEach(() => {
mocks = {
$toast: {
success: jest.fn(),
error: jest.fn(),
},
$t: jest.fn(),
$apollo: {
loading: false,
mutate: jest.fn().mockResolvedValue({ data: { Signup: { email: 'mail@example.org' } } }),
},
}
propsData = {}
})
describe('mount', () => {
beforeEach(jest.useFakeTimers)
Wrapper = () => {
return mount(Signup, {
mocks,
propsData,
localVue,
})
}
describe('without invitation code', () => {
it('renders signup form', () => {
wrapper = Wrapper()
expect(wrapper.find('.signup').exists()).toBe(true)
})
describe('submit', () => {
beforeEach(async () => {
wrapper = Wrapper()
wrapper.find('input#email').setValue('mail@example.org')
await wrapper.find('form').trigger('submit')
})
it('calls Signup graphql mutation', () => {
const expected = expect.objectContaining({ mutation: SignupMutation })
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
it('delivers email to backend', () => {
const expected = expect.objectContaining({
variables: { email: 'mail@example.org', token: null },
})
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
it('hides form to avoid re-submission', () => {
expect(wrapper.find('form').exists()).not.toBeTruthy()
})
it('displays a message that a mail for email verification was sent', () => {
const expected = ['registration.signup.form.success', { email: 'mail@example.org' }]
expect(mocks.$t).toHaveBeenCalledWith(...expected)
})
describe('after animation', () => {
beforeEach(jest.runAllTimers)
it('emits `handleSubmitted`', () => {
expect(wrapper.emitted('handleSubmitted')).toEqual([[{ email: 'mail@example.org' }]])
})
})
})
})
describe('with invitation code', () => {
let action
beforeEach(() => {
propsData.token = '666777'
action = async () => {
wrapper = Wrapper()
wrapper.find('input#email').setValue('mail@example.org')
await wrapper.find('form').trigger('submit')
await wrapper.html()
}
})
describe('submit', () => {
it('calls SignupByInvitation graphql mutation', async () => {
await action()
const expected = expect.objectContaining({ mutation: SignupByInvitationMutation })
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
it('delivers invitation token to backend', async () => {
await action()
const expected = expect.objectContaining({
variables: { email: 'mail@example.org', token: '666777' },
})
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
describe('in case a user account with the email already exists', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest
.fn()
.mockRejectedValue(
new Error('UserInputError: User account with this email already exists.'),
)
})
it('explains the error', async () => {
await action()
expect(mocks.$t).toHaveBeenCalledWith('registration.signup.form.errors.email-exists')
})
})
describe('in case the invitation code was incorrect', () => {
beforeEach(() => {
mocks.$apollo.mutate = jest
.fn()
.mockRejectedValue(
new Error('UserInputError: Invitation code already used or does not exist.'),
)
})
it('explains the error', async () => {
await action()
expect(mocks.$t).toHaveBeenCalledWith(
'registration.signup.form.errors.invalid-invitation-token',
)
})
})
})
})
})
})

View File

@ -0,0 +1,141 @@
<template>
<ds-card class="signup">
<ds-space margin="large">
<ds-form
v-if="!success && !error"
@input="handleInput"
@input-valid="handleInputValid"
v-model="formData"
:schema="formSchema"
@submit="handleSubmit"
>
<h1>{{ $t('registration.signup.title') }}</h1>
<ds-space v-if="token" margin-botton="large">
<ds-text v-html="$t('registration.signup.form.invitation-code', { code: token })" />
</ds-space>
<ds-space margin-botton="large">
<ds-text>
{{ $t('registration.signup.form.description') }}
</ds-text>
</ds-space>
<ds-input
:placeholder="$t('login.email')"
type="email"
id="email"
model="email"
name="email"
icon="envelope"
/>
<ds-button
:disabled="disabled"
:loading="$apollo.loading"
primary
fullwidth
name="submit"
type="submit"
icon="envelope"
>
{{ $t('registration.signup.form.submit') }}
</ds-button>
</ds-form>
<div v-else>
<template v-if="!error">
<sweetalert-icon icon="info" />
<ds-text align="center" v-html="submitMessage" />
</template>
<template v-else>
<sweetalert-icon icon="error" />
<ds-text align="center">
{{ error.message }}
</ds-text>
</template>
</div>
</ds-space>
</ds-card>
</template>
<script>
import gql from 'graphql-tag'
import { SweetalertIcon } from 'vue-sweetalert-icons'
export const SignupMutation = gql`
mutation($email: String!) {
Signup(email: $email) {
email
}
}
`
export const SignupByInvitationMutation = gql`
mutation($email: String!, $token: String!) {
SignupByInvitation(email: $email, token: $token) {
email
}
}
`
export default {
components: {
SweetalertIcon,
},
props: {
token: { type: String, default: null },
},
data() {
return {
formData: {
email: '',
},
formSchema: {
email: {
type: 'email',
required: true,
message: this.$t('common.validations.email'),
},
},
disabled: true,
success: false,
error: null,
}
},
computed: {
submitMessage() {
const { email } = this.formData
return this.$t('registration.signup.form.success', { email })
},
},
methods: {
handleInput() {
this.disabled = true
},
handleInputValid() {
this.disabled = false
},
async handleSubmit() {
const mutation = this.token ? SignupByInvitationMutation : SignupMutation
const { email } = this.formData
const { token } = this
try {
await this.$apollo.mutate({ mutation, variables: { email, token } })
this.success = true
setTimeout(() => {
this.$emit('handleSubmitted', { email })
}, 3000)
} catch (err) {
const { message } = err
const mapping = {
'User account with this email already exists': 'email-exists',
'Invitation code already used or does not exist': 'invalid-invitation-token',
}
for (const [pattern, key] of Object.entries(mapping)) {
if (message.includes(pattern))
this.error = { key, message: this.$t(`registration.signup.form.errors.${key}`) }
}
if (!this.error) {
this.$toast.error(message)
}
}
},
},
}
</script>

View File

@ -0,0 +1,36 @@
export default function PasswordForm({ translate }) {
const passwordMismatchMessage = translate(
'settings.security.change-password.message-new-password-missmatch',
)
return {
formData: {
password: '',
passwordConfirmation: '',
},
formSchema: {
password: {
type: 'string',
required: true,
message: translate('settings.security.change-password.message-new-password-required'),
},
passwordConfirmation: [
{
validator(rule, value, callback, source, options) {
var errors = []
if (source.password !== value) {
errors.push(new Error(passwordMismatchMessage))
}
callback(errors)
},
},
{
type: 'string',
required: true,
message: translate(
'settings.security.change-password.message-new-password-confirm-required',
),
},
],
},
}
}

View File

@ -114,13 +114,22 @@
</div>
</ds-container>
</div>
<ds-container style="word-break: break-all">
<div style="padding: 6rem 2rem 5rem;">
<div class="main-container" :width="{ base: '100%', md: '96%' }">
<nuxt />
</div>
</ds-container>
<div id="footer" class="ds-footer">
<a href="https://human-connection.org" target="_blank" v-html="$t('site.made')"></a>
&nbsp;-&nbsp;
<nuxt-link to="/imprint">{{ $t('site.imprint') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/terms-and-conditions">{{ $t('site.termsAc') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/privacy">{{ $t('site.privacy') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/changelog">{{ $t('site.changelog') }}</nuxt-link>
</div>
<div id="overlay" />
<no-ssr>
<modal />
@ -266,6 +275,11 @@ export default {
display: inline-flex;
}
.main-container {
padding-top: 6rem;
padding-botton: 5rem;
}
.main-navigation {
a {
color: $text-color-soft;
@ -341,4 +355,14 @@ export default {
display: none;
}
}
.ds-footer {
text-align: center;
position: fixed;
bottom: 0px;
z-index: 10;
background-color: white;
width: 100%;
padding: 10px 10px;
}
</style>

View File

@ -8,6 +8,21 @@
"header": "Themenkategorien",
"all": "Alle"
},
"site": {
"made": "Mit &#10084; gemacht",
"imprint": "Impressum",
"termsAc": "Nutzungsbedingungen",
"privacy": "Datenschutz",
"changelog": "Änderungen & Verlauf",
"contact": "Kontakt",
"tribunal": "Registergericht",
"register": "Registernummer",
"director": "Geschäftsführer",
"taxident": "Umsatzsteuer-Identifikationsnummer gemäß § 27 a Umsatzsteuergesetz (Deutschland)",
"responsible": "Verantwortlicher gemäß § 55 Abs. 2 RStV ",
"bank": "Bankverbindung",
"germany": "Deutschland"
},
"login": {
"copy": "Wenn Du bereits ein Konto bei Human Connection hast, melde Dich bitte hier an.",
"login": "Einloggen",
@ -18,7 +33,8 @@
"moreInfo": "Was ist Human Connection?",
"moreInfoURL": "https://human-connection.org",
"moreInfoHint": "zur Präsentationsseite",
"hello": "Hallo"
"hello": "Hallo",
"success": "Du bist eingeloggt!"
},
"password-reset": {
"title": "Passwort zurücksetzen",
@ -28,6 +44,24 @@
"submitted": "Eine E-Mail mit weiteren Instruktionen wurde verschickt an <b>{email}</b>"
}
},
"registration": {
"signup": {
"title": "Mach mit bei Human Connection!",
"form": {
"description": "Um loszulegen, gib deine E-Mail Adresse ein:",
"errors": {
"email-exists": "Es gibt schon ein Benutzerkonto mit dieser E-Mail Adresse!",
"invalid-invitation-token": "Es sieht so aus, als ob der Einladungscode schon eingelöst wurde. Jeder Code kann nur einmalig benutzt werden."
},
"submit": "Konto erstellen",
"success": "Eine Mail mit einem Bestätigungslink für die Registrierung wurde an <b>{email}</b> geschickt"
}
},
"create-user-account": {
"title": "Benutzerkonto anlegen",
"success": "Dein Benutzerkonto wurde erstellt!"
}
},
"verify-code": {
"form": {
"code": "Code eingeben",
@ -178,6 +212,11 @@
},
"settings": {
"name": "Einstellungen"
},
"invites": {
"name": "Benutzer einladen",
"title": "Benutzer als Admin anmelden",
"description": "Dieses Anmeldeformular ist zu sehen sobald die Anmeldung öffentlich zugänglich ist."
}
},
"post": {
@ -357,5 +396,8 @@
"categories": {
"infoSelectedNoOfMaxCategories": "{chosen} von {max} Kategorien ausgewählt"
}
},
"terms": {
"text": "<div ><ol><li><strong>UNFALLGEFAHR: </strong>Das ist eine Testversion! Alle Daten, Dein Profil und die Server können jederzeit komplett vernichtet, verloren, verbrannt und vielleicht auch in der Nähe von Alpha Centauri synchronisiert werden. Die Benutzung läuft auf eigene Gefahr. Mit kommerziellen Nebenwirkungen ist jedoch nicht zu rechnen.</li><br><li><strong>DU UND DEINE DATEN: </strong>Bitte beachte, dass wir die Inhalte der Alphaversion zu Werbezwecken, Webpräsentationen usw. verwenden, aber wir glauben, dass das auch in Deinem Interesse ist. Am besten keinen Nachnamen eingeben und bei noch mehr Datensparsamkeit ein Profilfoto ohne Identität verwenden. Mehr in unserer <a href='/pages/privacy' target='_blank'>Datenschutzerklärung</a>.</li><br><li><strong>BAUSTELLEN: </strong>Das ist immer noch eine Testversion. Wenn etwas nicht funktioniert, blockiert, irritiert, falsch angezeigt, verbogen oder nicht anklickbar ist, bitten wir dies zu entschuldigen. Fehler, Käfer und Bugs bitte melden! <a href='http://localhost:3000/%22https://human-connection.org/alpha/#bugreport%5C%22' target='_blank'>https://human-connection.org/support</a></li><br><li><strong>VERHALTENSCODEX</strong>: Die Verhaltensregeln dienen als Leitsätze für den persönlichen Auftritt und den Umgang untereinander. Wer als Nutzer im Human Connection Netzwerk aktiv ist, Beiträge verfasst, kommentiert oder mit anderen Nutzern, auch außerhalb des Netzwerkes, Kontakt aufnimmt, erkennt diese Verhaltensregeln als verbindlich an: <a href='https://alpha.human-connection.org/pages/code-of-conduct' target='_blank'>https://alpha.human-connection.org/pages/code-of-conduct</a></li><br><li><strong>MODERATION: </strong>Solange kein Community-Moderationssystem lauffähig ist, entscheidet ein Regenbogen-Einhorn darüber, ob Du körperlich und psychisch stabil genug bist, unsere Testversion zu bedienen. Das Einhorn kann Dich jederzeit von der Alpha entfernen. Also sei nett und lass Regenbogenfutter da!</li><br><li><strong>FAIRNESS: </strong>Sollte Dir die Alphaversion unseres Netzwerks wider Erwarten, egal aus welchen Gründen, nicht gefallen, überweisen wir Dir Deine gespendeten Monatsbeiträge innerhalb der ersten 2 Monate gerne zurück. Einfach Mail an: <a href='mailto:info@human-connection.org' target='_blank'>info@human-connection.org </a><strong>Achtung: Viele Funktionen werden erst nach und nach eingebaut. </strong></li><br><li><strong>FRAGEN?</strong> Die Termine und Links zu den Zoom-Räumen findest Du hier: <a href='http://localhost:3000/%22https://human-connection.org/events-und-news//%22' target='_blank'>https://human-connection.org/veranstaltungen/</a></li><br><li><strong>VON MENSCHEN FÜR MENSCHEN: </strong>Bitte hilf uns weitere monatlichen Spender für Human Connection zu bekommen, damit das Netzwerk so schnell wie möglich offiziell an den Start gehen kann. <a href='http://localhost:3000/%22https://human-connection.org/alpha/#bugreport%5C%22' target='_blank'>https://human-connection.org</a></li></ol><p>Jetzt aber viel Spaß mit der Alpha von Human Connection! Für den ersten Weltfrieden. ♥︎</p><br><p><strong>Herzlichst,</strong></p><p><strong>Euer Human Connection Team</strong></p></div>"
}
}

View File

@ -8,6 +8,21 @@
"header": "Categories of Content",
"all": "All"
},
"site": {
"made": "Made with &#10084;",
"imprint": "Imprint",
"termsAc": "Terms and conditions",
"privacy": "Data privacy",
"changelog": "Changes & History",
"contact": "Contact",
"tribunal": "Registry court",
"register": "Registry number",
"director": "Managing Director",
"taxident": "Value added tax identification number according to § 27 a Value Added Tax Act (Germany)",
"responsible": "Responsible according to § 55 Abs. 2 RStV (Germany) ",
"bank": "bank account",
"germany": "Germany"
},
"login": {
"copy": "If you already have a human-connection account, login here.",
"login": "Login",
@ -18,7 +33,8 @@
"moreInfo": "What is Human Connection?",
"moreInfoURL": "https://human-connection.org/en/",
"moreInfoHint": "to the presentation page",
"hello": "Hello"
"hello": "Hello",
"success": "You are logged in!"
},
"password-reset": {
"title": "Reset your password",
@ -28,6 +44,25 @@
"submitted": "A mail with further instruction has been sent to <b>{email}</b>"
}
},
"registration": {
"signup": {
"title": "Join Human Connection!",
"form": {
"description": "To get started, enter your email address:",
"invitation-code": "Your invitation code is: <b>{code}</b>",
"errors": {
"email-exists": "There is already a user account with this email address!",
"invalid-invitation-token": "It looks like as if the invitation has been used already. Invitation links can only be used once."
},
"submit": "Create an account",
"success": "A mail with a link to complete your registration has been sent to <b>{email}</b>"
}
},
"create-user-account": {
"title": "Create user account",
"success": "Your account has been created!"
}
},
"verify-code": {
"form": {
"code": "Enter your code",
@ -178,6 +213,11 @@
},
"settings": {
"name": "Settings"
},
"invites": {
"name": "Invite users",
"title": "Signup users as admin",
"description": "This registration form will be visible as soon as the registration is open to the public."
}
},
"post": {
@ -356,5 +396,8 @@
"categories": {
"infoSelectedNoOfMaxCategories": "{chosen} of {max} categories selected"
}
},
"terms": {
"text": "<div><ol><li><strong>RISK OF ACCIDENT:</strong> This is a test version! All data, your profile and the server can be completely destroyed, wiped out, lost, burnt and eventually synchronised near Alpha Centauri at any time. Use on your own risk. Commercial effects are not likely though.</li><br><li><strong>YOU AND YOUR DATA:</strong> Please notice, that the content of the alpha version will be used for publicity and web presentations etc. but we are sure, this is to your interest. If you like use no surnames and if you want to disclose less data use a profile picture without identity. You can find more information in our <a href='/pages/privacy' target='_blank'>privacy policy</a>.</li><br><li><strong>SITE:</strong> This is still a test version. Please excuse if some applications are not working, blocking, irritating, displayed falsely or not able to be clicked on. Please report faults and bugs! <a href='https://human-connection.org/support' target='_blank'>https://human-connection.org/support</a></li><br><li><strong>CODE OF CONDUCT</strong>: The code of conduct serves as guiding principles for our personal appearance and interaction with one another. Anyone who is active as a user in the Human Connection Network, writes articles, comments or contacts other users, including those outside the network, acknowledges these rules of conduct as binding: <a href='https://alpha.human-connection.org/pages/code-of-conduct' target='_blank'>https://alpha.human-connection.org/pages/code-of-conduct</a></li><br><li><strong>MODERATION:</strong> As long as there is no community moderation-system in operation, a rainbow colored unicorn decides, if you are physically and mentally stable enough to operate our test version. The unicorn can delete you from the alpha version at any time. So be so kind and leave rainbow food!</li><br><li><strong>FAIRNESS:</strong> If, against all expectations, our alpha version is not to your liking, we return your monthly payment within the first two months. Please send a mail to: <a href='mailto:info@human-connection.org' target='_blank'>info@human-connection.org</a>. <strong>Attention: Pleace note that more features are build in on regular basis.</strong></li><br><li><strong>QUESTIONS?</strong> You can find the dates and links to our zoom-rooms here: <a href='https://human-connection.org/events-und-news/' target='_blank'>https://human-connection.org/events-und-news/</a></li><br><li><strong>FROM HUMAN BEING TO HUMAN BEING: </strong>Please help us to get new donators for Human Connection, so the network can take off as soon as possible. <a href='https://human-connection.org/' target='_blank'>https://human-connection.org</a></li></ol><br><p>Now have fun with the alpha version of Human Connection! For the first universal peace.<strong> ♥︎</strong></p><p><strong> </strong></p><br><p><strong>Thank you very much, </strong></p><p><strong>your Human Connection Team</strong></p></div>"
}
}

View File

@ -2,6 +2,21 @@
"filter-menu": {
"title": "Su burbuja de filtro"
},
"site": {
"made": "Con &#10084; realizado",
"imprint": "Pie de imprenta",
"termsAc": "términos y condiciones",
"privacy": "protección de datos",
"changelog": "Cambios e historia",
"contact": "Contacto",
"tribunal": "tribunal de registro",
"register": "número de registro",
"director": "Director General",
"taxident": "Número de identificación del impuesto sobre el valor añadido según el § 27 a de la Ley del Impuesto sobre el Valor Añadido (Alemania)",
"responsible": "Responsable según § 55 Abs. 2 RStV (Alemania)",
"bank": "cuenta",
"germany": "Alemania"
},
"login": {
"copy": "Si ya tiene una cuenta de Human Connection, inicie sesión aquí.",
"login": "Iniciar sesión",

View File

@ -2,6 +2,21 @@
"filter-menu": {
"title": "Votre bulle de filtre"
},
"site": {
"made": "Avec &#10084; fait",
"imprint": "Mentions légales",
"termsAc": "modalités et conditions",
"privacy": "protection des données",
"changelog": "Changements et historique",
"contact": "Contacter",
"tribunal": "tribunal de registre",
"register": "numéro de registre",
"director": "Directeur Général",
"taxident": "Numéro d'identification à la taxe sur la valeur ajoutée selon § 27 a de la loi sur la taxe sur la valeur ajoutée (Allemagne)",
"responsible": "Responsable selon § 55 Abs. 2 RStV (Allemagne)",
"bank": "Bankverbindung",
"germany": "Allemagne"
},
"login": {
"copy": "Si vous avez déjà un compte human-connection, connectez-vous ici.",
"login": "Connexion",

View File

@ -1,4 +1,19 @@
{
"site": {
"made": "Con &#10084; fatto",
"imprint": "Impressum",
"termsAc": "Condizioni d'uso",
"privacy": "protezione dei dati",
"changelog": "Cambiamenti e storia",
"contact": "Contatto",
"tribunal": "registro tribunale",
"register": "numero di registro",
"director": "Direttore Generale",
"taxident": "Numero di identificazione dell'imposta sul valore aggiunto ai sensi del § 27 a Legge sull'imposta sul valore aggiunto (Germania)",
"responsible": "Responsabile ai sensi del § 55 Abs. 2 RStV (Germania)",
"bank": "conto bancario",
"germany": "Germania"
},
"login": {
"copy": "Se sei gia registrato su Human Connection, accedi qui.",
"login": "Accesso",
@ -126,4 +141,4 @@
"edit": "Modifica",
"delete": "Cancella"
}
}
}

View File

@ -1,4 +1,19 @@
{
"site": {
"made": "Met &#10084; gemaakt",
"imprint": "Afdruk",
"termsAc": "Gebruiksvoorwaarden",
"privacy": "gegevensbescherming",
"changelog": "Veranderingen & Geschiedenis",
"contact": "contact",
"tribunal": "registerrechtbank",
"register": "inschrijfnummer",
"director": "Directeur",
"taxident": "Identificatienummer voor de belasting over de toegevoegde waarde overeenkomstig § 27 a Wet op de belasting over de toegevoegde waarde (Duitsland).",
"responsible": "Verantwoordelijk volgens § 55 Abs. 2 RStV (Duitsland).",
"bank": "bankrekening",
"germany": "Duitsland"
},
"login": {
"copy": "Als u al een mini-aansluiting account heeft, log dan hier in.",
"login": "Inloggen",
@ -156,4 +171,4 @@
"shoutButton": {
"shouted": "uitgeroepen"
}
}
}

View File

@ -1,4 +1,19 @@
{
"site": {
"made": "Z &#10084; zrobiony",
"imprint": "Nadruk",
"termsAc": "Warunki użytkowania",
"privacy": "ochrona danych",
"changelog": "Zmiany i historia",
"contact": "Kontakt",
"tribunal": "sąd rejestrowy",
"register": "numer rejestracyjny",
"director": "Dyrektor zarządzający",
"taxident": "Numer identyfikacyjny podatku od wartości dodanej zgodnie z § 27 a Ustawa o podatku od wartości dodanej (Niemcy)",
"responsible": "Odpowiedzialny zgodnie z § 55 Abs. 2 RStV (Niemcy)",
"bank": "rachunek bankowy",
"germany": "Niemcy"
},
"login": {
"copy": "Jeśli masz już konto Human Connection, zaloguj się tutaj.",
"login": "logowanie",
@ -187,4 +202,4 @@
"shoutButton": {
"shouted": "krzyczeć"
}
}
}

View File

@ -1,4 +1,20 @@
{
"site": {
"made": "Com &#10084; feito",
"imprint": "Impressão",
"termsAc": "termos e condições",
"privacy": "protecção de dados",
"changelog": "Mudanças e Histórico",
"contact": "Contato",
"tribunal": "tribunal",
"tribunal": "tribunal de registo",
"register": "número de registo",
"director": "Diretor Administrativo",
"taxident": "Número de identificação do imposto sobre o valor acrescentado de acordo com o § 27 da Lei do Imposto sobre o Valor Acrescentado (Alemanha)",
"responsible": "Responsável segundo § 55 Abs. 2 RStV (Alemanha) ",
"bank": "conta bancária",
"germany": "Alemanha"
},
"login": {
"copy": "Se você já tem uma conta no Human Connection, entre aqui.",
"login": "Entrar",
@ -187,4 +203,4 @@
"shoutButton": {
"shouted": "Aclamou"
}
}
}

View File

@ -31,10 +31,10 @@ module.exports = {
'password-reset-request',
'password-reset-verify-code',
'password-reset-change-password',
'register',
'signup',
'reset',
'reset-token',
// 'registration-signup', TODO: uncomment to open public registration
'registration-signup-by-invitation-code',
'registration-verify-code',
'registration-create-user-account',
'pages-slug',
],
// pages to keep alive

View File

@ -80,9 +80,9 @@
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@babel/core": "~7.5.0",
"@babel/core": "~7.5.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "~7.4.5",
"@babel/preset-env": "~7.5.4",
"@vue/cli-shared-utils": "~3.9.0",
"@vue/eslint-config-prettier": "~4.0.1",
"@vue/server-test-utils": "~1.0.0-beta.29",

View File

@ -1,8 +1,6 @@
<template>
<div>
<ds-heading tag="h1">
{{ $t('admin.name') }}
</ds-heading>
<ds-heading tag="h1">{{ $t('admin.name') }}</ds-heading>
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', md: '200px' }">
<ds-menu :routes="routes" :is-exact="() => true" />
@ -54,6 +52,10 @@ export default {
name: this.$t('admin.tags.name'),
path: `/admin/tags`,
},
{
name: this.$t('admin.invites.name'),
path: `/admin/invite`,
},
// TODO implement
/* {
name: this.$t('admin.settings.name'),

View File

@ -0,0 +1,23 @@
<template>
<ds-section>
<ds-space>
<ds-heading size="h3">
{{ $t('admin.invites.title') }}
</ds-heading>
<ds-text>
{{ $t('admin.invites.description') }}
</ds-text>
</ds-space>
<signup />
</ds-section>
</template>
<script>
import Signup from '~/components/Registration/Signup'
export default {
components: {
Signup,
},
}
</script>

View File

@ -0,0 +1,24 @@
<template>
<div>
<ds-space>
<ds-heading tag="h2">{{ $t('site.changelog') }}</ds-heading>
</ds-space>
<ds-container>
<ds-space margin-top="large">
<ds-text>{{ $t('site.changelog') }}</ds-text>
<ds-text>...</ds-text>
</ds-space>
</ds-container>
</div>
</template>
<script>
export default {
head() {
return {
title: this.$t('site.changelog'),
}
},
}
</script>

82
webapp/pages/imprint.vue Normal file
View File

@ -0,0 +1,82 @@
<template>
<div>
<ds-space>
<ds-heading tag="h2">{{ $t('site.imprint') }}</ds-heading>
</ds-space>
<ds-container>
<ds-space margin-top="large">
<ds-text>
<div>
<p>
<strong>Human Connection gemeinnützige GmbH</strong>
</p>
<p>Bahnhofstr. 11</p>
<p>73235 Weilheim / Teck</p>
<p>{{ $t('site.germany') }}</p>
<br />
<p>
<strong>{{ $t('site.contact') }}</strong>
</p>
<p>Tel.: +49 151 / 43 80 42 22</p>
<p>
E-Mail:
<a
class="hc-editor-link-blot"
href="mailto:info@human-connection.org"
target="_blank"
>
info@human-connection.org
</a>
</p>
<br />
<p>
<strong>{{ $t('site.tribunal') }}</strong>
</p>
<p>Amtsgericht Stuttgart</p>
<br />
<p>
<strong>{{ $t('site.register') }}</strong>
</p>
<p>HRB 741951</p>
<br />
<p>
<strong>{{ $t('site.director') }}</strong>
</p>
<p>Dennis Hack</p>
<br />
<p>
<strong>{{ $t('site.taxident') }}</strong>
</p>
<p>DE284651760</p>
<br />
<p>
<strong>{{ $t('site.responsible') }}</strong>
</p>
<p>Dennis Hack</p>
<p>Bahnhofstr. 11</p>
<p>73235 Weilheim / Teck</p>
<p>{{ $t('site.germany') }}</p>
<br />
<p>
<strong>{{ $t('site.bank') }}</strong>
</p>
<p>GLS Bank</p>
<p>IBAN:&nbsp;DE08 4306 0967 7024 1934 00</p>
<p>BIC / SWIFT:&nbsp;GENODEM1GLS</p>
</div>
</ds-text>
</ds-space>
</ds-container>
</div>
</template>
<script>
export default {
head() {
return {
title: this.$t('site.imprint'),
}
},
}
</script>

View File

@ -115,7 +115,7 @@ export default {
async onSubmit() {
try {
await this.$store.dispatch('auth/login', { ...this.form })
this.$toast.success('You are logged in!')
this.$toast.success(this.$t('login.success'))
this.$router.replace(this.$route.query.path || '/')
} catch (err) {
this.$toast.error(err.message)

23
webapp/pages/privacy.vue Normal file
View File

@ -0,0 +1,23 @@
<template>
<div>
<ds-space>
<ds-heading tag="h2">{{ $t('site.privacy') }}</ds-heading>
</ds-space>
<ds-container>
<ds-space margin-top="large">
<ds-text>{{ $t('site.privacy') }}</ds-text>
<ds-text>...</ds-text>
</ds-space>
</ds-container>
</div>
</template>
<script>
export default {
head() {
return {
title: this.$t('site.privacy'),
}
},
}
</script>

View File

@ -0,0 +1,14 @@
<template>
<nuxt-child />
</template>
<script>
export default {
layout: 'default',
asyncData({ store, redirect }) {
if (store.getters['auth/isLoggedIn']) {
redirect('/')
}
},
}
</script>

View File

@ -0,0 +1,27 @@
<template>
<create-user-account @userCreated="handleUserCreated" :email="email" :nonce="nonce" />
</template>
<script>
import CreateUserAccount from '~/components/Registration/CreateUserAccount'
export default {
data() {
const { nonce = '', email = '' } = this.$route.query
return { nonce, email }
},
components: {
CreateUserAccount,
},
methods: {
async handleUserCreated({ email, password }) {
try {
await this.$store.dispatch('auth/login', { email, password })
this.$toast.success('You are logged in!')
this.$router.push('/')
} catch (err) {
this.$toast.error(err.message)
}
},
},
}
</script>

View File

@ -0,0 +1,23 @@
<template>
<div>
<ds-space>
<ds-heading tag="h2">{{ $t('site.termsAc') }}</ds-heading>
</ds-space>
<ds-container>
<ds-space margin-top="large">
<ds-text>{{ $t('site.termsAc') }}</ds-text>
<ds-text v-html="$t('terms.text')"></ds-text>
</ds-space>
</ds-container>
</div>
</template>
<script>
export default {
head() {
return {
title: this.$t('site.termsAc'),
}
},
}
</script>

View File

@ -21,14 +21,14 @@
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@~7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.0.tgz#6ed6a2881ad48a732c5433096d96d1b0ee5eb734"
integrity sha512-6Isr4X98pwXqHvtigw71CKgmhL1etZjPs5A67jL/w0TkLM9eqmFR40YrnJvEc1WnMZFsskjsmid8bHZyxKEAnw==
"@babel/core@^7.1.0", "@babel/core@^7.4.5", "@babel/core@~7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.4.tgz#4c32df7ad5a58e9ea27ad025c11276324e0b4ddd"
integrity sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/generator" "^7.5.0"
"@babel/helpers" "^7.5.0"
"@babel/helpers" "^7.5.4"
"@babel/parser" "^7.5.0"
"@babel/template" "^7.4.4"
"@babel/traverse" "^7.5.0"
@ -219,10 +219,10 @@
"@babel/traverse" "^7.1.0"
"@babel/types" "^7.2.0"
"@babel/helpers@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.0.tgz#7f0c17666e7ed8355ed6eff643dde12fb681ddb4"
integrity sha512-EgCUEa8cNwuMrwo87l2d7i2oShi8m2Q58H7h3t4TWtqATZalJYFwfL9DulRe02f3KdqM9xmMCw3v/7Ll+EiaWg==
"@babel/helpers@^7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.4.tgz#2f00608aa10d460bde0ccf665d6dcf8477357cf0"
integrity sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==
dependencies:
"@babel/template" "^7.4.4"
"@babel/traverse" "^7.5.0"
@ -268,6 +268,14 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-decorators" "^7.2.0"
"@babel/plugin-proposal-dynamic-import@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506"
integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-proposal-json-strings@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317"
@ -276,10 +284,10 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz#1ef173fcf24b3e2df92a678f027673b55e7e3005"
integrity sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==
"@babel/plugin-proposal-object-rest-spread@^7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz#250de35d867ce8260a31b1fdac6c4fc1baa99331"
integrity sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
@ -357,10 +365,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-async-to-generator@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz#a3f1d01f2f21cadab20b33a82133116f14fb5894"
integrity sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==
"@babel/plugin-transform-async-to-generator@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e"
integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
@ -402,10 +410,10 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-destructuring@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz#9d964717829cc9e4b601fc82a26a71a4d8faf20f"
integrity sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==
"@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==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
@ -418,10 +426,10 @@
"@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4"
"@babel/plugin-transform-duplicate-keys@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz#d952c4930f312a4dbfff18f0b2914e60c35530b3"
integrity sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==
"@babel/plugin-transform-duplicate-keys@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853"
integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
@ -462,30 +470,33 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-transform-modules-amd@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz#82a9bce45b95441f617a24011dc89d12da7f4ee6"
integrity sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==
"@babel/plugin-transform-modules-amd@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91"
integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg==
dependencies:
"@babel/helper-module-transforms" "^7.1.0"
"@babel/helper-plugin-utils" "^7.0.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-commonjs@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e"
integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==
"@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==
dependencies:
"@babel/helper-module-transforms" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/helper-simple-access" "^7.1.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-systemjs@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz#dc83c5665b07d6c2a7b224c00ac63659ea36a405"
integrity sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==
"@babel/plugin-transform-modules-systemjs@^7.5.0":
version "7.5.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249"
integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg==
dependencies:
"@babel/helper-hoist-variables" "^7.4.4"
"@babel/helper-plugin-utils" "^7.0.0"
babel-plugin-dynamic-import-node "^2.3.0"
"@babel/plugin-transform-modules-umd@^7.2.0":
version "7.2.0"
@ -603,39 +614,41 @@
"@babel/helper-regex" "^7.4.4"
regexpu-core "^4.5.4"
"@babel/preset-env@^7.4.5", "@babel/preset-env@~7.4.5":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.4.5.tgz#2fad7f62983d5af563b5f3139242755884998a58"
integrity sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==
"@babel/preset-env@^7.4.5", "@babel/preset-env@~7.5.4":
version "7.5.4"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.4.tgz#64bc15041a3cbb0798930319917e70fcca57713d"
integrity sha512-hFnFnouyRNiH1rL8YkX1ANCNAUVC8Djwdqfev8i1415tnAG+7hlA5zhZ0Q/3Q5gkop4HioIPbCEWAalqcbxRoQ==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-proposal-async-generator-functions" "^7.2.0"
"@babel/plugin-proposal-dynamic-import" "^7.5.0"
"@babel/plugin-proposal-json-strings" "^7.2.0"
"@babel/plugin-proposal-object-rest-spread" "^7.4.4"
"@babel/plugin-proposal-object-rest-spread" "^7.5.4"
"@babel/plugin-proposal-optional-catch-binding" "^7.2.0"
"@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
"@babel/plugin-syntax-async-generators" "^7.2.0"
"@babel/plugin-syntax-dynamic-import" "^7.2.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.2.0"
"@babel/plugin-transform-arrow-functions" "^7.2.0"
"@babel/plugin-transform-async-to-generator" "^7.4.4"
"@babel/plugin-transform-async-to-generator" "^7.5.0"
"@babel/plugin-transform-block-scoped-functions" "^7.2.0"
"@babel/plugin-transform-block-scoping" "^7.4.4"
"@babel/plugin-transform-classes" "^7.4.4"
"@babel/plugin-transform-computed-properties" "^7.2.0"
"@babel/plugin-transform-destructuring" "^7.4.4"
"@babel/plugin-transform-destructuring" "^7.5.0"
"@babel/plugin-transform-dotall-regex" "^7.4.4"
"@babel/plugin-transform-duplicate-keys" "^7.2.0"
"@babel/plugin-transform-duplicate-keys" "^7.5.0"
"@babel/plugin-transform-exponentiation-operator" "^7.2.0"
"@babel/plugin-transform-for-of" "^7.4.4"
"@babel/plugin-transform-function-name" "^7.4.4"
"@babel/plugin-transform-literals" "^7.2.0"
"@babel/plugin-transform-member-expression-literals" "^7.2.0"
"@babel/plugin-transform-modules-amd" "^7.2.0"
"@babel/plugin-transform-modules-commonjs" "^7.4.4"
"@babel/plugin-transform-modules-systemjs" "^7.4.4"
"@babel/plugin-transform-modules-amd" "^7.5.0"
"@babel/plugin-transform-modules-commonjs" "^7.5.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-new-target" "^7.4.4"
@ -650,7 +663,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.4.4"
"@babel/types" "^7.5.0"
browserslist "^4.6.0"
core-js-compat "^3.1.1"
invariant "^2.2.2"
@ -2352,6 +2365,13 @@ babel-messages@^6.23.0:
dependencies:
babel-runtime "^6.22.0"
babel-plugin-dynamic-import-node@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f"
integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==
dependencies:
object.assign "^4.1.0"
babel-plugin-istanbul@^5.1.0:
version "5.1.4"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.4.tgz#841d16b9a58eeb407a0ddce622ba02fe87a752ba"
@ -7710,7 +7730,7 @@ object-hash@^1.1.4:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
object-keys@^1.0.12:
object-keys@^1.0.11, object-keys@^1.0.12:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@ -7727,6 +7747,16 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
object.assign@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
dependencies:
define-properties "^1.1.2"
function-bind "^1.1.1"
has-symbols "^1.0.0"
object-keys "^1.0.11"
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"

View File

@ -1837,10 +1837,10 @@ cypress-plugin-retries@^1.2.2:
resolved "https://registry.yarnpkg.com/cypress-plugin-retries/-/cypress-plugin-retries-1.2.2.tgz#7235371ca575ad9e16f883169e7f1588379f80f2"
integrity sha512-+bVAqJAIwpFQbgM1mAdTgCXXhowEK0pF5DqhId2h0Wq+HQ+QQ2w3hspisVUPTY+HGvncMkddUQQGF5fATuaTvQ==
cypress@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.3.2.tgz#105d9283c747884d534b88a8e6c857d977887024"
integrity sha512-d2gFX0KBBdNfMMZ/ud9ouNqjDtMM3Tf5Z50hkl8Ldb8T+jKc7RLFo/4FjMu9i28T2x+50Sx8sN/kLzxr2oeWNg==
cypress@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.4.0.tgz#8053ee107eb6309f26abd57e882d05578bdc3391"
integrity sha512-vUE+sK3l23fhs5qTN3dKpveyP0fGr37VmK3FSYaTEjbqC/qh4DbA1Ych/3bLStUpHP4rpE5KAx7i1s/tpdD9vQ==
dependencies:
"@cypress/listr-verbose-renderer" "0.4.1"
"@cypress/xvfb" "1.2.4"
@ -1868,7 +1868,7 @@ cypress@^3.3.2:
moment "2.24.0"
ramda "0.24.1"
request "2.88.0"
request-progress "0.4.0"
request-progress "3.0.0"
supports-color "5.5.0"
tmp "0.1.0"
url "0.11.0"
@ -3596,11 +3596,6 @@ no-case@^2.2.0:
dependencies:
lower-case "^1.1.1"
node-eta@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/node-eta/-/node-eta-0.1.1.tgz#4066109b39371c761c72b7ebda9a9ea0a5de121f"
integrity sha1-QGYQmzk3HHYccrfr2pqeoKXeEh8=
node-fetch@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5"
@ -4208,13 +4203,12 @@ repeating@^2.0.0:
dependencies:
is-finite "^1.0.0"
request-progress@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.4.0.tgz#c1954e39086aa85269c5660bcee0142a6a70d7e7"
integrity sha1-wZVOOQhqqFJpxWYLzuAUKmpw1+c=
request-progress@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe"
integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=
dependencies:
node-eta "^0.1.1"
throttleit "^0.0.2"
throttleit "^1.0.0"
request@2.88.0:
version "2.88.0"
@ -4763,10 +4757,10 @@ thenify-all@^1.0.0:
dependencies:
any-promise "^1.0.0"
throttleit@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf"
integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8=
throttleit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=
through2@^2.0.0:
version "2.0.5"