Merge branch 'master' into 1923-Allow-Admin-to-CRUD-Contribution-Links

This commit is contained in:
Alexander Friedland 2022-06-02 07:19:59 +02:00 committed by GitHub
commit 85a4d8c22d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 199 additions and 369 deletions

View File

@ -4,7 +4,7 @@
"main": "index.js",
"author": "Moriz Wahl",
"version": "1.8.3",
"license": "Apache License 2.0",
"license": "Apache-2.0",
"private": false,
"scripts": {
"start": "node run/server.js",

View File

@ -5,7 +5,7 @@
"main": "src/index.ts",
"repository": "https://github.com/gradido/gradido/backend",
"author": "Ulf Gebhardt",
"license": "Apache License 2.0",
"license": "Apache-2.0",
"private": false,
"scripts": {
"build": "tsc --build",

View File

@ -5,7 +5,7 @@
"main": "src/index.ts",
"repository": "https://github.com/gradido/gradido/database",
"author": "Ulf Gebhardt",
"license": "Apache License 2.0",
"license": "Apache-2.0",
"private": false,
"scripts": {
"build": "mkdir -p build/src/config/ && cp src/config/*.txt build/src/config/ && tsc --build",

View File

@ -45,7 +45,6 @@ module.exports = {
extensions: ['.js', '.vue'],
// TODO: remove ignores
ignores: [
'/site.thx./',
'/form./',
'/time./',
'/decay.types./',
@ -55,7 +54,6 @@ module.exports = {
'settings.password.set',
'settings.password.set-password.text',
'settings.password.subtitle',
'site.login.signin',
],
enableFix: false,
},

View File

@ -99,6 +99,6 @@
"not ie <= 10"
],
"author": "Gradido-Akademie - https://www.gradido.net/",
"license": "Apache License 2.0",
"license": "Apache-2.0",
"description": "Gradido, the Natural Economy of Life, is a way to worldwide prosperity and peace in harmony with nature. - Gradido, die Natürliche Ökonomie des lebens, ist ein Weg zu weltweitem Wohlstand und Frieden in Harmonie mit der Natur."
}

View File

@ -15,6 +15,14 @@ body {
color: #0e79bc !important;
}
.text-gradido {
color: rgb(249 205 105 / 100%);
}
.gradient-gradido {
background-image: linear-gradient(146deg, rgb(220 167 44) 50%, rgb(197 141 56 / 100%) 100%);
}
/* Navbar */
a,
.navbar-light,
@ -32,14 +40,6 @@ a:hover,
color: rgb(35 121 188 / 90%);
}
.text-gradido {
color: rgb(249 205 105 / 100%);
}
.gradient-gradido {
background-image: linear-gradient(146deg, rgb(220 167 44) 50%, rgb(197 141 56 / 100%) 100%);
}
/* Button */
.btn {
border-radius: 25px;

View File

@ -19,13 +19,13 @@
<div class="text-center ml-3 ml-lg-0 text-lg-right pt-1">
{{ $t('followUs') }}
<b-link href="https://www.facebook.com/groups/Gradido/" target="_blank">
<b-icon-facebook class="ml-3 mr-3" font-scale="1"></b-icon-facebook>
<b-icon-facebook class="ml-3 mr-3 c-grey" font-scale="1"></b-icon-facebook>
</b-link>
<b-link href="https://twitter.com/gradido" target="_blank">
<b-icon-twitter class="mr-3" font-scale="1"></b-icon-twitter>
<b-icon-twitter class="mr-3 c-grey" font-scale="1"></b-icon-twitter>
</b-link>
<b-link href="https://www.youtube.com/c/GradidoNet" target="_blank">
<b-icon-youtube class="mr-3" font-scale="1"></b-icon-youtube>
<b-icon-youtube class="mr-3 c-grey" font-scale="1"></b-icon-youtube>
</b-link>
<b-link href="https://t.me/Gradido" target="_blank">
@ -34,7 +34,7 @@
width="16"
height="16"
fill="currentColor"
class="bi bi-telegram"
class="bi bi-telegram c-grey"
viewBox="0 0 16 16"
>
<path

View File

@ -124,4 +124,10 @@ export default {
min-width: 360px;
}
}
@media screen and (max-height: 700px) {
.mobil-start-box #img3 {
top: -104px;
}
}
</style>

View File

@ -4,8 +4,8 @@ import Message from './Message'
const localVue = global.localVue
const propsData = {
headline: 'site.thx.title',
subtitle: 'site.thx.email',
headline: 'Headline text',
subtitle: 'Subtitle text',
buttonText: 'login',
linkTo: '/login',
}
@ -32,8 +32,8 @@ describe('Message', () => {
describe('with button', () => {
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('Headline text')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Subtitle text')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
@ -51,8 +51,8 @@ describe('Message', () => {
})
it('renders title, subtitle, and button text', () => {
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('Headline text')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Subtitle text')
})
it('button is not shown', () => {

View File

@ -189,7 +189,7 @@ describe('UserCard_FormUserPasswort', () => {
})
it('toasts a success message', () => {
expect(toastSuccessSpy).toBeCalledWith('site.thx.reset')
expect(toastSuccessSpy).toBeCalledWith('message.reset')
})
it('cancels the edit process', () => {

View File

@ -89,7 +89,7 @@ export default {
},
})
.then(() => {
this.toastSuccess(this.$t('site.thx.reset'))
this.toastSuccess(this.$t('message.reset'))
this.cancelEdit()
})
.catch((error) => {

View File

@ -16,7 +16,11 @@
<div class="h0 text-white">{{ $t('auth.left.gratitude') }}</div>
<div class="h1 text-white">{{ $t('auth.left.newCurrency') }}</div>
<div class="h2 text-white">{{ $t('auth.left.oneAnotherNature') }}</div>
<b-button variant="gradido">{{ $t('auth.left.learnMore') }}</b-button>
<b-link :href="`https://gradido.net/${$i18n.locale}`" target="_blank">
<b-button variant="gradido">
{{ $t('auth.left.learnMore') }}
</b-button>
</b-link>
</div>
</div>
<b-row class="justify-content-md-center">

View File

@ -172,6 +172,16 @@
"minus": "",
"pipe": "|"
},
"message": {
"activateEmail": "Dein Konto wurde noch nicht aktiviert. Bitte überprüfe deine E-Mail und klicke den Aktivierungslink oder fordere einen neuen Aktivierungslink über die Password Reset Seite an.",
"checkEmail": "Deine E-Mail wurde erfolgreich verifiziert. Du kannst dich jetzt anmelden.",
"email": "Wir haben dir eine E-Mail gesendet.",
"errorTitle": "Achtung!",
"register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.",
"title": "Danke!",
"unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu."
},
"navigation": {
"admin_area": "Adminbereich",
"logout": "Abmelden",
@ -224,8 +234,7 @@
"heading": "Bitte gib deine E-Mail an mit der du bei Gradido angemeldet bist."
},
"login": {
"heading": "Melde dich mit deinen Zugangsdaten an. Bewahre sie stets sicher auf!",
"saveLogin": "Anmeldung speichern"
"heading": "Melde dich mit deinen Zugangsdaten an. Bewahre sie stets sicher auf!"
},
"resetPassword": {
"heading": "Trage bitte dein Passwort ein und wiederhole es."
@ -240,18 +249,6 @@
"one_number": "Zahl erforderlich.",
"special-char": "Sonderzeichen erforderlich (z.B. _ oder ä)",
"uppercase": "Großbuchstabe erforderlich."
},
"thx": {
"activateEmail": "Dein Konto wurde noch nicht aktiviert. Bitte überprüfe deine E-Mail und klicke den Aktivierungslink oder fordere einen neuen Aktivierungslink über die Password Reset Seite.",
"checkEmail": "Deine E-Mail wurde erfolgreich verifiziert. Du kannst dich jetzt anmelden.",
"email": "Wir haben dir eine E-Mail gesendet.",
"emailActivated": "Danke dass Du deine E-Mail bestätigt hast.",
"errorTitle": "Achtung!",
"register": "Du bist jetzt registriert, bitte überprüfe deine Emails und klicke auf den Aktivierungslink.",
"reset": "Dein Passwort wurde geändert.",
"resetPassword": "Den Code den Du genutzt hast ist zu alt bitte fordere ein neuen über die Passwort Reset Seite an.",
"title": "Danke!",
"unsetPassword": "Dein Passwort wurde noch nicht gesetzt. Bitte setze es neu."
}
},
"success": "Erfolg",

View File

@ -11,7 +11,7 @@
"hereLogin": "Log in here",
"learnMore": "Learn more …",
"newCurrency": "The new currency",
"oneAnotherNature": "FOR ONE ANOTHER, FOR ALL, FOR NATURE"
"oneAnotherNature": "FOR EACH OTHER, FOR ALL, FOR NATURE"
},
"navbar": {
"aboutGradido": "About Gradido"
@ -172,6 +172,16 @@
"minus": "",
"pipe": "|"
},
"message": {
"activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.",
"checkEmail": "Your email has been successfully verified. You can sign in now.",
"email": "We have sent you an email.",
"errorTitle": "Attention!",
"register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.",
"title": "Thank you!",
"unsetPassword": "Your password has not been set yet. Please set it again."
},
"navigation": {
"admin_area": "Admin Area",
"logout": "Logout",
@ -224,8 +234,7 @@
"heading": "Please enter the email address by which you're registered here."
},
"login": {
"heading": "Log in with your access data. Keep them safe!",
"saveLogin": "Save login"
"heading": "Log in with your access data. Keep them safe!"
},
"resetPassword": {
"heading": "Please enter your password and repeat it."
@ -240,18 +249,6 @@
"one_number": "One number required.",
"special-char": "One special character required (e.g. _ or ä)",
"uppercase": "One uppercase letter required."
},
"thx": {
"activateEmail": "Your account has not been activated yet. Please check your emails and click the activation link or order a new activation link over the password reset page.",
"checkEmail": "Your email has been successfully verified. You can sign in now.",
"email": "We have sent you an email.",
"emailActivated": "Thank you your email has been activated.",
"errorTitle": "Attention!",
"register": "You are registered now, please check your emails and click the activation link.",
"reset": "Your password has been changed.",
"resetPassword": "The code you used was to old please order a new on over the password reset page.",
"title": "Thank you!",
"unsetPassword": "Your password has not been set yet. Please set it again."
}
},
"success": "Success",

View File

@ -50,16 +50,6 @@ describe('ForgotPassword', () => {
expect(wrapper.find('div.forgot-password').exists()).toBe(true)
})
describe('back button', () => {
it('has a "back" button', () => {
expect(wrapper.findComponent(RouterLinkStub).text()).toEqual('back')
})
it('links to login', () => {
expect(wrapper.findComponent(RouterLinkStub).props().to).toEqual('/login')
})
})
describe('input form', () => {
let form
@ -111,7 +101,7 @@ describe('ForgotPassword', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('error.email-already-sent')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
@ -121,6 +111,8 @@ describe('ForgotPassword', () => {
})
it.skip('click redirects to "/login"', async () => {
// wrapper.find('.test-message-button').trigger('click')
// await wrapper.vm.$nextTick()
expect(mockRouterPush).toBeCalledWith('/login')
})
@ -144,14 +136,18 @@ describe('ForgotPassword', () => {
it('shows success title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.email')
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.email')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
it('button link redirects to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it.skip('click redirects to "/login"', () => {
// expect(mockRouterPush).toBeCalledWith('/login')
})
})
})
})

View File

@ -4,30 +4,23 @@
<div class="pb-5">{{ $t('site.forgotPassword.heading') }}</div>
<b-row class="justify-content-center">
<b-col>
<b-card no-body class="border-0 gradido-custom-background">
<b-card-body class="p-4">
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
<input-email v-model="form.email"></input-email>
<div class="text-center">
<b-button type="submit" variant="primary">
{{ $t('settings.password.send_now') }}
</b-button>
</div>
</b-form>
</validation-observer>
</b-card-body>
</b-card>
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
<input-email v-model="form.email"></input-email>
<div class="text-center">
<b-button type="submit" variant="gradido">
{{ $t('settings.password.send_now') }}
</b-button>
</div>
</b-form>
</validation-observer>
</b-col>
</b-row>
<div class="text-center py-lg-4">
<router-link to="/login" class="mt-3">{{ $t('back') }}</router-link>
</div>
</b-container>
<b-container v-else>
<message
:headline="success ? $t('site.thx.title') : $t('site.thx.errorTitle')"
:subtitle="success ? $t('site.thx.email') : $t('error.email-already-sent')"
:headline="success ? $t('message.title') : $t('message.errorTitle')"
:subtitle="success ? $t('message.email') : $t('error.email-already-sent')"
:buttonText="$t('login')"
linkTo="/login"
/>

View File

@ -198,8 +198,8 @@ describe('Login', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.activateEmail')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.activateEmail')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
@ -226,8 +226,8 @@ describe('Login', () => {
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.unsetPassword')
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.unsetPassword')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})

View File

@ -16,17 +16,6 @@
</b-col>
</b-row>
<b-row>
<b-col class="d-flex justify-content-start">
<b-form-checkbox
class="mt-3"
v-model="status"
name="checkbox-1"
value="saved"
unchecked-value="not_saved"
>
{{ $t('site.login.saveLogin') }}
</b-form-checkbox>
</b-col>
<b-col class="d-flex justify-content-end">
<router-link to="/forgot-password" class="mt-3">
{{ $t('settings.password.forgot_pwd') }}
@ -41,7 +30,7 @@
</b-container>
<b-container v-else>
<message
:headline="$t('site.thx.errorTitle')"
:headline="$t('message.errorTitle')"
:subtitle="errorSubtitle"
:buttonText="$t('settings.password.reset')"
:linkTo="errorLinkTo"
@ -70,7 +59,6 @@ export default {
password: '',
},
passwordVisible: false,
status: false,
showPageMessage: false,
errorReason: null,
errorSubtitle: '',
@ -107,12 +95,12 @@ export default {
.catch((error) => {
if (error.message.includes('User email not validated')) {
this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.activateEmail')
this.errorSubtitle = this.$t('message.activateEmail')
this.errorLinkTo = '/forgot-password'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('User has no password set yet')) {
this.showPageMessage = true
this.errorSubtitle = this.$t('site.thx.unsetPassword')
this.errorSubtitle = this.$t('message.unsetPassword')
this.errorLinkTo = '/reset-password/login'
this.toastError(this.$t('error.no-account'))
} else if (error.message.includes('No user with this credentials')) {

View File

@ -202,8 +202,8 @@ describe('Register', () => {
it('shows success title, subtitle', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('site.thx.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('site.thx.register')
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.register')
})
it('button is not present', () => {

View File

@ -90,7 +90,7 @@
</validation-observer>
</b-container>
<b-container v-else>
<message :headline="$t('site.thx.title')" :subtitle="$t('site.thx.register')" />
<message :headline="$t('message.title')" :subtitle="$t('message.register')" />
</b-container>
</div>
</template>

View File

@ -118,14 +118,32 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe(
'...email was sent more than 23 hours and 10 minutes ago',
)
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/forgot-password/resetPassword"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe(
'/forgot-password/resetPassword',
)
})
it('toasts an error message', () => {
expect(toastErrorSpy).toHaveBeenCalledWith(
'...email was sent more than 23 hours and 10 minutes ago',
)
})
it('router pushes to /forgot-password/resetPassword', () => {
expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
it.skip('click redirects to "/forgot-password/resetPassword"', () => {
// wrapper.find('.test-message-button').trigger('click')
// await flushPromises()
// await wrapper.vm.$nextTick()
// expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
})
})
@ -137,9 +155,26 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('shows error title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.errorTitle')
expect(wrapper.find('.test-message-subtitle').text()).toBe('Error')
expect(wrapper.find('.test-message-button').text()).toBe('settings.password.reset')
})
it('button link directs to "/forgot-password/resetPassword"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe(
'/forgot-password/resetPassword',
)
})
it('toasts an error message', () => {
expect(toastErrorSpy).toHaveBeenCalledWith('Error')
})
it.skip('click redirects to "/forgot-password/resetPassword"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/forgot-password/resetPassword')
})
})
describe('server response with success on /checkEmail', () => {
@ -168,30 +203,19 @@ describe('ResetPassword', () => {
)
})
it('redirects to "/thx/checkEmail"', () => {
expect(routerPushMock).toHaveBeenCalledWith('/thx/checkEmail')
it('shows message title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.checkEmail')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
describe('with param code', () => {
beforeEach(async () => {
mocks.$route.params.code = 'the-most-secret-code-ever'
apolloMutationMock.mockResolvedValue({
data: {
resetPassword: 'success',
},
})
wrapper = Wrapper()
await wrapper.findAll('input').at(0).setValue('Aa123456_')
await wrapper.findAll('input').at(1).setValue('Aa123456_')
await wrapper.find('form').trigger('submit')
await flushPromises()
})
it('button link directs to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it('redirects to "/thx/checkEmail/the-most-secret-code-ever"', () => {
expect(routerPushMock).toHaveBeenCalledWith(
'/thx/checkEmail/the-most-secret-code-ever',
)
})
it.skip('click redirects to "/login"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/login')
})
})
@ -210,8 +234,19 @@ describe('ResetPassword', () => {
await flushPromises()
})
it('redirects to "/thx/resetPassword"', () => {
expect(routerPushMock).toHaveBeenCalledWith('/thx/resetPassword')
it('shows message title, subtitle, login button', () => {
expect(wrapper.vm.showPageMessage).toBe(true)
expect(wrapper.find('.test-message-headline').text()).toBe('message.title')
expect(wrapper.find('.test-message-subtitle').text()).toBe('message.reset')
expect(wrapper.find('.test-message-button').text()).toBe('login')
})
it('button link directs to "/login"', () => {
expect(wrapper.find('.test-message-button').attributes('href')).toBe('/login')
})
it.skip('click redirects to "/login"', () => {
// expect(routerPushMock).toHaveBeenCalledWith('/login')
})
})
})

View File

@ -1,5 +1,5 @@
<template>
<div class="resetpwd-form">
<div v-if="enterData" class="resetpwd-form">
<div class="pb-5">{{ $t('site.resetPassword.heading') }}</div>
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
@ -13,12 +13,21 @@
</b-form>
</validation-observer>
</div>
<div v-else>
<message
:headline="messageHeadline"
:subtitle="messageSubtitle"
:buttonText="messageButtonText"
:linkTo="messageButtonLinktTo"
/>
</div>
</template>
<script>
import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirmation'
import { setPassword } from '@/graphql/mutations'
import { queryOptIn } from '@/graphql/queries'
import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirmation'
import Message from '@/components/Message/Message'
const textFields = {
reset: {
@ -39,6 +48,7 @@ export default {
name: 'ResetPassword',
components: {
InputPasswordConfirmation,
Message,
},
data() {
return {
@ -47,8 +57,17 @@ export default {
passwordRepeat: '',
},
displaySetup: {},
showPageMessage: false,
messageHeadline: null,
messageSubtitle: null,
messageButtonText: null,
messageButtonLinktTo: null,
}
},
created() {
this.$emit('set-mobile-start', false)
this.setDisplaySetup()
},
methods: {
async onSubmit() {
this.$apollo
@ -61,24 +80,33 @@ export default {
})
.then(() => {
this.form.password = ''
if (this.$route.path.includes('checkEmail')) {
if (this.$route.params.code) {
this.$router.push('/thx/checkEmail/' + this.$route.params.code)
} else {
this.$router.push('/thx/checkEmail')
}
} else {
this.$router.push('/thx/resetPassword')
}
this.form.passwordRepeat = ''
this.showPageMessage = true
this.messageHeadline = this.$t('message.title')
this.messageSubtitle = this.$route.path.includes('checkEmail')
? this.$t('message.checkEmail')
: this.$t('message.reset')
this.messageButtonText = this.$t('login')
this.messageButtonLinktTo = '/login'
})
.catch((error) => {
this.toastError(error.message)
let errorMessage
if (
error.message.match(
/email was sent more than ([0-9]+ hours)?( and )?([0-9]+ minutes)? ago/,
)
)
this.$router.push('/forgot-password/resetPassword')
) {
errorMessage = error.message
} else {
errorMessage = error.message
}
this.showPageMessage = true
this.messageHeadline = this.$t('message.errorTitle')
this.messageSubtitle = errorMessage
this.messageButtonText = this.$t('settings.password.reset')
this.messageButtonLinktTo = '/forgot-password/resetPassword'
this.toastError(errorMessage)
})
},
checkOptInCode() {
@ -105,9 +133,10 @@ export default {
}
},
},
created() {
this.$emit('set-mobile-start', false)
this.setDisplaySetup()
computed: {
enterData() {
return !this.showPageMessage
},
},
}
</script>

View File

@ -143,6 +143,7 @@ export default {
},
created() {
this.setTransactionLinkInformation()
this.$emit('set-mobile-start', false)
},
}
</script>

View File

@ -1,101 +0,0 @@
import { mount } from '@vue/test-utils'
import Thx from './thx'
const localVue = global.localVue
const createMockObject = (comingFrom) => {
return {
$t: jest.fn((t) => t),
$route: {
params: {
comingFrom,
},
},
}
}
describe('Thx', () => {
let wrapper
const Wrapper = (mocks) => {
return mount(Thx, { localVue, mocks })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('forgotPassword'))
})
it('renders the thx page', () => {
expect(wrapper.find('div.header').exists()).toBeTruthy()
})
it('renders the title', () => {
expect(wrapper.find('p.h1').text()).toBe('site.thx.title')
})
})
describe('coming from /forgot-password', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('forgotPassword'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.email')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('login')
})
it('links the redirect button to /login', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
})
})
describe('coming from /reset-password', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('resetPassword'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.reset')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('login')
})
it('links the redirect button to /login', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/login')
})
})
describe('coming from /register', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('register'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.register')
})
})
describe('coming from /login', () => {
beforeEach(() => {
wrapper = Wrapper(createMockObject('login'))
})
it('renders the thanks text', () => {
expect(wrapper.find('p.h4').text()).toBe('site.thx.activateEmail')
})
it('renders the thanks redirect button', () => {
expect(wrapper.find('a.btn').text()).toBe('settings.password.reset')
})
it('links the redirect button to /forgot-password', () => {
expect(wrapper.find('a.btn').attributes('href')).toBe('/forgot-password')
})
})
})

View File

@ -1,76 +0,0 @@
<template>
<div>
<!-- Header -->
<div class="header py-7 py-lg-8 pt-lg-9">
<b-container>
<div class="header-body text-center mb-7">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h1">{{ $t(displaySetup.headline) }}</p>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h4">{{ $t(displaySetup.subtitle) }}</p>
<hr />
<b-button v-if="$route.params.code" :to="`/login/${$route.params.code}`">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
<b-button v-else-if="displaySetup.linkTo" :to="displaySetup.linkTo">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
</div>
</b-container>
</div>
<!-- Page content -->
</div>
</template>
<script>
const textFields = {
forgotPassword: {
headline: 'site.thx.title',
subtitle: 'site.thx.email',
button: 'login',
linkTo: '/login',
},
resetPassword: {
headline: 'site.thx.title',
subtitle: 'site.thx.reset',
button: 'login',
linkTo: '/login',
},
register: {
headline: 'site.thx.title',
subtitle: 'site.thx.register',
button: 'signin',
// linkTo: '/login',
},
checkEmail: {
headline: 'site.thx.title',
subtitle: 'site.thx.checkEmail',
button: 'login',
linkTo: '/login',
},
login: {
headline: 'site.thx.errorTitle',
subtitle: 'site.thx.activateEmail',
button: 'settings.password.reset',
linkTo: '/forgot-password',
},
}
export default {
name: 'Thx',
data() {
return {
displaySetup: {},
}
},
methods: {
setDisplaySetup(from) {
this.displaySetup = textFields[this.$route.params.comingFrom]
},
},
created() {
this.setDisplaySetup()
},
}
</script>

View File

@ -49,8 +49,8 @@ describe('router', () => {
expect(routes.find((r) => r.path === '/').redirect()).toEqual({ path: '/login' })
})
it('has seventeen routes defined', () => {
expect(routes).toHaveLength(17)
it('has sixteen routes defined', () => {
expect(routes).toHaveLength(16)
})
describe('overview', () => {
@ -111,31 +111,6 @@ describe('router', () => {
})
})
describe('thx', () => {
const thx = routes.find((r) => r.path === '/thx/:comingFrom/:code?')
it('loads the "Thx" page', async () => {
const component = await thx.component()
expect(component.default.name).toBe('Thx')
})
describe('beforeEnter', () => {
const beforeEnter = thx.beforeEnter
const next = jest.fn()
it('redirects to login when not coming from a valid page', () => {
beforeEnter({}, { path: '' }, next)
expect(next).toBeCalledWith({ path: '/login' })
})
it('enters the page when coming from a valid page', () => {
jest.resetAllMocks()
beforeEnter({}, { path: '/forgot-password' }, next)
expect(next).toBeCalledWith()
})
})
})
describe('forgot password', () => {
it('loads the "ForgotPassword" page', async () => {
const component = await routes.find((r) => r.path === '/forgot-password').component()

View File

@ -46,18 +46,6 @@ const routes = [
path: '/register/:code?',
component: () => import('@/pages/Register.vue'),
},
{
path: '/thx/:comingFrom/:code?',
component: () => import('@/pages/thx.vue'),
beforeEnter: (to, from, next) => {
const validFrom = ['forgot-password', 'reset-password', 'register', 'login', 'checkEmail']
if (!validFrom.includes(from.path.split('/')[1])) {
next({ path: '/login' })
} else {
next()
}
},
},
{
path: '/forgot-password',
component: () => import('@/pages/ForgotPassword.vue'),

View File

@ -5,7 +5,7 @@
"main": "index.js",
"repository": "git@github.com:gradido/gradido.git",
"author": "Ulf Gebhardt <ulf.gebhardt@webcraft-media.de>",
"license": "Apache License 2.0",
"license": "Apache-2.0",
"scripts": {
"release": "scripts/release.sh"
},