diff --git a/.env.example b/.env.example index 48170e8f365..5049f4a4aa4 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,8 @@ APP_ORIGIN=http://localhost:3030 NODE_ENV=development # OPTIONAL VARIABLES +# This is used for Restricting logins other than whitelisted emails for self-hosted authentication. +WHITELISTED_EMAILS="matt@gmail\.com|jane@yahoo\.com" # This is used for logging in via GitHub. You can leave these commented out if you don't want to use GitHub for authentication. # AUTH_GITHUB_CLIENT_ID= # AUTH_GITHUB_CLIENT_SECRET= diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 4e229834c42..ae020eb0b27 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -10,6 +10,7 @@ const EnvironmentSchema = z.object({ SESSION_SECRET: z.string(), MAGIC_LINK_SECRET: z.string(), ENCRYPTION_KEY: z.string(), + WHITELISTED_EMAILS:z.string().optional(), REMIX_APP_PORT: z.string().optional(), LOGIN_ORIGIN: z.string().default("http://localhost:3030"), APP_ORIGIN: z.string().default("http://localhost:3030"), diff --git a/apps/webapp/app/models/user.server.ts b/apps/webapp/app/models/user.server.ts index 31e8621edb4..b953be25492 100644 --- a/apps/webapp/app/models/user.server.ts +++ b/apps/webapp/app/models/user.server.ts @@ -1,6 +1,7 @@ import type { Prisma, User } from "@trigger.dev/database"; import type { GitHubProfile } from "remix-auth-github"; import { prisma } from "~/db.server"; +import { env } from "app/env.server"; export type { User } from "@trigger.dev/database"; type FindOrCreateMagicLink = { @@ -36,6 +37,33 @@ export async function findOrCreateUser(input: FindOrCreateUser): Promise { + if(env.WHITELISTED_EMAILS){ + const emailRegx = new RegExp(env.WHITELISTED_EMAILS) + if(emailRegx.test(input.email)){ + const existingUser = await prisma.user.findFirst({ + where: { + email: input.email, + }, + }); + + const user = await prisma.user.upsert({ + where: { + email: input.email, + }, + update: { email: input.email }, + create: { email: input.email, authenticationMethod: "MAGIC_LINK" }, + }); + + return { + user, + isNewUser: !existingUser, + }; + } + else{ + throw new Error("Email does not match Whitelisted Email"); + } + + } const existingUser = await prisma.user.findFirst({ where: { email: input.email, diff --git a/apps/webapp/app/routes/magic.tsx b/apps/webapp/app/routes/magic.tsx index d41575357d5..725640c6f4b 100644 --- a/apps/webapp/app/routes/magic.tsx +++ b/apps/webapp/app/routes/magic.tsx @@ -7,6 +7,6 @@ export async function loader({ request }: LoaderFunctionArgs) { await authenticator.authenticate("email-link", request, { successRedirect: redirectTo ?? "/", - failureRedirect: "/login", + failureRedirect: "/login/magic", }); }