codekingpro/portable-devtools
114k
1import { Box, Icon } from '@mui/material';2import React, { useState } from 'react';3import LoginImage from '../../img/login.svg?svgr';4import { InputSelectNonSearch, InputText, MESSAGE_TYPE, NotifierMessage } from '../components/FormComponents';5import BasePage, { SecurityButton } from './BasePage';6import gettext from 'sources/gettext';7import PropTypes from 'prop-types';8 9export default function LoginPage({userLanguage, langOptions, forgotPassUrl, csrfToken, loginUrl, authSources, authSourcesEnum, oauth2Config, loginBanner, ...props}) {10 const [form, setForm] = useState(({email: '', password: '', language: userLanguage}));11 12 // Hide login form if auth source is only oauth2 and/or kerberos. #538613 const showLoginForm = !((authSources?.includes('oauth2') || authSources?.includes('kerberos')) && authSources?.length == 1 || (authSources?.includes('oauth2')14 && authSources?.includes('kerberos')) && authSources?.length == 2);15 16 const onTextChange = (n, val)=>{17 setForm((prev)=>({...prev, [n]: val}));18 };19 20 return (21 <>22 {loginBanner && <NotifierMessage showIcon={false} closable={false} type={MESSAGE_TYPE.ERROR} message={loginBanner} style={{23 position: 'absolute',24 width: '80%',25 top: '30px',26 left: 0,27 right: 0,28 marginRight: 'auto',29 marginLeft: 'auto'30 }} textCenter />}31 <BasePage title={gettext('Login')} pageImage={<LoginImage style={{height: '100%', width: '100%'}} />} {...props}>32 <form style={{display:'flex', gap:'15px', flexDirection:'column'}} action={loginUrl} method="POST">33 {showLoginForm &&34 <>35 <input name="csrf_token" defaultValue={csrfToken} hidden/>36 <InputText name="email" value={form.email} onChange={(v)=>onTextChange('email', v)} placeholder={gettext('Email Address / Username')} autoFocus37 controlProps={{autoComplete: null}} />38 <InputText name="password" value={form.password} onChange={(v)=>onTextChange('password', v)} type="password" placeholder={gettext('Password')}39 controlProps={{autoComplete: null}} />40 <Box textAlign="right" marginTop="-10px">41 <a style={{color: 'inherit'}} href={forgotPassUrl}>{gettext('Forgotten your password?')}</a>42 </Box>43 <InputSelectNonSearch name="language" options={langOptions} value={form.language} onChange={(v)=>onTextChange('language', v.target.value)} />44 <SecurityButton name="internal_button" value="Login" disabled={!(form.email && form.password)}>{gettext('Login')}</SecurityButton>45 </>46 }47 {authSources?.includes?.(authSourcesEnum.OAUTH2) &&48 oauth2Config.map((oauth)=>{49 return (50 <SecurityButton key={oauth.OAUTH2_NAME} name="oauth2_button" value={oauth.OAUTH2_NAME} style={{backgroundColor: oauth.OAUTH2_BUTTON_COLOR}}>51 <Icon className={'fab '+oauth.OAUTH2_ICON} style={{ fontSize: '1.5em', marginRight: '8px' }} />{gettext('Login with %s', oauth.OAUTH2_DISPLAY_NAME)}52 </SecurityButton>53 );54 })55 }56 </form>57 </BasePage>58 </>59 );60}61 62LoginPage.propTypes = {63 userLanguage: PropTypes.string,64 langOptions: PropTypes.arrayOf(PropTypes.object),65 forgotPassUrl: PropTypes.string,66 csrfToken: PropTypes.string,67 loginUrl: PropTypes.string,68 authSources: PropTypes.arrayOf(PropTypes.string),69 authSourcesEnum: PropTypes.object,70 oauth2Config: PropTypes.arrayOf(PropTypes.object),71 loginBanner: PropTypes.string72};73 