Files
calendar/packages/lib/validateUsername.ts
T
aabfd3b3f6 chore: Chore team metadata table + isOrganization migration from metadata (#12828)
* Migration+schema changes

* Remove org utils from schema

* Users fixture

* Auth signup handlers

* checkIsOrg fn

* use team.isOrganization > metadata

* Add isOrganization to getTeamWithMembers query

* list handler + optimise queries

* Update trpc handlers to use team.isOrganization && orgSettings table

* Update fixture

* Fix typo in prisma.schema

* next auth options use organizationSettings instread of tema metadata

* Admin tooling

* Updating components to use orgsettings over metadata

* Add unique index + fix org lib files

* validateUsername

* Add a seperate unique constraint between isOrg and slug

* Invite Member Logic

* fix resend file

* force isOrg to exist

* Team settings

* update createOrUpdateMemberships

* fix: admin get handler

* fix: team list handler - improve select

* fix: update admin update handler

* fix: settings layout - team get select

* organziationSettings Schema + adminupdate

* organziationSettings Schema + adminupdate

* typefix onSubtmi

* Fix:team repo throwing error if no metadata is found

* fix: add onDelete to be cascade instead of restri

* fix: org - team invite e2e

* fix: team invites not working in subteam context

* rename to organizationID

* fix user fixture team names

* Fix the organization created in tests

* fix: update organization metadata

* variable rename

* Reuse isOrganization

* variable rename

* Remove unnecessary optional chaining

* Update packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Update packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Update packages/trpc/server/routers/viewer/organizations/create.handler.ts

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-16 10:18:17 +00:00

131 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: { not: 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 };
}
};