Retry Matrix capture after chat login redirect
This commit is contained in:
1 parent
bffda95251
commit
d2b3a1b31d
2 files changed
+55
-7
No files matched your search
@@ -2,7 +2,10 @@ import type { BrowserContext } from 'playwright';
|
|||||||
import type { Logger } from '../../../utils/logger.js';
|
import type { Logger } from '../../../utils/logger.js';
|
||||||
import type { TokenRefresher } from '../service.js';
|
import type { TokenRefresher } from '../service.js';
|
||||||
import type { MatrixCredentials } from './types.js';
|
import type { MatrixCredentials } from './types.js';
|
||||||
import { extractMatrixCredentials } from './token-extractor.js';
|
import {
|
||||||
|
extractMatrixCredentials,
|
||||||
|
MatrixBrowserLoginRequiredError,
|
||||||
|
} from './token-extractor.js';
|
||||||
|
|
||||||
export interface MatrixSessionBrowser {
|
export interface MatrixSessionBrowser {
|
||||||
getContext(): BrowserContext | null;
|
getContext(): BrowserContext | null;
|
||||||
@@ -50,12 +53,10 @@ export class MatrixTokenRefresher implements TokenRefresher {
|
|||||||
|
|
||||||
private async performRefresh(): Promise<void> {
|
private async performRefresh(): Promise<void> {
|
||||||
const sessionValid = await this.browser.isSessionValid();
|
const sessionValid = await this.browser.isSessionValid();
|
||||||
|
let sessionRestored = false;
|
||||||
if (!sessionValid) {
|
if (!sessionValid) {
|
||||||
this.logger.warn('[matrix] Reddit browser session expired; attempting login recovery');
|
await this.restoreSession();
|
||||||
if (!(await this.browser.login())) {
|
sessionRestored = true;
|
||||||
throw new MatrixRemoteLoginRequiredError();
|
|
||||||
}
|
|
||||||
this.logger.info('[matrix] Reddit browser session restored');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const context = this.browser.getContext();
|
const context = this.browser.getContext();
|
||||||
@@ -63,7 +64,34 @@ export class MatrixTokenRefresher implements TokenRefresher {
|
|||||||
throw new Error('Matrix token refresh requires an initialized browser context');
|
throw new Error('Matrix token refresh requires an initialized browser context');
|
||||||
}
|
}
|
||||||
|
|
||||||
const credentials = await this.extract(context, this.logger);
|
let credentials: MatrixCredentials;
|
||||||
|
try {
|
||||||
|
credentials = await this.extract(context, this.logger);
|
||||||
|
} catch (error) {
|
||||||
|
if (!(error instanceof MatrixBrowserLoginRequiredError)) throw error;
|
||||||
|
if (sessionRestored) throw new MatrixRemoteLoginRequiredError();
|
||||||
|
|
||||||
|
this.logger.warn(
|
||||||
|
'[matrix] Reddit API session looked valid but chat requires login; attempting recovery',
|
||||||
|
);
|
||||||
|
await this.restoreSession();
|
||||||
|
try {
|
||||||
|
credentials = await this.extract(context, this.logger);
|
||||||
|
} catch (retryError) {
|
||||||
|
if (retryError instanceof MatrixBrowserLoginRequiredError) {
|
||||||
|
throw new MatrixRemoteLoginRequiredError();
|
||||||
|
}
|
||||||
|
throw retryError;
|
||||||
|
}
|
||||||
|
}
|
||||||
this.applyCredentials(credentials);
|
this.applyCredentials(credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async restoreSession(): Promise<void> {
|
||||||
|
this.logger.warn('[matrix] Reddit browser session expired; attempting login recovery');
|
||||||
|
if (!(await this.browser.login())) {
|
||||||
|
throw new MatrixRemoteLoginRequiredError();
|
||||||
|
}
|
||||||
|
this.logger.info('[matrix] Reddit browser session restored');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
MatrixRemoteLoginRequiredError,
|
MatrixRemoteLoginRequiredError,
|
||||||
MatrixTokenRefresher,
|
MatrixTokenRefresher,
|
||||||
} from '../src/services/chat/matrix/token-refresher.js';
|
} from '../src/services/chat/matrix/token-refresher.js';
|
||||||
|
import { MatrixBrowserLoginRequiredError } from '../src/services/chat/matrix/token-extractor.js';
|
||||||
import type { MatrixCredentials } from '../src/services/chat/matrix/types.js';
|
import type { MatrixCredentials } from '../src/services/chat/matrix/types.js';
|
||||||
|
|
||||||
const credentials: MatrixCredentials = {
|
const credentials: MatrixCredentials = {
|
||||||
@@ -75,4 +76,23 @@ describe('MatrixTokenRefresher', () => {
|
|||||||
|
|
||||||
expect(applyCredentials).toHaveBeenCalledOnce();
|
expect(applyCredentials).toHaveBeenCalledOnce();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('repairs and retries when chat redirects to login despite a valid Reddit API session', async () => {
|
||||||
|
const { refresher, browser, context, extract, applyCredentials } = setup({
|
||||||
|
sessionValid: true,
|
||||||
|
loginSucceeds: true,
|
||||||
|
});
|
||||||
|
extract
|
||||||
|
.mockRejectedValueOnce(
|
||||||
|
new MatrixBrowserLoginRequiredError('https://www.reddit.com/login/?dest=/chat/'),
|
||||||
|
)
|
||||||
|
.mockResolvedValueOnce(credentials);
|
||||||
|
|
||||||
|
await refresher.refresh();
|
||||||
|
|
||||||
|
expect(browser.login).toHaveBeenCalledOnce();
|
||||||
|
expect(extract).toHaveBeenCalledTimes(2);
|
||||||
|
expect(extract).toHaveBeenNthCalledWith(2, context, expect.anything());
|
||||||
|
expect(applyCredentials).toHaveBeenCalledWith(credentials);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user