Skip to content

Commit 4c519c1

Browse files
authored
feat: support meta logout (#2998)
1 parent da03b66 commit 4c519c1

File tree

7 files changed

+62
-30
lines changed

7 files changed

+62
-30
lines changed

src/components/LoaderWrapper/LoaderWrapper.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ interface LoaderWrapperProps {
99
size?: LoaderSize;
1010
className?: string;
1111
children: React.ReactNode;
12+
delay?: number;
1213
}
1314

14-
export function LoaderWrapper({loading, size = 'm', className, children}: LoaderWrapperProps) {
15+
export function LoaderWrapper({
16+
loading,
17+
size = 'm',
18+
className,
19+
children,
20+
delay,
21+
}: LoaderWrapperProps) {
1522
if (loading) {
16-
return <Loader size={size} className={className} />;
23+
return <Loader size={size} className={className} delay={delay} />;
1724
}
1825
return children;
1926
}

src/containers/App/Content.tsx

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ import React from 'react';
22

33
import {connect} from 'react-redux';
44
import type {RedirectProps} from 'react-router-dom';
5-
import {Redirect, Route, Switch, useLocation} from 'react-router-dom';
5+
import {Redirect, Route, Switch} from 'react-router-dom';
66

77
import {AccessDenied} from '../../components/Errors/403';
88
import {PageError} from '../../components/Errors/PageError/PageError';
99
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
1010
import {useSlots} from '../../components/slots';
1111
import type {SlotMap} from '../../components/slots/SlotMap';
1212
import type {SlotComponent} from '../../components/slots/types';
13-
import routes, {checkIsClustersPage} from '../../routes';
13+
import routes from '../../routes';
1414
import type {RootState} from '../../store';
1515
import {authenticationApi} from '../../store/reducers/authentication/authentication';
1616
import {
1717
useCapabilitiesQuery,
1818
useClusterWithoutAuthInUI,
1919
useMetaCapabilitiesLoaded,
2020
useMetaCapabilitiesQuery,
21-
useMetaLoginAvailable,
2221
} from '../../store/reducers/capabilities/hooks';
2322
import {nodesListApi} from '../../store/reducers/nodesList';
2423
import {uiFactory} from '../../uiFactory/uiFactory';
2524
import {cn} from '../../utils/cn';
2625
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
26+
import {useMetaAuth, useMetaAuthUnavailable} from '../../utils/hooks/useMetaAuth';
2727
import {lazyComponent} from '../../utils/lazyComponent';
2828
import {isAccessError, isRedirectToAuth} from '../../utils/response';
2929
import Authentication from '../Authentication/Authentication';
@@ -201,13 +201,9 @@ function ClustersDataWrapper({children}: {children: React.ReactNode}) {
201201
}
202202

203203
function GetMetaUser({children}: {children: React.ReactNode}) {
204-
const location = useLocation();
204+
const metaAuth = useMetaAuth();
205205

206-
const isClustersPage = checkIsClustersPage(location.pathname);
207-
208-
const isMetaLoginAvailable = useMetaLoginAvailable();
209-
210-
if (isClustersPage && isMetaLoginAvailable) {
206+
if (metaAuth) {
211207
return <GetUser useMeta>{children}</GetUser>;
212208
}
213209
return children;
@@ -216,7 +212,7 @@ function GetMetaUser({children}: {children: React.ReactNode}) {
216212
function GetUser({children, useMeta}: {children: React.ReactNode; useMeta?: boolean}) {
217213
const database = useDatabaseFromQuery();
218214

219-
const {isLoading, error} = authenticationApi.useWhoamiQuery({
215+
const {isFetching, error} = authenticationApi.useWhoamiQuery({
220216
database,
221217
useMeta,
222218
});
@@ -225,7 +221,7 @@ function GetUser({children, useMeta}: {children: React.ReactNode; useMeta?: bool
225221
const errorProps = error ? {...uiFactory.clusterOrDatabaseAccessError} : undefined;
226222

227223
return (
228-
<LoaderWrapper loading={isLoading} size="l">
224+
<LoaderWrapper loading={isFetching} size="l" delay={0}>
229225
<PageError error={error} {...errorProps} errorPageTitle={appTitle}>
230226
{children}
231227
</PageError>
@@ -288,15 +284,10 @@ function ContentWrapper(props: ContentWrapperProps) {
288284
const {singleClusterMode, isAuthenticated} = props;
289285
const authUnavailable = useClusterWithoutAuthInUI();
290286

291-
const location = useLocation();
292-
const isClustersPage = checkIsClustersPage(location.pathname);
293-
294-
const isMetaLoginAvailable = useMetaLoginAvailable();
295-
296-
const isClustersAuthUnavailable = isClustersPage && !isMetaLoginAvailable;
287+
const metaAuthUnavailable = useMetaAuthUnavailable();
297288

298289
const renderNotAuthenticated = () => {
299-
if (authUnavailable || isClustersAuthUnavailable) {
290+
if (authUnavailable || metaAuthUnavailable) {
300291
return <AccessDenied />;
301292
}
302293
return <Authentication />;

src/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {authenticationApi} from '../../../store/reducers/authentication/authenti
77
import {useClusterWithoutAuthInUI} from '../../../store/reducers/capabilities/hooks';
88
import {cn} from '../../../utils/cn';
99
import {useDatabaseFromQuery} from '../../../utils/hooks/useDatabaseFromQuery';
10+
import {useMetaAuth, useMetaAuthUnavailable} from '../../../utils/hooks/useMetaAuth';
1011
import i18n from '../i18n';
1112

1213
import './YdbInternalUser.scss';
@@ -16,6 +17,8 @@ const b = cn('kv-ydb-internal-user');
1617
export function YdbInternalUser({login}: {login?: string}) {
1718
const [logout] = authenticationApi.useLogoutMutation();
1819
const authUnavailable = useClusterWithoutAuthInUI();
20+
const metaAuthUnavailable = useMetaAuthUnavailable();
21+
const metaAuth = useMetaAuth();
1922
const database = useDatabaseFromQuery();
2023

2124
const history = useHistory();
@@ -29,11 +32,11 @@ export function YdbInternalUser({login}: {login?: string}) {
2932
};
3033

3134
const handleLogout = () => {
32-
logout(undefined);
35+
logout({useMeta: metaAuth});
3336
};
3437

3538
const renderLoginButton = () => {
36-
if (authUnavailable) {
39+
if (authUnavailable || metaAuthUnavailable) {
3740
return null;
3841
}
3942
return (

src/containers/Authentication/Authentication.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {Eye, EyeSlash, Xmark} from '@gravity-ui/icons';
44
import {Button, Link as ExternalLink, Icon, TextInput} from '@gravity-ui/uikit';
55
import {useHistory, useLocation} from 'react-router-dom';
66

7-
import {checkIsClustersPage, parseQuery} from '../../routes';
7+
import {parseQuery} from '../../routes';
88
import {authenticationApi} from '../../store/reducers/authentication/authentication';
9-
import {useLoginWithDatabase, useMetaLoginAvailable} from '../../store/reducers/capabilities/hooks';
9+
import {useLoginWithDatabase} from '../../store/reducers/capabilities/hooks';
1010
import {cn} from '../../utils/cn';
11+
import {useMetaAuth} from '../../utils/hooks/useMetaAuth';
1112

1213
import {isDatabaseError, isPasswordError, isUserError} from './utils';
1314

@@ -27,8 +28,7 @@ function Authentication({closable = false}: AuthenticationProps) {
2728

2829
const needDatabase = useLoginWithDatabase();
2930

30-
const isClustersPage = checkIsClustersPage(location.pathname);
31-
const isMetaLoginAvailable = useMetaLoginAvailable();
31+
const useMeta = useMetaAuth();
3232

3333
const [authenticate, {isLoading}] = authenticationApi.useAuthenticateMutation();
3434

@@ -56,8 +56,6 @@ function Authentication({closable = false}: AuthenticationProps) {
5656
setPasswordError('');
5757
};
5858

59-
const useMeta = isClustersPage && isMetaLoginAvailable;
60-
6159
const onLoginClick = () => {
6260
authenticate({user: login, password, database, useMeta})
6361
.unwrap()

src/services/api/meta.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export class MetaAPI extends BaseYdbAPI {
3333
return this.post(this.getPath('/meta/login'), params, {});
3434
}
3535

36+
metaLogout() {
37+
return this.post(this.getPath('/meta/logout'), {}, {});
38+
}
39+
3640
metaWhoami() {
3741
return this.post<TUserToken>(this.getPath('/meta/whoami'), {}, {});
3842
}

src/store/reducers/authentication/authentication.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,14 @@ export const authenticationApi = api.injectEndpoints({
9696
invalidatesTags: (_, error) => (error ? [] : ['UserData']),
9797
}),
9898
logout: build.mutation({
99-
queryFn: async (_, {dispatch}) => {
99+
queryFn: async ({useMeta}: {useMeta?: boolean}, {dispatch}) => {
100100
try {
101-
const data = await window.api.auth.logout();
101+
let data;
102+
if (useMeta && window.api.meta) {
103+
data = await window.api.meta.metaLogout();
104+
} else {
105+
data = await window.api.auth.logout();
106+
}
102107
dispatch(setIsAuthenticated(false));
103108
return {data};
104109
} catch (error) {

src/utils/hooks/useMetaAuth.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {useLocation} from 'react-router-dom';
2+
3+
import {checkIsClustersPage} from '../../routes';
4+
import {useMetaLoginAvailable} from '../../store/reducers/capabilities/hooks';
5+
6+
function useMetaAuthState() {
7+
const location = useLocation();
8+
const isClustersPage = checkIsClustersPage(location.pathname);
9+
const metaLoginAvailable = useMetaLoginAvailable();
10+
11+
return {isClustersPage, metaLoginAvailable};
12+
}
13+
14+
export function useMetaAuth() {
15+
const {isClustersPage, metaLoginAvailable} = useMetaAuthState();
16+
17+
return isClustersPage && metaLoginAvailable;
18+
}
19+
20+
export function useMetaAuthUnavailable() {
21+
const {isClustersPage, metaLoginAvailable} = useMetaAuthState();
22+
23+
return isClustersPage && !metaLoginAvailable;
24+
}

0 commit comments

Comments
 (0)