refactor(App, Router, Login): streamline authentication flow and enhance route management

- Replaced manual logout handling in App.vue with a dedicated logout method for cleaner code.
- Updated router.js to add public meta properties to several routes, improving route access management.
- Implemented a global navigation guard to redirect unauthenticated users to the login page when accessing protected routes.
- Modified the login process in Login.vue to support redirecting users back to their intended destination after successful login.
This commit is contained in:
Torsten Schulz (local)
2026-03-18 18:20:28 +01:00
parent c441d4a049
commit dc15b48b80
3 changed files with 32 additions and 12 deletions

View File

@@ -353,9 +353,7 @@ export default {
this.handleLogout();
}
} catch (error) {
this.isAuthenticated = false;
this.username = '';
this.currentClub = '';
this.logout();
}
},

View File

@@ -27,14 +27,15 @@ import PersonalSettings from './views/PersonalSettings.vue';
import Impressum from './views/Impressum.vue';
import Datenschutz from './views/Datenschutz.vue';
import { applySeoForPath } from './utils/seo.js';
import { safeSessionStorage } from './utils/storage.js';
const routes = [
{ path: '/register', name: 'register', component: Register },
{ path: '/login', name: 'login', component: Login },
{ path: '/activate/:activationCode', name: 'activate', component: Activate },
{ path: '/forgot-password', name: 'forgot-password', component: ForgotPassword },
{ path: '/reset-password/:token', name: 'reset-password', component: ResetPassword },
{ path: '/', name: 'home', component: Home },
{ path: '/register', name: 'register', component: Register, meta: { public: true } },
{ path: '/login', name: 'login', component: Login, meta: { public: true } },
{ path: '/activate/:activationCode', name: 'activate', component: Activate, meta: { public: true } },
{ path: '/forgot-password', name: 'forgot-password', component: ForgotPassword, meta: { public: true } },
{ path: '/reset-password/:token', name: 'reset-password', component: ResetPassword, meta: { public: true } },
{ path: '/', name: 'home', component: Home, meta: { public: true } },
{ path: '/createclub', name: 'create-club', component: CreateClub },
{ path: '/showclub/:clubId', name: 'show-club', component: ClubView },
{ path: '/members', name: 'members', component: MembersView },
@@ -54,8 +55,8 @@ const routes = [
{ path: '/clicktt', name: 'clicktt', component: ClickTtView },
{ path: '/member-transfer-settings', name: 'member-transfer-settings', component: MemberTransferSettingsView },
{ path: '/personal-settings', name: 'personal-settings', component: PersonalSettings },
{ path: '/impressum', name: 'impressum', component: Impressum },
{ path: '/datenschutz', name: 'datenschutz', component: Datenschutz },
{ path: '/impressum', name: 'impressum', component: Impressum, meta: { public: true } },
{ path: '/datenschutz', name: 'datenschutz', component: Datenschutz, meta: { public: true } },
];
const router = createRouter({
@@ -63,6 +64,26 @@ const router = createRouter({
routes,
});
router.beforeEach((to, from, next) => {
const isAuthenticated = Boolean(safeSessionStorage.getItem('token'));
const isPublicRoute = to.matched.some((record) => record.meta?.public);
if (!isAuthenticated && !isPublicRoute) {
next({
path: '/login',
query: to.fullPath && to.fullPath !== '/' ? { redirect: to.fullPath } : {}
});
return;
}
if (isAuthenticated && (to.path === '/login' || to.path === '/register')) {
next('/');
return;
}
next();
});
router.afterEach((to) => {
applySeoForPath(to.path);
});

View File

@@ -105,7 +105,8 @@ export default {
timeout: 5000,
});
await this.login({ token: response.data.token, username: this.email });
this.$router.push('/');
const redirectTarget = typeof this.$route.query.redirect === 'string' ? this.$route.query.redirect : '/';
this.$router.push(redirectTarget);
} catch (error) {
const message = safeErrorMessage(error, this.$t('auth.loginFailed'));
await this.showInfo(this.$t('messages.error'), message, '', 'error');