1414// You should have received a copy of the GNU Affero General Public License
1515// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17- import React from "react" ;
17+ import React , { useEffect , useState } from "react" ;
1818import request from "superagent" ;
1919import storage from "local-storage-fallback" ;
2020import { connect , ConnectedProps } from "react-redux" ;
@@ -26,9 +26,8 @@ import { CircularProgress, Paper } from "@material-ui/core";
2626import { createStyles , Theme , withStyles } from "@material-ui/core/styles" ;
2727import { SystemState } from "../../types" ;
2828import { userLoggedIn } from "../../actions" ;
29- import history from "../../history" ;
3029import api from "../../common/api" ;
31- import { ILoginDetails } from "./types" ;
30+ import { ILoginDetails , loginStrategyType } from "./types" ;
3231import { setCookie } from "../../common/utils" ;
3332
3433const styles = ( theme : Theme ) =>
@@ -109,42 +108,36 @@ interface ILoginState {
109108 loginStrategy : ILoginDetails ;
110109}
111110
112- class Login extends React . Component < ILoginProps , ILoginState > {
113- state : ILoginState = {
114- accessKey : "" ,
115- secretKey : "" ,
116- error : "" ,
117- loading : false ,
118- loginStrategy : {
119- loginStrategy : "" ,
120- redirect : "" ,
121- } ,
122- } ;
111+ const Login = ( { classes, userLoggedIn } : ILoginProps ) => {
112+ const [ accessKey , setAccessKey ] = useState < string > ( "" ) ;
113+ const [ jwt , setJwt ] = useState < string > ( "" ) ;
114+ const [ secretKey , setSecretKey ] = useState < string > ( "" ) ;
115+ const [ error , setError ] = useState < string > ( "" ) ;
116+ const [ loading , setLoading ] = useState < boolean > ( false ) ;
117+ const [ loginStrategy , setLoginStrategy ] = useState < ILoginDetails > ( {
118+ loginStrategy : loginStrategyType . unknown ,
119+ redirect : "" ,
120+ } ) ;
123121
124- fetchConfiguration ( ) {
125- this . setState ( { loading : true } , ( ) => {
126- api
127- . invoke ( "GET" , "/api/v1/login" )
128- . then ( ( loginDetails : ILoginDetails ) => {
129- this . setState ( {
130- loading : false ,
131- } ) ;
132- this . setState ( {
133- loading : false ,
134- loginStrategy : loginDetails ,
135- error : "" ,
136- } ) ;
137- } )
138- . catch ( ( err : any ) => {
139- this . setState ( { loading : false , error : err } ) ;
140- } ) ;
141- } ) ;
142- }
122+ const fetchConfiguration = ( ) => {
123+ setLoading ( true ) ;
124+
125+ api
126+ . invoke ( "GET" , "/api/v1/login" )
127+ . then ( ( loginDetails : ILoginDetails ) => {
128+ setLoading ( false ) ;
129+ setLoginStrategy ( loginDetails ) ;
130+ setError ( "" ) ;
131+ } )
132+ . catch ( ( err : any ) => {
133+ setLoading ( false ) ;
134+ setError ( err ) ;
135+ } ) ;
136+ } ;
143137
144- formSubmit = ( e : React . FormEvent < HTMLFormElement > ) => {
138+ const formSubmit = ( e : React . FormEvent < HTMLFormElement > ) => {
145139 e . preventDefault ( ) ;
146140 const url = "/api/v1/login" ;
147- const { accessKey, secretKey } = this . state ;
148141
149142 request
150143 . post ( url )
@@ -164,134 +157,173 @@ class Login extends React.Component<ILoginProps, ILoginState> {
164157 } )
165158 . then ( ( ) => {
166159 // We set the state in redux
167- this . props . userLoggedIn ( true ) ;
160+ userLoggedIn ( true ) ;
168161 // There is a browser cache issue if we change the policy associated to an account and then logout and history.push("/") after login
169162 // therefore after login we need to use window.location redirect
170163 window . location . href = "/" ;
171164 } )
172165 . catch ( ( err ) => {
173- this . setState ( { error : ` ${ err } ` } ) ;
166+ setError ( err ) ;
174167 } ) ;
175168 } ;
176169
177- componentDidMount ( ) : void {
178- this . fetchConfiguration ( ) ;
179- }
180-
181- render ( ) {
182- const { error, accessKey, secretKey, loginStrategy } = this . state ;
183- const { classes } = this . props ;
170+ useEffect ( ( ) => {
171+ fetchConfiguration ( ) ;
172+ } , [ ] ) ;
184173
185- let loginComponent = null ;
174+ let loginComponent = null ;
186175
187- switch ( loginStrategy . loginStrategy ) {
188- case "form" : {
189- loginComponent = (
190- < React . Fragment >
191- < Typography component = "h1" variant = "h6" >
192- Login
193- </ Typography >
194- < form
195- className = { classes . form }
196- noValidate
197- onSubmit = { this . formSubmit }
198- >
199- < Grid container spacing = { 2 } >
200- { error !== "" && (
201- < Grid item xs = { 12 } >
202- < Typography
203- component = "p"
204- variant = "body1"
205- className = { classes . errorBlock }
206- >
207- { error }
208- </ Typography >
209- </ Grid >
210- ) }
176+ switch ( loginStrategy . loginStrategy ) {
177+ case loginStrategyType . form : {
178+ loginComponent = (
179+ < React . Fragment >
180+ < Typography component = "h1" variant = "h6" >
181+ Login
182+ </ Typography >
183+ < form className = { classes . form } noValidate onSubmit = { formSubmit } >
184+ < Grid container spacing = { 2 } >
185+ { error !== "" && (
211186 < Grid item xs = { 12 } >
212- < TextField
213- required
214- fullWidth
215- id = "accessKey"
216- value = { accessKey }
217- onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
218- this . setState ( { accessKey : e . target . value } )
219- }
220- label = "Access Key"
221- name = "accessKey"
222- autoComplete = "username"
223- />
187+ < Typography
188+ component = "p"
189+ variant = "body1"
190+ className = { classes . errorBlock }
191+ >
192+ { error }
193+ </ Typography >
224194 </ Grid >
195+ ) }
196+ < Grid item xs = { 12 } >
197+ < TextField
198+ required
199+ fullWidth
200+ id = "accessKey"
201+ value = { accessKey }
202+ onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
203+ setAccessKey ( e . target . value )
204+ }
205+ label = "Access Key"
206+ name = "accessKey"
207+ autoComplete = "username"
208+ />
209+ </ Grid >
210+ < Grid item xs = { 12 } >
211+ < TextField
212+ required
213+ fullWidth
214+ value = { secretKey }
215+ onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
216+ setSecretKey ( e . target . value )
217+ }
218+ name = "secretKey"
219+ label = "Secret Key"
220+ type = "password"
221+ id = "secretKey"
222+ autoComplete = "current-password"
223+ />
224+ </ Grid >
225+ </ Grid >
226+ < Button
227+ type = "submit"
228+ fullWidth
229+ variant = "contained"
230+ color = "primary"
231+ className = { classes . submit }
232+ >
233+ Login
234+ </ Button >
235+ </ form >
236+ </ React . Fragment >
237+ ) ;
238+ break ;
239+ }
240+ case loginStrategyType . redirect : {
241+ loginComponent = (
242+ < React . Fragment >
243+ < Typography component = "h1" variant = "h6" >
244+ Login
245+ </ Typography >
246+ < Button
247+ component = { "a" }
248+ href = { loginStrategy . redirect }
249+ type = "submit"
250+ fullWidth
251+ variant = "contained"
252+ color = "primary"
253+ className = { classes . submit }
254+ >
255+ Welcome
256+ </ Button >
257+ </ React . Fragment >
258+ ) ;
259+ break ;
260+ }
261+ case loginStrategyType . serviceAccount : {
262+ loginComponent = (
263+ < React . Fragment >
264+ < Typography component = "h1" variant = "h6" >
265+ Login
266+ </ Typography >
267+ < form className = { classes . form } noValidate onSubmit = { formSubmit } >
268+ < Grid container spacing = { 2 } >
269+ { error !== "" && (
225270 < Grid item xs = { 12 } >
226- < TextField
227- required
228- fullWidth
229- value = { secretKey }
230- onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
231- this . setState ( { secretKey : e . target . value } )
232- }
233- name = "secretKey"
234- label = "Secret Key"
235- type = "password"
236- id = "secretKey"
237- autoComplete = "current-password"
238- />
271+ < Typography
272+ component = "p"
273+ variant = "body1"
274+ className = { classes . errorBlock }
275+ >
276+ { error }
277+ </ Typography >
239278 </ Grid >
279+ ) }
280+ < Grid item xs = { 12 } >
281+ < TextField
282+ required
283+ fullWidth
284+ id = "jwt"
285+ value = { jwt }
286+ onChange = { ( e : React . ChangeEvent < HTMLInputElement > ) =>
287+ setJwt ( e . target . value )
288+ }
289+ label = "JWT"
290+ name = "jwt"
291+ autoComplete = "Service Account JWT Token"
292+ />
240293 </ Grid >
241- < Button
242- type = "submit"
243- fullWidth
244- variant = "contained"
245- color = "primary"
246- className = { classes . submit }
247- >
248- Login
249- </ Button >
250- </ form >
251- </ React . Fragment >
252- ) ;
253- break ;
254- }
255- case "redirect" : {
256- loginComponent = (
257- < React . Fragment >
258- < Typography component = "h1" variant = "h6" >
259- Login
260- </ Typography >
294+ </ Grid >
261295 < Button
262- component = { "a" }
263- href = { loginStrategy . redirect }
264296 type = "submit"
265297 fullWidth
266298 variant = "contained"
267299 color = "primary"
268300 className = { classes . submit }
269301 >
270- Welcome
302+ Login
271303 </ Button >
272- </ React . Fragment >
273- ) ;
274- break ;
275- }
276- default :
277- loginComponent = (
278- < CircularProgress className = { classes . loadingLoginStrategy } />
279- ) ;
304+ </ form >
305+ </ React . Fragment >
306+ ) ;
307+ break ;
280308 }
309+ default :
310+ loginComponent = (
311+ < CircularProgress className = { classes . loadingLoginStrategy } />
312+ ) ;
313+ }
281314
282- return (
283- < Paper className = { classes . paper } >
284- < Grid container className = { classes . mainContainer } >
285- < Grid item xs = { 7 } className = { classes . theOcean } >
286- < div className = { classes . oceanBg } />
287- </ Grid >
288- < Grid item xs = { 5 } className = { classes . theLogin } >
289- { loginComponent }
290- </ Grid >
315+ return (
316+ < Paper className = { classes . paper } >
317+ < Grid container className = { classes . mainContainer } >
318+ < Grid item xs = { 7 } className = { classes . theOcean } >
319+ < div className = { classes . oceanBg } />
291320 </ Grid >
292- </ Paper >
293- ) ;
294- }
295- }
321+ < Grid item xs = { 5 } className = { classes . theLogin } >
322+ { loginComponent }
323+ </ Grid >
324+ </ Grid >
325+ </ Paper >
326+ ) ;
327+ } ;
296328
297329export default connector ( withStyles ( styles ) ( Login ) ) ;
0 commit comments