make useAuthLinks more general and use it

This commit is contained in:
einhornimmond 2025-07-15 11:23:27 +02:00
parent f46d478bdc
commit 2fb4e9f3d4
11 changed files with 55 additions and 42 deletions

View File

@ -8,11 +8,11 @@
<BImg class="sheet-img position-absolute d-block d-lg-none zindex1000" :src="sheet"></BImg>
<BCollapse id="nav-collapse" is-nav>
<BNavbarNav class="ms-auto me-4 d-none d-lg-flex" right>
<NavItem :to="register()" class="auth-navbar ms-lg-5">
<NavItem :to="routeWithParamsAndQuery('Register')" class="auth-navbar ms-lg-5">
{{ $t('signup') }}
</NavItem>
<span class="d-none d-lg-block py-1">{{ $t('|') }}</span>
<NavItem :to="login()" class="auth-navbar">
<NavItem :to="routeWithParamsAndQuery('Login')" class="auth-navbar">
{{ $t('signin') }}
</NavItem>
</BNavbarNav>
@ -25,7 +25,7 @@
import { useAuthLinks } from '@/composables/useAuthLinks'
import NavItem from '../Menu/NavItem.vue'
const { login, register } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
const backgroundHeader = '/img/template/gradido_background_header.png'
const logo = '/img/brand/gradido-logo_200x59.png'

View File

@ -2,9 +2,9 @@
<div class="navbar-small">
<BNavbar class="navi">
<BNavbarNav>
<NavItem :to="register()" class="auth-navbar">{{ $t('signup') }}</NavItem>
<NavItem :to="routeWithParamsAndQuery('Register')" class="auth-navbar">{{ $t('signup') }}</NavItem>
<span class="mt-1">{{ $t('|') }}</span>
<NavItem :to="login()" class="auth-navbar">{{ $t('signin') }}</NavItem>
<NavItem :to="routeWithParamsAndQuery('Login')" class="auth-navbar">{{ $t('signin') }}</NavItem>
</BNavbarNav>
</BNavbar>
</div>
@ -14,7 +14,7 @@
import { useAuthLinks } from '@/composables/useAuthLinks'
import NavItem from '../Menu/NavItem.vue'
const { login, register } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
</script>
<style scoped>
.navi {

View File

@ -10,13 +10,13 @@
<BRow>
<BCol sm="12" md="6">
<p>{{ $t('gdd_per_link.no-account') }}</p>
<BButton variant="primary" :to="register()">
<BButton variant="primary" :to="routeWithParamsAndQuery('Register')">
{{ $t('gdd_per_link.to-register') }}
</BButton>
</BCol>
<BCol sm="12" md="6" class="mt-4 mt-lg-0">
<p>{{ $t('gdd_per_link.has-account') }}</p>
<BButton variant="gradido" :to="login()">{{ $t('gdd_per_link.to-login') }}</BButton>
<BButton variant="gradido" :to="routeWithParamsAndQuery('Login')">{{ $t('gdd_per_link.to-login') }}</BButton>
</BCol>
</BRow>
</BCard>
@ -26,7 +26,7 @@
<script setup>
import { useAuthLinks } from '@/composables/useAuthLinks'
const { login, register } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
defineProps({
linkData: { type: Object, required: true },
isContributionLink: { type: Boolean, default: false },

View File

@ -17,13 +17,13 @@
<BRow>
<BCol sm="12" md="6">
<p>{{ $t('gdd_per_link.no-account') }}</p>
<BButton variant="primary" :disabled="isForeignCommunitySelected" :to="register()">
<BButton variant="primary" :disabled="isForeignCommunitySelected" :to="routeWithParamsAndQuery('Register')">
{{ $t('gdd_per_link.to-register') }}
</BButton>
</BCol>
<BCol sm="12" md="6" class="mt-4 mt-lg-0">
<p>{{ $t('gdd_per_link.has-account') }}</p>
<BButton variant="gradido" :disabled="isForeignCommunitySelected" :to="login()">
<BButton variant="gradido" :disabled="isForeignCommunitySelected" :to="routeWithParamsAndQuery('Login')">
{{ $t('gdd_per_link.to-login') }}
</BButton>
</BCol>
@ -37,7 +37,7 @@ import { ref, computed } from 'vue'
import CONFIG from '@/config'
import { useAuthLinks } from '@/composables/useAuthLinks'
const { login, register } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
const props = defineProps({
linkData: { type: Object, required: true },
redeemCode: { type: String, required: true },

View File

@ -3,7 +3,7 @@
<span v-if="isActive" class="nav-link active" aria-current="page">
<slot></slot>
</span>
<BNavItem v-else :to="href" class="auth-navbar"><slot></slot></BNavItem>
<BNavItem v-else v-bind="props" class="auth-navbar"><slot></slot></BNavItem>
</li>
</template>

View File

@ -1,19 +1,20 @@
import { useRoute } from 'vue-router'
export function useAuthLinks() {
const { params } = useRoute()
const login = () => {
if (params.code) return '/login/' + params.code
return '/login'
}
const register = () => {
if (params.code) return '/register/' + params.code
return '/register'
const route = useRoute()
/**
* Combine current route params and query with given params and query
* @param {string} name
* @param {{ params: {}, query: {} }} options
* @returns {{ name: string, params: {}, query: {} }} a vue3 routing object for :to
*/
const routeWithParamsAndQuery = (name, options = { params: {}, query: {} }) => {
return {
name,
params: { ...route.params, ...options.params },
query: { ...route.query, ...options.query }
}
}
return {
login,
register,
}
return { routeWithParamsAndQuery }
}

View File

@ -13,7 +13,7 @@
</BRow>
<BRow>
<BCol class="d-flex justify-content-end mb-4 mb-lg-0">
<router-link to="/forgot-password" data-test="forgot-password-link">
<router-link :to="routeWithParamsAndQuery('ForgotPassword')" data-test="forgot-password-link">
{{ $t('settings.password.forgot_pwd') }}
</router-link>
</BCol>
@ -39,7 +39,7 @@
</BRow>
<BRow>
<BCol class="mt-1 auth-navbar">
<BLink :to="register()">
<BLink :to="routeWithParamsAndQuery('Register')">
{{ $t('signup') }}
</BLink>
</BCol>
@ -82,7 +82,7 @@ const { mutate } = useMutation(login)
const { mutate: mutateHumhubAutoLogin } = useMutation(authenticateHumhubAutoLoginProject)
// const $loading = useLoading() // TODO needs to be updated but there is some sort of an issue that breaks the app.
const { toastError } = useAppToast()
const { register } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
const form = ref({
email: '',
@ -123,7 +123,7 @@ const onSubmit = handleSubmit(async (values) => {
}
if (route.params.code) {
await router.push(`/redeem/${route.params.code}`)
await router.push(routeWithParamsAndQuery('Redeem'))
} else {
await router.push(store.state.redirectPath)
}
@ -131,12 +131,12 @@ const onSubmit = handleSubmit(async (values) => {
if (error.message.includes('User email not validated')) {
showPageMessage.value = true
errorSubtitle.value = t('message.activateEmail')
errorLinkTo.value = '/forgot-password'
errorLinkTo.value = routeWithParamsAndQuery('ForgotPassword')
toastError(t('error.no-account'))
} else if (error.message.includes('User has no password set yet')) {
showPageMessage.value = true
errorSubtitle.value = t('message.unsetPassword')
errorLinkTo.value = '/reset-password/login'
errorLinkTo.value = routeWithParamsAndQuery('ResetPassword')
toastError(t('error.no-account'))
} else if (error.message.includes('No user with this credentials')) {
toastError(t('error.no-user'))

View File

@ -77,7 +77,7 @@
</BRow>
<BRow>
<BCol class="mt-1 auth-navbar">
<BLink :to="login()">
<BLink :to="routeWithParamsAndQuery('Login')">
{{ $t('signin') }}
</BLink>
</BCol>
@ -105,7 +105,7 @@ import { useAuthLinks } from '@/composables/useAuthLinks'
import CONFIG from '@/config'
const { toastError } = useAppToast()
const { login } = useAuthLinks()
const { routeWithParamsAndQuery } = useAuthLinks()
const { mutate } = useMutation(createUser)

View File

@ -362,6 +362,7 @@ describe('ResetPassword', () => {
})
it('redirects to /forgot-password/resetPassword', () => {
console.log(router.currentRoute.value)
expect(router.currentRoute.value.path).toBe('/forgot-password/resetPassword')
})
})
@ -417,7 +418,7 @@ describe('ResetPassword', () => {
'...email was sent more than 23 hours and 10 minutes ago',
)
expect(message.props('buttonText')).toBe('settings.password.reset')
expect(message.props('linkTo')).toBe('/forgot-password/resetPassword')
expect(message.props('linkTo')).toMatchObject({ name: 'ForgotPassword', params: { comingFrom: 'reset-password' } })
expect(mockToastError).toHaveBeenCalledWith(
'...email was sent more than 23 hours and 10 minutes ago',
)
@ -435,7 +436,7 @@ describe('ResetPassword', () => {
expect(message.props('headline')).toBe('message.title')
expect(message.props('subtitle')).toBe('message.checkEmail')
expect(message.props('buttonText')).toBe('login')
expect(message.props('linkTo')).toBe('/login')
expect(message.props('linkTo')).toMatchObject({ name: 'Login' })
})
it('handles success response on /reset-password', async () => {
@ -454,7 +455,7 @@ describe('ResetPassword', () => {
expect(message.props('headline')).toBe('message.title')
expect(message.props('subtitle')).toBe('message.checkEmail')
expect(message.props('buttonText')).toBe('login')
expect(message.props('linkTo')).toBe('/login')
expect(message.props('linkTo')).toMatchObject({ name: 'Login' })
})
})

View File

@ -41,19 +41,22 @@ import InputPasswordConfirmation from '@/components/Inputs/InputPasswordConfirma
import Message from '@/components/Message/Message.vue'
import { useAppToast } from '@/composables/useToast'
import { useForm } from 'vee-validate'
import { useAuthLinks } from '@/composables/useAuthLinks'
const { routeWithParamsAndQuery } = useAuthLinks()
const textFields = {
reset: {
title: 'settings.password.change-password',
text: 'settings.password.reset-password.text',
button: 'settings.password.change-password',
linkTo: '/login',
linkTo: routeWithParamsAndQuery('Login'),
},
checkEmail: {
title: 'settings.password.set',
text: 'settings.password.set-password.text',
button: 'settings.password.set',
linkTo: '/login',
linkTo: routeWithParamsAndQuery('Login'),
},
}
@ -82,6 +85,7 @@ const { load: queryOptInQuery } = useLazyQuery(queryOptIn)
const { toastError } = useAppToast()
const { meta: formMeta, values: formValues, setFieldValue } = useForm()
const onSubmit = async () => {
@ -100,7 +104,7 @@ const onSubmit = async () => {
? t('message.checkEmail')
: t('message.reset')
messageButtonText.value = t('login')
messageButtonLinkTo.value = route.params.code ? `/login/${route.params.code}` : '/login'
messageButtonLinkTo.value = routeWithParamsAndQuery('Login')
} catch (error) {
const errorMessage = error.message.match(
/email was sent more than ([0-9]+ hours)?( and )?([0-9]+ minutes)? ago/,
@ -112,7 +116,7 @@ const onSubmit = async () => {
messageHeadline.value = t('message.errorTitle')
messageSubtitle.value = errorMessage
messageButtonText.value = t('settings.password.reset')
messageButtonLinkTo.value = '/forgot-password/resetPassword'
messageButtonLinkTo.value = routeWithParamsAndQuery('ForgotPassword', { params: { comingFrom: 'reset-password' } })
toastError(errorMessage)
}
}
@ -124,7 +128,7 @@ const checkOptInCode = async () => {
})
} catch (error) {
toastError(error.message)
await router.push('/forgot-password/resetPassword')
await router.push(routeWithParamsAndQuery('ForgotPassword', { params: { comingFrom: 'reset-password' } }))
}
}

View File

@ -114,18 +114,22 @@ const routes = [
},
},
{
name: 'Login',
path: '/login/:code?',
component: () => import('@/pages/Login'),
},
{
name: 'Register',
path: '/register/:code?',
component: () => import('@/pages/Register'),
},
{
name: 'ForgotPassword',
path: '/forgot-password',
component: () => import('@/pages/ForgotPassword'),
},
{
name: 'ForgotPasswordComingFrom',
path: '/forgot-password/:comingFrom',
component: () => import('@/pages/ForgotPassword'),
},
@ -138,14 +142,17 @@ const routes = [
// component: () => import('@/pages/SelectCommunity'),
// },
{
name: 'ResetPassword',
path: '/reset-password/:optin',
component: () => import('@/pages/ResetPassword'),
},
{
name: 'CheckEmail',
path: '/checkEmail/:optin/:code?',
component: () => import('@/pages/ResetPassword'),
},
{
name: 'Redeem',
path: '/redeem/:code',
component: () => import('@/pages/TransactionLink'),
},