diff --git a/.env.example b/.env.example index a19ff46f2..da0e45084 100644 --- a/.env.example +++ b/.env.example @@ -20,6 +20,8 @@ NODE_ENV=development # OPTIONAL VARIABLES # This is used for validating emails that are allowed to log in. Every email that do not match this regex will be rejected. # WHITELISTED_EMAILS="authorized@yahoo\.com|authorized@gmail\.com" +# Accounts with these emails will get global admin rights. This grants access to the admin UI. +# ADMIN_EMAILS="admin@example\.com|another-admin@example\.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 cde3aeb77..9df6b35e4 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -27,6 +27,7 @@ const EnvironmentSchema = z.object({ .string() .refine(isValidRegex, "WHITELISTED_EMAILS must be a valid regex.") .optional(), + ADMIN_EMAILS: z.string().refine(isValidRegex, "ADMIN_EMAILS must be a valid regex.").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 19d5a2ee7..df4d43ca4 100644 --- a/apps/webapp/app/models/user.server.ts +++ b/apps/webapp/app/models/user.server.ts @@ -47,12 +47,21 @@ export async function findOrCreateMagicLinkUser( }, }); + const adminEmailRegex = env.ADMIN_EMAILS ? new RegExp(env.ADMIN_EMAILS) : undefined; + const makeAdmin = adminEmailRegex ? adminEmailRegex.test(input.email) : false; + const user = await prisma.user.upsert({ where: { email: input.email, }, - update: { email: input.email }, - create: { email: input.email, authenticationMethod: "MAGIC_LINK" }, + update: { + email: input.email, + }, + create: { + email: input.email, + authenticationMethod: "MAGIC_LINK", + admin: makeAdmin, // only on create, to prevent automatically removing existing admins + }, }); return {