feat(auth): enhance logout and login flow with return URL handling
This commit is contained in:
@@ -55,7 +55,7 @@ export function useClient() {
|
||||
return client(originalRequest);
|
||||
} catch (refreshError) {
|
||||
console.error('Token refresh failed, logging out user:', refreshError);
|
||||
await authStore.logout();
|
||||
await authStore.logout('/login');
|
||||
throw refreshError;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ const routes = [
|
||||
name: 'login',
|
||||
component: LoginView,
|
||||
meta: { notAuthenticated: true },
|
||||
props: (route) => ({ returnUrl: route.query.returnUrl || '/landing' })
|
||||
},
|
||||
{
|
||||
path: '/profile',
|
||||
@@ -119,11 +120,20 @@ router.beforeEach((to, from, next) => {
|
||||
const authStore = useAuthStore();
|
||||
|
||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||
if (!authStore.isAuthenticated) next({ name: 'login' });
|
||||
if (!authStore.isAuthenticated) {
|
||||
next({
|
||||
name: 'login',
|
||||
query: { returnUrl: to.fullPath }
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} else if (to.matched.some((record) => record.meta.notAuthenticated)) {
|
||||
if (authStore.isAuthenticated) next({ name: 'landing' });
|
||||
else next();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -72,7 +72,7 @@ export const useAuthStore = defineStore(
|
||||
// Clear any other auth-related data if needed
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
async function logout(redirectTo = '/landing') {
|
||||
try {
|
||||
// Optionally call logout endpoint if you have one
|
||||
// await clientApi.post('api/users/logout');
|
||||
@@ -80,7 +80,7 @@ export const useAuthStore = defineStore(
|
||||
console.error('Logout failed:', error);
|
||||
} finally {
|
||||
cleanTokens();
|
||||
await router.push('/');
|
||||
await router.push(redirectTo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,8 +201,15 @@ export const useAuthStore = defineStore(
|
||||
// Only clear tokens and session storage after a failed refresh attempt
|
||||
cleanTokens();
|
||||
|
||||
// Force a redirect to the login page
|
||||
await router.push('/login');
|
||||
// Get the current route to use as returnUrl
|
||||
const currentRoute = router.currentRoute.value;
|
||||
const returnUrl = currentRoute.fullPath;
|
||||
|
||||
// Force a redirect to the login page with returnUrl
|
||||
await router.push({
|
||||
name: 'login',
|
||||
query: { returnUrl }
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -3,16 +3,30 @@ import {ref} from 'vue';
|
||||
import {GoogleLogin} from "vue3-google-login";
|
||||
import {useAuthStore} from '@/stores/authStore.js';
|
||||
import {useI18n} from 'vue-i18n';
|
||||
import {useRouter} from 'vue-router';
|
||||
|
||||
const {t} = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const errorSnackBar = ref(false);
|
||||
const props = defineProps({
|
||||
returnUrl: {
|
||||
type: String,
|
||||
default: '/landing'
|
||||
}
|
||||
});
|
||||
|
||||
async function googleCallback(token) {
|
||||
const response = await authStore.loginWithGoogle(JSON.stringify(token));
|
||||
if (response !== true) {
|
||||
try {
|
||||
const response = await authStore.loginWithGoogle(JSON.stringify(token));
|
||||
if (response === true) {
|
||||
await router.push(props.returnUrl);
|
||||
} else {
|
||||
errorSnackBar.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Login failed:', error);
|
||||
errorSnackBar.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@ import {useAuthStore} from "@/stores/authStore.js";
|
||||
import {useCreatorProfileStore} from "@/stores/creatorProfileStore.js";
|
||||
import {useUserProfileStore} from "@/stores/userProfileStore.js";
|
||||
import {useLanguageStore} from "@/stores/languageStore.js";
|
||||
import {useRouter, useRoute} from 'vue-router';
|
||||
|
||||
const {locale, t} = useI18n();
|
||||
const languageStore = useLanguageStore();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const userProfileStore = useUserProfileStore();
|
||||
const creatorProfileStore = useCreatorProfileStore();
|
||||
@@ -18,6 +21,14 @@ function toggleLanguage() {
|
||||
const nextIndex = (currentIndex + 1) % languages.length;
|
||||
languageStore.setLocale(languages[nextIndex]);
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
// Check if current route requires authentication
|
||||
const requiresAuth = route.matched.some(record => record.meta.requiresAuth);
|
||||
// If on a protected page, redirect to landing, otherwise stay on current page
|
||||
const redirectTo = requiresAuth ? '/landing' : route.fullPath;
|
||||
authStore.logout(redirectTo);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -85,7 +96,7 @@ function toggleLanguage() {
|
||||
</template>
|
||||
<div v-else>
|
||||
<button class="menu-item-action"
|
||||
@click="authStore.logout">
|
||||
@click="handleLogout">
|
||||
<i class="mdi mdi-logout"></i>
|
||||
<span class="label">{{ t('sidebar.signOut') }}</span>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user