GeneIT/geneit_app/src/routes/auth/LoginRoute.tsx

207 lines
5.5 KiB
TypeScript
Raw Normal View History

import { Visibility, VisibilityOff } from "@mui/icons-material";
2023-06-13 08:42:28 +00:00
import {
Alert,
CircularProgress,
FormControl,
IconButton,
InputAdornment,
InputLabel,
OutlinedInput,
Tooltip,
} from "@mui/material";
2023-06-09 08:45:01 +00:00
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Grid from "@mui/material/Grid";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import * as React from "react";
import { Link, useNavigate } from "react-router-dom";
import { useAuth } from "../../App";
2023-06-13 08:42:28 +00:00
import { AuthApi, PasswordLoginResult } from "../../api/AuthApi";
2023-06-09 08:45:01 +00:00
import { ServerApi } from "../../api/ServerApi";
/**
* Login form
*/
export function LoginRoute(): React.ReactElement {
const [loading, setLoading] = React.useState(false);
const [error, setError] = React.useState<string | null>(null);
const auth = useAuth();
2023-06-13 08:42:28 +00:00
const navigate = useNavigate();
const [mail, setMail] = React.useState("");
const [password, setPassword] = React.useState("");
const canSubmit = mail.length > 0 && password.length > 0;
const [showPassword, setShowPassword] = React.useState(false);
const handleClickShowPassword = () => setShowPassword((show) => !show);
const handleMouseDownPassword = (
event: React.MouseEvent<HTMLButtonElement>
) => {
2023-06-09 08:45:01 +00:00
event.preventDefault();
2023-06-13 08:42:28 +00:00
};
const handleLoginSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!canSubmit) return;
try {
const res = await AuthApi.LoginWithPassword(mail, password);
switch (res) {
case PasswordLoginResult.TooManyRequests:
setError(
"Trop de tentatives de connection. Veuillez réessayer ultérieurement."
);
break;
case PasswordLoginResult.InvalidCredentials:
setError("Identifiants saisis invalides !");
break;
case PasswordLoginResult.Success:
navigate("/");
auth.setSignedIn(true);
2023-06-13 08:42:28 +00:00
break;
case PasswordLoginResult.Error:
setError("Echec de la connexion !");
break;
}
} catch (e) {
console.error(e);
setError("Echec de l'authentification !");
}
setLoading(false);
2023-06-09 08:45:01 +00:00
};
const authWithProvider = async (id: string) => {
try {
setLoading(true);
const res = await AuthApi.StartOpenIDLogin(id);
window.location.href = res.url;
} catch (e) {
console.error(e);
setError("Echec de l'initialisation de l'authentification OpenID !");
}
};
if (loading)
return (
<>
<CircularProgress />
</>
);
return (
<>
2023-06-13 08:42:28 +00:00
{error && (
2023-06-09 08:45:01 +00:00
<Alert style={{ width: "100%" }} severity="error">
{error}
</Alert>
)}
<Typography component="h2" variant="body1">
Connexion
</Typography>
2023-06-13 08:42:28 +00:00
<Box
component="form"
noValidate
onSubmit={handleLoginSubmit}
sx={{ mt: 1 }}
>
2023-06-09 08:45:01 +00:00
<TextField
margin="normal"
required
fullWidth
id="email"
label="Adresse mail"
name="email"
2023-06-13 08:42:28 +00:00
value={mail}
onChange={(e) => setMail(e.target.value)}
2023-06-09 08:45:01 +00:00
autoComplete="email"
autoFocus
/>
2023-06-13 08:42:28 +00:00
<FormControl fullWidth variant="outlined">
<InputLabel htmlFor="password">Mot de passe</InputLabel>
<OutlinedInput
required
fullWidth
name="password"
label="Mot de passe"
type={showPassword ? "text" : "password"}
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
autoComplete="current-password"
endAdornment={
<InputAdornment position="end">
<Tooltip title="Afficher le mot de passe">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
edge="end"
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
</Tooltip>
</InputAdornment>
}
/>
</FormControl>
2023-06-09 08:45:01 +00:00
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
2023-06-13 08:42:28 +00:00
disabled={!canSubmit}
2023-06-09 08:45:01 +00:00
>
Connexion
</Button>
<Grid container>
<Grid item xs>
2023-06-09 16:55:36 +00:00
<Typography variant="body2" color={"primary"}>
<Link
to="/password_forgotten"
style={{ color: "inherit", textDecorationColor: "inherit" }}
>
Mot de passe oublié
</Link>
</Typography>
2023-06-09 08:45:01 +00:00
</Grid>
<Grid item>
2023-06-09 16:55:36 +00:00
<Typography variant="body2" color={"primary"}>
<Link
to="/new-account"
2023-06-09 16:55:36 +00:00
style={{ color: "inherit", textDecorationColor: "inherit" }}
>
Créer un nouveau compte
</Link>
</Typography>
2023-06-09 08:45:01 +00:00
</Grid>
</Grid>
<div>
{ServerApi.Config.oidc_providers.map((p) => (
<Button
2023-06-09 09:19:40 +00:00
key={p.id}
2023-06-09 08:45:01 +00:00
style={{ textAlign: "center", width: "100%", marginTop: "20px" }}
onClick={() => authWithProvider(p.id)}
>
2023-06-13 08:42:28 +00:00
Connexion avec {p.name}
2023-06-09 08:45:01 +00:00
</Button>
))}
</div>
</Box>
</>
);
}