Check reset token validity

This commit is contained in:
Pierre HUBERT 2023-06-12 16:25:38 +02:00
parent 3e5648afca
commit 1bd18133b3
4 changed files with 89 additions and 7 deletions

View File

@ -8,6 +8,7 @@ import { OIDCCbRoute } from "./routes/auth/OIDCCbRoute";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage"; import { BaseAuthenticatedPage } from "./widgets/BaseAuthenticatedPage";
import { PasswordForgottenRoute } from "./routes/auth/PasswordForgottenRoute"; import { PasswordForgottenRoute } from "./routes/auth/PasswordForgottenRoute";
import { ResetPasswordRoute } from "./routes/auth/ResetPasswordRoute";
/** /**
* Core app * Core app
@ -27,6 +28,7 @@ function App() {
path="password_forgotten" path="password_forgotten"
element={<PasswordForgottenRoute />} element={<PasswordForgottenRoute />}
/> />
<Route path="reset_password" element={<ResetPasswordRoute />} />
<Route path="*" element={<NotFoundRoute />} /> <Route path="*" element={<NotFoundRoute />} />
</Route> </Route>
)} )}

View File

@ -1,6 +1,10 @@
import { atom } from "jotai"; import { atom } from "jotai";
import { APIClient } from "./ApiClient"; import { APIClient } from "./ApiClient";
export interface CheckResetTokenResponse {
name: string;
}
const TokenStateKey = "auth-token"; const TokenStateKey = "auth-token";
export class AuthApi { export class AuthApi {
@ -73,4 +77,19 @@ export class AuthApi {
jsonData: { mail: mail }, jsonData: { mail: mail },
}); });
} }
/**
* Check reset password token
*/
static async CheckResetPasswordToken(
token: string
): Promise<CheckResetTokenResponse> {
return (
await APIClient.exec({
uri: "/auth/check_reset_password_token",
method: "POST",
jsonData: { token: token },
})
).data;
}
} }

View File

@ -0,0 +1,54 @@
import { Alert, CircularProgress } from "@mui/material";
import React, { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";
import { AuthApi, CheckResetTokenResponse } from "../../api/AuthApi";
export function ResetPasswordRoute(): React.ReactElement {
const [error, setError] = React.useState<string | null>(null);
const { hash } = useLocation();
const token = hash.substring(1);
const info = React.useState<null | CheckResetTokenResponse>(null);
const checkedToken = useRef<null | string>(null);
useEffect(() => {
(async () => {
if (token === checkedToken.current) return;
checkedToken.current = token;
try {
setError(null);
await AuthApi.CheckResetPasswordToken(token);
} catch (e) {
console.error(e);
setError(
"Echec de validation du jeton de réinitialisation de mot de passe!"
);
}
})();
});
if (error)
return (
<Alert style={{ width: "100%" }} severity="error">
{error}
</Alert>
);
if (info === null)
return (
<>
<CircularProgress />
</>
);
return <ResetPasswordForm token={token} info={info as any} />;
}
function ResetPasswordForm(p: {
token: string;
info: CheckResetTokenResponse;
}): React.ReactElement {
return <p>TODO</p>;
}

View File

@ -4,11 +4,10 @@ import Avatar from "@mui/material/Avatar";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import CssBaseline from "@mui/material/CssBaseline"; import CssBaseline from "@mui/material/CssBaseline";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import Link from "@mui/material/Link";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import * as React from "react"; import * as React from "react";
import { Outlet } from "react-router-dom"; import { Link, Outlet } from "react-router-dom";
function Copyright(props: any) { function Copyright(props: any) {
return ( return (
@ -20,9 +19,15 @@ function Copyright(props: any) {
{...props} {...props}
> >
{"Copyright © "} {"Copyright © "}
<Link color="inherit" href="https://0ph.fr/" target="_blank"> <a
color="inherit"
href="https://0ph.fr/"
target="_blank"
rel="noreferrer"
style={{ color: "inherit" }}
>
Pierre HUBERT Pierre HUBERT
</Link>{" "} </a>{" "}
{new Date().getFullYear()} {new Date().getFullYear()}
{"."} {"."}
</Typography> </Typography>
@ -71,9 +76,11 @@ export function BaseLoginPage() {
<Avatar sx={{ m: 1, bgcolor: "secondary.main" }}> <Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
<Icon path={mdiFamilyTree} size={1} /> <Icon path={mdiFamilyTree} size={1} />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Link to="/" style={{ color: "inherit", textDecoration: "none" }}>
GeneIT <Typography component="h1" variant="h5">
</Typography> GeneIT
</Typography>
</Link>
<Typography <Typography
component="h1" component="h1"
variant="h6" variant="h6"