diff --git a/src/components/Errors/PageError/PageError.tsx b/src/components/Errors/PageError/PageError.tsx
index 17a03f35a..75bea83c2 100644
--- a/src/components/Errors/PageError/PageError.tsx
+++ b/src/components/Errors/PageError/PageError.tsx
@@ -1,5 +1,6 @@
import React from 'react';
+import {isAccessError, isRedirectToAuth} from '../../../utils/response';
import type {EmptyStateProps} from '../../EmptyState';
import {EmptyState} from '../../EmptyState';
import {Illustration} from '../../Illustration';
@@ -15,6 +16,11 @@ interface PageErrorProps extends Omit;
}
@@ -32,12 +38,3 @@ export function PageError({title, description, error, children, ...restProps}: P
return {children};
}
-
-export function isAccessError(error: unknown) {
- return Boolean(
- error &&
- typeof error === 'object' &&
- 'status' in error &&
- (error.status === 403 || error.status === 401),
- );
-}
diff --git a/src/containers/Operations/Operations.tsx b/src/containers/Operations/Operations.tsx
index 1f12d1631..ffa916eff 100644
--- a/src/containers/Operations/Operations.tsx
+++ b/src/containers/Operations/Operations.tsx
@@ -1,12 +1,12 @@
import React from 'react';
import {AccessDenied} from '../../components/Errors/403';
-import {isAccessError} from '../../components/Errors/PageError/PageError';
import {ResponseError} from '../../components/Errors/ResponseError';
import {ResizeableDataTable} from '../../components/ResizeableDataTable/ResizeableDataTable';
import {TableWithControlsLayout} from '../../components/TableWithControlsLayout/TableWithControlsLayout';
import {operationsApi} from '../../store/reducers/operations';
import {useAutoRefreshInterval} from '../../utils/hooks';
+import {isAccessError} from '../../utils/response';
import {OperationsControls} from './OperationsControls';
import {getColumns} from './columns';
diff --git a/src/containers/Tenant/Tenant.tsx b/src/containers/Tenant/Tenant.tsx
index c12a23ada..a40b9be6b 100644
--- a/src/containers/Tenant/Tenant.tsx
+++ b/src/containers/Tenant/Tenant.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import {Helmet} from 'react-helmet-async';
import {StringParam, useQueryParams} from 'use-query-params';
-import {PageError, isAccessError} from '../../components/Errors/PageError/PageError';
+import {PageError} from '../../components/Errors/PageError/PageError';
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
import SplitPane from '../../components/SplitPane';
import {setHeaderBreadcrumbs} from '../../store/reducers/header/header';
@@ -12,6 +12,7 @@ import type {AdditionalNodesProps, AdditionalTenantsProps} from '../../types/add
import {cn} from '../../utils/cn';
import {DEFAULT_IS_TENANT_SUMMARY_COLLAPSED, DEFAULT_SIZE_TENANT_KEY} from '../../utils/constants';
import {useAutoRefreshInterval, useTypedDispatch} from '../../utils/hooks';
+import {isAccessError} from '../../utils/response';
import ObjectGeneral from './ObjectGeneral/ObjectGeneral';
import {ObjectSummary} from './ObjectSummary/ObjectSummary';
diff --git a/src/services/api/base.ts b/src/services/api/base.ts
index 623ffe19b..ac5858b17 100644
--- a/src/services/api/base.ts
+++ b/src/services/api/base.ts
@@ -4,6 +4,7 @@ import axiosRetry from 'axios-retry';
import {backend as BACKEND} from '../../store';
import {DEV_ENABLE_TRACING_FOR_ALL_REQUESTS} from '../../utils/constants';
+import {isRedirectToAuth} from '../../utils/response';
import {settingsManager} from '../settings';
export type AxiosOptions = {
@@ -63,7 +64,7 @@ export class BaseYdbAPI extends AxiosWrapper {
// OIDC proxy returns 401 response with authUrl in it
// authUrl - external auth service link, after successful auth additional cookies will be appended
// that will allow access to clusters where OIDC proxy is a balancer
- if (response && response.status === 401 && response.data?.authUrl) {
+ if (isRedirectToAuth(response)) {
window.location.assign(response.data.authUrl);
}
diff --git a/src/utils/response.ts b/src/utils/response.ts
index aff517d40..f040ce229 100644
--- a/src/utils/response.ts
+++ b/src/utils/response.ts
@@ -24,3 +24,25 @@ export function isAxiosError(error: unknown): error is AxiosErrorObject {
error && typeof error === 'object' && 'name' in error && error.name === 'AxiosError',
);
}
+
+export function isAccessError(error: unknown): error is {status: number} {
+ return Boolean(
+ error &&
+ typeof error === 'object' &&
+ 'status' in error &&
+ (error.status === 403 || error.status === 401),
+ );
+}
+
+export function isRedirectToAuth(error: unknown): error is {status: 401; data: {authUrl: string}} {
+ return Boolean(
+ isAccessError(error) &&
+ error.status === 401 &&
+ 'data' in error &&
+ error.data &&
+ typeof error.data === 'object' &&
+ 'authUrl' in error.data &&
+ error.data.authUrl &&
+ typeof error.data.authUrl === 'string',
+ );
+}