Entfernt die myTischtennis-Integration aus dem Backend und Frontend. Löscht Controller, Routen und Service für myTischtennis. Aktualisiert die Datenmodelle, um die neue ExternalServiceAccount-Integration zu unterstützen. Ändert die API-Routen und Frontend-Komponenten, um die neuen Endpunkte zu verwenden.
This commit is contained in:
347
backend/services/externalServiceService.js
Normal file
347
backend/services/externalServiceService.js
Normal file
@@ -0,0 +1,347 @@
|
||||
import ExternalServiceAccount from '../models/ExternalServiceAccount.js';
|
||||
import User from '../models/User.js';
|
||||
import myTischtennisClient from '../clients/myTischtennisClient.js';
|
||||
import hettvClient from '../clients/hettvClient.js';
|
||||
import HttpError from '../exceptions/HttpError.js';
|
||||
|
||||
class ExternalServiceService {
|
||||
/**
|
||||
* Get the appropriate client for a service
|
||||
*/
|
||||
getClientForService(service) {
|
||||
switch (service) {
|
||||
case 'mytischtennis':
|
||||
return myTischtennisClient;
|
||||
case 'hettv':
|
||||
return hettvClient;
|
||||
default:
|
||||
throw new HttpError(400, `Unbekannter Service: ${service}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get account for user and service
|
||||
*/
|
||||
async getAccount(userId, service = 'mytischtennis') {
|
||||
const account = await ExternalServiceAccount.findOne({
|
||||
where: { userId, service },
|
||||
attributes: ['id', 'service', 'email', 'savePassword', 'lastLoginAttempt', 'lastLoginSuccess', 'expiresAt', 'userData', 'clubId', 'clubName', 'fedNickname', 'createdAt', 'updatedAt']
|
||||
});
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update external service account
|
||||
*/
|
||||
async upsertAccount(userId, email, password, savePassword, userPassword, service = 'mytischtennis') {
|
||||
// Verify user's app password
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
throw new HttpError(404, 'Benutzer nicht gefunden');
|
||||
}
|
||||
|
||||
let loginResult = null;
|
||||
|
||||
// Wenn ein Passwort gesetzt/geändert wird, App-Passwort verifizieren
|
||||
if (password) {
|
||||
const isValidPassword = await user.validatePassword(userPassword);
|
||||
if (!isValidPassword) {
|
||||
throw new HttpError(401, 'Ungültiges Passwort');
|
||||
}
|
||||
|
||||
// Login-Versuch beim entsprechenden Service
|
||||
const client = this.getClientForService(service);
|
||||
loginResult = await client.login(email, password);
|
||||
if (!loginResult.success) {
|
||||
throw new HttpError(401, loginResult.error || `${service}-Login fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.`);
|
||||
}
|
||||
}
|
||||
|
||||
// Find or create account
|
||||
let account = await ExternalServiceAccount.findOne({ where: { userId, service } });
|
||||
|
||||
const now = new Date();
|
||||
|
||||
if (account) {
|
||||
// Update existing
|
||||
account.email = email;
|
||||
account.savePassword = savePassword;
|
||||
|
||||
if (password && savePassword) {
|
||||
account.setPassword(password);
|
||||
} else if (!savePassword) {
|
||||
account.encryptedPassword = null;
|
||||
}
|
||||
|
||||
if (loginResult && loginResult.success) {
|
||||
account.lastLoginAttempt = now;
|
||||
account.lastLoginSuccess = now;
|
||||
account.accessToken = loginResult.accessToken;
|
||||
account.refreshToken = loginResult.refreshToken;
|
||||
account.expiresAt = loginResult.expiresAt;
|
||||
account.cookie = loginResult.cookie;
|
||||
account.userData = loginResult.user;
|
||||
|
||||
// Hole Club-ID und Federation (nur für myTischtennis)
|
||||
if (service === 'mytischtennis') {
|
||||
console.log('[externalServiceService] - Getting user profile...');
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
console.log('[externalServiceService] - Profile result:', {
|
||||
success: profileResult.success,
|
||||
clubId: profileResult.clubId,
|
||||
clubName: profileResult.clubName,
|
||||
fedNickname: profileResult.fedNickname
|
||||
});
|
||||
|
||||
if (profileResult.success) {
|
||||
account.clubId = profileResult.clubId;
|
||||
account.clubName = profileResult.clubName;
|
||||
account.fedNickname = profileResult.fedNickname;
|
||||
console.log('[externalServiceService] - Updated account with club data');
|
||||
} else {
|
||||
console.error('[externalServiceService] - Failed to get profile:', profileResult.error);
|
||||
}
|
||||
}
|
||||
} else if (password) {
|
||||
account.lastLoginAttempt = now;
|
||||
}
|
||||
|
||||
console.log('[externalServiceService] - Speichere Account (update).');
|
||||
try {
|
||||
await account.save();
|
||||
} catch (e) {
|
||||
console.error('[externalServiceService] - Fehler beim Speichern (update):', e.message, e.parent?.sqlMessage);
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
// Create new
|
||||
const accountData = {
|
||||
userId,
|
||||
service,
|
||||
email,
|
||||
savePassword,
|
||||
lastLoginAttempt: password ? now : null,
|
||||
lastLoginSuccess: loginResult?.success ? now : null
|
||||
};
|
||||
|
||||
if (loginResult && loginResult.success) {
|
||||
accountData.accessToken = loginResult.accessToken;
|
||||
accountData.refreshToken = loginResult.refreshToken;
|
||||
accountData.expiresAt = loginResult.expiresAt;
|
||||
accountData.cookie = loginResult.cookie;
|
||||
accountData.userData = loginResult.user;
|
||||
|
||||
// Hole Club-/Verbandsdaten nur für myTischtennis
|
||||
if (service === 'mytischtennis') {
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
if (profileResult.success) {
|
||||
accountData.clubId = profileResult.clubId;
|
||||
accountData.clubName = profileResult.clubName;
|
||||
accountData.fedNickname = profileResult.fedNickname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[externalServiceService] - Erstelle Account (create).');
|
||||
try {
|
||||
account = await ExternalServiceAccount.create(accountData);
|
||||
} catch (e) {
|
||||
console.error('[externalServiceService] - Fehler beim Erstellen (create):', e.message, e.parent?.sqlMessage);
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (password && savePassword) {
|
||||
account.setPassword(password);
|
||||
console.log('[externalServiceService] - Speichere Passwort (nach create).');
|
||||
try {
|
||||
await account.save();
|
||||
} catch (e) {
|
||||
console.error('[externalServiceService] - Fehler beim Speichern (nach create):', e.message, e.parent?.sqlMessage);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: account.id,
|
||||
email: account.email,
|
||||
savePassword: account.savePassword,
|
||||
lastLoginAttempt: account.lastLoginAttempt,
|
||||
lastLoginSuccess: account.lastLoginSuccess,
|
||||
expiresAt: account.expiresAt
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete external service account
|
||||
*/
|
||||
async deleteAccount(userId, service = 'mytischtennis') {
|
||||
const deleted = await ExternalServiceAccount.destroy({
|
||||
where: { userId, service }
|
||||
});
|
||||
return deleted > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify login with stored or provided credentials
|
||||
*/
|
||||
async verifyLogin(userId, providedPassword = null, service = 'mytischtennis') {
|
||||
const account = await ExternalServiceAccount.findOne({ where: { userId, service } });
|
||||
|
||||
if (!account) {
|
||||
throw new HttpError(404, `Kein ${service}-Account verknüpft`);
|
||||
}
|
||||
|
||||
let password = providedPassword;
|
||||
|
||||
// Wenn kein Passwort übergeben wurde, versuche gespeichertes Passwort zu verwenden
|
||||
if (!password) {
|
||||
if (!account.savePassword || !account.encryptedPassword) {
|
||||
throw new HttpError(400, 'Kein Passwort gespeichert. Bitte geben Sie Ihr Passwort ein.');
|
||||
}
|
||||
password = account.getPassword();
|
||||
}
|
||||
|
||||
// Login-Versuch
|
||||
const now = new Date();
|
||||
account.lastLoginAttempt = now;
|
||||
const client = this.getClientForService(service);
|
||||
const loginResult = await client.login(account.email, password);
|
||||
|
||||
if (loginResult.success) {
|
||||
account.lastLoginSuccess = now;
|
||||
account.accessToken = loginResult.accessToken;
|
||||
account.refreshToken = loginResult.refreshToken;
|
||||
account.expiresAt = loginResult.expiresAt;
|
||||
account.cookie = loginResult.cookie;
|
||||
account.userData = loginResult.user;
|
||||
|
||||
// Hole Club-/Verbandsdaten nur für myTischtennis
|
||||
if (service === 'mytischtennis') {
|
||||
console.log('[externalServiceService] - Getting myTischtennis user profile...');
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
console.log('[externalServiceService] - Profile result:', {
|
||||
success: profileResult.success,
|
||||
clubId: profileResult.clubId,
|
||||
clubName: profileResult.clubName,
|
||||
fedNickname: profileResult.fedNickname
|
||||
});
|
||||
|
||||
if (profileResult.success) {
|
||||
account.clubId = profileResult.clubId;
|
||||
account.clubName = profileResult.clubName;
|
||||
account.fedNickname = profileResult.fedNickname;
|
||||
console.log('[externalServiceService] - Updated account with club data');
|
||||
} else {
|
||||
console.error('[externalServiceService] - Failed to get profile:', profileResult.error);
|
||||
}
|
||||
}
|
||||
|
||||
await account.save();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
accessToken: loginResult.accessToken,
|
||||
refreshToken: loginResult.refreshToken,
|
||||
expiresAt: loginResult.expiresAt,
|
||||
user: loginResult.user,
|
||||
clubId: account.clubId,
|
||||
clubName: account.clubName
|
||||
};
|
||||
} else {
|
||||
await account.save(); // Save lastLoginAttempt
|
||||
throw new HttpError(401, loginResult.error || 'myTischtennis-Login fehlgeschlagen');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if account is configured and ready
|
||||
*/
|
||||
async checkAccountStatus(userId, service = 'mytischtennis') {
|
||||
const account = await ExternalServiceAccount.findOne({ where: { userId, service } });
|
||||
|
||||
return {
|
||||
exists: !!account,
|
||||
hasEmail: !!account?.email,
|
||||
hasPassword: !!(account?.savePassword && account?.encryptedPassword),
|
||||
hasValidSession: !!account?.accessToken && account?.expiresAt > Date.now() / 1000,
|
||||
needsConfiguration: !account || !account.email,
|
||||
needsPassword: !!account && (!account.savePassword || !account.encryptedPassword)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored session for user (for authenticated API requests)
|
||||
*/
|
||||
async getSession(userId, service = 'mytischtennis') {
|
||||
const account = await ExternalServiceAccount.findOne({ where: { userId, service } });
|
||||
|
||||
if (!account) {
|
||||
throw new HttpError(404, `Kein ${service}-Account verknüpft`);
|
||||
}
|
||||
|
||||
// Check if session is valid
|
||||
if (service === 'hettv') {
|
||||
// HeTTV nutzt Cookie-basierte Session, kein expiresAt verfügbar
|
||||
if (!account.cookie) {
|
||||
throw new HttpError(401, 'Session abgelaufen. Bitte erneut einloggen.');
|
||||
}
|
||||
} else {
|
||||
if (!account.accessToken || !account.expiresAt || account.expiresAt < Date.now() / 1000) {
|
||||
throw new HttpError(401, 'Session abgelaufen. Bitte erneut einloggen.');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken: account.accessToken,
|
||||
refreshToken: account.refreshToken,
|
||||
cookie: account.cookie,
|
||||
expiresAt: account.expiresAt,
|
||||
userData: account.userData
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Load HeTTV main page and find download links
|
||||
*/
|
||||
async loadHettvMainPage(userId) {
|
||||
const client = this.getClientForService('hettv');
|
||||
let session = await this.getSession(userId, 'hettv');
|
||||
|
||||
const finalUrl = session.userData?.finalUrl || null;
|
||||
let result = await client.getMainPageWithDownloads(session.cookie, finalUrl);
|
||||
|
||||
// Wenn Session abgelaufen: versuche automatischen Re-Login mit gespeichertem Passwort
|
||||
if (!result.success && result.status === 401) {
|
||||
const account = await ExternalServiceAccount.findOne({ where: { userId, service: 'hettv' } });
|
||||
if (account && account.savePassword && account.encryptedPassword) {
|
||||
const password = account.getPassword();
|
||||
const login = await client.login(account.email, password);
|
||||
if (login.success) {
|
||||
// Session aktualisieren
|
||||
account.cookie = login.cookie;
|
||||
account.userData = login.user;
|
||||
await account.save();
|
||||
// Erneut versuchen
|
||||
result = await client.getMainPageWithDownloads(login.cookie, login.user?.finalUrl || null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load specific HeTTV download page
|
||||
*/
|
||||
async loadHettvDownloadPage(userId, downloadUrl) {
|
||||
const session = await this.getSession(userId, 'hettv');
|
||||
const client = this.getClientForService('hettv');
|
||||
|
||||
const finalUrl = session.userData?.finalUrl || null;
|
||||
return await client.loadDownloadPage(downloadUrl, session.cookie, finalUrl);
|
||||
}
|
||||
}
|
||||
|
||||
export default new ExternalServiceService();
|
||||
|
||||
@@ -159,20 +159,20 @@ class MemberService {
|
||||
const user = await getUserByToken(userToken);
|
||||
devLog('[updateRatingsFromMyTischtennis] - User:', user.id);
|
||||
|
||||
const myTischtennisService = (await import('./myTischtennisService.js')).default;
|
||||
const externalServiceService = (await import('./externalServiceService.js')).default;
|
||||
const myTischtennisClient = (await import('../clients/myTischtennisClient.js')).default;
|
||||
|
||||
try {
|
||||
// 1. myTischtennis-Session abrufen
|
||||
devLog('[updateRatingsFromMyTischtennis] - Get session for user', user.id);
|
||||
const session = await myTischtennisService.getSession(user.id);
|
||||
const session = await externalServiceService.getSession(user.id, 'mytischtennis');
|
||||
devLog('[updateRatingsFromMyTischtennis] - Session retrieved:', {
|
||||
hasAccessToken: !!session.accessToken,
|
||||
hasCookie: !!session.cookie,
|
||||
expiresAt: session.expiresAt
|
||||
});
|
||||
|
||||
const account = await myTischtennisService.getAccount(user.id);
|
||||
const account = await externalServiceService.getAccount(user.id, 'mytischtennis');
|
||||
devLog('[updateRatingsFromMyTischtennis] - Account data:', {
|
||||
id: account?.id,
|
||||
email: account?.email,
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
import MyTischtennis from '../models/MyTischtennis.js';
|
||||
import User from '../models/User.js';
|
||||
import myTischtennisClient from '../clients/myTischtennisClient.js';
|
||||
import HttpError from '../exceptions/HttpError.js';
|
||||
|
||||
import { devLog } from '../utils/logger.js';
|
||||
class MyTischtennisService {
|
||||
/**
|
||||
* Get myTischtennis account for user
|
||||
*/
|
||||
async getAccount(userId) {
|
||||
const account = await MyTischtennis.findOne({
|
||||
where: { userId },
|
||||
attributes: ['id', 'email', 'savePassword', 'lastLoginAttempt', 'lastLoginSuccess', 'expiresAt', 'userData', 'clubId', 'clubName', 'fedNickname', 'createdAt', 'updatedAt']
|
||||
});
|
||||
return account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update myTischtennis account
|
||||
*/
|
||||
async upsertAccount(userId, email, password, savePassword, userPassword) {
|
||||
// Verify user's app password
|
||||
const user = await User.findByPk(userId);
|
||||
if (!user) {
|
||||
throw new HttpError(404, 'Benutzer nicht gefunden');
|
||||
}
|
||||
|
||||
let loginResult = null;
|
||||
|
||||
// Wenn ein Passwort gesetzt/geändert wird, App-Passwort verifizieren
|
||||
if (password) {
|
||||
const isValidPassword = await user.validatePassword(userPassword);
|
||||
if (!isValidPassword) {
|
||||
throw new HttpError(401, 'Ungültiges Passwort');
|
||||
}
|
||||
|
||||
// Login-Versuch bei myTischtennis
|
||||
loginResult = await myTischtennisClient.login(email, password);
|
||||
if (!loginResult.success) {
|
||||
throw new HttpError(401, loginResult.error || 'myTischtennis-Login fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.');
|
||||
}
|
||||
}
|
||||
|
||||
// Find or create account
|
||||
let account = await MyTischtennis.findOne({ where: { userId } });
|
||||
|
||||
const now = new Date();
|
||||
|
||||
if (account) {
|
||||
// Update existing
|
||||
account.email = email;
|
||||
account.savePassword = savePassword;
|
||||
|
||||
if (password && savePassword) {
|
||||
account.setPassword(password);
|
||||
} else if (!savePassword) {
|
||||
account.encryptedPassword = null;
|
||||
}
|
||||
|
||||
if (loginResult && loginResult.success) {
|
||||
account.lastLoginAttempt = now;
|
||||
account.lastLoginSuccess = now;
|
||||
account.accessToken = loginResult.accessToken;
|
||||
account.refreshToken = loginResult.refreshToken;
|
||||
account.expiresAt = loginResult.expiresAt;
|
||||
account.cookie = loginResult.cookie;
|
||||
account.userData = loginResult.user;
|
||||
|
||||
// Hole Club-ID und Federation
|
||||
devLog('[myTischtennisService] - Getting user profile...');
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
devLog('[myTischtennisService] - Profile result:', {
|
||||
success: profileResult.success,
|
||||
clubId: profileResult.clubId,
|
||||
clubName: profileResult.clubName,
|
||||
fedNickname: profileResult.fedNickname
|
||||
});
|
||||
|
||||
if (profileResult.success) {
|
||||
account.clubId = profileResult.clubId;
|
||||
account.clubName = profileResult.clubName;
|
||||
account.fedNickname = profileResult.fedNickname;
|
||||
devLog('[myTischtennisService] - Updated account with club data');
|
||||
} else {
|
||||
console.error('[myTischtennisService] - Failed to get profile:', profileResult.error);
|
||||
}
|
||||
} else if (password) {
|
||||
account.lastLoginAttempt = now;
|
||||
}
|
||||
|
||||
await account.save();
|
||||
} else {
|
||||
// Create new
|
||||
const accountData = {
|
||||
userId,
|
||||
email,
|
||||
savePassword,
|
||||
lastLoginAttempt: password ? now : null,
|
||||
lastLoginSuccess: loginResult?.success ? now : null
|
||||
};
|
||||
|
||||
if (loginResult && loginResult.success) {
|
||||
accountData.accessToken = loginResult.accessToken;
|
||||
accountData.refreshToken = loginResult.refreshToken;
|
||||
accountData.expiresAt = loginResult.expiresAt;
|
||||
accountData.cookie = loginResult.cookie;
|
||||
accountData.userData = loginResult.user;
|
||||
|
||||
// Hole Club-ID
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
if (profileResult.success) {
|
||||
accountData.clubId = profileResult.clubId;
|
||||
accountData.clubName = profileResult.clubName;
|
||||
}
|
||||
}
|
||||
|
||||
account = await MyTischtennis.create(accountData);
|
||||
|
||||
if (password && savePassword) {
|
||||
account.setPassword(password);
|
||||
await account.save();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
id: account.id,
|
||||
email: account.email,
|
||||
savePassword: account.savePassword,
|
||||
lastLoginAttempt: account.lastLoginAttempt,
|
||||
lastLoginSuccess: account.lastLoginSuccess,
|
||||
expiresAt: account.expiresAt
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete myTischtennis account
|
||||
*/
|
||||
async deleteAccount(userId) {
|
||||
const deleted = await MyTischtennis.destroy({
|
||||
where: { userId }
|
||||
});
|
||||
return deleted > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify login with stored or provided credentials
|
||||
*/
|
||||
async verifyLogin(userId, providedPassword = null) {
|
||||
const account = await MyTischtennis.findOne({ where: { userId } });
|
||||
|
||||
if (!account) {
|
||||
throw new HttpError(404, 'Kein myTischtennis-Account verknüpft');
|
||||
}
|
||||
|
||||
let password = providedPassword;
|
||||
|
||||
// Wenn kein Passwort übergeben wurde, versuche gespeichertes Passwort zu verwenden
|
||||
if (!password) {
|
||||
if (!account.savePassword || !account.encryptedPassword) {
|
||||
throw new HttpError(400, 'Kein Passwort gespeichert. Bitte geben Sie Ihr Passwort ein.');
|
||||
}
|
||||
password = account.getPassword();
|
||||
}
|
||||
|
||||
// Login-Versuch
|
||||
const now = new Date();
|
||||
account.lastLoginAttempt = now;
|
||||
const loginResult = await myTischtennisClient.login(account.email, password);
|
||||
|
||||
if (loginResult.success) {
|
||||
account.lastLoginSuccess = now;
|
||||
account.accessToken = loginResult.accessToken;
|
||||
account.refreshToken = loginResult.refreshToken;
|
||||
account.expiresAt = loginResult.expiresAt;
|
||||
account.cookie = loginResult.cookie;
|
||||
account.userData = loginResult.user;
|
||||
|
||||
// Hole Club-ID und Federation
|
||||
devLog('[myTischtennisService] - Getting user profile...');
|
||||
const profileResult = await myTischtennisClient.getUserProfile(loginResult.cookie);
|
||||
devLog('[myTischtennisService] - Profile result:', {
|
||||
success: profileResult.success,
|
||||
clubId: profileResult.clubId,
|
||||
clubName: profileResult.clubName,
|
||||
fedNickname: profileResult.fedNickname
|
||||
});
|
||||
|
||||
if (profileResult.success) {
|
||||
account.clubId = profileResult.clubId;
|
||||
account.clubName = profileResult.clubName;
|
||||
account.fedNickname = profileResult.fedNickname;
|
||||
devLog('[myTischtennisService] - Updated account with club data');
|
||||
} else {
|
||||
console.error('[myTischtennisService] - Failed to get profile:', profileResult.error);
|
||||
}
|
||||
|
||||
await account.save();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
accessToken: loginResult.accessToken,
|
||||
refreshToken: loginResult.refreshToken,
|
||||
expiresAt: loginResult.expiresAt,
|
||||
user: loginResult.user,
|
||||
clubId: account.clubId,
|
||||
clubName: account.clubName
|
||||
};
|
||||
} else {
|
||||
await account.save(); // Save lastLoginAttempt
|
||||
throw new HttpError(401, loginResult.error || 'myTischtennis-Login fehlgeschlagen');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if account is configured and ready
|
||||
*/
|
||||
async checkAccountStatus(userId) {
|
||||
const account = await MyTischtennis.findOne({ where: { userId } });
|
||||
|
||||
return {
|
||||
exists: !!account,
|
||||
hasEmail: !!account?.email,
|
||||
hasPassword: !!(account?.savePassword && account?.encryptedPassword),
|
||||
hasValidSession: !!account?.accessToken && account?.expiresAt > Date.now() / 1000,
|
||||
needsConfiguration: !account || !account.email,
|
||||
needsPassword: !!account && (!account.savePassword || !account.encryptedPassword)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stored session for user (for authenticated API requests)
|
||||
*/
|
||||
async getSession(userId) {
|
||||
const account = await MyTischtennis.findOne({ where: { userId } });
|
||||
|
||||
if (!account) {
|
||||
throw new HttpError(404, 'Kein myTischtennis-Account verknüpft');
|
||||
}
|
||||
|
||||
// Check if session is valid
|
||||
if (!account.accessToken || !account.expiresAt || account.expiresAt < Date.now() / 1000) {
|
||||
throw new HttpError(401, 'Session abgelaufen. Bitte erneut einloggen.');
|
||||
}
|
||||
|
||||
return {
|
||||
accessToken: account.accessToken,
|
||||
refreshToken: account.refreshToken,
|
||||
cookie: account.cookie,
|
||||
expiresAt: account.expiresAt,
|
||||
userData: account.userData
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default new MyTischtennisService();
|
||||
|
||||
Reference in New Issue
Block a user