fix: Inconsistent Location Handling for Event Types API - Map office365-video to msteams in Validation Handling (#21255)

* refactor: rename office365-video to msteams across API and platform code

* Revert "refactor: rename office365-video to msteams across API and platform code"

This reverts commit 7a823ab6aa7ecd739da941d3b315735220bd99de.

* Fix: inconsistency in default location values for create and update event-types
This commit is contained in:
Somay Chauhan authored and GitHub committed 2025-05-13 13:04:03 +00:00
1 parent 0e6f365dc2
commit e669996442
6 files changed
+309 -266

No files matched your search

@@ -8,7 +8,6 @@ import { InputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_
import { OutputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/output-event-types.service";
import { SchedulesRepository_2024_06_11 } from "@/ee/schedules/schedules_2024_06_11/schedules.repository";
import { AppsRepository } from "@/modules/apps/apps.repository";
import { ConferencingModule } from "@/modules/conferencing/conferencing.module";
import { CredentialsRepository } from "@/modules/credentials/credentials.repository";
import { MembershipsModule } from "@/modules/memberships/memberships.module";
import { PrismaModule } from "@/modules/prisma/prisma.module";
@@ -19,7 +18,7 @@ import { UsersRepository } from "@/modules/users/users.repository";
import { Module } from "@nestjs/common";
@Module({
imports: [PrismaModule, MembershipsModule, TokensModule, SelectedCalendarsModule, ConferencingModule],
imports: [PrismaModule, MembershipsModule, TokensModule, SelectedCalendarsModule],
providers: [
EventTypesRepository_2024_06_14,
EventTypesService_2024_06_14,
@@ -5,6 +5,9 @@ import { ConferencingService } from "@/modules/conferencing/services/conferencin
import { UserWithProfile } from "@/modules/users/users.repository";
import { Injectable, BadRequestException } from "@nestjs/common";
import { CONFERENCING_APPS } from "@calcom/platform-constants";
import { getUsersCredentials } from "@calcom/platform-libraries";
import { getApps } from "@calcom/platform-libraries/app-store";
import {
transformBookingFieldsApiToInternal,
transformLocationsApiToInternal,
@@ -50,8 +53,7 @@ interface ValidationContext {
export class InputEventTypesService_2024_06_14 {
constructor(
private readonly eventTypesRepository: EventTypesRepository_2024_06_14,
private readonly calendarsService: CalendarsService,
private readonly conferencingService: ConferencingService
private readonly calendarsService: CalendarsService
) {}
async transformAndValidateCreateEventTypeInput(
@@ -457,10 +459,32 @@ export class InputEventTypesService_2024_06_14 {
if (location.type === "integration") {
// cal-video is global, so we can skip this check
if (location.integration !== "cal-video") {
await this.conferencingService.checkAppIsValidAndConnected(user, location.integration);
await this.checkAppIsValidAndConnected(user, location.integration);
}
}
}) ?? []
);
}
async checkAppIsValidAndConnected(user: UserWithProfile, appSlug: string) {
const conferencingApps = ["google-meet", "office365-video", "zoom"];
if (!conferencingApps.includes(appSlug)) {
throw new BadRequestException("Invalid app, available apps are: ", conferencingApps.join(", "));
}
if (appSlug === "office365-video") {
appSlug = "msteams";
}
const credentials = await getUsersCredentials(user);
const foundApp = getApps(credentials, true).filter((app) => app.slug === appSlug)[0];
const appLocation = foundApp?.appData?.location;
if (!foundApp || !appLocation) {
throw new BadRequestException(`${appSlug} not connected.`);
}
return foundApp.credential;
}
}
@@ -1,4 +1,5 @@
import { InputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/input-event-types.service";
import { ConferencingRepository } from "@/modules/conferencing/repositories/conferencing.repository";
import { OrganizationsConferencingService } from "@/modules/organizations/conferencing/services/organizations-conferencing.service";
import { TeamsEventTypesRepository } from "@/modules/teams/event-types/teams-event-types.repository";
import { TeamsRepository } from "@/modules/teams/teams/teams.repository";
@@ -27,7 +28,8 @@ export class InputOrganizationsEventTypesService {
private readonly teamsRepository: TeamsRepository,
private readonly usersRepository: UsersRepository,
private readonly teamsEventTypesRepository: TeamsEventTypesRepository,
private readonly conferencingService: OrganizationsConferencingService
private readonly conferencingService: OrganizationsConferencingService,
private readonly conferencingRepository: ConferencingRepository
) {}
async transformAndValidateCreateTeamEventTypeInput(
userId: number,
@@ -306,6 +308,22 @@ export class InputOrganizationsEventTypesService {
}) ?? []
);
}
async checkAppIsValidAndConnected(teamId: number, app: string) {
const conferencingApps = ["google-meet", "office365-video", "zoom"];
if (!conferencingApps.includes(app)) {
throw new BadRequestException("Invalid app, available apps are: ", conferencingApps.join(", "));
}
if (app === "office365-video") {
app = "msteams";
}
const credential = await this.conferencingRepository.findTeamConferencingApp(teamId, app);
if (!credential) {
throw new BadRequestException(`${app} not connected.`);
}
return credential;
}
}
function getPriorityValue(priority: keyof typeof HostPriority): number {
@@ -1,4 +1,5 @@
import { EventTypesModule_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.module";
import { ConferencingRepository } from "@/modules/conferencing/repositories/conferencing.repository";
import { MembershipsModule } from "@/modules/memberships/memberships.module";
import { OrganizationsConferencingModule } from "@/modules/organizations/conferencing/organizations-conferencing.module";
import { OutputTeamEventTypesResponsePipe } from "@/modules/organizations/event-types/pipes/team-event-types-response.transformer";
@@ -31,6 +32,7 @@ import { Module } from "@nestjs/common";
OrganizationsTeamsRepository,
OutputTeamEventTypesResponsePipe,
OutputOrganizationsEventTypesService,
ConferencingRepository,
],
exports: [TeamsEventTypesRepository, TeamsEventTypesService],
controllers: [TeamsEventTypesController],
+148 -148
View File
@@ -17104,154 +17104,6 @@
"data"
]
},
"ConferencingAppsOutputDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "Id of the conferencing app credentials"
},
"type": {
"type": "string",
"example": "google_video",
"description": "Type of conferencing app"
},
"userId": {
"type": "number",
"description": "Id of the user associated to the conferencing app"
},
"invalid": {
"type": "boolean",
"nullable": true,
"example": true,
"description": "Whether if the connection is working or not."
}
},
"required": [
"id",
"type",
"userId"
]
},
"ConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
},
"required": [
"status",
"data"
]
},
"GetConferencingAppsOauthUrlResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ConferencingAppsOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"error"
]
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
}
},
"required": [
"status",
"data"
]
},
"SetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"DefaultConferencingAppsOutputDto": {
"type": "object",
"properties": {
"appSlug": {
"type": "string"
},
"appLink": {
"type": "string"
}
}
},
"GetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
}
},
"required": [
"status"
]
},
"DisconnectConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"OrgTeamOutputDto": {
"type": "object",
"properties": {
@@ -21143,6 +20995,154 @@
"data"
]
},
"ConferencingAppsOutputDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "Id of the conferencing app credentials"
},
"type": {
"type": "string",
"example": "google_video",
"description": "Type of conferencing app"
},
"userId": {
"type": "number",
"description": "Id of the user associated to the conferencing app"
},
"invalid": {
"type": "boolean",
"nullable": true,
"example": true,
"description": "Whether if the connection is working or not."
}
},
"required": [
"id",
"type",
"userId"
]
},
"ConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
},
"required": [
"status",
"data"
]
},
"GetConferencingAppsOauthUrlResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"ConferencingAppsOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"success",
"error"
]
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
}
},
"required": [
"status",
"data"
]
},
"SetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"DefaultConferencingAppsOutputDto": {
"type": "object",
"properties": {
"appSlug": {
"type": "string"
},
"appLink": {
"type": "string"
}
}
},
"GetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
},
"data": {
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
}
},
"required": [
"status"
]
},
"DisconnectConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": [
"success",
"error"
]
}
},
"required": [
"status"
]
},
"GoogleServiceAccountKeyInput": {
"type": "object",
"properties": {
+112 -112
View File
@@ -15979,118 +15979,6 @@
},
"required": ["status", "data"]
},
"ConferencingAppsOutputDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "Id of the conferencing app credentials"
},
"type": {
"type": "string",
"example": "google_video",
"description": "Type of conferencing app"
},
"userId": {
"type": "number",
"description": "Id of the user associated to the conferencing app"
},
"invalid": {
"type": "boolean",
"nullable": true,
"example": true,
"description": "Whether if the connection is working or not."
}
},
"required": ["id", "type", "userId"]
},
"ConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["success", "error"]
},
"data": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
},
"required": ["status", "data"]
},
"GetConferencingAppsOauthUrlResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"ConferencingAppsOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["success", "error"]
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
}
},
"required": ["status", "data"]
},
"SetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"DefaultConferencingAppsOutputDto": {
"type": "object",
"properties": {
"appSlug": {
"type": "string"
},
"appLink": {
"type": "string"
}
}
},
"GetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
},
"data": {
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
}
},
"required": ["status"]
},
"DisconnectConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"OrgTeamOutputDto": {
"type": "object",
"properties": {
@@ -19417,6 +19305,118 @@
},
"required": ["status", "data"]
},
"ConferencingAppsOutputDto": {
"type": "object",
"properties": {
"id": {
"type": "number",
"description": "Id of the conferencing app credentials"
},
"type": {
"type": "string",
"example": "google_video",
"description": "Type of conferencing app"
},
"userId": {
"type": "number",
"description": "Id of the user associated to the conferencing app"
},
"invalid": {
"type": "boolean",
"nullable": true,
"example": true,
"description": "Whether if the connection is working or not."
}
},
"required": ["id", "type", "userId"]
},
"ConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["success", "error"]
},
"data": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
},
"required": ["status", "data"]
},
"GetConferencingAppsOauthUrlResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"ConferencingAppsOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["success", "error"]
},
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ConferencingAppsOutputDto"
}
}
},
"required": ["status", "data"]
},
"SetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"DefaultConferencingAppsOutputDto": {
"type": "object",
"properties": {
"appSlug": {
"type": "string"
},
"appLink": {
"type": "string"
}
}
},
"GetDefaultConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
},
"data": {
"$ref": "#/components/schemas/DefaultConferencingAppsOutputDto"
}
},
"required": ["status"]
},
"DisconnectConferencingAppOutputResponseDto": {
"type": "object",
"properties": {
"status": {
"type": "string",
"example": "success",
"enum": ["success", "error"]
}
},
"required": ["status"]
},
"GoogleServiceAccountKeyInput": {
"type": "object",
"properties": {