Return to same page after log in

This commit is contained in:
Kalle (Sendou) 2021-12-19 11:11:17 +02:00
parent 0a319200ae
commit e4e1b11ff0
5 changed files with 45 additions and 11 deletions

View File

@ -7,3 +7,4 @@ DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_CALLBACK_URL=http://localhost:3000/auth/discord/callback
COOKIE_SECRET=
FRONT_PAGE_URL=http://localhost:3000

View File

@ -1,9 +1,11 @@
import { useLocation } from "react-router";
import { getLogInUrl } from "~/utils";
import { useUser } from "~/utils/hooks";
import { DiscordIcon } from "../icons/Discord";
// TODO: redirect to same page on login
export function UserItem() {
const user = useUser();
const location = useLocation();
if (user)
return (
@ -14,7 +16,7 @@ export function UserItem() {
);
return (
<form action="/auth/discord" method="post" data-cy="log-in-form">
<form action={getLogInUrl(location)} method="post" data-cy="log-in-form">
<button
type="submit"
className="layout__log-in-button"

View File

@ -3,6 +3,7 @@ import { DiscordIcon } from "~/components/icons/Discord";
import { TwitterIcon } from "~/components/icons/Twitter";
import { resolveTournamentFormatString } from "~/core/tournament/bracket";
import { FindTournamentByNameForUrlI } from "~/services/tournament";
import { getLogInUrl } from "~/utils";
import { useUser } from "~/utils/hooks";
export function InfoBanner() {
@ -106,10 +107,11 @@ function dateYYYYMMDD(date: string) {
function InfoBannerActionButton() {
const data = useLoaderData<FindTournamentByNameForUrlI>();
const user = useUser();
const location = useLocation();
if (!user) {
return (
<form action="/auth/discord" method="post">
<form action={getLogInUrl(location)} method="post">
<button
className="info-banner__action-button"
data-cy="log-in-to-join-button"

View File

@ -1,5 +1,6 @@
import { json } from "remix";
import invariant from "tiny-invariant";
import { useLocation } from "remix";
export const makeTitle = (endOfTitle?: string) =>
endOfTitle ? `sendou.ink | ${endOfTitle}` : "sendou.ink";
@ -22,6 +23,11 @@ export const getUser = (ctx: any) => {
return user as LoggedInUser;
};
/** Get link to log in with query param set as current page */
export const getLogInUrl = (location: ReturnType<typeof useLocation>) => {
return `/auth/discord?origin=${encodeURIComponent(location.pathname)}`;
};
/** Get fields from `request.formData()`. Throw an error if the formData doesn't contain a requested field. */
export const formDataFromRequest = async <T extends string>({
request,

View File

@ -6,6 +6,12 @@ import passport from "passport";
import { Strategy as DiscordStrategy } from "passport-discord";
import { db } from "../app/utils/db.server";
declare module "express-session" {
export interface SessionData {
returnTo?: string;
}
}
export function setUpAuth(app: Express): void {
invariant(
process.env.DISCORD_CLIENT_ID,
@ -111,13 +117,30 @@ export function setUpAuth(app: Express): void {
);
app.use(passport.initialize());
app.use(passport.session());
app.post("/auth/discord", passport.authenticate("discord"));
app.get(
"/auth/discord/callback",
passport.authenticate("discord", {
app.post("/auth/discord", (req, res) => {
const returnTo = req.query.origin ?? req.header("Referer");
if (returnTo) {
invariant(typeof returnTo === "string", "returnTo is not string");
req.session.returnTo = returnTo;
}
return passport.authenticate("discord")(req, res);
});
app.get("/auth/discord/callback", (req, res) => {
const returnTo = req.session.returnTo ?? process.env.FRONT_PAGE_URL;
if (req.session.returnTo) {
delete req.session.returnTo;
}
return passport.authenticate("discord", {
failureRedirect: "/login",
// TODO: fix for prod + redirect to same page
successRedirect: "http://localhost:3000",
})
);
successRedirect: returnTo,
})(req, res);
});
app.use(function (req, _res, next) {
if (req.session.returnTo) {
delete req.session.returnTo;
}
next();
});
}