/
Login.tsx
77 lines (68 loc) · 2.27 KB
/
Login.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { useEffect } from 'react'
import { useLoginQuery } from '../codegen/generates'
import { create } from 'zustand'
import { useTranslation, Trans } from 'react-i18next';
function jwtDecode(jwt: string) {
/* Just parses the payload — Be aware that signature is not checked */
return jwt && JSON.parse(atob(jwt.split('.')[1]))
}
export interface AuthState {
mail: string,
password: string,
setLogin: (mail: string, password: string) => void
jwt: string,
setJwt: (jwt: string) => void,
logout: () => void
}
export const useAuthStore = create<AuthState>(set => ({
mail: '',
password: '',
setLogin: (mail, password) => set( _orig => ({mail, password})),
jwt: '',
setJwt: jwt => set( _orig => ({jwt}) ),
logout: () => { localStorage.removeItem('jwt')
set({mail: '', password: '', jwt: ''}) }
}))
export function jwtFromLocalStorage() {
return localStorage.getItem('jwt') || ''
}
export function Login() {
const {t} = useTranslation()
const auth = useAuthStore()
const { data } = useLoginQuery({auth}, {enabled: Boolean(!auth.jwt && auth.mail && auth.password)})
useEffect(() => {
if(auth.jwt) {
localStorage.setItem('jwt', auth.jwt)
}
else {
auth.setJwt(data?.login.jwt || jwtFromLocalStorage())
}
if(jwtDecode(auth.jwt).exp < Date.now()/1000) {
console.log('session expired')
auth.logout()
}
}, [auth.jwt, data])
if(!auth.jwt) {
return (
<form onSubmit={ (event) => {event.preventDefault()
auth.setLogin((document.getElementById('mail') as HTMLInputElement).value,
(document.getElementById('password') as HTMLInputElement).value) }}>
<label>{ t('Email') }:
<input id='mail' name='mail'/>
</label>
<label>{ t('Password') }:
<input id='password' type='password' name='password'/>
</label>
<input type='submit' value={ t('Login') as string }/>
</form>
)
} else {
return (
<form onSubmit={ async (event) => {event.preventDefault()
auth.logout()}}
style={{width: "100%", textAlign: "right"}}>
<input type='submit' value={ t('Logout') as string }/>
</form>
)
}
}