import { CONFIG } from '../../src/utils/config.js'; import fs from 'fs'; import path from 'path'; export class FlixArtAuth { private static sessionCookie: string | null = null; private static lastLoginTime: number = 0; private static readonly COOKIE_FILE = path.resolve(process.cwd(), 'database', 'flixart_cookie.txt'); public static async getCookie(forceRefresh = false): Promise { if (!this.sessionCookie && fs.existsSync(this.COOKIE_FILE)) { try { const stats = fs.statSync(this.COOKIE_FILE); // Si le cookie a moins de 7 jours, on le réutilise (le renouvellement se fera si on obtient une 403) if (Date.now() - stats.mtimeMs < 7 * 24 * 60 * 60 * 1000) { this.sessionCookie = fs.readFileSync(this.COOKIE_FILE, 'utf-8'); this.lastLoginTime = stats.mtimeMs; } } catch (e) { console.warn('[FlixArt Auth] Impossible de lire le cookie sauvegardé:', e); } } if (!forceRefresh && this.sessionCookie && Date.now() - this.lastLoginTime < 12 * 60 * 60 * 1000) { return this.sessionCookie; } const username = CONFIG.FLIXART_USERNAME; const password = CONFIG.FLIXART_PASSWORD; const baseUrl = CONFIG.FLIXART_URL || ''; const ajaxUrl = `${baseUrl}/wp-admin/admin-ajax.php`; if (!username || !password) { throw new Error('[FlixArt Auth] Identifiants manquants.'); } console.log(`[FlixArt] Tentative de connexion avec l'utilisateur: ${username}...`); try { // 1. Obtenir un nouveau nonce de login const refreshParams = new URLSearchParams({ action: 'flixart_auth_refresh_nonces' }); const refreshRes = await fetch(ajaxUrl, { method: 'POST', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest', 'Referer': baseUrl }, body: refreshParams.toString() }); const refreshData = await refreshRes.json(); if (!refreshData.success || !refreshData.data || !refreshData.data.loginNonce) { throw new Error("Impossible d'obtenir le nonce de connexion."); } const loginNonce = refreshData.data.loginNonce; const refreshCookies = (refreshRes.headers.getSetCookie ? refreshRes.headers.getSetCookie() : [refreshRes.headers.get('set-cookie') || '']).map(c => c.split(';')[0]).filter(Boolean); const refreshCookieStr = refreshCookies.join('; '); // 2. Se connecter const dataParams = new URLSearchParams(); dataParams.append('log', username); dataParams.append('pwd', password); dataParams.append('redirect', baseUrl + '/membership-account/'); const loginParams = new URLSearchParams(); loginParams.append('action', 'flixart_auth_login'); loginParams.append('nonce', loginNonce); loginParams.append('data', dataParams.toString()); const loginRes = await fetch(ajaxUrl, { method: 'POST', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Accept': 'application/json, text/javascript, */*; q=0.01', 'X-Requested-With': 'XMLHttpRequest', 'Origin': baseUrl, 'Referer': baseUrl + '/', 'Cookie': refreshCookieStr }, body: loginParams.toString(), redirect: 'manual' }); const loginBody = await loginRes.clone().json().catch(() => ({})); if (loginBody.success === false) { const code = loginBody.data?.code || loginBody.data?.[0]?.code; if (code === 'too_many_devices') { console.log(`[FlixArt] ⚠️ Limite d'appareils atteinte. Tentative de libération...`); const recoveryParams = new URLSearchParams({ action: 'flixart_device_recovery', nonce: refreshData.data.deviceRecoveryNonce, username: username, password: password }); await fetch(ajaxUrl, { method: 'POST', headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'X-Requested-With': 'XMLHttpRequest', 'Referer': baseUrl, 'Cookie': refreshCookieStr }, body: recoveryParams.toString() }); console.log(`[FlixArt] ✅ Appareils libérés, nouvelle tentative de connexion...`); return this.getCookie(true); } throw new Error(loginBody.data?.[0]?.message || loginBody.data?.message || 'Échec de la connexion.'); } // FlixArt returns 200 OK with success: true and sets cookies const setCookieHeader = loginRes.headers.get('set-cookie') || loginRes.headers.get('Set-Cookie'); let cookies: string[] = []; if (setCookieHeader) { const setCookieHeaders = loginRes.headers.getSetCookie ? loginRes.headers.getSetCookie() : [setCookieHeader]; cookies = setCookieHeaders.map(c => c.split(';')[0]); } if (!cookies.some(c => c.includes('wordpress_logged_in_'))) { console.warn(`[FlixArt] ⚠️ Pas de cookie wordpress_logged_in trouvé.`); throw new Error('Échec de la connexion (Pas de cookie de session complet).'); } this.sessionCookie = cookies.join('; '); this.lastLoginTime = Date.now(); try { fs.writeFileSync(this.COOKIE_FILE, this.sessionCookie, 'utf-8'); } catch (e) { console.warn('[FlixArt Auth] Impossible de sauvegarder le cookie:', e); } console.log(`[FlixArt] ✅ Connexion réussie ! (Cookie généré)`); return this.sessionCookie; } catch (error: any) { console.error('[FlixArt] ❌ Erreur lors de la connexion:', error.message); throw error; } } }