149 lines
6.9 KiB
TypeScript
149 lines
6.9 KiB
TypeScript
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<string> {
|
|
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;
|
|
}
|
|
}
|
|
}
|