diff --git a/backend/src/constants/registration.js b/backend/src/constants/registration.js
new file mode 100644
index 000000000..9e63e478e
--- /dev/null
+++ b/backend/src/constants/registration.js
@@ -0,0 +1,5 @@
+// this file is duplicated in `backend/src/config/metadata.js` and `webapp/constants/metadata.js`
+export default {
+ NONCE_LENGTH: 5,
+ INVITE_CODE_LENGTH: 6,
+}
diff --git a/backend/src/db/seed.js b/backend/src/db/seed.js
index 786ad6fc8..7bfd4f159 100644
--- a/backend/src/db/seed.js
+++ b/backend/src/db/seed.js
@@ -537,7 +537,7 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
await Factory.build(
'inviteCode',
{
- code: 'AAAAAA',
+ code: 'ABCDEF',
},
{
generatedBy: jennyRostock,
diff --git a/backend/src/middleware/helpers/email/templateBuilder.js b/backend/src/middleware/helpers/email/templateBuilder.js
index 12624f5ac..bf174ef48 100644
--- a/backend/src/middleware/helpers/email/templateBuilder.js
+++ b/backend/src/middleware/helpers/email/templateBuilder.js
@@ -19,9 +19,9 @@ const defaultParams = {
}
const englishHint = 'English version below!'
-export const signupTemplate = ({ email, nonce, inviteCode = null }) => {
+export const signupTemplate = ({ email, variables: { nonce, inviteCode = null } }) => {
const subject = `Willkommen, Bienvenue, Welcome to ${CONFIG.APPLICATION_NAME}!`
- // dev format example: http://localhost:3000/registration?method=invite-mail&email=wolle.huss%40pjannto.com&nonce=64853
+ // dev format example: http://localhost:3000/registration?method=invite-mail&email=huss%40pjannto.com&nonce=64853
const actionUrl = new URL('/registration', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('email', email)
actionUrl.searchParams.set('nonce', nonce)
@@ -31,72 +31,60 @@ export const signupTemplate = ({ email, nonce, inviteCode = null }) => {
} else {
actionUrl.searchParams.set('method', 'invite-mail')
}
+ const renderParams = { ...defaultParams, englishHint, actionUrl, nonce, subject }
return {
from,
to: email,
subject,
- html: mustache.render(
- templates.layout,
- { ...defaultParams, englishHint, actionUrl, nonce, subject },
- { content: templates.signup },
- ),
+ html: mustache.render(templates.layout, renderParams, { content: templates.signup }),
}
}
-export const emailVerificationTemplate = ({ email, nonce, name }) => {
+export const emailVerificationTemplate = ({ email, variables: { nonce, name } }) => {
const subject = 'Neue E-Mail Adresse | New E-Mail Address'
const actionUrl = new URL('/settings/my-email-address/verify', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('email', email)
actionUrl.searchParams.set('nonce', nonce)
+ const renderParams = { ...defaultParams, englishHint, actionUrl, name, nonce, subject }
return {
from,
to: email,
subject,
- html: mustache.render(
- templates.layout,
- { ...defaultParams, englishHint, actionUrl, name, nonce, subject },
- { content: templates.emailVerification },
- ),
+ html: mustache.render(templates.layout, renderParams, { content: templates.emailVerification }),
}
}
-export const resetPasswordTemplate = ({ email, nonce, name }) => {
+export const resetPasswordTemplate = ({ email, variables: { nonce, name } }) => {
const subject = 'Neues Passwort | Reset Password'
const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI)
actionUrl.searchParams.set('nonce', nonce)
actionUrl.searchParams.set('email', email)
+ const renderParams = { ...defaultParams, englishHint, actionUrl, name, nonce, subject }
return {
from,
to: email,
subject,
- html: mustache.render(
- templates.layout,
- { ...defaultParams, englishHint, actionUrl, name, nonce, subject },
- { content: templates.passwordReset },
- ),
+ html: mustache.render(templates.layout, renderParams, { content: templates.passwordReset }),
}
}
-export const wrongAccountTemplate = ({ email }) => {
+export const wrongAccountTemplate = ({ email, _variables = {} }) => {
const subject = 'Falsche Mailadresse? | Wrong E-mail?'
const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI)
+ const renderParams = { ...defaultParams, englishHint, actionUrl }
return {
from,
to: email,
subject,
- html: mustache.render(
- templates.layout,
- { ...defaultParams, englishHint, actionUrl },
- { content: templates.wrongAccount },
- ),
+ html: mustache.render(templates.layout, renderParams, { content: templates.wrongAccount }),
}
}
-export const notificationTemplate = ({ email, notification }) => {
+export const notificationTemplate = ({ email, variables: { notification } }) => {
const actionUrl = new URL('/notifications', CONFIG.CLIENT_URI)
const settingsUrl = new URL('/settings/notifications', CONFIG.CLIENT_URI)
const renderParams = { ...defaultParams, name: notification.to.name, settingsUrl, actionUrl }
diff --git a/backend/src/middleware/helpers/email/templateBuilder.spec.js b/backend/src/middleware/helpers/email/templateBuilder.spec.js
new file mode 100644
index 000000000..7b4310483
--- /dev/null
+++ b/backend/src/middleware/helpers/email/templateBuilder.spec.js
@@ -0,0 +1,246 @@
+import CONFIG from '../../../config'
+import logosWebapp from '../../../config/logos.js'
+import {
+ signupTemplate,
+ emailVerificationTemplate,
+ resetPasswordTemplate,
+ wrongAccountTemplate,
+ notificationTemplate,
+} from './templateBuilder'
+
+const englishHint = 'English version below!'
+const welcomeImageUrl = new URL(logosWebapp.LOGO_WELCOME_PATH, CONFIG.CLIENT_URI)
+const supportUrl = CONFIG.SUPPORT_URL.toString()
+let actionUrl, name, settingsUrl
+
+const signupTemplateData = () => ({
+ email: 'test@example.org',
+ variables: {
+ nonce: '12345',
+ inviteCode: 'AAAAAA',
+ },
+})
+const emailVerificationTemplateData = () => ({
+ email: 'test@example.org',
+ variables: {
+ nonce: '12345',
+ name: 'Mr Example',
+ },
+})
+const resetPasswordTemplateData = () => ({
+ email: 'test@example.org',
+ variables: {
+ nonce: '12345',
+ name: 'Mr Example',
+ },
+})
+const wrongAccountTemplateData = () => ({
+ email: 'test@example.org',
+ variables: {},
+})
+const notificationTemplateData = (locale) => ({
+ email: 'test@example.org',
+ variables: {
+ notification: {
+ to: { name: 'Mr Example', locale },
+ },
+ },
+})
+const textsStandard = [
+ {
+ templPropName: 'from',
+ isContaining: false,
+ text: CONFIG.EMAIL_DEFAULT_SENDER,
+ },
+ {
+ templPropName: 'to',
+ isContaining: false,
+ text: 'test@example.org',
+ },
+ // is contained in html
+ welcomeImageUrl.toString(),
+ CONFIG.ORGANIZATION_URL,
+ CONFIG.APPLICATION_NAME,
+]
+const testEmailData = (emailTemplate, templateBuilder, templateData, texts) => {
+ if (!emailTemplate) {
+ emailTemplate = templateBuilder(templateData)
+ }
+ texts.forEach((element) => {
+ if (typeof element === 'object') {
+ if (element.isContaining) {
+ expect(emailTemplate[element.templPropName]).toEqual(expect.stringContaining(element.text))
+ } else {
+ expect(emailTemplate[element.templPropName]).toEqual(element.text)
+ }
+ } else {
+ expect(emailTemplate.html).toEqual(expect.stringContaining(element))
+ }
+ })
+ return emailTemplate
+}
+
+// beforeAll(async () => {
+// await cleanDatabase()
+// })
+
+// afterAll(async () => {
+// await cleanDatabase()
+// })
+
+describe('templateBuilder', () => {
+ describe('signupTemplate', () => {
+ describe('multi language', () => {
+ it('e-mail is build with all data', () => {
+ const subject = `Willkommen, Bienvenue, Welcome to ${CONFIG.APPLICATION_NAME}!`
+ const actionUrl = new URL('/registration', CONFIG.CLIENT_URI).toString()
+ const theSignupTemplateData = signupTemplateData()
+ const enContent = "Thank you for joining our cause – it's awesome to have you on board."
+ const deContent =
+ 'Danke, dass Du dich angemeldet hast – wir freuen uns, Dich dabei zu haben.'
+ testEmailData(null, signupTemplate, theSignupTemplateData, [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ englishHint,
+ actionUrl,
+ theSignupTemplateData.variables.nonce,
+ theSignupTemplateData.variables.inviteCode,
+ enContent,
+ deContent,
+ supportUrl,
+ ])
+ })
+ })
+ })
+
+ describe('emailVerificationTemplate', () => {
+ describe('multi language', () => {
+ it('e-mail is build with all data', () => {
+ const subject = 'Neue E-Mail Adresse | New E-Mail Address'
+ const actionUrl = new URL('/settings/my-email-address/verify', CONFIG.CLIENT_URI).toString()
+ const theEmailVerificationTemplateData = emailVerificationTemplateData()
+ const enContent = 'So, you want to change your e-mail? No problem!'
+ const deContent = 'Du möchtest also deine E-Mail ändern? Kein Problem!'
+ testEmailData(null, emailVerificationTemplate, theEmailVerificationTemplateData, [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ englishHint,
+ actionUrl,
+ theEmailVerificationTemplateData.variables.nonce,
+ theEmailVerificationTemplateData.variables.name,
+ enContent,
+ deContent,
+ supportUrl,
+ ])
+ })
+ })
+ })
+
+ describe('resetPasswordTemplate', () => {
+ describe('multi language', () => {
+ it('e-mail is build with all data', () => {
+ const subject = 'Neues Passwort | Reset Password'
+ const actionUrl = new URL('/password-reset/change-password', CONFIG.CLIENT_URI).toString()
+ const theResetPasswordTemplateData = resetPasswordTemplateData()
+ const enContent = 'So, you forgot your password? No problem!'
+ const deContent = 'Du hast also dein Passwort vergessen? Kein Problem!'
+ testEmailData(null, resetPasswordTemplate, theResetPasswordTemplateData, [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ englishHint,
+ actionUrl,
+ theResetPasswordTemplateData.variables.nonce,
+ theResetPasswordTemplateData.variables.name,
+ enContent,
+ deContent,
+ supportUrl,
+ ])
+ })
+ })
+ })
+
+ describe('wrongAccountTemplate', () => {
+ describe('multi language', () => {
+ it('e-mail is build with all data', () => {
+ const subject = 'Falsche Mailadresse? | Wrong E-mail?'
+ const actionUrl = new URL('/password-reset/request', CONFIG.CLIENT_URI).toString()
+ const theWrongAccountTemplateData = wrongAccountTemplateData()
+ const enContent =
+ "You requested a password reset but unfortunately we couldn't find an account associated with your e-mail address."
+ const deContent =
+ 'Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen Account mit Deiner E-Mailadresse gefunden.'
+ testEmailData(null, wrongAccountTemplate, theWrongAccountTemplateData, [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ englishHint,
+ actionUrl,
+ enContent,
+ deContent,
+ supportUrl,
+ ])
+ })
+ })
+ })
+
+ describe('notificationTemplate', () => {
+ beforeEach(() => {
+ actionUrl = new URL('/notifications', CONFIG.CLIENT_URI).toString()
+ name = notificationTemplateData('en').variables.notification.to.name
+ settingsUrl = new URL('/settings/notifications', CONFIG.CLIENT_URI)
+ })
+
+ describe('en', () => {
+ it('e-mail is build with all data', () => {
+ const subject = `${CONFIG.APPLICATION_NAME} – Notification`
+ const content = 'You received at least one notification. Click on this button to view them:'
+ testEmailData(null, notificationTemplate, notificationTemplateData('en'), [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ actionUrl,
+ name,
+ content,
+ settingsUrl,
+ ])
+ })
+ })
+
+ describe('de', () => {
+ it('e-mail is build with all data', async () => {
+ const subject = `${CONFIG.APPLICATION_NAME} – Benachrichtigung`
+ const content = `Du hast mindestens eine Benachrichtigung erhalten. Klick auf diesen Button, um sie anzusehen:`
+ testEmailData(null, notificationTemplate, notificationTemplateData('de'), [
+ ...textsStandard,
+ {
+ templPropName: 'subject',
+ isContaining: false,
+ text: subject,
+ },
+ actionUrl,
+ name,
+ content,
+ settingsUrl,
+ ])
+ })
+ })
+ })
+})
diff --git a/backend/src/middleware/helpers/email/templates/de/notification.html b/backend/src/middleware/helpers/email/templates/de/notification.html
index d935424be..a54943310 100644
--- a/backend/src/middleware/helpers/email/templates/de/notification.html
+++ b/backend/src/middleware/helpers/email/templates/de/notification.html
@@ -25,8 +25,7 @@
Hallo {{ name }},
- Du hast mindestens eine Benachrichtigung erhalten. Klick auf diesen Button,
- um sie anzusehen:
+ Du hast mindestens eine Benachrichtigung erhalten. Klick auf diesen Button, um sie anzusehen:
diff --git a/backend/src/middleware/helpers/email/templates/wrongAccount.html b/backend/src/middleware/helpers/email/templates/wrongAccount.html
index 8f17e3335..e8f71e9ea 100644
--- a/backend/src/middleware/helpers/email/templates/wrongAccount.html
+++ b/backend/src/middleware/helpers/email/templates/wrongAccount.html
@@ -24,8 +24,8 @@
Hallo!
- Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen
- Account mit Deiner E-Mailadresse gefunden. Kann es sein, dass Du mit einer anderen Adresse bei uns
+
Du hast bei uns ein neues Passwort angefordert – leider haben wir aber keinen Account mit Deiner E-Mailadresse gefunden.
+ Kann es sein, dass Du mit einer anderen Adresse bei uns
angemeldet bist?
@@ -122,8 +122,8 @@
Hello!
- You requested a password reset but unfortunately we couldn't find an account
- associated with your e-mail address. Did you maybe use another one when you signed up?
+ You requested a password reset but unfortunately we couldn't find an account associated with your e-mail address.
+ Did you maybe use another one when you signed up?
diff --git a/backend/src/middleware/login/loginMiddleware.js b/backend/src/middleware/login/loginMiddleware.js
index b7fe0239a..3cd2158c2 100644
--- a/backend/src/middleware/login/loginMiddleware.js
+++ b/backend/src/middleware/login/loginMiddleware.js
@@ -11,9 +11,9 @@ const sendSignupMail = async (resolve, root, args, context, resolveInfo) => {
const response = await resolve(root, args, context, resolveInfo)
const { email, nonce } = response
if (inviteCode) {
- await sendMail(signupTemplate({ email, nonce, inviteCode }))
+ await sendMail(signupTemplate({ email, variables: { nonce, inviteCode } }))
} else {
- await sendMail(signupTemplate({ email, nonce }))
+ await sendMail(signupTemplate({ email, variables: { nonce } }))
}
delete response.nonce
return response
@@ -23,14 +23,14 @@ const sendPasswordResetMail = async (resolve, root, args, context, resolveInfo)
const { email } = args
const { email: userFound, nonce, name } = await resolve(root, args, context, resolveInfo)
const template = userFound ? resetPasswordTemplate : wrongAccountTemplate
- await sendMail(template({ email, nonce, name }))
+ await sendMail(template({ email, variables: { nonce, name } }))
return true
}
const sendEmailVerificationMail = async (resolve, root, args, context, resolveInfo) => {
const response = await resolve(root, args, context, resolveInfo)
const { email, nonce, name } = response
- await sendMail(emailVerificationTemplate({ email, nonce, name }))
+ await sendMail(emailVerificationTemplate({ email, variables: { nonce, name } }))
delete response.nonce
return response
}
diff --git a/backend/src/middleware/notifications/notificationsMiddleware.js b/backend/src/middleware/notifications/notificationsMiddleware.js
index 5419771ea..a871605f7 100644
--- a/backend/src/middleware/notifications/notificationsMiddleware.js
+++ b/backend/src/middleware/notifications/notificationsMiddleware.js
@@ -44,7 +44,7 @@ const publishNotifications = async (context, promises) => {
sendMail(
notificationTemplate({
email: notificationsEmailAddresses[index].email,
- notification: notificationAdded,
+ variables: { notification: notificationAdded },
}),
)
}
diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.js
index 80e3dc05c..e29e0a4af 100644
--- a/backend/src/middleware/permissionsMiddleware.spec.js
+++ b/backend/src/middleware/permissionsMiddleware.spec.js
@@ -182,12 +182,12 @@ describe('authorization', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
- inviteCode: 'AAAAAA',
+ inviteCode: 'ABCDEF',
}
CONFIG.INVITE_REGISTRATION = false
CONFIG.PUBLIC_REGISTRATION = false
await Factory.build('inviteCode', {
- code: 'AAAAAA',
+ code: 'ABCDEF',
})
})
@@ -224,12 +224,12 @@ describe('authorization', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
- inviteCode: 'AAAAAA',
+ inviteCode: 'ABCDEF',
}
CONFIG.INVITE_REGISTRATION = false
CONFIG.PUBLIC_REGISTRATION = true
await Factory.build('inviteCode', {
- code: 'AAAAAA',
+ code: 'ABCDEF',
})
})
@@ -254,7 +254,7 @@ describe('authorization', () => {
CONFIG.INVITE_REGISTRATION = true
CONFIG.PUBLIC_REGISTRATION = false
await Factory.build('inviteCode', {
- code: 'AAAAAA',
+ code: 'ABCDEF',
})
})
@@ -262,7 +262,7 @@ describe('authorization', () => {
beforeEach(async () => {
variables = {
email: 'some@email.org',
- inviteCode: 'AAAAAA',
+ inviteCode: 'ABCDEF',
}
authenticatedUser = null
})
diff --git a/backend/src/middleware/slugifyMiddleware.spec.js b/backend/src/middleware/slugifyMiddleware.spec.js
index 9f1969c0c..7c6f18ab1 100644
--- a/backend/src/middleware/slugifyMiddleware.spec.js
+++ b/backend/src/middleware/slugifyMiddleware.spec.js
@@ -195,7 +195,7 @@ describe('slugifyMiddleware', () => {
variables = {
...variables,
name: 'I am a user',
- nonce: '123456',
+ nonce: '12345',
password: 'yo',
email: '123@example.org',
termsAndConditionsAgreedVersion: '0.0.1',
@@ -206,7 +206,7 @@ describe('slugifyMiddleware', () => {
beforeEach(async () => {
await Factory.build('emailAddress', {
email: '123@example.org',
- nonce: '123456',
+ nonce: '12345',
verifiedAt: null,
})
})
diff --git a/backend/src/schema/resolvers/emails.spec.js b/backend/src/schema/resolvers/emails.spec.js
index 60f5ae899..39b70ac0b 100644
--- a/backend/src/schema/resolvers/emails.spec.js
+++ b/backend/src/schema/resolvers/emails.spec.js
@@ -158,7 +158,7 @@ describe('VerifyEmailAddress', () => {
`
beforeEach(() => {
- variables = { ...variables, email: 'to-be-verified@example.org', nonce: '123456' }
+ variables = { ...variables, email: 'to-be-verified@example.org', nonce: '12345' }
})
describe('unauthenticated', () => {
diff --git a/backend/src/schema/resolvers/helpers/generateInviteCode.js b/backend/src/schema/resolvers/helpers/generateInviteCode.js
index 70e122d26..99c752eb0 100644
--- a/backend/src/schema/resolvers/helpers/generateInviteCode.js
+++ b/backend/src/schema/resolvers/helpers/generateInviteCode.js
@@ -1,8 +1,13 @@
+import CONSTANTS_REGISTRATION from './../../../constants/registration'
+
export default function generateInviteCode() {
// 6 random numbers in [ 0, 35 ] are 36 possible numbers (10 [0-9] + 26 [A-Z])
- return Array.from({ length: 6 }, (n = Math.floor(Math.random() * 36)) => {
- // n > 9: it is a letter (ASCII 65 is A) -> 10 + 55 = 65
- // else: it is a number (ASCII 48 is 0) -> 0 + 48 = 48
- return String.fromCharCode(n > 9 ? n + 55 : n + 48)
- }).join('')
+ return Array.from(
+ { length: CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH },
+ (n = Math.floor(Math.random() * 36)) => {
+ // n > 9: it is a letter (ASCII 65 is A) -> 10 + 55 = 65
+ // else: it is a number (ASCII 48 is 0) -> 0 + 48 = 48
+ return String.fromCharCode(n > 9 ? n + 55 : n + 48)
+ },
+ ).join('')
}
diff --git a/backend/src/schema/resolvers/helpers/generateNonce.js b/backend/src/schema/resolvers/helpers/generateNonce.js
index 6da40b5c2..50aa8489e 100644
--- a/backend/src/schema/resolvers/helpers/generateNonce.js
+++ b/backend/src/schema/resolvers/helpers/generateNonce.js
@@ -1,5 +1,11 @@
+import CONSTANTS_REGISTRATION from './../../../constants/registration'
+
+// TODO: why this is not used in resolver 'requestPasswordReset'?
export default function generateNonce() {
- return Array.from({ length: 5 }, (n = Math.floor(Math.random() * 10)) => {
- return String.fromCharCode(n + 48)
- }).join('')
+ return Array.from(
+ { length: CONSTANTS_REGISTRATION.NONCE_LENGTH },
+ (n = Math.floor(Math.random() * 10)) => {
+ return String.fromCharCode(n + 48)
+ },
+ ).join('')
}
diff --git a/backend/src/schema/resolvers/inviteCodes.spec.js b/backend/src/schema/resolvers/inviteCodes.spec.js
index 094716871..72e2a2492 100644
--- a/backend/src/schema/resolvers/inviteCodes.spec.js
+++ b/backend/src/schema/resolvers/inviteCodes.spec.js
@@ -3,6 +3,7 @@ import { getDriver } from '../../db/neo4j'
import { gql } from '../../helpers/jest'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
+import CONSTANTS_REGISTRATION from './../../constants/registration'
let user
let query
@@ -107,7 +108,11 @@ describe('inviteCodes', () => {
errors: undefined,
data: {
GenerateInviteCode: {
- code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
+ code: expect.stringMatching(
+ new RegExp(
+ `^[0-9A-Z]{${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH},${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH}}$`,
+ ),
+ ),
expiresAt: null,
createdAt: expect.any(String),
},
@@ -129,7 +134,11 @@ describe('inviteCodes', () => {
errors: undefined,
data: {
GenerateInviteCode: {
- code: expect.stringMatching(/^[0-9A-Z]{6,6}$/),
+ code: expect.stringMatching(
+ new RegExp(
+ `^[0-9A-Z]{${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH},${CONSTANTS_REGISTRATION.INVITE_CODE_LENGTH}}$`,
+ ),
+ ),
expiresAt: nextWeek.toISOString(),
createdAt: expect.any(String),
},
diff --git a/backend/src/schema/resolvers/passwordReset.js b/backend/src/schema/resolvers/passwordReset.js
index d1f49876b..6fea020dd 100644
--- a/backend/src/schema/resolvers/passwordReset.js
+++ b/backend/src/schema/resolvers/passwordReset.js
@@ -1,11 +1,13 @@
import { v4 as uuid } from 'uuid'
import bcrypt from 'bcryptjs'
+import CONSTANTS_REGISTRATION from './../../constants/registration'
import createPasswordReset from './helpers/createPasswordReset'
export default {
Mutation: {
requestPasswordReset: async (_parent, { email }, { driver }) => {
- const nonce = uuid().substring(0, 6)
+ // TODO: why this is generated differntly from 'backend/src/schema/resolvers/helpers/generateNonce.js'?
+ const nonce = uuid().substring(0, CONSTANTS_REGISTRATION.NONCE_LENGTH)
return createPasswordReset({ driver, nonce, email })
},
resetPassword: async (_parent, { email, nonce, newPassword }, { driver }) => {
diff --git a/backend/src/schema/resolvers/passwordReset.spec.js b/backend/src/schema/resolvers/passwordReset.spec.js
index 0a66a7a64..bc2a48bc8 100644
--- a/backend/src/schema/resolvers/passwordReset.spec.js
+++ b/backend/src/schema/resolvers/passwordReset.spec.js
@@ -1,6 +1,7 @@
import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import { getNeode, getDriver } from '../../db/neo4j'
+import CONSTANTS_REGISTRATION from './../../constants/registration'
import createPasswordReset from './helpers/createPasswordReset'
import createServer from '../../server'
import { createTestClient } from 'apollo-server-testing'
@@ -109,7 +110,7 @@ describe('passwordReset', () => {
const resets = await getAllPasswordResets()
const [reset] = resets
const { nonce } = reset.properties
- expect(nonce).toHaveLength(6)
+ expect(nonce).toHaveLength(CONSTANTS_REGISTRATION.NONCE_LENGTH)
})
})
})
@@ -118,7 +119,7 @@ describe('passwordReset', () => {
describe('resetPassword', () => {
const setup = async (options = {}) => {
- const { email = 'user@example.org', issuedAt = new Date(), nonce = 'abcdef' } = options
+ const { email = 'user@example.org', issuedAt = new Date(), nonce = '12345' } = options
await createPasswordReset({ driver, email, issuedAt, nonce })
}
@@ -148,7 +149,7 @@ describe('resetPassword', () => {
describe('invalid email', () => {
it('resolves to false', async () => {
await setup()
- variables = { ...variables, email: 'non-existent@example.org', nonce: 'abcdef' }
+ variables = { ...variables, email: 'non-existent@example.org', nonce: '12345' }
await expect(mutate({ mutation, variables })).resolves.toMatchObject({
data: { resetPassword: false },
})
@@ -162,7 +163,7 @@ describe('resetPassword', () => {
describe('but invalid nonce', () => {
beforeEach(() => {
- variables = { ...variables, nonce: 'slkdjf' }
+ variables = { ...variables, nonce: 'slkdj' }
})
it('resolves to false', async () => {
@@ -177,7 +178,7 @@ describe('resetPassword', () => {
beforeEach(() => {
variables = {
...variables,
- nonce: 'abcdef',
+ nonce: '12345',
}
})
diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js
index 753639118..573af1d35 100644
--- a/backend/src/schema/resolvers/registration.spec.js
+++ b/backend/src/schema/resolvers/registration.spec.js
@@ -179,7 +179,7 @@ describe('SignupVerification', () => {
beforeEach(async () => {
variables = {
...variables,
- nonce: '123456',
+ nonce: '12345',
name: 'John Doe',
password: '123',
email: 'john@example.org',
@@ -207,7 +207,7 @@ describe('SignupVerification', () => {
describe('sending a valid nonce', () => {
beforeEach(() => {
- variables = { ...variables, nonce: '123456' }
+ variables = { ...variables, nonce: '12345' }
})
it('rejects', async () => {
@@ -222,7 +222,7 @@ describe('SignupVerification', () => {
beforeEach(async () => {
const args = {
email: 'john@example.org',
- nonce: '123456',
+ nonce: '12345',
}
await neode.model('EmailAddress').create(args)
})
diff --git a/webapp/components/PasswordReset/ChangePassword.spec.js b/webapp/components/PasswordReset/ChangePassword.spec.js
index d6f451604..cef110798 100644
--- a/webapp/components/PasswordReset/ChangePassword.spec.js
+++ b/webapp/components/PasswordReset/ChangePassword.spec.js
@@ -40,7 +40,7 @@ describe('ChangePassword ', () => {
describe('given email and nonce', () => {
beforeEach(() => {
propsData.email = 'mail@example.org'
- propsData.nonce = '123456'
+ propsData.nonce = '12345'
})
describe('submitting new password', () => {
@@ -57,7 +57,7 @@ describe('ChangePassword ', () => {
it('delivers new password to backend', () => {
const expected = expect.objectContaining({
- variables: { nonce: '123456', email: 'mail@example.org', password: 'supersecret' },
+ variables: { nonce: '12345', email: 'mail@example.org', password: 'supersecret' },
})
expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected)
})
diff --git a/webapp/components/Registration/RegistrationSlideInvite.vue b/webapp/components/Registration/RegistrationSlideInvite.vue
index 5a3aee777..f9ce15ee9 100644
--- a/webapp/components/Registration/RegistrationSlideInvite.vue
+++ b/webapp/components/Registration/RegistrationSlideInvite.vue
@@ -22,6 +22,7 @@