authelia/web/src/App.tsx
James Elliott a2eb0316c8
feat(web): password reset custom url (#3111)
This allows providing a custom URL for password resets. If provided the disable_reset_password option is ignored, the password reset API is disabled, and the button provided in the UI to reset the password redirects users to the configured endpoint.

Closes #1934, Closes #2854

Co-authored-by: you1996 <youssri@flyweight.tech>
2022-04-04 17:46:55 +10:00

102 lines
4.2 KiB
TypeScript

import React, { useState, useEffect, Suspense } from "react";
import { config as faConfig } from "@fortawesome/fontawesome-svg-core";
import { CssBaseline, ThemeProvider } from "@material-ui/core";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import NotificationBar from "@components/NotificationBar";
import {
ConsentRoute,
IndexRoute,
LogoutRoute,
RegisterOneTimePasswordRoute,
RegisterWebauthnRoute,
ResetPasswordStep2Route,
ResetPasswordStep1Route,
} from "@constants/Routes";
import NotificationsContext from "@hooks/NotificationsContext";
import { Notification } from "@models/Notifications";
import * as themes from "@themes/index";
import { getBasePath } from "@utils/BasePath";
import {
getDuoSelfEnrollment,
getRememberMe,
getResetPassword,
getResetPasswordCustomURL,
getTheme,
} from "@utils/Configuration";
import RegisterOneTimePassword from "@views/DeviceRegistration/RegisterOneTimePassword";
import RegisterWebauthn from "@views/DeviceRegistration/RegisterWebauthn";
import BaseLoadingPage from "@views/LoadingPage/BaseLoadingPage";
import ConsentView from "@views/LoginPortal/ConsentView/ConsentView";
import LoginPortal from "@views/LoginPortal/LoginPortal";
import SignOut from "@views/LoginPortal/SignOut/SignOut";
import ResetPasswordStep1 from "@views/ResetPassword/ResetPasswordStep1";
import ResetPasswordStep2 from "@views/ResetPassword/ResetPasswordStep2";
import "@fortawesome/fontawesome-svg-core/styles.css";
faConfig.autoAddCss = false;
function Theme() {
switch (getTheme()) {
case "dark":
return themes.Dark;
case "grey":
return themes.Grey;
case "auto":
return window.matchMedia("(prefers-color-scheme: dark)").matches ? themes.Dark : themes.Light;
default:
return themes.Light;
}
}
const App: React.FC = () => {
const [notification, setNotification] = useState(null as Notification | null);
const [theme, setTheme] = useState(Theme());
useEffect(() => {
if (getTheme() === "auto") {
const query = window.matchMedia("(prefers-color-scheme: dark)");
// MediaQueryLists does not inherit from EventTarget in Internet Explorer
if (query.addEventListener) {
query.addEventListener("change", (e) => {
setTheme(e.matches ? themes.Dark : themes.Light);
});
}
}
}, []);
return (
<ThemeProvider theme={theme}>
<Suspense fallback={<BaseLoadingPage message={"Loading"} />}>
<CssBaseline />
<NotificationsContext.Provider value={{ notification, setNotification }}>
<Router basename={getBasePath()}>
<NotificationBar onClose={() => setNotification(null)} />
<Routes>
<Route path={ResetPasswordStep1Route} element={<ResetPasswordStep1 />} />
<Route path={ResetPasswordStep2Route} element={<ResetPasswordStep2 />} />
<Route path={RegisterWebauthnRoute} element={<RegisterWebauthn />} />
<Route path={RegisterOneTimePasswordRoute} element={<RegisterOneTimePassword />} />
<Route path={LogoutRoute} element={<SignOut />} />
<Route path={ConsentRoute} element={<ConsentView />} />
<Route
path={`${IndexRoute}*`}
element={
<LoginPortal
duoSelfEnrollment={getDuoSelfEnrollment()}
rememberMe={getRememberMe()}
resetPassword={getResetPassword()}
resetPasswordCustomURL={getResetPasswordCustomURL()}
/>
}
/>
</Routes>
</Router>
</NotificationsContext.Provider>
</Suspense>
</ThemeProvider>
);
};
export default App;