Skip to content

Commit 43a5eed

Browse files
committed
Reject GitHub OAuth users not on the email whitelist
1 parent 2e354d3 commit 43a5eed

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

apps/webapp/app/models/user.server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ export async function findOrCreateGithubUser({
6666
authenticationProfile,
6767
authenticationExtraParams,
6868
}: FindOrCreateGithub): Promise<LoggedInUser> {
69+
if (env.WHITELISTED_EMAILS && !new RegExp(env.WHITELISTED_EMAILS).test(email)) {
70+
throw new Error("This email is unauthorized");
71+
}
72+
6973
const name = authenticationProfile._json.name;
7074
let avatarUrl: string | undefined = undefined;
7175
if (authenticationProfile.photos[0]) {

apps/webapp/app/routes/login._index/route.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { LoginPageLayout } from "~/components/LoginPageLayout";
1212
import { Button, LinkButton } from "~/components/primitives/Buttons";
1313
import { Fieldset } from "~/components/primitives/Fieldset";
14+
import { FormError } from "~/components/primitives/FormError";
1415
import { Header1 } from "~/components/primitives/Headers";
1516
import { NamedIcon } from "~/components/primitives/NamedIcon";
1617
import { Paragraph } from "~/components/primitives/Paragraph";
@@ -19,6 +20,10 @@ import type { LoaderType as RootLoader } from "~/root";
1920
import { isGithubAuthSupported } from "~/services/auth.server";
2021
import { commitSession, setRedirectTo } from "~/services/redirectTo.server";
2122
import { getUserId } from "~/services/session.server";
23+
import {
24+
getUserSession,
25+
commitSession as commitAuthSession,
26+
} from "~/services/sessionStorage.server";
2227
import { appEnvTitleTag } from "~/utils";
2328
import { requestUrl } from "~/utils/requestUrl.server";
2429

@@ -41,22 +46,36 @@ export async function loader({ request }: LoaderFunctionArgs) {
4146
const url = requestUrl(request);
4247
const redirectTo = url.searchParams.get("redirectTo");
4348

49+
const session = await getUserSession(request);
50+
const error = session.get("auth:error");
51+
52+
let githubError: string | undefined;
53+
if (error) {
54+
if ("message" in error) {
55+
githubError = error.message;
56+
} else {
57+
githubError = JSON.stringify(error, null, 2);
58+
}
59+
}
60+
4461
if (redirectTo) {
4562
const session = await setRedirectTo(request, redirectTo);
4663

4764
return typedjson(
48-
{ redirectTo, showGithubAuth: isGithubAuthSupported },
65+
{ redirectTo, showGithubAuth: isGithubAuthSupported, githubError },
4966
{
5067
headers: {
5168
"Set-Cookie": await commitSession(session),
5269
},
5370
}
5471
);
5572
} else {
56-
return typedjson({
57-
redirectTo: null,
58-
showGithubAuth: isGithubAuthSupported,
59-
});
73+
return typedjson(
74+
{ redirectTo: null, showGithubAuth: isGithubAuthSupported, githubError },
75+
{
76+
headers: { "Set-Cookie": await commitAuthSession(session) },
77+
}
78+
);
6079
}
6180
}
6281

@@ -78,7 +97,7 @@ export default function LoginPage() {
7897
Create an account or login
7998
</Paragraph>
8099
<Fieldset className="w-full">
81-
<div className="flex flex-col gap-y-2">
100+
<div className="flex flex-col items-center gap-y-2">
82101
{data.showGithubAuth && (
83102
<Button
84103
type="submit"
@@ -102,6 +121,8 @@ export default function LoginPage() {
102121
/>
103122
Continue with Email
104123
</LinkButton>
124+
125+
{data.githubError && <FormError>{data.githubError}</FormError>}
105126
</div>
106127
<Paragraph variant="extra-small" className="mt-2 text-center">
107128
By signing up you agree to our{" "}

0 commit comments

Comments
 (0)