1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-20 12:02:22 +03:00
Files
authentication-service/frontend/src/routing/Router.tsx

87 lines
2.7 KiB
TypeScript

// Copyright 2022, 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { useAtom, useAtomValue } from "jotai";
import { useEffect } from "react";
import LoadingSpinner from "../components/LoadingSpinner";
import BrowserSession from "../pages/BrowserSession";
import BrowserSessionList from "../pages/BrowserSessionList";
import OAuth2Client from "../pages/OAuth2Client";
import Profile from "../pages/Profile";
import SessionDetail from "../pages/SessionDetail";
import SessionsOverview from "../pages/SessionsOverview";
import VerifyEmail from "../pages/VerifyEmail";
import { getRouteActionRedirection } from "./actions";
import { locationAtom, routeAtom } from "./atoms";
import type { Route } from "./routes";
/**
* Check for actions in URL query params requiring a redirect
* Get route from path
* @returns Route
*/
const useRouteWithRedirect = (): [Route, boolean] => {
const location = useAtomValue(locationAtom);
const redirect = getRouteActionRedirection(location);
const [route, setRoute] = useAtom(routeAtom);
useEffect(() => {
if (redirect) {
setRoute(redirect.route, redirect.searchParams);
}
}, [redirect, setRoute]);
const redirecting = !!redirect;
return [route, redirecting];
};
// A type-safe way to ensure we've handled all routes
const unknownRoute = (route: never): never => {
throw new Error(`Invalid route: ${JSON.stringify(route)}`);
};
const Router: React.FC = () => {
const [route, redirecting] = useRouteWithRedirect();
if (redirecting) {
return <LoadingSpinner />;
}
switch (route.type) {
case "profile":
return <Profile />;
case "sessions-overview":
return <SessionsOverview />;
case "session":
return <SessionDetail deviceId={route.id} />;
case "browser-session-list":
return <BrowserSessionList />;
case "client":
return <OAuth2Client id={route.id} />;
case "browser-session":
return <BrowserSession id={route.id} />;
case "verify-email":
return <VerifyEmail id={route.id} />;
case "unknown":
return <>Unknown route {JSON.stringify(route.segments)}</>;
default:
unknownRoute(route);
}
};
export default Router;