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.
This commit is contained in:
Torsten Schulz (local)
2025-11-07 14:54:15 +01:00
parent b2d47c7a37
commit f0e3c6a717
2 changed files with 60 additions and 18 deletions

View File

@@ -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)
};

View File

@@ -16,7 +16,7 @@
<div class="info-row">
<label>Passwort gespeichert:</label>
<span>{{ account.savePassword ? 'Ja' : 'Nein' }}</span>
<span>{{ accountStatus && accountStatus.hasPassword ? 'Ja' : 'Nein' }}</span>
</div>
<div class="info-row" v-if="account.clubId">
@@ -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);