From 3aff79e7d1a590e3a725a6184c803658703e5dcd Mon Sep 17 00:00:00 2001 From: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:25:50 -0400 Subject: [PATCH] fix: Get `dsyncData` based on database (#14067) * Set unique tenant * Rely on current DB for dsync data * Fix rendering dsync config * Remove console.log * Address feedback * Add relationship between dsync data and team group mapping * Fix `dsyncData` and `organizationSetting` relationship --- .../components/ConfigureDirectorySync.tsx | 2 +- .../migration.sql | 17 +++++++++++++++ packages/prisma/schema.prisma | 16 +++++++------- .../routers/viewer/dsync/create.handler.ts | 6 ++++-- .../routers/viewer/dsync/get.handler.ts | 21 ++++++++++++++++--- 5 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 packages/prisma/migrations/20240313151954_connect_dsync_data_to_org_settings_org_id/migration.sql diff --git a/packages/features/ee/dsync/components/ConfigureDirectorySync.tsx b/packages/features/ee/dsync/components/ConfigureDirectorySync.tsx index c8d4f7bcd3..056cf43fb7 100644 --- a/packages/features/ee/dsync/components/ConfigureDirectorySync.tsx +++ b/packages/features/ee/dsync/components/ConfigureDirectorySync.tsx @@ -39,7 +39,7 @@ const ConfigureDirectorySync = ({ organizationId }: { organizationId: number | n return ; } - const directory = data ? data[0] : null; + const directory = data ?? null; const onDeleteConfirmation = (e: Event | React.MouseEvent) => { e.preventDefault(); diff --git a/packages/prisma/migrations/20240313151954_connect_dsync_data_to_org_settings_org_id/migration.sql b/packages/prisma/migrations/20240313151954_connect_dsync_data_to_org_settings_org_id/migration.sql new file mode 100644 index 0000000000..a365326cba --- /dev/null +++ b/packages/prisma/migrations/20240313151954_connect_dsync_data_to_org_settings_org_id/migration.sql @@ -0,0 +1,17 @@ +/* + Warnings: + + - A unique constraint covering the columns `[directoryId]` on the table `DSyncData` will be added. If there are existing duplicate values, this will fail. + +*/ +-- DropForeignKey +ALTER TABLE "DSyncData" DROP CONSTRAINT "DSyncData_organizationId_fkey"; + +-- CreateIndex +CREATE UNIQUE INDEX "DSyncData_directoryId_key" ON "DSyncData"("directoryId"); + +-- AddForeignKey +ALTER TABLE "DSyncData" ADD CONSTRAINT "DSyncData_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "OrganizationSettings"("organizationId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "DSyncTeamGroupMapping" ADD CONSTRAINT "DSyncTeamGroupMapping_directoryId_fkey" FOREIGN KEY ("directoryId") REFERENCES "DSyncData"("directoryId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 77debff2aa..f9642e0e33 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -1151,19 +1151,21 @@ model OutOfOfficeEntry { } model DSyncData { - id Int @id @default(autoincrement()) - directoryId String - tenant String - organizationId Int? @unique - org OrganizationSettings? @relation(fields: [organizationId], references: [id], onDelete: Cascade) + id Int @id @default(autoincrement()) + directoryId String @unique + tenant String + organizationId Int? @unique + org OrganizationSettings? @relation(fields: [organizationId], references: [organizationId], onDelete: Cascade) + teamGroupMapping DSyncTeamGroupMapping[] } model DSyncTeamGroupMapping { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) organizationId Int teamId Int - team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) directoryId String + directory DSyncData @relation(fields: [directoryId], references: [directoryId], onDelete: Cascade) groupName String @@unique([teamId, groupName]) diff --git a/packages/trpc/server/routers/viewer/dsync/create.handler.ts b/packages/trpc/server/routers/viewer/dsync/create.handler.ts index f143af0361..3252ecdfec 100644 --- a/packages/trpc/server/routers/viewer/dsync/create.handler.ts +++ b/packages/trpc/server/routers/viewer/dsync/create.handler.ts @@ -1,7 +1,7 @@ import type { DirectoryType } from "@boxyhq/saml-jackson"; import jackson from "@calcom/features/ee/sso/lib/jackson"; -import { canAccess, samlProductID, samlTenantID, tenantPrefix } from "@calcom/features/ee/sso/lib/saml"; +import { canAccess, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml"; import prisma from "@calcom/prisma"; import { TRPCError } from "@trpc/server"; @@ -30,7 +30,9 @@ export const createHandler = async ({ ctx, input }: Options) => { }); } - const tenant = organizationId ? `${tenantPrefix}${organizationId}` : (samlTenantID as string); + const { organization } = ctx.user; + + const tenant = input.organizationId ? `${organization.slug}-${organization.id}` : (samlTenantID as string); const { data, error } = await dsyncController.directories.create({ tenant, diff --git a/packages/trpc/server/routers/viewer/dsync/get.handler.ts b/packages/trpc/server/routers/viewer/dsync/get.handler.ts index 0de777ab8f..b48ba00598 100644 --- a/packages/trpc/server/routers/viewer/dsync/get.handler.ts +++ b/packages/trpc/server/routers/viewer/dsync/get.handler.ts @@ -1,5 +1,6 @@ import jackson from "@calcom/features/ee/sso/lib/jackson"; -import { canAccess, samlProductID, samlTenantID, tenantPrefix } from "@calcom/features/ee/sso/lib/saml"; +import { canAccess } from "@calcom/features/ee/sso/lib/saml"; +import prisma from "@calcom/prisma"; import { TRPCError } from "@trpc/server"; @@ -26,9 +27,23 @@ export const getHandler = async ({ ctx, input }: Options) => { }); } - const tenant = input.organizationId ? `${tenantPrefix}${input.organizationId}` : (samlTenantID as string); + // Right now dsync is only available for organizations + if (!input.organizationId) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: "Organization ID is required", + }); + } - const { data, error } = await dsyncController.directories.getByTenantAndProduct(tenant, samlProductID); + const dsyncData = await prisma.dSyncData.findUnique({ + where: { + organizationId: input.organizationId, + }, + }); + + if (!dsyncData) return null; + + const { data, error } = await dsyncController.directories.get(dsyncData.directoryId); if (error) { console.error("Error fetching directory sync connection", error);