feat: Auto join team if already in org [CAL-2248] (#10450)
* Auto join if in org. * Only handle accepted org memberships * Add comment * TODO: fix prisma mockpull/10305/head^2
parent
0f84102f1e
commit
8f9f096723
|
@ -21,6 +21,7 @@ import {
|
|||
createProvisionalMembership,
|
||||
getIsOrgVerified,
|
||||
sendVerificationEmail,
|
||||
createAndAutoJoinIfInOrg,
|
||||
} from "./utils";
|
||||
|
||||
type InviteMemberOptions = {
|
||||
|
@ -69,6 +70,17 @@ export const inviteMemberHandler = async ({ ctx, input }: InviteMemberOptions) =
|
|||
} else {
|
||||
throwIfInviteIsToOrgAndUserExists(invitee, team, input.isOrg);
|
||||
|
||||
const shouldAutoJoinOrgTeam = await createAndAutoJoinIfInOrg({
|
||||
invitee,
|
||||
role: input.role,
|
||||
team,
|
||||
});
|
||||
if (shouldAutoJoinOrgTeam.autoJoined) {
|
||||
// Continue here because if this is true we dont need to send an email to the user
|
||||
// we also dont need to update stripe as thats handled on an ORG level and not a team level.
|
||||
continue;
|
||||
}
|
||||
|
||||
// create provisional membership
|
||||
await createProvisionalMembership({
|
||||
input,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, it, vi, expect } from "vitest";
|
||||
import { isOrganisationAdmin } from "@calcom/lib/server/queries/organisations";
|
||||
import { checkInputEmailIsValid, checkPermissions, getEmailsToInvite, getIsOrgVerified, getOrgConnectionInfo, throwIfInviteIsToOrgAndUserExists } from "./utils";
|
||||
import { checkInputEmailIsValid, checkPermissions, getEmailsToInvite, getIsOrgVerified, getOrgConnectionInfo, throwIfInviteIsToOrgAndUserExists,createAndAutoJoinIfInOrg } from "./utils";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { isTeamAdmin } from "@calcom/lib/server/queries";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
@ -305,4 +305,24 @@ describe("Invite Member Utils", () => {
|
|||
).not.toThrow();
|
||||
});
|
||||
});
|
||||
})
|
||||
describe("createAndAutoJoinIfInOrg", () => {
|
||||
it("should return autoJoined: false if the user is not in the same organization as the team", async () => {
|
||||
const result = await createAndAutoJoinIfInOrg({
|
||||
team: mockedTeam,
|
||||
role: MembershipRole.ADMIN,
|
||||
invitee: mockUser,
|
||||
});
|
||||
expect(result).toEqual({ autoJoined: false });
|
||||
});
|
||||
|
||||
it("should return autoJoined: false if the team does not have a parent organization", async () => {
|
||||
const result = await createAndAutoJoinIfInOrg({
|
||||
team: { ...mockedTeam, parentId: null },
|
||||
role: MembershipRole.ADMIN,
|
||||
invitee: mockUser,
|
||||
});
|
||||
expect(result).toEqual({ autoJoined: false });
|
||||
});
|
||||
// TODO: Add test for when the user is already a member of the organization - need to mock prisma response value
|
||||
});
|
||||
})
|
||||
|
|
|
@ -325,3 +325,53 @@ export function getIsOrgVerified(
|
|||
isInOrgScope: false,
|
||||
} as { isInOrgScope: false; orgVerified: never; autoAcceptEmailDomain: never };
|
||||
}
|
||||
|
||||
export async function createAndAutoJoinIfInOrg({
|
||||
team,
|
||||
role,
|
||||
invitee,
|
||||
}: {
|
||||
team: TeamWithParent;
|
||||
invitee: User;
|
||||
role: MembershipRole;
|
||||
}) {
|
||||
if (invitee.organizationId && invitee.organizationId !== team.parentId) {
|
||||
return {
|
||||
autoJoined: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (!team.parentId) {
|
||||
return {
|
||||
autoJoined: false,
|
||||
};
|
||||
}
|
||||
|
||||
const orgMembership = await prisma.membership.findFirst({
|
||||
where: {
|
||||
userId: invitee.id,
|
||||
teamId: team.parentId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!orgMembership?.accepted) {
|
||||
return {
|
||||
autoJoined: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Since we early return if the user is not a member of the org. Or the team they are being invited to is an org (not having a parentID)
|
||||
// We create the membership in the child team
|
||||
await prisma.membership.create({
|
||||
data: {
|
||||
userId: invitee.id,
|
||||
teamId: team.id,
|
||||
accepted: true,
|
||||
role: role,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
autoJoined: true,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue