Files
calendar/packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts
T
d30fb213d2 fix: Add adminReview option to allow impersonating org members (#14275)
* added layouts for moving teams step

* added admin section for org creation step

* extended org creation to also move existing teams

* wip

* wip

* wip

* further changes

* Add checkout for org in onboarding

* Fix ts errors

* Self review feedback

* Self review addressed

* Fix unit tests

* Fix ts error

* Seans feedback addressed

* feat: fix correct accounts pending

* fix: unit tests for new invite member permissions

* tests: org admin onboarding tests for existing user

* tests: Inital user self serve flow

* chore: update teamAndUserFixture to create X amount of teams

* chore: add testId to card actionButton

* test: add test-Id to continue or checkout button

* tests: add tests for migrating existing teams

* feat: match new designs

* fix: isAdminCheck

* chore: fix pricing copy

* fix: flacky tests

* Fix tests?

* More test fixes

* Check all checkboxes

* Fix type error

* Fix failing test and typescript issues

* Fix unpaid org allowing auto-add users

* Add self-serve flag

* Skip tests

* Add adminReview option

* Fixes

* Add server checks for impersonation

* Improved error

* feat: extract - and disalow updating from org uset list if not reviewed

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: sean-brydon <sean@cal.com>
Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2024-04-04 04:48:41 +00:00

117 lines
3.4 KiB
TypeScript

import type { Prisma } from "@prisma/client";
import { renameDomain } from "@calcom/lib/domainManager/organization";
import { getMetadataHelpers } from "@calcom/lib/getMetadataHelpers";
import { HttpError } from "@calcom/lib/http-error";
import { prisma } from "@calcom/prisma";
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
import type { TrpcSessionUser } from "../../../trpc";
import type { TAdminUpdate } from "./adminUpdate.schema";
type AdminUpdateOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
input: TAdminUpdate;
};
export const adminUpdateHandler = async ({ input }: AdminUpdateOptions) => {
const { id, organizationSettings, ...restInput } = input;
const existingOrg = await prisma.team.findUnique({
where: {
id: id,
},
include: {
organizationSettings: true,
},
});
if (!existingOrg) {
throw new HttpError({
message: "Organization not found",
statusCode: 404,
});
}
const { mergeMetadata } = getMetadataHelpers(teamMetadataSchema.unwrap(), existingOrg.metadata);
const data: Prisma.TeamUpdateArgs["data"] = restInput;
if (restInput.slug) {
await throwIfSlugConflicts({ id, slug: restInput.slug });
const isSlugChanged = restInput.slug !== existingOrg.slug;
if (isSlugChanged) {
// If slug is changed, we need to rename the domain first
// If renaming fails, we don't want to update the new slug in DB
await renameDomain(existingOrg.slug, restInput.slug);
}
data.slug = input.slug;
data.metadata = mergeMetadata({
// If we save slug, we don't need the requestedSlug anymore
requestedSlug: undefined,
});
}
const updatedOrganization = await prisma.$transaction(async (tx) => {
const updatedOrganization = await tx.team.update({
where: { id },
data,
});
if (organizationSettings || existingOrg.organizationSettings) {
await tx.organizationSettings.update({
where: {
organizationId: updatedOrganization.id,
},
data: {
isOrganizationConfigured:
organizationSettings?.isOrganizationConfigured ||
existingOrg.organizationSettings?.isOrganizationConfigured,
isOrganizationVerified:
organizationSettings?.isOrganizationVerified ||
existingOrg.organizationSettings?.isOrganizationVerified,
isAdminReviewed: organizationSettings?.isAdminReviewed,
orgAutoAcceptEmail:
organizationSettings?.orgAutoAcceptEmail || existingOrg.organizationSettings?.orgAutoAcceptEmail,
},
});
}
return updatedOrganization;
});
return updatedOrganization;
};
export default adminUpdateHandler;
async function throwIfSlugConflicts({ id, slug }: { id: number; slug: string }) {
const organizationsWithSameSlug = await prisma.team.findMany({
where: {
slug: slug,
parentId: null,
},
});
if (organizationsWithSameSlug.length > 1) {
throw new HttpError({
message: "There can only be one organization with a given slug",
statusCode: 400,
});
}
const foundOrg = organizationsWithSameSlug[0];
if (!foundOrg) {
// No org with same slug found - So, no conflict.
return;
}
// If foundOrg isn't same as the org being edited
if (foundOrg.id !== id) {
throw new HttpError({
message: "Organization or a Team with same slug already exists",
statusCode: 400,
});
}
}