Fix login auto-retry deadlock
This commit is contained in:
Vendored
+1
@@ -48,6 +48,7 @@ export declare class AgrarmonitorConnector implements AgrarmonitorConnectorResul
|
|||||||
private performLogin;
|
private performLogin;
|
||||||
private performRedirectLogin;
|
private performRedirectLogin;
|
||||||
private isSessionValid;
|
private isSessionValid;
|
||||||
|
private loginRequestConfig;
|
||||||
private isLoginRequiredResponse;
|
private isLoginRequiredResponse;
|
||||||
private retryAfterLogin;
|
private retryAfterLogin;
|
||||||
private createDateienLivesearchParams;
|
private createDateienLivesearchParams;
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"AgrarmonitorConnector.d.ts","sourceRoot":"","sources":["../src/AgrarmonitorConnector.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"AgrarmonitorConnector.d.ts","sourceRoot":"","sources":["../src/AgrarmonitorConnector.ts"],"names":[],"mappings":"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"}
|
||||||
Vendored
+21
-9
@@ -406,14 +406,16 @@ class AgrarmonitorConnector {
|
|||||||
}));
|
}));
|
||||||
client.interceptors.response.use(async (response) => {
|
client.interceptors.response.use(async (response) => {
|
||||||
await this.options.cookieStore.save(this.cookieJar);
|
await this.options.cookieStore.save(this.cookieJar);
|
||||||
if (this.autoRetry && this.isLoginRequiredResponse(response)) {
|
const config = response.config;
|
||||||
return this.retryAfterLogin(response.config);
|
if (this.autoRetry && !config._agrarmonitorLoginRequest && this.isLoginRequiredResponse(response)) {
|
||||||
|
return this.retryAfterLogin(config);
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}, async (error) => {
|
}, async (error) => {
|
||||||
const response = error.response;
|
const response = error.response;
|
||||||
if (this.autoRetry && response && this.isLoginRequiredResponse(response)) {
|
const config = error.config;
|
||||||
return this.retryAfterLogin(error.config);
|
if (this.autoRetry && response && config && !config._agrarmonitorLoginRequest && this.isLoginRequiredResponse(response)) {
|
||||||
|
return this.retryAfterLogin(config);
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
@@ -487,11 +489,14 @@ class AgrarmonitorConnector {
|
|||||||
this.logger?.warn?.('loginStrategy "auto" ist veraltet; verwende Redirect-Login');
|
this.logger?.warn?.('loginStrategy "auto" ist veraltet; verwende Redirect-Login');
|
||||||
}
|
}
|
||||||
await this.performRedirectLogin();
|
await this.performRedirectLogin();
|
||||||
|
if (!(await this.isSessionValid({ skipAutoRetry: true }))) {
|
||||||
|
throw new Error('Agrarmonitor-Login durchgefuehrt, Session weiterhin ungueltig - Geraet freigeschaltet? Credentials korrekt?');
|
||||||
|
}
|
||||||
await this.options.cookieStore.save(this.cookieJar);
|
await this.options.cookieStore.save(this.cookieJar);
|
||||||
this.logger?.info?.('Agrarmonitor-Login erfolgreich');
|
this.logger?.info?.('Agrarmonitor-Login erfolgreich');
|
||||||
}
|
}
|
||||||
async performRedirectLogin() {
|
async performRedirectLogin() {
|
||||||
const loginPageResponse = await this.http.get('/');
|
const loginPageResponse = await this.http.get('/', this.loginRequestConfig());
|
||||||
const loginPageText = typeof loginPageResponse.data === 'string' ? loginPageResponse.data : '';
|
const loginPageText = typeof loginPageResponse.data === 'string' ? loginPageResponse.data : '';
|
||||||
if (!this.isLoginPageText(loginPageText)) {
|
if (!this.isLoginPageText(loginPageText)) {
|
||||||
return;
|
return;
|
||||||
@@ -504,25 +509,32 @@ class AgrarmonitorConnector {
|
|||||||
ssoAction: "",
|
ssoAction: "",
|
||||||
ssoReturn: "",
|
ssoReturn: "",
|
||||||
};
|
};
|
||||||
const response = await this.http.post('/login/api/login.php', loginData, {
|
const loginPostConfig = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
_agrarmonitorLoginRequest: true,
|
||||||
|
};
|
||||||
|
const response = await this.http.post('/login/api/login.php', loginData, loginPostConfig);
|
||||||
const responseText = typeof response.data === 'string' ? response.data : '';
|
const responseText = typeof response.data === 'string' ? response.data : '';
|
||||||
if (this.isLoginPageText(responseText)) {
|
if (this.isLoginPageText(responseText)) {
|
||||||
throw new Error('Agrarmonitor-Redirect-Login fehlgeschlagen');
|
throw new Error('Agrarmonitor-Redirect-Login fehlgeschlagen');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async isSessionValid() {
|
async isSessionValid(options = {}) {
|
||||||
try {
|
try {
|
||||||
const response = await this.http.get('/');
|
const response = await this.http.get('/', options.skipAutoRetry ? this.loginRequestConfig() : undefined);
|
||||||
return !this.isLoginRequiredResponse(response);
|
return !this.isLoginRequiredResponse(response);
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
loginRequestConfig() {
|
||||||
|
return {
|
||||||
|
_agrarmonitorLoginRequest: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
isLoginRequiredResponse(response) {
|
isLoginRequiredResponse(response) {
|
||||||
const responseUrl = this.getResponseUrl(response);
|
const responseUrl = this.getResponseUrl(response);
|
||||||
const responseText = typeof response.data === 'string' ? response.data : '';
|
const responseText = typeof response.data === 'string' ? response.data : '';
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -11,6 +11,7 @@
|
|||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
|
"test": "npm run build && node --test test/*.test.js",
|
||||||
"typecheck": "tsc -p tsconfig.json --noEmit"
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import type {
|
|||||||
|
|
||||||
type RetryableAxiosRequestConfig = AxiosRequestConfig & {
|
type RetryableAxiosRequestConfig = AxiosRequestConfig & {
|
||||||
_agrarmonitorRetry?: boolean;
|
_agrarmonitorRetry?: boolean;
|
||||||
|
_agrarmonitorLoginRequest?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AgrarmonitorCustomerPage = {
|
type AgrarmonitorCustomerPage = {
|
||||||
@@ -557,17 +558,20 @@ export class AgrarmonitorConnector implements AgrarmonitorConnectorResult {
|
|||||||
async response => {
|
async response => {
|
||||||
await this.options.cookieStore.save(this.cookieJar);
|
await this.options.cookieStore.save(this.cookieJar);
|
||||||
|
|
||||||
if (this.autoRetry && this.isLoginRequiredResponse(response)) {
|
const config = response.config as RetryableAxiosRequestConfig;
|
||||||
return this.retryAfterLogin(response.config);
|
|
||||||
|
if (this.autoRetry && !config._agrarmonitorLoginRequest && this.isLoginRequiredResponse(response)) {
|
||||||
|
return this.retryAfterLogin(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
async error => {
|
async error => {
|
||||||
const response = error.response as AxiosResponse | undefined;
|
const response = error.response as AxiosResponse | undefined;
|
||||||
|
const config = error.config as RetryableAxiosRequestConfig | undefined;
|
||||||
|
|
||||||
if (this.autoRetry && response && this.isLoginRequiredResponse(response)) {
|
if (this.autoRetry && response && config && !config._agrarmonitorLoginRequest && this.isLoginRequiredResponse(response)) {
|
||||||
return this.retryAfterLogin(error.config);
|
return this.retryAfterLogin(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw error;
|
throw error;
|
||||||
@@ -663,12 +667,16 @@ export class AgrarmonitorConnector implements AgrarmonitorConnectorResult {
|
|||||||
|
|
||||||
await this.performRedirectLogin();
|
await this.performRedirectLogin();
|
||||||
|
|
||||||
|
if (!(await this.isSessionValid({ skipAutoRetry: true }))) {
|
||||||
|
throw new Error('Agrarmonitor-Login durchgefuehrt, Session weiterhin ungueltig - Geraet freigeschaltet? Credentials korrekt?');
|
||||||
|
}
|
||||||
|
|
||||||
await this.options.cookieStore.save(this.cookieJar);
|
await this.options.cookieStore.save(this.cookieJar);
|
||||||
this.logger?.info?.('Agrarmonitor-Login erfolgreich');
|
this.logger?.info?.('Agrarmonitor-Login erfolgreich');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async performRedirectLogin(): Promise<void> {
|
private async performRedirectLogin(): Promise<void> {
|
||||||
const loginPageResponse = await this.http.get('/');
|
const loginPageResponse = await this.http.get('/', this.loginRequestConfig());
|
||||||
const loginPageText = typeof loginPageResponse.data === 'string' ? loginPageResponse.data : '';
|
const loginPageText = typeof loginPageResponse.data === 'string' ? loginPageResponse.data : '';
|
||||||
|
|
||||||
if (!this.isLoginPageText(loginPageText)) {
|
if (!this.isLoginPageText(loginPageText)) {
|
||||||
@@ -684,11 +692,14 @@ export class AgrarmonitorConnector implements AgrarmonitorConnectorResult {
|
|||||||
ssoReturn: "",
|
ssoReturn: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await this.http.post('/login/api/login.php', loginData, {
|
const loginPostConfig: RetryableAxiosRequestConfig = {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
});
|
_agrarmonitorLoginRequest: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await this.http.post('/login/api/login.php', loginData, loginPostConfig);
|
||||||
|
|
||||||
const responseText = typeof response.data === 'string' ? response.data : '';
|
const responseText = typeof response.data === 'string' ? response.data : '';
|
||||||
|
|
||||||
@@ -697,15 +708,21 @@ export class AgrarmonitorConnector implements AgrarmonitorConnectorResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async isSessionValid(): Promise<boolean> {
|
private async isSessionValid(options: { skipAutoRetry?: boolean } = {}): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const response = await this.http.get('/');
|
const response = await this.http.get('/', options.skipAutoRetry ? this.loginRequestConfig() : undefined);
|
||||||
return !this.isLoginRequiredResponse(response);
|
return !this.isLoginRequiredResponse(response);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loginRequestConfig(): RetryableAxiosRequestConfig {
|
||||||
|
return {
|
||||||
|
_agrarmonitorLoginRequest: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private isLoginRequiredResponse(response: AxiosResponse): boolean {
|
private isLoginRequiredResponse(response: AxiosResponse): boolean {
|
||||||
const responseUrl = this.getResponseUrl(response);
|
const responseUrl = this.getResponseUrl(response);
|
||||||
const responseText = typeof response.data === 'string' ? response.data : '';
|
const responseText = typeof response.data === 'string' ? response.data : '';
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
const assert = require('node:assert/strict');
|
||||||
|
const http = require('node:http');
|
||||||
|
const test = require('node:test');
|
||||||
|
|
||||||
|
const { AgrarmonitorConnector, MemoryCookieStore } = require('../dist');
|
||||||
|
|
||||||
|
const loginPage = `
|
||||||
|
<html>
|
||||||
|
<head><title>Anmeldung - AGRARMONITOR</title></head>
|
||||||
|
<body>
|
||||||
|
<form>
|
||||||
|
<input name="nonce" value="test-nonce" />
|
||||||
|
<button>Einloggen</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
|
||||||
|
function createServer() {
|
||||||
|
let loggedIn = false;
|
||||||
|
const requests = [];
|
||||||
|
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
requests.push({ method: req.method, url: req.url });
|
||||||
|
|
||||||
|
if (req.method === 'GET' && req.url === '/') {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||||
|
res.end(loggedIn ? '<html><body>Mein AM</body></html>' : loginPage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.method === 'POST' && req.url === '/login/api/login.php') {
|
||||||
|
let body = '';
|
||||||
|
req.on('data', chunk => {
|
||||||
|
body += chunk;
|
||||||
|
});
|
||||||
|
req.on('end', () => {
|
||||||
|
const parsed = JSON.parse(body);
|
||||||
|
assert.equal(req.headers['content-type'], 'application/json');
|
||||||
|
assert.equal(parsed.username, 'demo');
|
||||||
|
assert.equal(parsed.passwort, 'secret');
|
||||||
|
assert.equal(parsed.nonce, 'test-nonce');
|
||||||
|
assert.equal(parsed.ssoAction, '');
|
||||||
|
assert.equal(parsed.ssoReturn, '');
|
||||||
|
|
||||||
|
loggedIn = true;
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Set-Cookie': 'agrar_session=test; Path=/',
|
||||||
|
});
|
||||||
|
res.end(JSON.stringify({ success: true }));
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(404);
|
||||||
|
res.end('not found');
|
||||||
|
});
|
||||||
|
|
||||||
|
return { server, requests };
|
||||||
|
}
|
||||||
|
|
||||||
|
test('autoRetry does not deadlock on login-internal requests', async t => {
|
||||||
|
const { server, requests } = createServer();
|
||||||
|
|
||||||
|
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||||
|
t.after(() => new Promise(resolve => server.close(resolve)));
|
||||||
|
|
||||||
|
const address = server.address();
|
||||||
|
const baseUrl = `http://127.0.0.1:${address.port}`;
|
||||||
|
|
||||||
|
const connector = new AgrarmonitorConnector({
|
||||||
|
baseUrl,
|
||||||
|
username: 'demo',
|
||||||
|
password: 'secret',
|
||||||
|
cookieStore: new MemoryCookieStore(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const timeout = new Promise((_, reject) => {
|
||||||
|
const timer = setTimeout(() => reject(new Error('Login deadlocked')), 2000);
|
||||||
|
timer.unref();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.race([connector.init(), timeout]);
|
||||||
|
|
||||||
|
const response = await Promise.race([connector.http.get('/'), timeout]);
|
||||||
|
assert.equal(response.status, 200);
|
||||||
|
assert.equal(requests.filter(request => request.url === '/login/api/login.php').length, 1);
|
||||||
|
assert.ok(requests.filter(request => request.method === 'GET' && request.url === '/').length >= 3);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user