diff --git a/src/containers/App/Content.tsx b/src/containers/App/Content.tsx
index e24803b45..82741845c 100644
--- a/src/containers/App/Content.tsx
+++ b/src/containers/App/Content.tsx
@@ -4,6 +4,7 @@ import {connect} from 'react-redux';
import type {RedirectProps} from 'react-router-dom';
import {Redirect, Route, Switch} from 'react-router-dom';
+import {AccessDenied} from '../../components/Errors/403';
import {PageError} from '../../components/Errors/PageError/PageError';
import {LoaderWrapper} from '../../components/LoaderWrapper/LoaderWrapper';
import {useSlots} from '../../components/slots';
@@ -12,7 +13,11 @@ import type {SlotComponent} from '../../components/slots/types';
import routes from '../../routes';
import type {RootState} from '../../store';
import {authenticationApi} from '../../store/reducers/authentication/authentication';
-import {useCapabilitiesLoaded, useCapabilitiesQuery} from '../../store/reducers/capabilities/hooks';
+import {
+ useCapabilitiesLoaded,
+ useCapabilitiesQuery,
+ useClusterWithoutAuthInUI,
+} from '../../store/reducers/capabilities/hooks';
import {nodesListApi} from '../../store/reducers/nodesList';
import {cn} from '../../utils/cn';
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
@@ -177,10 +182,14 @@ export function Content(props: ContentProps) {
function DataWrapper({children}: {children: React.ReactNode}) {
return (
-
-
- {children}
-
+ // capabilities is going to work without authentication, but not all running systems are supporting this yet
+
+
+
+ {/* this GetCapabilities will be removed */}
+ {children}
+
+
);
}
@@ -219,15 +228,25 @@ interface ContentWrapperProps {
function ContentWrapper(props: ContentWrapperProps) {
const {singleClusterMode, isAuthenticated} = props;
+ const authUnavailable = useClusterWithoutAuthInUI();
+
+ const renderNotAuthenticated = () => {
+ if (authUnavailable) {
+ return ;
+ }
+ return ;
+ };
return (
-
-
-
+ {!authUnavailable && (
+
+
+
+ )}
- {isAuthenticated ? props.children :
}
+ {isAuthenticated ? props.children : renderNotAuthenticated()}
diff --git a/src/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.tsx b/src/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.tsx
index 6c7397d27..c0490b467 100644
--- a/src/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.tsx
+++ b/src/containers/AsideNavigation/YdbInternalUser/YdbInternalUser.tsx
@@ -4,7 +4,9 @@ import {useHistory} from 'react-router-dom';
import routes, {createHref} from '../../../routes';
import {authenticationApi} from '../../../store/reducers/authentication/authentication';
+import {useClusterWithoutAuthInUI} from '../../../store/reducers/capabilities/hooks';
import {cn} from '../../../utils/cn';
+import {useDatabaseFromQuery} from '../../../utils/hooks/useDatabaseFromQuery';
import i18n from '../i18n';
import './YdbInternalUser.scss';
@@ -13,11 +15,16 @@ const b = cn('kv-ydb-internal-user');
export function YdbInternalUser({login}: {login?: string}) {
const [logout] = authenticationApi.useLogoutMutation();
+ const authUnavailable = useClusterWithoutAuthInUI();
+ const database = useDatabaseFromQuery();
const history = useHistory();
const handleLoginClick = () => {
history.push(
- createHref(routes.auth, undefined, {returnUrl: encodeURIComponent(location.href)}),
+ createHref(routes.auth, undefined, {
+ returnUrl: encodeURIComponent(location.href),
+ database,
+ }),
);
};
@@ -25,6 +32,17 @@ export function YdbInternalUser({login}: {login?: string}) {
logout(undefined);
};
+ const renderLoginButton = () => {
+ if (authUnavailable) {
+ return null;
+ }
+ return (
+
+ );
+ };
+
return (
@@ -36,13 +54,7 @@ export function YdbInternalUser({login}: {login?: string}) {
) : (
-
+ renderLoginButton()
)}
);
diff --git a/src/containers/Authentication/Authentication.tsx b/src/containers/Authentication/Authentication.tsx
index fbee833cf..5f87792b4 100644
--- a/src/containers/Authentication/Authentication.tsx
+++ b/src/containers/Authentication/Authentication.tsx
@@ -6,9 +6,10 @@ import {useHistory, useLocation} from 'react-router-dom';
import {parseQuery} from '../../routes';
import {authenticationApi} from '../../store/reducers/authentication/authentication';
+import {useLoginWithDatabase} from '../../store/reducers/capabilities/hooks';
import {cn} from '../../utils/cn';
-import {isPasswordError, isUserError} from './utils';
+import {isDatabaseError, isPasswordError, isUserError} from './utils';
import ydbLogoIcon from '../../assets/icons/ydb.svg';
@@ -24,20 +25,28 @@ function Authentication({closable = false}: AuthenticationProps) {
const history = useHistory();
const location = useLocation();
+ const needDatabase = useLoginWithDatabase();
+
const [authenticate, {isLoading}] = authenticationApi.useAuthenticateMutation(undefined);
- const {returnUrl} = parseQuery(location);
+ const {returnUrl, database: databaseFromQuery} = parseQuery(location);
const [login, setLogin] = React.useState('');
+ const [database, setDatabase] = React.useState(databaseFromQuery?.toString() ?? '');
const [password, setPass] = React.useState('');
const [loginError, setLoginError] = React.useState('');
const [passwordError, setPasswordError] = React.useState('');
+ const [databaseError, setDatabaseError] = React.useState('');
const [showPassword, setShowPassword] = React.useState(false);
const onLoginUpdate = (value: string) => {
setLogin(value);
setLoginError('');
};
+ const onDatabaseUpdate = (value: string) => {
+ setDatabase(value);
+ setDatabaseError('');
+ };
const onPassUpdate = (value: string) => {
setPass(value);
@@ -45,7 +54,7 @@ function Authentication({closable = false}: AuthenticationProps) {
};
const onLoginClick = () => {
- authenticate({user: login, password})
+ authenticate({user: login, password, database})
.unwrap()
.then(() => {
if (returnUrl) {
@@ -66,6 +75,9 @@ function Authentication({closable = false}: AuthenticationProps) {
if (isPasswordError(error)) {
setPasswordError(error.data.error);
}
+ if (isDatabaseError(error)) {
+ setDatabaseError(error.data.error);
+ }
});
};
@@ -125,6 +137,18 @@ function Authentication({closable = false}: AuthenticationProps) {
+ {needDatabase && (
+
+
+
+ )}