Skip to content

Commit

Permalink
fix-moving-a-team-with-just-owner (#15595)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex van Andel <me@alexvanandel.com>
  • Loading branch information
hariombalhara and emrysal authored Jun 27, 2024
1 parent aa65475 commit f84fe4f
Showing 1 changed file with 33 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ type CreateTeamsOptions = {
};

export const createTeamsHandler = async ({ ctx, input }: CreateTeamsOptions) => {
// Get User From context
const user = ctx.user;
// Whether self-serve or not, createTeams endpoint is accessed by Org Owner only.
// Even when instance admin creates an org, then by the time he reaches team creation steps, he has impersonated the org owner.
const organizationOwner = ctx.user;

if (!user) {
if (!organizationOwner) {
throw new NoUserError();
}

Expand All @@ -37,14 +38,14 @@ export const createTeamsHandler = async ({ ctx, input }: CreateTeamsOptions) =>
// Remove empty team names that could be there due to the default empty team name
const teamNames = input.teamNames.filter((name) => name.trim().length > 0);

if (orgId !== user.organizationId) {
if (orgId !== organizationOwner.organizationId) {
throw new NotAuthorizedError();
}

// Validate user membership role
const userMembershipRole = await prisma.membership.findFirst({
where: {
userId: user.id,
userId: organizationOwner.id,
teamId: orgId,
role: {
in: ["OWNER", "ADMIN"],
Expand Down Expand Up @@ -100,7 +101,10 @@ export const createTeamsHandler = async ({ ctx, input }: CreateTeamsOptions) =>
await moveTeam({
teamId,
newSlug,
org: organization,
org: {
...organization,
ownerId: organizationOwner.id,
},
ctx,
});
})
Expand Down Expand Up @@ -175,6 +179,7 @@ async function moveTeam({
org: {
id: number;
slug: string | null;
ownerId: number;
metadata: Prisma.JsonValue;
};
ctx: CreateTeamsOptions["ctx"];
Expand Down Expand Up @@ -221,26 +226,35 @@ async function moveTeam({
},
});

// Invite team members to the new org. They are already members of the team.
await inviteMemberHandler({
ctx,
input: {
teamId: org.id,
language: "en",
usernameOrEmail: team.members.map((m) => ({
email: m.user.email,
role: m.role,
})),
isOrg: true,
},
});
// Owner is already a member of the team. Inviting an existing member can throw error
const invitableMembers = team.members.filter(isMembershipNotWithOwner).map((membership) => ({
email: membership.user.email,
role: membership.role,
}));

if (invitableMembers.length) {
// Invite team members to the new org. They are already members of the team.
await inviteMemberHandler({
ctx,
input: {
teamId: org.id,
language: "en",
usernameOrEmail: invitableMembers,
isOrg: true,
},
});
}

await addTeamRedirect({
oldTeamSlug: team.slug,
teamSlug: newSlug,
orgSlug: org.slug || (orgMetadata?.requestedSlug ?? null),
});

function isMembershipNotWithOwner(membership: { userId: number }) {
// Org owner is already a member of the team
return membership.userId !== org.ownerId;
}
// Cancel existing stripe subscriptions once the team is migrated
const subscriptionId = getSubscriptionId(team.metadata);
if (subscriptionId) {
Expand Down

0 comments on commit f84fe4f

Please sign in to comment.