Recreate ws client when receiving auth error message

This commit is contained in:
schroda
2025-11-19 21:35:37 +01:00
parent 48b57c4a74
commit e5eda76ea7

View File

@@ -28,6 +28,7 @@ import { removeTypenameFromVariables } from '@apollo/client/link/remove-typename
import { d } from 'koration'; import { d } from 'koration';
import { useId } from '@mantine/hooks'; import { useId } from '@mantine/hooks';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { GraphQLFormattedError } from 'graphql';
import { BaseClient } from '@/lib/requests/client/BaseClient.ts'; import { BaseClient } from '@/lib/requests/client/BaseClient.ts';
import { StrictTypedTypePolicies } from '@/lib/graphql/generated/apollo-helpers.ts'; import { StrictTypedTypePolicies } from '@/lib/graphql/generated/apollo-helpers.ts';
import { AuthManager } from '@/features/authentication/AuthManager.ts'; import { AuthManager } from '@/features/authentication/AuthManager.ts';
@@ -260,16 +261,18 @@ export class GraphQLClient extends BaseClient<
}); });
} }
private isAuthError(errors: readonly GraphQLFormattedError[]): boolean {
return errors.some((graphQLError) =>
graphQLError.message.includes('suwayomi.tachidesk.server.user.UnauthorizedException'),
);
}
private createErrorLink() { private createErrorLink() {
return onError(({ graphQLErrors, operation, forward }) => { return onError(({ graphQLErrors, operation, forward }) => {
if (!graphQLErrors) { if (!graphQLErrors) {
return undefined; return undefined;
} }
if (!this.isAuthError(graphQLErrors)) {
const isAuthError = graphQLErrors.some((graphQLError) =>
graphQLError.message.includes('suwayomi.tachidesk.server.user.UnauthorizedException'),
);
if (!isAuthError) {
return undefined; return undefined;
} }
@@ -355,9 +358,22 @@ export class GraphQLClient extends BaseClient<
let triedForcedReconnection = false; let triedForcedReconnection = false;
let lastHeartbeat: number = Date.now(); let lastHeartbeat: number = Date.now();
this.wsClient.on('message', () => { this.wsClient.on('message', async (e) => {
lastHeartbeat = Date.now(); lastHeartbeat = Date.now();
triedForcedReconnection = false; triedForcedReconnection = false;
if (e.type !== 'error') {
return;
}
if (!AuthManager.isRefreshingToken() && this.isAuthError(e.payload)) {
try {
await BaseClient.refreshAccessToken(this.handleRefreshToken);
this.resetWsClient(true);
} catch (_) {
// Ignore
}
}
}); });
const checkHeartbeatInterval = heartbeatInterval + d(30).seconds.inWholeMilliseconds; const checkHeartbeatInterval = heartbeatInterval + d(30).seconds.inWholeMilliseconds;
@@ -375,6 +391,7 @@ export class GraphQLClient extends BaseClient<
return; return;
} }
clearInterval(this.wsClientAliveCheckInterval);
this.resetWsClient(true); this.resetWsClient(true);
}, checkHeartbeatInterval); }, checkHeartbeatInterval);
} }