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);