Can authenticate using OpenID
This commit is contained in:
116
geneit_app/src/routes/auth/LoginRoute.tsx
Normal file
116
geneit_app/src/routes/auth/LoginRoute.tsx
Normal file
@ -0,0 +1,116 @@
|
||||
import { Alert, CircularProgress } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Link from "@mui/material/Link";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import * as React from "react";
|
||||
import { AuthApi } from "../../api/AuthApi";
|
||||
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 handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
const data = new FormData(event.currentTarget);
|
||||
console.log({
|
||||
email: data.get("email"),
|
||||
password: data.get("password"),
|
||||
});
|
||||
};
|
||||
|
||||
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 (
|
||||
<>
|
||||
{error === null ? (
|
||||
<></>
|
||||
) : (
|
||||
<Alert style={{ width: "100%" }} severity="error">
|
||||
{error}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<Typography component="h2" variant="body1">
|
||||
Connexion
|
||||
</Typography>
|
||||
<Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 1 }}>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="email"
|
||||
label="Adresse mail"
|
||||
name="email"
|
||||
autoComplete="email"
|
||||
autoFocus
|
||||
/>
|
||||
<TextField
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
name="password"
|
||||
label="Mot de passe"
|
||||
type="password"
|
||||
id="password"
|
||||
autoComplete="current-password"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
sx={{ mt: 3, mb: 2 }}
|
||||
>
|
||||
Connexion
|
||||
</Button>
|
||||
|
||||
<Grid container>
|
||||
<Grid item xs>
|
||||
<Link href="#" variant="body2">
|
||||
Mot de passe oublié
|
||||
</Link>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Link href="#" variant="body2">
|
||||
Créer un nouveau compte
|
||||
</Link>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<div>
|
||||
{ServerApi.Config.oidc_providers.map((p) => (
|
||||
<Button
|
||||
style={{ textAlign: "center", width: "100%", marginTop: "20px" }}
|
||||
onClick={() => authWithProvider(p.id)}
|
||||
>
|
||||
Connection avec {p.name}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
55
geneit_app/src/routes/auth/OIDCCbRoute.tsx
Normal file
55
geneit_app/src/routes/auth/OIDCCbRoute.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import { Button, CircularProgress } from "@mui/material";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Link, useSearchParams } from "react-router-dom";
|
||||
import { AuthApi } from "../../api/AuthApi";
|
||||
import { useSetAtom } from "jotai";
|
||||
|
||||
/**
|
||||
* OpenID login callback route
|
||||
*/
|
||||
export function OIDCCbRoute(): React.ReactElement {
|
||||
const setAuth = useSetAtom(AuthApi.authStatus);
|
||||
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const [searchParams] = useSearchParams();
|
||||
const code = searchParams.get("code");
|
||||
const state = searchParams.get("state");
|
||||
|
||||
const count = useRef("");
|
||||
|
||||
useEffect(() => {
|
||||
const load = async () => {
|
||||
try {
|
||||
if (count.current === code) {
|
||||
return;
|
||||
}
|
||||
count.current = code!;
|
||||
|
||||
await AuthApi.FinishOpenIDLogin(code!, state!);
|
||||
setAuth(true);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
setError(true);
|
||||
}
|
||||
};
|
||||
|
||||
load();
|
||||
}, [code, state]);
|
||||
|
||||
if (error)
|
||||
return (
|
||||
<>
|
||||
<p>Echec de la finalisation de l'authentification !</p>
|
||||
<Link to={"/"}>
|
||||
<Button>Retour à l'accueil</Button>
|
||||
</Link>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<CircularProgress />
|
||||
</>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user