diff --git a/frontend/src/components/Inputs/InputPasswordConfirmation.vue b/frontend/src/components/Inputs/InputPasswordConfirmation.vue index 19d4ab02e..d0dc81156 100644 --- a/frontend/src/components/Inputs/InputPasswordConfirmation.vue +++ b/frontend/src/components/Inputs/InputPasswordConfirmation.vue @@ -9,6 +9,7 @@ containsUppercaseCharacter: true, containsNumericCharacter: true, atLeastEightCharactera: true, + atLeastOneSpecialCharater: true, }" :label="register ? $t('form.password') : $t('form.password_new')" :showAllErrors="true" diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 5db1c0a82..c7a0946f5 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -168,6 +168,7 @@ "lowercase": "Ein Kleinbuchstabe erforderlich.", "minimum": "Mindestens 8 Zeichen.", "one_number": "Eine Zahl erforderlich.", + "special-char": "Ein Sonderzeichen erforderlich (z.B. _ oder ä)", "subtitle": "Werde Teil der Gemeinschaft!", "title": "Erstelle dein Gradido-Konto", "uppercase": "Ein Großbuchstabe erforderlich." diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 9ca544440..b3148fe3f 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -168,6 +168,7 @@ "lowercase": "One lowercase letter required.", "minimum": "8 characters minimum.", "one_number": "One number required.", + "special-char": "One special character required (e.g. _ or ä)", "subtitle": "Become a part of the community!", "title": "Create your Gradido account", "uppercase": "One uppercase letter required." diff --git a/frontend/src/validation-rules.js b/frontend/src/validation-rules.js index da4e07b78..e836de56b 100644 --- a/frontend/src/validation-rules.js +++ b/frontend/src/validation-rules.js @@ -112,6 +112,13 @@ export const loadAllRules = (i18nCallback) => { message: (_, values) => i18nCallback.t('site.signup.minimum', values), }) + extend('atLeastOneSpecialCharater', { + validate(value) { + return !!value.match(/[^a-zA-Z0-9 \t\n]/) + }, + message: (_, values) => i18nCallback.t('site.signup.special-char', values), + }) + extend('samePassword', { validate(value, [pwd]) { return value === pwd diff --git a/frontend/src/views/Pages/Register.spec.js b/frontend/src/views/Pages/Register.spec.js index a0de965d5..2529b118d 100644 --- a/frontend/src/views/Pages/Register.spec.js +++ b/frontend/src/views/Pages/Register.spec.js @@ -131,8 +131,8 @@ describe('Register', () => { wrapper.find('#registerFirstname').setValue('Max') wrapper.find('#registerLastname').setValue('Mustermann') wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net') - wrapper.find('input[name="form.password"]').setValue('Aa123456') - wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456') + wrapper.find('input[name="form.password"]').setValue('Aa123456_') + wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456_') wrapper.find('.language-switch-select').findAll('option').at(1).setSelected() wrapper.find('input[name="site.signup.agree"]').setChecked(true) }) @@ -185,8 +185,8 @@ describe('Register', () => { wrapper.find('#registerFirstname').setValue('Max') wrapper.find('#registerLastname').setValue('Mustermann') wrapper.find('#Email-input-field').setValue('max.mustermann@gradido.net') - wrapper.find('input[name="form.password"]').setValue('Aa123456') - wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456') + wrapper.find('input[name="form.password"]').setValue('Aa123456_') + wrapper.find('input[name="form.passwordRepeat"]').setValue('Aa123456_') wrapper.find('.language-switch-select').findAll('option').at(1).setSelected() }) @@ -233,7 +233,7 @@ describe('Register', () => { email: 'max.mustermann@gradido.net', firstName: 'Max', lastName: 'Mustermann', - password: 'Aa123456', + password: 'Aa123456_', language: 'de', }, }), diff --git a/frontend/src/views/Pages/ResetPassword.spec.js b/frontend/src/views/Pages/ResetPassword.spec.js index 9f3830a55..a28051502 100644 --- a/frontend/src/views/Pages/ResetPassword.spec.js +++ b/frontend/src/views/Pages/ResetPassword.spec.js @@ -138,8 +138,8 @@ describe('ResetPassword', () => { beforeEach(async () => { await wrapper.setData({ authenticated: true, sessionId: 1 }) await wrapper.vm.$nextTick() - await wrapper.findAll('input').at(0).setValue('Aa123456') - await wrapper.findAll('input').at(1).setValue('Aa123456') + await wrapper.findAll('input').at(0).setValue('Aa123456_') + await wrapper.findAll('input').at(1).setValue('Aa123456_') await flushPromises() await wrapper.find('form').trigger('submit') }) @@ -167,7 +167,7 @@ describe('ResetPassword', () => { variables: { sessionId: 1, email: 'user@example.org', - password: 'Aa123456', + password: 'Aa123456_', }, }), ) diff --git a/frontend/src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js b/frontend/src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js index fa4aceb0c..7e9703c02 100644 --- a/frontend/src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js +++ b/frontend/src/views/Pages/UserProfile/UserCard_FormUserPasswort.spec.js @@ -105,12 +105,13 @@ describe('UserCard_FormUserPasswort', () => { describe('validation', () => { it('displays all password requirements', () => { const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') - expect(feedbackArray).toHaveLength(5) + expect(feedbackArray).toHaveLength(6) expect(feedbackArray.at(0).text()).toBe('validations.messages.required') expect(feedbackArray.at(1).text()).toBe('site.signup.lowercase') expect(feedbackArray.at(2).text()).toBe('site.signup.uppercase') expect(feedbackArray.at(3).text()).toBe('site.signup.one_number') expect(feedbackArray.at(4).text()).toBe('site.signup.minimum') + expect(feedbackArray.at(5).text()).toBe('site.signup.special-char') }) it('removes first message when a character is given', async () => { @@ -125,7 +126,7 @@ describe('UserCard_FormUserPasswort', () => { await wrapper.findAll('input').at(1).setValue('a') await flushPromises() const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') - expect(feedbackArray).toHaveLength(3) + expect(feedbackArray).toHaveLength(4) expect(feedbackArray.at(0).text()).toBe('site.signup.uppercase') }) @@ -133,7 +134,7 @@ describe('UserCard_FormUserPasswort', () => { await wrapper.findAll('input').at(1).setValue('Aa') await flushPromises() const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') - expect(feedbackArray).toHaveLength(2) + expect(feedbackArray).toHaveLength(3) expect(feedbackArray.at(0).text()).toBe('site.signup.one_number') }) @@ -141,14 +142,22 @@ describe('UserCard_FormUserPasswort', () => { await wrapper.findAll('input').at(1).setValue('Aa1') await flushPromises() const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') - expect(feedbackArray).toHaveLength(1) + expect(feedbackArray).toHaveLength(2) expect(feedbackArray.at(0).text()).toBe('site.signup.minimum') }) - it('removes all messages when all rules are fulfilled', async () => { + it('removes the first five messages when a eight lowercase, uppercase and numeric characters are given', async () => { await wrapper.findAll('input').at(1).setValue('Aa123456') await flushPromises() const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') + expect(feedbackArray).toHaveLength(1) + expect(feedbackArray.at(0).text()).toBe('site.signup.special-char') + }) + + it('removes all messages when a eight lowercase, uppercase and numeric characters are given', async () => { + await wrapper.findAll('input').at(1).setValue('Aa123456_') + await flushPromises() + const feedbackArray = wrapper.findAll('div.invalid-feedback').at(1).findAll('span') expect(feedbackArray).toHaveLength(0) }) }) @@ -164,8 +173,8 @@ describe('UserCard_FormUserPasswort', () => { }, }) await form.findAll('input').at(0).setValue('1234') - await form.findAll('input').at(1).setValue('Aa123456') - await form.findAll('input').at(2).setValue('Aa123456') + await form.findAll('input').at(1).setValue('Aa123456_') + await form.findAll('input').at(2).setValue('Aa123456_') await form.trigger('submit') await flushPromises() }) @@ -176,7 +185,7 @@ describe('UserCard_FormUserPasswort', () => { variables: { email: 'user@example.org', password: '1234', - passwordNew: 'Aa123456', + passwordNew: 'Aa123456_', }, }), ) @@ -197,8 +206,8 @@ describe('UserCard_FormUserPasswort', () => { message: 'error', }) await form.findAll('input').at(0).setValue('1234') - await form.findAll('input').at(1).setValue('Aa123456') - await form.findAll('input').at(2).setValue('Aa123456') + await form.findAll('input').at(1).setValue('Aa123456_') + await form.findAll('input').at(2).setValue('Aa123456_') await form.trigger('submit') await flushPromises() })