301 lines
11 KiB
JavaScript
301 lines
11 KiB
JavaScript
"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
|