refactor: use query parameter only when looking for password reset token
This commit is contained in:
parent
59aca9fd5d
commit
3658cde42f
|
|
@ -15,7 +15,7 @@ context('Password Reset', () => {
|
||||||
const token: TokenAttributes = tokenArray[0] as TokenAttributes
|
const token: TokenAttributes = tokenArray[0] as TokenAttributes
|
||||||
|
|
||||||
cy.visit(`/?userPasswordReset=${token.token}`)
|
cy.visit(`/?userPasswordReset=${token.token}`)
|
||||||
cy.url().should('include', `/password-reset?token=${token.token}`)
|
cy.url().should('include', `/password-reset?userPasswordReset=${token.token}`)
|
||||||
|
|
||||||
const newPassword = 'newSecurePassword123'
|
const newPassword = 'newSecurePassword123'
|
||||||
cy.get('input[id=password]').type(newPassword)
|
cy.get('input[id=password]').type(newPassword)
|
||||||
|
|
@ -34,7 +34,7 @@ context('Password Reset', () => {
|
||||||
|
|
||||||
it('Should show an error for an invalid token', () => {
|
it('Should show an error for an invalid token', () => {
|
||||||
cy.visit('/?userPasswordReset=invalidtoken123')
|
cy.visit('/?userPasswordReset=invalidtoken123')
|
||||||
cy.url().should('include', '/password-reset?token=invalidtoken123')
|
cy.url().should('include', '/password-reset?userPasswordReset=invalidtoken123')
|
||||||
|
|
||||||
// Attempt to reset password
|
// Attempt to reset password
|
||||||
const newPassword = 'newSecurePassword123'
|
const newPassword = 'newSecurePassword123'
|
||||||
|
|
|
||||||
|
|
@ -77,17 +77,6 @@ watch(accountDeletionConfirm, async (accountDeletionConfirm) => {
|
||||||
authStore.refreshUserInfo()
|
authStore.refreshUserInfo()
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
// setup password reset redirect
|
|
||||||
const userPasswordReset = computed(() => route.query?.userPasswordReset as (string | undefined))
|
|
||||||
watch(userPasswordReset, (userPasswordReset) => {
|
|
||||||
if (userPasswordReset === undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
authStore.setPasswordResetToken(userPasswordReset)
|
|
||||||
router.push({name: 'user.password-reset.reset', query: { token: userPasswordReset }})
|
|
||||||
}, { immediate: true })
|
|
||||||
|
|
||||||
// setup email verification redirect
|
// setup email verification redirect
|
||||||
const userEmailConfirm = computed(() => route.query?.userEmailConfirm as (string | undefined))
|
const userEmailConfirm = computed(() => route.query?.userEmailConfirm as (string | undefined))
|
||||||
watch(userEmailConfirm, (userEmailConfirm) => {
|
watch(userEmailConfirm, (userEmailConfirm) => {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import {getNextWeekDate} from '@/helpers/time/getNextWeekDate'
|
||||||
import {LINK_SHARE_HASH_PREFIX} from '@/constants/linkShareHash'
|
import {LINK_SHARE_HASH_PREFIX} from '@/constants/linkShareHash'
|
||||||
|
|
||||||
import {useAuthStore} from '@/stores/auth'
|
import {useAuthStore} from '@/stores/auth'
|
||||||
import {useBaseStore} from '@/stores/base'
|
|
||||||
|
|
||||||
import Login from '@/views/user/Login.vue'
|
import Login from '@/views/user/Login.vue'
|
||||||
import Register from '@/views/user/Register.vue'
|
import Register from '@/views/user/Register.vue'
|
||||||
|
|
@ -396,13 +395,14 @@ export async function getAuthForRoute(to: RouteLocation, authStore) {
|
||||||
|
|
||||||
// Check if password reset token is in query params
|
// Check if password reset token is in query params
|
||||||
const resetToken = to.query.userPasswordReset as string | undefined
|
const resetToken = to.query.userPasswordReset as string | undefined
|
||||||
if (resetToken) {
|
|
||||||
authStore.setPasswordResetToken(resetToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Redirect to password reset page if we have a token stored
|
// Redirect to password reset page if we have a token stored
|
||||||
if (authStore.passwordResetToken && to.name !== 'user.password-reset.reset') {
|
if (resetToken && to.name !== 'user.password-reset.reset') {
|
||||||
return {name: 'user.password-reset.reset', query: { token: authStore.passwordResetToken }}
|
return {name: 'user.password-reset.reset', query: { userPasswordReset: resetToken }}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof resetToken === 'undefined' && to.name === 'user.password-reset.reset') {
|
||||||
|
return {name: 'user.login'}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the route the user wants to go to is a route which needs authentication. We use this to
|
// Check if the route the user wants to go to is a route which needs authentication. We use this to
|
||||||
|
|
@ -415,21 +415,12 @@ export async function getAuthForRoute(to: RouteLocation, authStore) {
|
||||||
'link-share.auth',
|
'link-share.auth',
|
||||||
'openid.auth',
|
'openid.auth',
|
||||||
].includes(to.name as string) &&
|
].includes(to.name as string) &&
|
||||||
authStore.passwordResetToken === null &&
|
localStorage.getItem('emailConfirmToken') === null
|
||||||
localStorage.getItem('emailConfirmToken') === null &&
|
|
||||||
!(to.name === 'home' && (typeof to.query.userPasswordReset !== 'undefined' || typeof to.query.userEmailConfirm !== 'undefined'))
|
|
||||||
|
|
||||||
if (isValidUserAppRoute) {
|
if (isValidUserAppRoute) {
|
||||||
saveLastVisited(to.name as string, to.params, to.query)
|
saveLastVisited(to.name as string, to.params, to.query)
|
||||||
}
|
}
|
||||||
|
|
||||||
const baseStore = useBaseStore()
|
|
||||||
// When trying this before the current user was fully loaded we might get a flash of the login screen
|
|
||||||
// in the user shell. To make sure this does not happen we check if everything is ready before trying.
|
|
||||||
if (!baseStore.ready) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValidUserAppRoute) {
|
if (isValidUserAppRoute) {
|
||||||
return {name: 'user.login'}
|
return {name: 'user.login'}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
const authenticated = ref(false)
|
const authenticated = ref(false)
|
||||||
const isLinkShareAuth = ref(false)
|
const isLinkShareAuth = ref(false)
|
||||||
const needsTotpPasscode = ref(false)
|
const needsTotpPasscode = ref(false)
|
||||||
const passwordResetToken = ref<string | null>(null)
|
|
||||||
|
|
||||||
const info = ref<IUser | null>(null)
|
const info = ref<IUser | null>(null)
|
||||||
const avatarUrl = ref('')
|
const avatarUrl = ref('')
|
||||||
|
|
@ -150,10 +149,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
needsTotpPasscode.value = newNeedsTotpPasscode
|
needsTotpPasscode.value = newNeedsTotpPasscode
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPasswordResetToken(token: string | null) {
|
|
||||||
passwordResetToken.value = token
|
|
||||||
}
|
|
||||||
|
|
||||||
function reloadAvatar() {
|
function reloadAvatar() {
|
||||||
if (!info.value) return
|
if (!info.value) return
|
||||||
avatarUrl.value = `${getAvatarUrl(info.value)}&=${new Date().valueOf()}`
|
avatarUrl.value = `${getAvatarUrl(info.value)}&=${new Date().valueOf()}`
|
||||||
|
|
@ -449,7 +444,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
authenticated: readonly(authenticated),
|
authenticated: readonly(authenticated),
|
||||||
isLinkShareAuth: readonly(isLinkShareAuth),
|
isLinkShareAuth: readonly(isLinkShareAuth),
|
||||||
needsTotpPasscode: readonly(needsTotpPasscode),
|
needsTotpPasscode: readonly(needsTotpPasscode),
|
||||||
passwordResetToken: readonly(passwordResetToken),
|
|
||||||
|
|
||||||
info: readonly(info),
|
info: readonly(info),
|
||||||
avatarUrl: readonly(avatarUrl),
|
avatarUrl: readonly(avatarUrl),
|
||||||
|
|
@ -472,7 +466,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||||
setAuthenticated,
|
setAuthenticated,
|
||||||
setIsLinkShareAuth,
|
setIsLinkShareAuth,
|
||||||
setNeedsTotpPasscode,
|
setNeedsTotpPasscode,
|
||||||
setPasswordResetToken,
|
|
||||||
|
|
||||||
reloadAvatar,
|
reloadAvatar,
|
||||||
updateLastUserRefresh,
|
updateLastUserRefresh,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import {ref, computed, readonly} from 'vue'
|
import {ref, computed, readonly} from 'vue'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useRouter, useRoute} from 'vue-router'
|
|
||||||
import {defineStore, acceptHMRUpdate} from 'pinia'
|
import {defineStore, acceptHMRUpdate} from 'pinia'
|
||||||
|
|
||||||
import {getAuthForRoute} from '@/router'
|
|
||||||
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
|
import {getBlobFromBlurHash} from '@/helpers/getBlobFromBlurHash'
|
||||||
|
|
||||||
import ProjectModel from '@/models/project'
|
import ProjectModel from '@/models/project'
|
||||||
|
|
@ -22,9 +20,6 @@ export const useBaseStore = defineStore('base', () => {
|
||||||
|
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const ready = ref(false)
|
const ready = ref(false)
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
const loading = computed(() => !ready.value && error.value === '')
|
const loading = computed(() => !ready.value && error.value === '')
|
||||||
|
|
@ -147,10 +142,6 @@ export const useBaseStore = defineStore('base', () => {
|
||||||
await checkAndSetApiUrl(window.API_URL)
|
await checkAndSetApiUrl(window.API_URL)
|
||||||
await authStore.checkAuth()
|
await authStore.checkAuth()
|
||||||
ready.value = true
|
ready.value = true
|
||||||
const redirectTo = await getAuthForRoute(route, authStore)
|
|
||||||
if (typeof redirectTo !== 'undefined') {
|
|
||||||
await router.push(redirectTo)
|
|
||||||
}
|
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (e instanceof NoApiUrlProvidedError) {
|
if (e instanceof NoApiUrlProvidedError) {
|
||||||
error.value = ERROR_NO_API_URL
|
error.value = ERROR_NO_API_URL
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,6 @@
|
||||||
import {ref, reactive} from 'vue'
|
import {ref, reactive} from 'vue'
|
||||||
import {useRoute} from 'vue-router'
|
import {useRoute} from 'vue-router'
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import {useAuthStore} from '@/stores/auth'
|
|
||||||
|
|
||||||
import PasswordResetModel from '@/models/passwordReset'
|
import PasswordResetModel from '@/models/passwordReset'
|
||||||
import PasswordResetService from '@/services/passwordReset'
|
import PasswordResetService from '@/services/passwordReset'
|
||||||
|
|
@ -66,7 +65,6 @@ const credentials = reactive({
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const authStore = useAuthStore()
|
|
||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
|
|
||||||
const passwordResetService = reactive(new PasswordResetService())
|
const passwordResetService = reactive(new PasswordResetService())
|
||||||
|
|
@ -75,7 +73,7 @@ const successMessage = ref('')
|
||||||
|
|
||||||
async function resetPassword() {
|
async function resetPassword() {
|
||||||
errorMsg.value = ''
|
errorMsg.value = ''
|
||||||
const token = route.query.token as string
|
const token = route.query.userPasswordReset as string
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
errorMsg.value = t('user.auth.passwordResetTokenMissing')
|
errorMsg.value = t('user.auth.passwordResetTokenMissing')
|
||||||
|
|
@ -90,7 +88,6 @@ async function resetPassword() {
|
||||||
try {
|
try {
|
||||||
const {message} = await passwordResetService.resetPassword(passwordReset)
|
const {message} = await passwordResetService.resetPassword(passwordReset)
|
||||||
successMessage.value = message
|
successMessage.value = message
|
||||||
authStore.setPasswordResetToken(null)
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorMsg.value = e.response.data.message
|
errorMsg.value = e.response.data.message
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue