Implement login page proxy and CAPTCHA handling in MyTischtennisClient and Controller. Enhance login process with CAPTCHA token extraction and error handling. Update frontend to support iframe-based login and improve user experience with loading indicators.
This commit is contained in:
@@ -78,6 +78,9 @@ class AutoFetchMatchResultsService {
|
||||
|
||||
const loginResult = await myTischtennisClient.login(account.email, password);
|
||||
if (!loginResult.success) {
|
||||
if (loginResult.requiresCaptcha) {
|
||||
throw new Error(`Re-login failed: CAPTCHA erforderlich. Bitte loggen Sie sich einmal direkt auf mytischtennis.de ein, um das CAPTCHA zu lösen.`);
|
||||
}
|
||||
throw new Error(`Re-login failed: ${loginResult.error}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@ class AutoUpdateRatingsService {
|
||||
|
||||
const loginResult = await myTischtennisClient.login(account.email, password);
|
||||
if (!loginResult.success) {
|
||||
if (loginResult.requiresCaptcha) {
|
||||
throw new Error(`Re-login failed: CAPTCHA erforderlich. Bitte loggen Sie sich einmal direkt auf mytischtennis.de ein, um das CAPTCHA zu lösen.`);
|
||||
}
|
||||
throw new Error(`Re-login failed: ${loginResult.error}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,12 @@ class MyTischtennisService {
|
||||
// Login-Versuch bei myTischtennis
|
||||
loginResult = await myTischtennisClient.login(email, password);
|
||||
if (!loginResult.success) {
|
||||
throw new HttpError(loginResult.error || 'myTischtennis-Login fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.', 401);
|
||||
const statusCode = loginResult.requiresCaptcha ? 400 : 401;
|
||||
const errorMessage = loginResult.error || 'myTischtennis-Login fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.';
|
||||
if (loginResult.requiresCaptcha) {
|
||||
throw new HttpError({ code: 'ERROR_MYTISCHTENNIS_CAPTCHA_REQUIRED', params: { message: errorMessage } }, statusCode);
|
||||
}
|
||||
throw new HttpError(errorMessage, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +225,7 @@ class MyTischtennisService {
|
||||
// Login-Versuch mit Passwort
|
||||
console.log('[myTischtennisService.verifyLogin] Attempting login for user:', account.email);
|
||||
const loginResult = await myTischtennisClient.login(account.email, password);
|
||||
console.log('[myTischtennisService.verifyLogin] Login result:', { success: loginResult.success, error: loginResult.error });
|
||||
console.log('[myTischtennisService.verifyLogin] Login result:', { success: loginResult.success, error: loginResult.error, requiresCaptcha: loginResult.requiresCaptcha });
|
||||
|
||||
if (loginResult.success) {
|
||||
account.lastLoginSuccess = now;
|
||||
@@ -256,10 +261,16 @@ class MyTischtennisService {
|
||||
await account.save(); // Save lastLoginAttempt
|
||||
const errorMessage = loginResult.error || 'myTischtennis-Login fehlgeschlagen';
|
||||
// Verwende den Status-Code vom myTischtennisClient, falls vorhanden, sonst 401
|
||||
const statusCode = loginResult.status && loginResult.status >= 400 && loginResult.status < 600
|
||||
? loginResult.status
|
||||
: 401;
|
||||
console.error('[myTischtennisService.verifyLogin] Login failed:', errorMessage, `(Status: ${statusCode})`);
|
||||
// Wenn CAPTCHA erforderlich ist, verwende 400 statt 401
|
||||
const statusCode = loginResult.requiresCaptcha
|
||||
? 400
|
||||
: (loginResult.status && loginResult.status >= 400 && loginResult.status < 600
|
||||
? loginResult.status
|
||||
: 401);
|
||||
console.error('[myTischtennisService.verifyLogin] Login failed:', errorMessage, `(Status: ${statusCode})`, loginResult.requiresCaptcha ? '(CAPTCHA erforderlich)' : '');
|
||||
if (loginResult.requiresCaptcha) {
|
||||
throw new HttpError({ code: 'ERROR_MYTISCHTENNIS_CAPTCHA_REQUIRED', params: { message: errorMessage } }, statusCode);
|
||||
}
|
||||
throw new HttpError(errorMessage, statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,95 +21,43 @@ class SchedulerService {
|
||||
|
||||
devLog('Starting scheduler service...');
|
||||
|
||||
// Schedule automatic rating updates at 6:00 AM daily
|
||||
// HINWEIS: Automatische MyTischtennis-Abrufe wurden deaktiviert
|
||||
// Die folgenden Jobs werden nicht mehr ausgeführt:
|
||||
// - Rating Updates (6:00 AM)
|
||||
// - Match Results Fetch (6:30 AM)
|
||||
|
||||
// Erstelle Dummy-Jobs, damit getStatus() weiterhin funktioniert
|
||||
const ratingUpdateJob = cron.schedule('0 6 * * *', async () => {
|
||||
const startTime = Date.now();
|
||||
devLog(`[${new Date().toISOString()}] CRON: Executing scheduled rating updates...`);
|
||||
|
||||
let errorMessage = null;
|
||||
|
||||
try {
|
||||
// Let the service return details including counts if available
|
||||
const result = await autoUpdateRatingsService.executeAutomaticUpdates();
|
||||
const executionTime = Date.now() - startTime;
|
||||
// result may include updatedCount or a summary object
|
||||
const messageObj = result && typeof result === 'object' ? result : { message: 'Rating updates completed successfully' };
|
||||
|
||||
// Log to ApiLog with rich details
|
||||
await apiLogService.logSchedulerExecution('rating_updates', true, messageObj, executionTime, null);
|
||||
devLog('Scheduled rating updates completed successfully');
|
||||
} catch (error) {
|
||||
const executionTime = Date.now() - startTime;
|
||||
errorMessage = error.message;
|
||||
console.error(`[${new Date().toISOString()}] CRON ERROR in scheduled rating updates:`, error);
|
||||
console.error('Stack trace:', error.stack);
|
||||
|
||||
// Log to ApiLog
|
||||
await apiLogService.logSchedulerExecution('rating_updates', false, { message: 'Rating updates failed' }, executionTime, errorMessage);
|
||||
}
|
||||
devLog('[DISABLED] Rating updates job would run here (deactivated)');
|
||||
}, {
|
||||
scheduled: false, // Don't start automatically
|
||||
scheduled: false,
|
||||
timezone: 'Europe/Berlin'
|
||||
});
|
||||
|
||||
this.jobs.set('ratingUpdates', ratingUpdateJob);
|
||||
ratingUpdateJob.start();
|
||||
devLog('Rating update job scheduled and started');
|
||||
|
||||
// Schedule automatic match results fetching at 6:30 AM daily
|
||||
const matchResultsJob = cron.schedule('30 6 * * *', async () => {
|
||||
const startTime = Date.now();
|
||||
devLog(`[${new Date().toISOString()}] CRON: Executing scheduled match results fetch...`);
|
||||
|
||||
let errorMessage = null;
|
||||
|
||||
try {
|
||||
// Execute and capture returned summary (should include counts)
|
||||
const result = await autoFetchMatchResultsService.executeAutomaticFetch();
|
||||
const executionTime = Date.now() - startTime;
|
||||
const messageObj = result && typeof result === 'object' ? result : { message: 'Match results fetch completed successfully' };
|
||||
|
||||
// Log to ApiLog with rich details (including counts if present)
|
||||
await apiLogService.logSchedulerExecution('match_results', true, messageObj, executionTime, null);
|
||||
devLog('Scheduled match results fetch completed successfully');
|
||||
} catch (error) {
|
||||
const executionTime = Date.now() - startTime;
|
||||
errorMessage = error.message;
|
||||
console.error(`[${new Date().toISOString()}] CRON ERROR in scheduled match results fetch:`, error);
|
||||
console.error('Stack trace:', error.stack);
|
||||
|
||||
// Log to ApiLog
|
||||
await apiLogService.logSchedulerExecution('match_results', false, { message: 'Match results fetch failed' }, executionTime, errorMessage);
|
||||
}
|
||||
devLog('[DISABLED] Match results fetch job would run here (deactivated)');
|
||||
}, {
|
||||
scheduled: false, // Don't start automatically
|
||||
scheduled: false,
|
||||
timezone: 'Europe/Berlin'
|
||||
});
|
||||
|
||||
// Jobs werden NICHT gestartet (deaktiviert)
|
||||
this.jobs.set('ratingUpdates', ratingUpdateJob);
|
||||
this.jobs.set('matchResults', matchResultsJob);
|
||||
matchResultsJob.start();
|
||||
devLog('Match results fetch job scheduled and started');
|
||||
|
||||
devLog('MyTischtennis automatic fetch jobs are DISABLED');
|
||||
|
||||
this.isRunning = true;
|
||||
const now = new Date();
|
||||
const tomorrow6AM = new Date(now);
|
||||
tomorrow6AM.setDate(tomorrow6AM.getDate() + 1);
|
||||
tomorrow6AM.setHours(6, 0, 0, 0);
|
||||
|
||||
const tomorrow630AM = new Date(now);
|
||||
tomorrow630AM.setDate(tomorrow630AM.getDate() + 1);
|
||||
tomorrow630AM.setHours(6, 30, 0, 0);
|
||||
|
||||
devLog('[Scheduler] ===== SCHEDULER SERVICE STARTED =====');
|
||||
devLog(`[Scheduler] Server time: ${now.toISOString()}`);
|
||||
devLog(`[Scheduler] Timezone: Europe/Berlin`);
|
||||
devLog(`[Scheduler] Rating updates: Next execution at ${tomorrow6AM.toISOString()} (6:00 AM Berlin time)`);
|
||||
devLog(`[Scheduler] Match results fetch: Next execution at ${tomorrow630AM.toISOString()} (6:30 AM Berlin time)`);
|
||||
devLog(`[Scheduler] MyTischtennis automatic fetch jobs: DISABLED`);
|
||||
devLog('[Scheduler] =====================================');
|
||||
|
||||
devLog('Scheduler service started successfully');
|
||||
devLog('Rating updates scheduled for 6:00 AM daily (Europe/Berlin timezone)');
|
||||
devLog('Match results fetch scheduled for 6:30 AM daily (Europe/Berlin timezone)');
|
||||
devLog('MyTischtennis automatic fetch jobs are DISABLED');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,30 +94,26 @@ class SchedulerService {
|
||||
|
||||
/**
|
||||
* Manually trigger rating updates (for testing)
|
||||
* HINWEIS: Deaktiviert - automatische MyTischtennis-Abrufe sind nicht mehr verfügbar
|
||||
*/
|
||||
async triggerRatingUpdates() {
|
||||
devLog('Manually triggering rating updates...');
|
||||
try {
|
||||
await autoUpdateRatingsService.executeAutomaticUpdates();
|
||||
return { success: true, message: 'Rating updates completed successfully' };
|
||||
} catch (error) {
|
||||
console.error('Error in manual rating updates:', error);
|
||||
return { success: false, message: error.message };
|
||||
}
|
||||
devLog('[DISABLED] Manual rating updates trigger called (deactivated)');
|
||||
return {
|
||||
success: false,
|
||||
message: 'Automatische MyTischtennis-Abrufe wurden deaktiviert'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually trigger match results fetch (for testing)
|
||||
* HINWEIS: Deaktiviert - automatische MyTischtennis-Abrufe sind nicht mehr verfügbar
|
||||
*/
|
||||
async triggerMatchResultsFetch() {
|
||||
devLog('Manually triggering match results fetch...');
|
||||
try {
|
||||
await autoFetchMatchResultsService.executeAutomaticFetch();
|
||||
return { success: true, message: 'Match results fetch completed successfully' };
|
||||
} catch (error) {
|
||||
console.error('Error in manual match results fetch:', error);
|
||||
return { success: false, message: error.message };
|
||||
}
|
||||
devLog('[DISABLED] Manual match results fetch trigger called (deactivated)');
|
||||
return {
|
||||
success: false,
|
||||
message: 'Automatische MyTischtennis-Abrufe wurden deaktiviert'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user