Skip to content

Commit

Permalink
Handle authentication directly in /join.
Browse files Browse the repository at this point in the history
Authenticated users are handled as before - by attempting to join a hunt
and redirecting to the hunt page on success. Unauthenticated users are
handled by redirecting to /login, but with the parsed invitation code
from the router included in the location state where it can be read
directly by LoginForm instead of needing it to be parsed from the prior
location.
  • Loading branch information
jpd236 committed Jun 19, 2024
1 parent 30eab58 commit 01bca26
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 20 deletions.
38 changes: 29 additions & 9 deletions imports/client/components/JoinHunt.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
import React, { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import acceptHuntInvitationCode from "../../methods/acceptHuntInvitationCode";
import { useAuthenticated } from "./authentication";

const JoinHunt = () => {
const [loading, loggedIn] = useAuthenticated();
const location = useLocation();

const invitationCode = useParams<"invitationCode">().invitationCode!;
const [status, setStatus] = useState<string>("loading...");

const navigate = useNavigate();

useEffect(() => {
acceptHuntInvitationCode.call({ invitationCode }, (error, huntId) => {
if (error) {
setStatus(error.reason ?? "Unknown error");
} else {
navigate(`/hunts/${huntId}`);
}
});
}, [invitationCode, navigate]);
if (loading) {
return;
}
if (loggedIn) {
// Accept the invitation and redirect to the hunt page on success.
acceptHuntInvitationCode.call({ invitationCode }, (error, huntId) => {
if (error) {
setStatus(error.reason ?? "Unknown error");
} else {
navigate(`/hunts/${huntId}`);
}
});
} else {
// Redirect to /login with the invitation code present in state.
// LoginForm will look for it and show the invitation welcome page if present.
const { pathname, search } = location;
const state = {
pathname,
search,
invitationCode,
};
navigate("/login", { state });
}
}, [loading, loggedIn, invitationCode, navigate, location]);

return <div>{status}</div>;
};
Expand Down
15 changes: 6 additions & 9 deletions imports/client/components/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@ const LoginForm = () => {

useEffect(() => {
if (!format) {
if (location.state?.pathname) {
const invitationPattern = /^\/join\/(.+)$/;
const matchResult = invitationPattern.exec(location.state.pathname);
if (matchResult?.[1]) {
setHuntInvitationCode(matchResult[1]);
if (format == null) {
setFormat(AccountFormFormat.INVITATION_WELCOME);
return;
}
// Set by JoinHunt when users open an invitation link and are unauthenticated.
if (location.state?.invitationCode) {
setHuntInvitationCode(location.state?.invitationCode);
if (format == null) {
setFormat(AccountFormFormat.INVITATION_WELCOME);
return;
}
}
setFormat(AccountFormFormat.LOGIN);
Expand Down
5 changes: 4 additions & 1 deletion imports/client/components/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export const AuthenticatedRouteList: RouteObject[] = [
},
{ path: "/setup", element: <SetupPage /> },
{ path: "/rtcdebug", element: <RTCDebugPage /> },
{ path: "/join/:invitationCode", element: <JoinHunt /> },
].map((r) => {
return {
...r,
Expand Down Expand Up @@ -101,6 +100,10 @@ export const RouteList: RouteObject[] = [
},
...AuthenticatedRouteList,
...UnauthenticatedRouteList,
// Join is essentially an authenticated route, but needs custom handling for unauthenticated
// users so it can redirect them to /login with the parsed hunt invitation code in the location
// state.
{ path: "/join/:invitationCode", element: <JoinHunt /> },
];

const Routes = React.memo(() => {
Expand Down
2 changes: 1 addition & 1 deletion imports/client/components/authentication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Navigate, useLocation } from "react-router-dom";
import App from "./App";
import SplashPage from "./SplashPage";

const useAuthenticated = () => {
export const useAuthenticated = () => {
const { loggingIn, loggedIn } = useTracker(() => {
return {
loggingIn: Meteor.loggingIn(),
Expand Down

0 comments on commit 01bca26

Please sign in to comment.