fix: Add strict checks for email to create an organization (#15976)
* Verify email first * Only allow company emails for org creation --------- Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
co-authored by
sean-brydon
Peer Richelsen
parent
58cabe974c
commit
40df4cf511
@@ -23,6 +23,47 @@ import type { TrpcSessionUser } from "../../../trpc";
|
||||
import { BillingPeriod } from "./create.schema";
|
||||
import type { TCreateInputSchema } from "./create.schema";
|
||||
|
||||
/**
|
||||
* We can only say for sure that the email is not a company email. We can't say for sure if it is a company email.
|
||||
*/
|
||||
function isNotACompanyEmail(email: string) {
|
||||
// A list of popular @domains that can't be used to allow automatic acceptance of memberships to organization
|
||||
const emailProviders = [
|
||||
"gmail.com",
|
||||
"yahoo.com",
|
||||
"outlook.com",
|
||||
"hotmail.com",
|
||||
"aol.com",
|
||||
"icloud.com",
|
||||
"mail.com",
|
||||
"protonmail.com",
|
||||
"zoho.com",
|
||||
"yandex.com",
|
||||
"gmx.com",
|
||||
"fastmail.com",
|
||||
"inbox.com",
|
||||
"me.com",
|
||||
"hushmail.com",
|
||||
"live.com",
|
||||
"rediffmail.com",
|
||||
"tutanota.com",
|
||||
"mail.ru",
|
||||
"usa.com",
|
||||
"qq.com",
|
||||
"163.com",
|
||||
"web.de",
|
||||
"rocketmail.com",
|
||||
"excite.com",
|
||||
"lycos.com",
|
||||
"outlook.co",
|
||||
"hotmail.co.uk",
|
||||
];
|
||||
|
||||
const emailParts = email.split("@");
|
||||
if (emailParts.length < 2) return true;
|
||||
return emailProviders.includes(emailParts[1]);
|
||||
}
|
||||
|
||||
type CreateOptions = {
|
||||
ctx: {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
@@ -69,6 +110,7 @@ export const createHandler = async ({ input, ctx }: CreateOptions) => {
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!loggedInUser) throw new TRPCError({ code: "UNAUTHORIZED", message: "You are not authorized." });
|
||||
|
||||
const IS_USER_ADMIN = loggedInUser.role === UserPermissionRole.ADMIN;
|
||||
@@ -87,6 +129,10 @@ export const createHandler = async ({ input, ctx }: CreateOptions) => {
|
||||
});
|
||||
}
|
||||
|
||||
if (isNotACompanyEmail(orgOwnerEmail)) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Use company email to create an organization" });
|
||||
}
|
||||
|
||||
const publishedTeams = loggedInUser.teams.filter((team) => !!team.team.slug);
|
||||
|
||||
if (!IS_USER_ADMIN && publishedTeams.length < ORG_MINIMUM_PUBLISHED_TEAMS_SELF_SERVE && !isPlatform) {
|
||||
@@ -206,7 +252,11 @@ export const createHandler = async ({ input, ctx }: CreateOptions) => {
|
||||
// If we are making the loggedIn user the owner of the organization and he is already a part of an organization, we don't allow it because multi-org is not supported yet
|
||||
const isLoggedInUserOrgOwner = orgOwner.id === loggedInUser.id;
|
||||
if (ctx.user.profile.organizationId && isLoggedInUserOrgOwner) {
|
||||
throw new TRPCError({ code: "FORBIDDEN", message: "User is part of an organization already" });
|
||||
throw new TRPCError({ code: "FORBIDDEN", message: "You are part of an organization already" });
|
||||
}
|
||||
|
||||
if (!orgOwner.emailVerified) {
|
||||
throw new TRPCError({ code: "FORBIDDEN", message: "You need to verify your email first" });
|
||||
}
|
||||
|
||||
const nonOrgUsernameForOwner = orgOwner.username || "";
|
||||
|
||||
@@ -248,7 +248,7 @@ export function getOrgConnectionInfo({
|
||||
if (team.parentId || isOrg) {
|
||||
orgId = team.parentId || team.id;
|
||||
if (email.split("@")[1] == orgAutoAcceptDomain) {
|
||||
// We discourage self-served organizations from being able to auto-accept feature by having a barrier of a fixed number of paying teams in the account for creating the organization
|
||||
// We discourage self-served organizations from being able to use auto-accept feature by having a barrier of a fixed number of paying teams in the account for creating the organization
|
||||
// We can't put restriction of a published organization here because when we move teams during the onboarding of the organization, it isn't published at the moment and we really need those members to be auto-added
|
||||
// Further, sensitive operations like member editing and impersonating are disabled by default, unless reviewed by the ADMIN team
|
||||
autoAccept = !!orgVerified;
|
||||
|
||||
Reference in New Issue
Block a user