2
0
Files
cal/calcom/packages/lib/validateUsername.ts
2024-08-09 00:39:27 +02:00

129 lines
3.5 KiB
TypeScript

import { getOrgUsernameFromEmail } from "@calcom/features/auth/signup/utils/getOrgUsernameFromEmail";
import prisma from "@calcom/prisma";
export const getUsernameForOrgMember = async ({
email,
orgAutoAcceptEmail,
isSignup,
username,
}: {
username?: string;
email: string;
orgAutoAcceptEmail?: string;
isSignup: boolean;
}) => {
if (isSignup) {
// We ensure that the username is always derived from the email during signup.
return getOrgUsernameFromEmail(email, orgAutoAcceptEmail || "");
}
if (!username) {
throw new Error("Username is required");
}
// Right now it's not possible to change username in an org by the user but when that's allowed we would simply accept the provided username
return username;
};
export const validateAndGetCorrectedUsernameAndEmail = async ({
username,
email,
organizationId,
orgAutoAcceptEmail,
isSignup,
}: {
username: string;
email: string;
organizationId?: number;
orgAutoAcceptEmail?: string;
isSignup: boolean;
}) => {
if (username.includes("+")) {
return { isValid: false, username: undefined, email };
}
// There is an existingUser if, within an org context or not, the username matches
// OR if the email matches AND either the email is verified
// or both username and password are set
const existingUser = await prisma.user.findFirst({
where: {
...(organizationId ? { organizationId } : {}),
OR: [
// When inviting to org, invited user gets created with username now, so in an org context we
// can't check for username as it will exist on signup
...(!organizationId ? [{ username }] : [{}]),
{
AND: [
{ email },
{
OR: [
{ emailVerified: { not: null } },
{ AND: [{ password: { isNot: null } }, { username: { not: null } }] },
],
},
],
},
],
},
select: {
email: true,
},
});
let validatedUsername = username;
if (organizationId) {
validatedUsername = await getUsernameForOrgMember({
email,
orgAutoAcceptEmail,
isSignup,
});
}
return { isValid: !existingUser, username: validatedUsername, email: existingUser?.email };
};
export const validateAndGetCorrectedUsernameInTeam = async (
username: string,
email: string,
teamId: number,
isSignup: boolean
) => {
try {
const team = await prisma.team.findFirst({
where: {
id: teamId,
},
select: {
metadata: true,
isOrganization: true,
parentId: true,
organizationSettings: true,
parent: {
select: {
organizationSettings: true,
},
},
},
});
console.log("validateAndGetCorrectedUsernameInTeam", {
teamId,
team,
});
const organization = team?.isOrganization ? team : team?.parent;
if (organization) {
// Organization context -> org-context username check
const orgId = team?.parentId || teamId;
return validateAndGetCorrectedUsernameAndEmail({
username,
email,
organizationId: orgId,
orgAutoAcceptEmail: organization?.organizationSettings?.orgAutoAcceptEmail || "",
isSignup,
});
} else {
// Regular team context -> regular username check
return validateAndGetCorrectedUsernameAndEmail({ username, email, isSignup });
}
} catch (error) {
console.error(error);
return { isValid: false, username: undefined, email: undefined };
}
};