From f0e3c6a717d798ae29f8dc3c4510a8a7ff2751bf Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 7 Nov 2025 14:54:15 +0100 Subject: [PATCH] Enhance MyTischtennisService and MyTischtennisAccount.vue for improved login handling and account status display Updated MyTischtennisService to include federation nickname in account data and refined login logic to utilize stored passwords or valid sessions more effectively. Enhanced error handling for login failures. In MyTischtennisAccount.vue, added account status management to display password storage status and improved account loading logic to fetch both account and status data concurrently. --- backend/services/myTischtennisService.js | 61 ++++++++++++++++----- frontend/src/views/MyTischtennisAccount.vue | 17 +++++- 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/backend/services/myTischtennisService.js b/backend/services/myTischtennisService.js index 127e445..8abc8ac 100644 --- a/backend/services/myTischtennisService.js +++ b/backend/services/myTischtennisService.js @@ -107,6 +107,7 @@ class MyTischtennisService { if (profileResult.success) { accountData.clubId = profileResult.clubId; accountData.clubName = profileResult.clubName; + accountData.fedNickname = profileResult.fedNickname; } } @@ -150,19 +151,49 @@ class MyTischtennisService { throw new HttpError('Kein myTischtennis-Account verknüpft', 404); } - let password = providedPassword; - - // Wenn kein Passwort übergeben wurde, versuche gespeichertes Passwort zu verwenden - if (!password) { - if (!account.savePassword || !account.encryptedPassword) { - throw new HttpError('Kein Passwort gespeichert. Bitte geben Sie Ihr Passwort ein.', 400); - } - password = account.getPassword(); - } - - // Login-Versuch const now = new Date(); account.lastLoginAttempt = now; + + let password = providedPassword; + const hasStoredPassword = !!(account.savePassword && account.encryptedPassword); + const hasValidSession = !!(account.accessToken && account.cookie && account.expiresAt && account.expiresAt > Date.now() / 1000); + + // Wenn kein Passwort angegeben wurde, entweder gespeichertes Passwort oder bestehende Session verwenden + if (!password) { + if (hasStoredPassword) { + password = account.getPassword(); + } else if (hasValidSession) { + // Prüfe, ob bestehende Session noch gültig ist + const profileResult = await myTischtennisClient.getUserProfile(account.cookie); + if (profileResult.success) { + account.lastLoginSuccess = now; + account.clubId = profileResult.clubId || account.clubId; + account.clubName = profileResult.clubName || account.clubName; + account.fedNickname = profileResult.fedNickname || account.fedNickname; + await account.save(); + return { + success: true, + accessToken: account.accessToken, + refreshToken: account.refreshToken, + expiresAt: account.expiresAt, + user: account.userData, + clubId: account.clubId, + clubName: account.clubName + }; + } + // Session ungültig -> Session-Daten zurücksetzen und speichern + account.accessToken = null; + account.refreshToken = null; + account.cookie = null; + account.expiresAt = null; + await account.save(); + throw new HttpError('Kein Passwort gespeichert und Session abgelaufen. Bitte Passwort eingeben.', 400); + } else { + throw new HttpError('Kein Passwort gespeichert. Bitte geben Sie Ihr Passwort ein.', 400); + } + } + + // Login-Versuch mit Passwort const loginResult = await myTischtennisClient.login(account.email, password); if (loginResult.success) { @@ -177,9 +208,9 @@ class MyTischtennisService { const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie); if (profileResult.success) { - account.clubId = profileResult.clubId; - account.clubName = profileResult.clubName; - account.fedNickname = profileResult.fedNickname; + account.clubId = profileResult.clubId || account.clubId; + account.clubName = profileResult.clubName || account.clubName; + account.fedNickname = profileResult.fedNickname || account.fedNickname; } else { console.error('[myTischtennisService] - Failed to get profile:', profileResult.error); } @@ -211,7 +242,7 @@ class MyTischtennisService { exists: !!account, hasEmail: !!account?.email, hasPassword: !!(account?.savePassword && account?.encryptedPassword), - hasValidSession: !!account?.accessToken && account?.expiresAt > Date.now() / 1000, + hasValidSession: !!(account?.accessToken && account?.cookie && account?.expiresAt && account?.expiresAt > Date.now() / 1000), needsConfiguration: !account || !account.email, needsPassword: !!account && (!account.savePassword || !account.encryptedPassword) }; diff --git a/frontend/src/views/MyTischtennisAccount.vue b/frontend/src/views/MyTischtennisAccount.vue index 5780ad3..cb35258 100644 --- a/frontend/src/views/MyTischtennisAccount.vue +++ b/frontend/src/views/MyTischtennisAccount.vue @@ -16,7 +16,7 @@
- {{ account.savePassword ? 'Ja' : 'Nein' }} + {{ accountStatus && accountStatus.hasPassword ? 'Ja' : 'Nein' }}
@@ -195,6 +195,7 @@ export default { loading: true, loadingStats: false, account: null, + accountStatus: null, latestFetches: null, showDialog: false, showHistoryDialog: false @@ -240,10 +241,16 @@ export default { async loadAccount() { try { this.loading = true; - const response = await apiClient.get('/mytischtennis/account'); - this.account = response.data.account; + const [accountResponse, statusResponse] = await Promise.all([ + apiClient.get('/mytischtennis/account'), + apiClient.get('/mytischtennis/status') + ]); + this.account = accountResponse.data.account; + this.accountStatus = statusResponse.data; } catch (error) { console.error('Fehler beim Laden des Accounts:', error); + this.account = null; + this.accountStatus = null; this.$store.dispatch('showMessage', { text: 'Fehler beim Laden des myTischtennis-Accounts', type: 'error' @@ -292,6 +299,9 @@ export default { if (error.response?.status === 400 && message.includes('Kein Passwort gespeichert')) { // Passwort-Dialog öffnen this.showDialog = true; + this.showInfo('Passwort benötigt', message, '', 'warning'); + } else { + this.showInfo('Login fehlgeschlagen', message, '', 'error'); } this.$store.dispatch('showMessage', { @@ -314,6 +324,7 @@ export default { try { await apiClient.delete('/mytischtennis/account'); this.account = null; + this.accountStatus = null; this.showInfo('Erfolg', 'myTischtennis-Account erfolgreich getrennt', '', 'success'); } catch (error) { console.error('Fehler beim Löschen des Accounts:', error);