From 2a7aec9c55c6e118aefe9949627fedeeabd73021 Mon Sep 17 00:00:00 2001 From: Valerii Sidorenko Date: Wed, 8 Jan 2025 11:13:15 +0100 Subject: [PATCH] fix(Auth): do not show access error when redirecting to auth --- src/components/Errors/PageError/PageError.tsx | 15 +++++-------- src/containers/Operations/Operations.tsx | 2 +- src/containers/Tenant/Tenant.tsx | 3 ++- src/services/api/base.ts | 3 ++- src/utils/response.ts | 22 +++++++++++++++++++ 5 files changed, 33 insertions(+), 12 deletions(-) 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', + ); +}