"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AgrarmonitorConnector = void 0; const axios_1 = __importDefault(require("axios")); const axios_cookiejar_support_1 = require("axios-cookiejar-support"); const jsdom_1 = require("jsdom"); const tough_cookie_1 = require("tough-cookie"); class AgrarmonitorConnector { options; http; baseUrl; apiBaseUrl; timeoutMs; autoLogin; autoRetry; loginStrategy; logger; cookieJar; loginInProgress = null; constructor(options) { this.options = options; this.baseUrl = options.baseUrl ?? 'https://admin7.agrarmonitor.de'; this.apiBaseUrl = options.apiBaseUrl ?? 'https://api.agrarmonitor.de'; this.timeoutMs = options.timeoutMs ?? 15000; this.autoLogin = options.autoLogin ?? true; this.autoRetry = options.autoRetry ?? true; this.loginStrategy = options.loginStrategy ?? 'auto'; this.logger = options.logger; } async init() { this.cookieJar = await this.options.cookieStore.load(); this.http = this.createHttpClient(); if (this.autoLogin) { const valid = await this.isSessionValid(); if (!valid) { await this.login(); } } return this; } async login() { if (this.loginInProgress) { return this.loginInProgress; } this.loginInProgress = this.performLogin().finally(() => { this.loginInProgress = null; }); return this.loginInProgress; } async clearSession() { this.cookieJar = new tough_cookie_1.CookieJar(); await this.options.cookieStore.clear(); this.http = this.createHttpClient(); } async saveSession() { await this.options.cookieStore.save(this.cookieJar); } async getCookieCount(url = this.baseUrl) { return this.cookieJar.getCookiesSync(url).length; } async checkFreigeschaltet() { const response = await this.http.get('/', { maxRedirects: 0, validateStatus: status => status >= 200 && status < 400, }); await this.saveSession(); const redirectLocation = this.getHeader(response, 'location'); const redirected = response.status >= 300 && response.status < 400 && this.isFreischaltungUrl(redirectLocation); return { freigeschaltet: !redirected, status: response.status, redirected, redirectLocation, timestamp: new Date().toISOString(), cookies: await this.getCookieCount(), }; } async checkRegistriert() { const response = await this.http.get('/', { maxRedirects: 5, validateStatus: status => status >= 200 && status < 500, }); await this.saveSession(); const pageContent = typeof response.data === 'string' ? response.data : ''; const hasRegistrationText = pageContent.includes('Neues Gerät registrieren'); return { registriert: !hasRegistrationText, status: response.status, hasRegistrationText, timestamp: new Date().toISOString(), cookies: await this.getCookieCount(), }; } async registerDevice(registration) { const agrarmonitorId = registration.agrarmonitorId.trim(); const pcName = registration.pcName.trim(); if (!agrarmonitorId || !pcName) { throw new Error('AgrarmonitorID und PC-Name sind erforderlich'); } const freischaltungResponse = await this.http.get('/freischaltung/'); const responseContent = typeof freischaltungResponse.data === 'string' ? freischaltungResponse.data : ''; const nonce = this.extractNonce(responseContent, '#nonce, input[name="nonce"]'); const registerResponse = await this.http.post('/freischaltung/api/register.php', { firma: agrarmonitorId, name: pcName, nonce, }, { headers: { 'Content-Type': 'application/json', }, validateStatus: status => status >= 200 && status < 500, }); await this.saveSession(); const success = registerResponse.status >= 200 && registerResponse.status < 300; return { success, status: registerResponse.status, message: success ? 'Registrierung erfolgreich' : 'Registrierung fehlgeschlagen', data: { agrarmonitorId, pcName, nonce: this.maskNonce(nonce), }, timestamp: new Date().toISOString(), cookies: await this.getCookieCount(), }; } async fetchCustomers(options = {}) { const apiToken = options.apiToken ?? this.options.apiToken; if (!apiToken) { throw new Error('Agrarmonitor API-Token nicht konfiguriert'); } const response = await this.http.get(`${this.apiBaseUrl}/v1/kunden`, { params: { per_page: options.perPage ?? 99999, api_token: apiToken, }, }); await this.saveSession(); const responseData = response.data; if (!responseData || !Array.isArray(responseData.data)) { throw new Error('Ungueltige Agrarmonitor API-Antwort'); } return responseData.data; } createHttpClient() { const client = (0, axios_cookiejar_support_1.wrapper)(axios_1.default.create({ baseURL: this.baseUrl, jar: this.cookieJar, withCredentials: true, timeout: this.timeoutMs, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', }, maxRedirects: 5, validateStatus: status => status >= 200 && status < 400, })); client.interceptors.response.use(async (response) => { await this.options.cookieStore.save(this.cookieJar); if (this.autoRetry && this.isLoginRequiredResponse(response)) { return this.retryAfterLogin(response.config); } return response; }, async (error) => { const response = error.response; if (this.autoRetry && response && this.isLoginRequiredResponse(response)) { return this.retryAfterLogin(error.config); } throw error; }); return client; } async performLogin() { if (!this.options.username || !this.options.password) { throw new Error('Agrarmonitor-Credentials nicht konfiguriert'); } this.logger?.info?.('Fuehre Agrarmonitor-Login durch'); if (this.loginStrategy === 'auth') { await this.performAuthLogin(); } else if (this.loginStrategy === 'legacy') { await this.performLegacyLogin(); } else { await this.performAutoLogin(); } await this.options.cookieStore.save(this.cookieJar); this.logger?.info?.('Agrarmonitor-Login erfolgreich'); } async performAutoLogin() { try { await this.performAuthLogin(); } catch (authError) { this.logger?.warn?.('Agrarmonitor-Login via /auth/login fehlgeschlagen, versuche Legacy-Login', authError); await this.performLegacyLogin(); } } async performAuthLogin() { await this.http.get('/auth/login'); const loginData = new URLSearchParams({ email: this.options.username, password: this.options.password, remember: 'on', }); const response = await this.http.post('/auth/login', loginData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }); const responseText = typeof response.data === 'string' ? response.data : ''; if (responseText.includes('Anmeldung fehlgeschlagen')) { throw new Error('Agrarmonitor-Login fehlgeschlagen'); } } async performLegacyLogin() { const loginPageResponse = await this.http.get('/'); const loginPageText = typeof loginPageResponse.data === 'string' ? loginPageResponse.data : ''; if (!this.isLoginPageText(loginPageText)) { return; } const nonce = this.extractNonce(loginPageText, 'input[name="nonce"]'); const loginData = new URLSearchParams({ username: this.options.username, passwort: this.options.password, nonce, }); const response = await this.http.post('/redirect.php?id=benutzerverwaltung&action=login', loginData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }); const responseText = typeof response.data === 'string' ? response.data : ''; if (this.isLoginPageText(responseText)) { throw new Error('Agrarmonitor-Legacy-Login fehlgeschlagen'); } } async isSessionValid() { try { const response = await this.http.get('/'); return !this.isLoginRequiredResponse(response); } catch { return false; } } isLoginRequiredResponse(response) { const responseUrl = this.getResponseUrl(response); const responseText = typeof response.data === 'string' ? response.data : ''; return (response.status === 401 || response.status === 403 || responseUrl.includes('/auth/login') || responseText.includes('/auth/login') || this.isLoginPageText(responseText) || responseText.includes('Anmeldung') || responseText.includes('Einloggen')); } async retryAfterLogin(config) { if (config._agrarmonitorRetry) { throw new Error('Agrarmonitor-Request nach erneutem Login weiterhin nicht autorisiert'); } config._agrarmonitorRetry = true; this.logger?.info?.('Agrarmonitor-Session abgelaufen, erneuter Login wird ausgefuehrt'); await this.login(); return this.http.request(config); } getResponseUrl(response) { const request = response.request; return request?.res?.responseUrl ?? ''; } getHeader(response, header) { const value = response.headers[header.toLowerCase()]; if (Array.isArray(value)) { return value[0] ?? null; } return typeof value === 'string' ? value : null; } isFreischaltungUrl(value) { return Boolean(value?.includes('freischaltung')); } isLoginPageText(responseText) { return responseText.includes('Anmeldung - AGRARMONITOR'); } extractNonce(html, selector) { const dom = new jsdom_1.JSDOM(html); const element = dom.window.document.querySelector(selector); const nonce = element?.getAttribute('value') ?? element?.value ?? ''; if (!nonce) { throw new Error('Nonce-Element nicht gefunden oder leer'); } return nonce; } maskNonce(nonce) { return nonce.length <= 10 ? nonce : `${nonce.slice(0, 10)}...`; } } exports.AgrarmonitorConnector = AgrarmonitorConnector; //# sourceMappingURL=AgrarmonitorConnector.js.map