@@ -2,19 +2,25 @@ import React from 'react';
22
33import { Eye , EyeSlash , Xmark } from '@gravity-ui/icons' ;
44import { ActionTooltip , Button , Link as ExternalLink , Icon , TextInput } from '@gravity-ui/uikit' ;
5- import { useHistory , useLocation } from 'react-router-dom' ;
5+ import { useHistory , useLocation , useRouteMatch } from 'react-router-dom' ;
66
7- import { parseQuery } from '../../routes' ;
7+ import routes , { getHomePagePath , parseQuery } from '../../routes' ;
88import { basename } from '../../store' ;
99import { authenticationApi } from '../../store/reducers/authentication/authentication' ;
10- import { useLoginWithDatabase } from '../../store/reducers/capabilities/hooks' ;
10+ import { useLoginWithDatabase , useOidcAvailable } from '../../store/reducers/capabilities/hooks' ;
1111import { cn } from '../../utils/cn' ;
1212import { BRAND_BUTTON_CLASS } from '../../utils/constants' ;
1313import { prepareCommonErrorMessage } from '../../utils/errors' ;
1414import { useMetaAuth } from '../../utils/hooks/useMetaAuth' ;
1515
1616import i18n from './i18n' ;
17- import { isDatabaseError , isPasswordError , isUserError } from './utils' ;
17+ import {
18+ createSsoAuthorizeUrl ,
19+ getSsoReturnTo ,
20+ isDatabaseError ,
21+ isPasswordError ,
22+ isUserError ,
23+ } from './utils' ;
1824
1925import ydbLogoIcon from '../../assets/icons/ydb.svg' ;
2026
@@ -29,12 +35,15 @@ interface AuthenticationProps {
2935function Authentication ( { closable = false } : AuthenticationProps ) {
3036 const history = useHistory ( ) ;
3137 const location = useLocation ( ) ;
38+ const isDirectAuthPage = Boolean ( useRouteMatch ( { path : routes . auth , exact : true } ) ) ;
3239
3340 const needDatabase = useLoginWithDatabase ( ) ;
41+ const oidcAvailable = useOidcAvailable ( ) ;
3442
3543 const [ authenticate , { isLoading} ] = authenticationApi . useAuthenticateMutation ( ) ;
3644
3745 const { returnUrl, database : databaseFromQuery } = parseQuery ( location ) ;
46+ const currentHref = window . location . href ;
3847
3948 const path = React . useMemo ( ( ) => {
4049 let path : string | undefined ;
@@ -65,6 +74,22 @@ function Authentication({closable = false}: AuthenticationProps) {
6574
6675 const useMeta = useMetaAuth ( path ) ;
6776
77+ const ssoUrl = React . useMemo ( ( ) => {
78+ if ( ! oidcAvailable ) {
79+ return undefined ;
80+ }
81+
82+ const homePath = getHomePagePath ( undefined , undefined , { withBasename : true } ) ;
83+ const currentUrl = new URL ( currentHref ) ;
84+ const returnTo = getSsoReturnTo ( {
85+ currentUrl,
86+ fallbackPath : homePath ,
87+ isDirectAuthPage,
88+ returnUrl,
89+ } ) ;
90+ return createSsoAuthorizeUrl ( currentUrl . host , returnTo ) ;
91+ } , [ currentHref , isDirectAuthPage , oidcAvailable , returnUrl ] ) ;
92+
6893 const [ login , setLogin ] = React . useState ( '' ) ;
6994 const [ database , setDatabase ] = React . useState ( databaseFromQuery ?. toString ( ) || undefined ) ;
7095 const [ password , setPass ] = React . useState ( '' ) ;
@@ -208,6 +233,17 @@ function Authentication({closable = false}: AuthenticationProps) {
208233 >
209234 Sign in
210235 </ Button >
236+ { ssoUrl && (
237+ < Button
238+ view = "outlined"
239+ href = { ssoUrl }
240+ width = "max"
241+ size = "l"
242+ className = { b ( 'button-sso' ) }
243+ >
244+ { i18n ( 'action_via-sso' ) }
245+ </ Button >
246+ ) }
211247 { /* always preserve place for general error to prevent container height jumping */ }
212248 < div className = { b ( 'general-error' ) } > { generalError } </ div >
213249 </ form >
0 commit comments