diff --git a/.gitignore b/.gitignore index 3beab0401..5e12a63a2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ build node_modules/* .env .log +.vscode/* npm-debug.log stats.json .DS_Store diff --git a/app/scenes/Login/Notices.tsx b/app/scenes/Login/Notices.tsx index 480222986..6b3a890c5 100644 --- a/app/scenes/Login/Notices.tsx +++ b/app/scenes/Login/Notices.tsx @@ -18,6 +18,13 @@ export default function Notices() { invite email. )} + {notice === "gmail-account-creation" && ( + + Sorry, a new account cannot be created with a personal Gmail address. +
+ Please use a Google Workspaces account instead. +
+ )} {notice === "maximum-teams" && ( The team you authenticated with is not authorized on this diff --git a/server/errors.ts b/server/errors.ts index 42358c6d3..40233102a 100644 --- a/server/errors.ts +++ b/server/errors.ts @@ -136,6 +136,14 @@ export function TeamDomainRequiredError( }); } +export function GmailAccountCreationError( + message = "Cannot create account using personal gmail address" +) { + return httpErrors(400, message, { + id: "gmail_account_creation", + }); +} + export function AuthRedirectError( message = "Redirect to the correct domain after authentication", redirectUrl: string diff --git a/server/routes/auth/providers/google.ts b/server/routes/auth/providers/google.ts index ffb5641f8..4d4b48642 100644 --- a/server/routes/auth/providers/google.ts +++ b/server/routes/auth/providers/google.ts @@ -9,7 +9,11 @@ import accountProvisioner, { AccountProvisionerResult, } from "@server/commands/accountProvisioner"; import env from "@server/env"; -import { InviteRequiredError, TeamDomainRequiredError } from "@server/errors"; +import { + GmailAccountCreationError, + InviteRequiredError, + TeamDomainRequiredError, +} from "@server/errors"; import passportMiddleware from "@server/middlewares/passport"; import { Team, User } from "@server/models"; import { StateStore, parseState } from "@server/utils/passport"; @@ -99,7 +103,8 @@ if (env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) { }); } else { // No domain means it's a personal Gmail account - // We only allow sign-in to existing invites here + // We only allow sign-in to existing user accounts + let team; if (appDomain.custom) { team = await Team.findOne({ where: { domain: appDomain.host } }); @@ -112,6 +117,17 @@ if (env.GOOGLE_CLIENT_ID && env.GOOGLE_CLIENT_SECRET) { } if (!team) { + // No team usually means this is the apex domain + // Throw different errors depending on whether we think the user is + // trying to create a new account, or log-in to an existing one + const userExists = await User.count({ + where: { email: profile.email.toLowerCase() }, + }); + + if (!userExists) { + throw GmailAccountCreationError(); + } + throw TeamDomainRequiredError(); }