From f7710be95cf99b66a44f01d2608bc408e6ad605e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Mar 2021 13:54:47 +0100 Subject: [PATCH 1/4] Remove mutation 'SignupByInvitation' --- .../src/middleware/email/emailMiddleware.js | 1 - .../src/middleware/permissionsMiddleware.js | 1 - .../src/schema/types/type/EmailAddress.gql | 1 - .../Registration/RegistrationSlideEmail.vue | 31 ++++++------------- .../Registration/RegistrationSlider.story.js | 5 +-- webapp/components/Registration/Signup.spec.js | 25 +-------------- webapp/components/Registration/Signup.vue | 17 ++-------- webapp/locales/de.json | 1 - webapp/locales/en.json | 1 - webapp/locales/es.json | 1 - webapp/locales/fr.json | 1 - webapp/locales/it.json | 1 - webapp/locales/pt.json | 1 - webapp/locales/ru.json | 1 - 14 files changed, 14 insertions(+), 74 deletions(-) diff --git a/backend/src/middleware/email/emailMiddleware.js b/backend/src/middleware/email/emailMiddleware.js index 1143e3d0f..ea69dcd95 100644 --- a/backend/src/middleware/email/emailMiddleware.js +++ b/backend/src/middleware/email/emailMiddleware.js @@ -71,6 +71,5 @@ export default { AddEmailAddress: sendEmailVerificationMail, requestPasswordReset: sendPasswordResetMail, Signup: sendSignupMail, - SignupByInvitation: sendSignupMail, }, } diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index c64699ac3..1bca3bb26 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -128,7 +128,6 @@ export default shield( Mutation: { '*': deny, login: allow, - SignupByInvitation: allow, Signup: or(publicRegistration, isAdmin), SignupVerification: allow, UpdateUser: onlyYourself, diff --git a/backend/src/schema/types/type/EmailAddress.gql b/backend/src/schema/types/type/EmailAddress.gql index 509a7ae28..06eb964c3 100644 --- a/backend/src/schema/types/type/EmailAddress.gql +++ b/backend/src/schema/types/type/EmailAddress.gql @@ -10,7 +10,6 @@ type Query { type Mutation { Signup(email: String!): EmailAddress - SignupByInvitation(email: String!, token: String!): EmailAddress SignupVerification( nonce: String! email: String! diff --git a/webapp/components/Registration/RegistrationSlideEmail.vue b/webapp/components/Registration/RegistrationSlideEmail.vue index 35e80bf4c..b82edcaeb 100644 --- a/webapp/components/Registration/RegistrationSlideEmail.vue +++ b/webapp/components/Registration/RegistrationSlideEmail.vue @@ -13,10 +13,10 @@ : $t('components.registration.signup.title', metadata) }} --> - + /> --> {{ invitation @@ -75,13 +75,6 @@ export const SignupMutation = gql` } } ` -export const SignupByInvitationMutation = gql` - mutation($email: String!, $token: String!) { - SignupByInvitation(email: $email, token: $token) { - email - } - } -` export default { name: 'RegistrationSlideEmail', components: { @@ -89,8 +82,8 @@ export default { }, props: { sliderData: { type: Object, required: true }, - token: { type: String, default: null }, // Wolle not used??? - invitation: { type: Boolean, default: false }, + // token: { type: String, default: null }, // Wolle not used??? + invitation: { type: Boolean, default: false }, // Wolle ??? }, data() { return { @@ -185,15 +178,11 @@ export default { this.sliderData.sliders[this.sliderIndex].data.request && this.sliderData.sliders[this.sliderIndex].data.request.variables && this.sliderData.sliders[this.sliderIndex].data.request.variables.email === variables.email - // Wolle && - // this.sliderData.sliders[this.sliderIndex].data.request.variables.token === variables.code ) }, async onNextClick() { - const mutation = this.token ? SignupByInvitationMutation : SignupMutation - const { token } = this const { email } = this.formData - const variables = { email, token } + const variables = { email } if (!this.sendEmailAgain && this.sliderData.collectedInputData.emailSend) { return true @@ -201,7 +190,7 @@ export default { if (this.sendEmailAgain || !this.isVariablesRequested(variables)) { try { - const response = await this.$apollo.mutate({ mutation, variables }) // e-mail is send in emailMiddleware of backend + const response = await this.$apollo.mutate({ SignupMutation, variables }) // e-mail is send in emailMiddleware of backend this.sliderData.setSliderValuesCallback( this.sliderData.sliders[this.sliderIndex].validated, { sliderData: { request: { variables }, response: response.data } }, @@ -213,9 +202,9 @@ export default { }) this.setButtonValues() - const { email: respnseEmail } = - this.sliderData.sliders[this.sliderIndex].data.response.Signup || - this.sliderData.sliders[this.sliderIndex].data.response.SignupByInvitation + const { email: respnseEmail } = this.sliderData.sliders[ + this.sliderIndex + ].data.response.Signup this.$toast.success( this.$t('components.registration.email.form.success', { email: respnseEmail }), ) @@ -234,7 +223,7 @@ export default { const { message } = err const mapping = { 'A user account with this email already exists': 'email-exists', - 'Invitation code already used or does not exist': 'invalid-invitation-token', + // Wolle 'Invitation code already used or does not exist': 'invalid-invitation-token', } for (const [pattern, key] of Object.entries(mapping)) { if (message.includes(pattern)) diff --git a/webapp/components/Registration/RegistrationSlider.story.js b/webapp/components/Registration/RegistrationSlider.story.js index a8d145ef2..607325dbe 100644 --- a/webapp/components/Registration/RegistrationSlider.story.js +++ b/webapp/components/Registration/RegistrationSlider.story.js @@ -14,11 +14,8 @@ const plugins = [ if (JSON.stringify(data).includes('Signup')) { return { data: { Signup: { email: data.variables.email } } } } - if (JSON.stringify(data).includes('SignupByInvitation')) { - return { data: { SignupByInvitation: { email: data.variables.email } } } - } if (JSON.stringify(data).includes('SignupVerification')) { - return { data: { SignupByInvitation: { ...data.variables } } } + return { data: { SignupVerification: { ...data.variables } } } } throw new Error(`Mutation name not found!`) }, diff --git a/webapp/components/Registration/Signup.spec.js b/webapp/components/Registration/Signup.spec.js index b8970b1dc..23934be23 100644 --- a/webapp/components/Registration/Signup.spec.js +++ b/webapp/components/Registration/Signup.spec.js @@ -1,5 +1,5 @@ import { config, mount } from '@vue/test-utils' -import Signup, { SignupMutation, SignupByInvitationMutation } from './Signup' +import Signup, { SignupMutation } from './Signup' const localVue = global.localVue @@ -98,12 +98,6 @@ describe('Signup', () => { }) 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({ @@ -128,23 +122,6 @@ describe('Signup', () => { ) }) }) - - 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( - 'components.registration.signup.form.errors.invalid-invitation-token', - ) - }) - }) }) }) }) diff --git a/webapp/components/Registration/Signup.vue b/webapp/components/Registration/Signup.vue index 0a8bed612..64173a115 100644 --- a/webapp/components/Registration/Signup.vue +++ b/webapp/components/Registration/Signup.vue @@ -14,9 +14,6 @@ : $t('components.registration.signup.title', metadata) }} - - - {{ @@ -78,20 +75,12 @@ export const SignupMutation = gql` } } ` -export const SignupByInvitationMutation = gql` - mutation($email: String!, $token: String!) { - SignupByInvitation(email: $email, token: $token) { - email - } - } -` export default { name: 'Signup', components: { SweetalertIcon, }, props: { - token: { type: String, default: null }, invitation: { type: Boolean, default: false }, }, data() { @@ -126,12 +115,10 @@ export default { this.disabled = false }, async handleSubmit() { - const mutation = this.token ? SignupByInvitationMutation : SignupMutation - const { token } = this const { email } = this.formData try { - const response = await this.$apollo.mutate({ mutation, variables: { email, token } }) + const response = await this.$apollo.mutate({ SignupMutation, variables: { email } }) this.data = response.data setTimeout(() => { this.$emit('submit', { email: this.data.Signup.email }) @@ -140,7 +127,7 @@ export default { const { message } = err const mapping = { 'A user account with this email already exists': 'email-exists', - 'Invitation code already used or does not exist': 'invalid-invitation-token', + // Wolle 'Invitation code already used or does not exist': 'invalid-invitation-token', } for (const [pattern, key] of Object.entries(mapping)) { if (message.includes(pattern)) diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 0165ce558..766e720ba 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -183,7 +183,6 @@ "description": "Um loszulegen, kannst Du Dich hier kostenfrei registrieren:", "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." }, "invitation-code": "Dein Einladungscode lautet: {code}", "minimum-age": "Ich bin 18 Jahre oder älter.", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 4fd7c2934..42ab15d22 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -183,7 +183,6 @@ "description": "To get started, you can register here for free:", "errors": { "email-exists": "There is already a user account with this e-mail address!", - "invalid-invitation-token": "It looks like as if the invitation has been used already. Invitation links can only be used once." }, "invitation-code": "Your invitation code is: {code}", "minimum-age": "I'm 18 years or older.", diff --git a/webapp/locales/es.json b/webapp/locales/es.json index 659fd1995..d921064df 100644 --- a/webapp/locales/es.json +++ b/webapp/locales/es.json @@ -154,7 +154,6 @@ "description": "Para empezar, introduzca su dirección de correo electrónico:", "errors": { "email-exists": "¡Ya hay una cuenta de usuario con esta dirección de correo electrónico!", - "invalid-invitation-token": "Parece que el código de invitación ya ha sido canjeado. Cada código sólo se puede utilizar una vez." }, "invitation-code": "Su código de invitación es: {code}", "minimum-age": "Tengo 18 años o más.", diff --git a/webapp/locales/fr.json b/webapp/locales/fr.json index d43007cf7..3ff42aadc 100644 --- a/webapp/locales/fr.json +++ b/webapp/locales/fr.json @@ -154,7 +154,6 @@ "description": "Pour commencer, entrez votre adresse mail :", "errors": { "email-exists": "Il existe déjà un compte utilisateur avec cette adresse mail!", - "invalid-invitation-token": "On dirait que l'invitation a déjà été utilisée. Les liens d'invitation ne peuvent être utilisés qu'une seule fois." }, "invitation-code": "Votre code d'invitation est: {code} ", "minimum-age": "J'ai 18 ans ou plus.", diff --git a/webapp/locales/it.json b/webapp/locales/it.json index 982f6f871..7135cd71c 100644 --- a/webapp/locales/it.json +++ b/webapp/locales/it.json @@ -161,7 +161,6 @@ "description": null, "errors": { "email-exists": null, - "invalid-invitation-token": "Sembra che l'invito sia già stato utilizzato. I link di invito possono essere utilizzati una sola volta." }, "invitation-code": null, "minimum-age": null, diff --git a/webapp/locales/pt.json b/webapp/locales/pt.json index 6afddc3bb..0dfc6e72c 100644 --- a/webapp/locales/pt.json +++ b/webapp/locales/pt.json @@ -201,7 +201,6 @@ "description": "Para começar, digite seu endereço de e-mail:", "errors": { "email-exists": "Já existe uma conta de usuário com este endereço de e-mail!", - "invalid-invitation-token": "Parece que o convite já foi usado. Os links para convites só podem ser usados uma vez." }, "invitation-code": "O seu código de convite é: {code}", "minimum-age": "Tenho 18 anos ou mais.", diff --git a/webapp/locales/ru.json b/webapp/locales/ru.json index fe2e35969..637ca2184 100644 --- a/webapp/locales/ru.json +++ b/webapp/locales/ru.json @@ -154,7 +154,6 @@ "description": "Для начала работы введите свой адрес электронной почты:", "errors": { "email-exists": "Уже есть учетная запись пользователя с этим адресом электронной почты!", - "invalid-invitation-token": "Похоже, что приглашение уже было использовано. Ссылку из приглашения можно использовать только один раз." }, "invitation-code": "Код приглашения: {code}", "minimum-age": "Мне 18 лет или более", From a9fc72b1bd7614c6fd7f08fc0a204395557935bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Mar 2021 14:53:53 +0100 Subject: [PATCH 2/4] Comment for adding 'nonce' in case --- webapp/components/Registration/RegistrationSlideCreate.vue | 2 +- webapp/components/Registration/RegistrationSlideEmail.vue | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/components/Registration/RegistrationSlideCreate.vue b/webapp/components/Registration/RegistrationSlideCreate.vue index 532bf0bc1..908b5d953 100644 --- a/webapp/components/Registration/RegistrationSlideCreate.vue +++ b/webapp/components/Registration/RegistrationSlideCreate.vue @@ -285,7 +285,7 @@ export default { const locale = this.$i18n.locale() try { await this.$apollo.mutate({ - mutation: SignupVerificationMutation, + mutation: SignupVerificationMutation, // Wolle add nonce in 'SignupVerificationMutation' definition in case variables: { name, password, diff --git a/webapp/components/Registration/RegistrationSlideEmail.vue b/webapp/components/Registration/RegistrationSlideEmail.vue index b82edcaeb..b5306602c 100644 --- a/webapp/components/Registration/RegistrationSlideEmail.vue +++ b/webapp/components/Registration/RegistrationSlideEmail.vue @@ -68,6 +68,7 @@ import { isEmail } from 'validator' import normalizeEmail from '~/components/utils/NormalizeEmail' // Wolle import { SweetalertIcon } from 'vue-sweetalert-icons' +// Wolle add nonce in in case export const SignupMutation = gql` mutation($email: String!) { Signup(email: $email) { @@ -182,7 +183,7 @@ export default { }, async onNextClick() { const { email } = this.formData - const variables = { email } + const variables = { email } // Wolle add nonce in case if (!this.sendEmailAgain && this.sliderData.collectedInputData.emailSend) { return true From 8a2f80e619cc5a2db33f86e5cd2d256820e3dff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Mar 2021 15:01:53 +0100 Subject: [PATCH 3/4] Fix locales json --- webapp/locales/de.json | 2 +- webapp/locales/en.json | 2 +- webapp/locales/es.json | 2 +- webapp/locales/fr.json | 2 +- webapp/locales/it.json | 2 +- webapp/locales/pt.json | 2 +- webapp/locales/ru.json | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 766e720ba..1078e17ad 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -182,7 +182,7 @@ "data-privacy": "Ich habe die Datenschutzerklärung gelesen und verstanden.", "description": "Um loszulegen, kannst Du Dich hier kostenfrei registrieren:", "errors": { - "email-exists": "Es gibt schon ein Benutzerkonto mit dieser E-Mail-Adresse!", + "email-exists": "Es gibt schon ein Benutzerkonto mit dieser E-Mail-Adresse!" }, "invitation-code": "Dein Einladungscode lautet: {code}", "minimum-age": "Ich bin 18 Jahre oder älter.", diff --git a/webapp/locales/en.json b/webapp/locales/en.json index 42ab15d22..27b7bf73f 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -182,7 +182,7 @@ "data-privacy": "I have read and understood the privacy statement.", "description": "To get started, you can register here for free:", "errors": { - "email-exists": "There is already a user account with this e-mail address!", + "email-exists": "There is already a user account with this e-mail address!" }, "invitation-code": "Your invitation code is: {code}", "minimum-age": "I'm 18 years or older.", diff --git a/webapp/locales/es.json b/webapp/locales/es.json index d921064df..3cc53af5e 100644 --- a/webapp/locales/es.json +++ b/webapp/locales/es.json @@ -153,7 +153,7 @@ "data-privacy": "He leido y entendido la declaración de protección de datos.", "description": "Para empezar, introduzca su dirección de correo electrónico:", "errors": { - "email-exists": "¡Ya hay una cuenta de usuario con esta dirección de correo electrónico!", + "email-exists": "¡Ya hay una cuenta de usuario con esta dirección de correo electrónico!" }, "invitation-code": "Su código de invitación es: {code}", "minimum-age": "Tengo 18 años o más.", diff --git a/webapp/locales/fr.json b/webapp/locales/fr.json index 3ff42aadc..c5467f459 100644 --- a/webapp/locales/fr.json +++ b/webapp/locales/fr.json @@ -153,7 +153,7 @@ "data-privacy": "J'ai lu et compris la Déclaration de confidentialité.", "description": "Pour commencer, entrez votre adresse mail :", "errors": { - "email-exists": "Il existe déjà un compte utilisateur avec cette adresse mail!", + "email-exists": "Il existe déjà un compte utilisateur avec cette adresse mail!" }, "invitation-code": "Votre code d'invitation est: {code} ", "minimum-age": "J'ai 18 ans ou plus.", diff --git a/webapp/locales/it.json b/webapp/locales/it.json index 7135cd71c..cdff1c3ec 100644 --- a/webapp/locales/it.json +++ b/webapp/locales/it.json @@ -160,7 +160,7 @@ "data-privacy": null, "description": null, "errors": { - "email-exists": null, + "email-exists": null }, "invitation-code": null, "minimum-age": null, diff --git a/webapp/locales/pt.json b/webapp/locales/pt.json index 0dfc6e72c..790197c9d 100644 --- a/webapp/locales/pt.json +++ b/webapp/locales/pt.json @@ -200,7 +200,7 @@ "data-privacy": "Eu li e entendi o Política de Privacidade.", "description": "Para começar, digite seu endereço de e-mail:", "errors": { - "email-exists": "Já existe uma conta de usuário com este endereço de e-mail!", + "email-exists": "Já existe uma conta de usuário com este endereço de e-mail!" }, "invitation-code": "O seu código de convite é: {code}", "minimum-age": "Tenho 18 anos ou mais.", diff --git a/webapp/locales/ru.json b/webapp/locales/ru.json index 637ca2184..f97fff9b8 100644 --- a/webapp/locales/ru.json +++ b/webapp/locales/ru.json @@ -153,7 +153,7 @@ "data-privacy": "Я прочитал и понял Заявление о конфиденциальности", "description": "Для начала работы введите свой адрес электронной почты:", "errors": { - "email-exists": "Уже есть учетная запись пользователя с этим адресом электронной почты!", + "email-exists": "Уже есть учетная запись пользователя с этим адресом электронной почты!" }, "invitation-code": "Код приглашения: {code}", "minimum-age": "Мне 18 лет или более", From db9ef6a83250d10d4baa2443131163ed6ad5fc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Mar 2021 16:10:20 +0100 Subject: [PATCH 4/4] Fix env 'PUBLIC_REGISTRATION' and invent env 'INVITE_REGISTRATION' in backend and frontend --- backend/.env.template | 1 + backend/src/config/index.js | 1 + .../ComponentSlider/ComponentSlider.vue | 7 +++-- webapp/config/index.js | 2 ++ webapp/pages/registration.vue | 28 +++++++++++-------- webapp/pages/registration/signup.vue | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/backend/.env.template b/backend/.env.template index fc9766478..2d2374698 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -17,6 +17,7 @@ PRIVATE_KEY_PASSPHRASE="a7dsf78sadg87ad87sfagsadg78" SENTRY_DSN_BACKEND= COMMIT= PUBLIC_REGISTRATION=false +INVITE_REGISTRATION=true AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= diff --git a/backend/src/config/index.js b/backend/src/config/index.js index 47771029b..14b539799 100644 --- a/backend/src/config/index.js +++ b/backend/src/config/index.js @@ -83,6 +83,7 @@ const options = { APPLICATION_NAME: metadata.APPLICATION_NAME, ORGANIZATION_URL: links.ORGANIZATION, PUBLIC_REGISTRATION: env.PUBLIC_REGISTRATION === 'true', + INVITE_REGISTRATION: env.INVITE_REGISTRATION === 'true', } // Check if all required configs are present diff --git a/webapp/components/ComponentSlider/ComponentSlider.vue b/webapp/components/ComponentSlider/ComponentSlider.vue index 483c46dbf..177d40bd3 100644 --- a/webapp/components/ComponentSlider/ComponentSlider.vue +++ b/webapp/components/ComponentSlider/ComponentSlider.vue @@ -9,7 +9,7 @@ - +
1 + }, }, methods: { async onNextClick() { diff --git a/webapp/config/index.js b/webapp/config/index.js index fd564f350..678239729 100644 --- a/webapp/config/index.js +++ b/webapp/config/index.js @@ -29,6 +29,8 @@ const sentry = { const options = { VERSION: process.env.VERSION || pkg.version, DESCRIPTION: process.env.DESCRIPTION || pkg.description, + PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION === 'true', + INVITE_REGISTRATION: process.env.INVITE_REGISTRATION === 'true', // Cookies COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 730, // Two years by default COOKIE_HTTPS_ONLY: process.env.COOKIE_HTTPS_ONLY || process.env.NODE_ENV === 'production', // ensure true in production if not set explicitly diff --git a/webapp/pages/registration.vue b/webapp/pages/registration.vue index 216d4aa4d..4863f05df 100644 --- a/webapp/pages/registration.vue +++ b/webapp/pages/registration.vue @@ -1,12 +1,16 @@