Compare commits

...
Author SHA1 Message Date
Lauris Skraucis 947b05bf90 fix: v2 CI breaking changes check (#24445)
Post release / release (push) Canceled after 0s
* fix: v2 CI breaking changes check

* fix: ensure defaults

* fix
2025-10-14 13:46:36 +02:00
Hariom BalharaandDevin AI a0e5e03903 feat: Add async spam check and decoy booking response (#24326)
* feat: Add async spam check integration and decoy booking response

- Integrate SpamCheckService with handleNewBooking workflow
- Implement parallel spam check execution for minimal performance impact
- Add decoy booking response with localStorage-based success page
- Extract organization ID from event type for org-specific blocking
- Add comprehensive test coverage for spam detection scenarios
- Create reusable components for booking success cards
- Implement fail-open behavior to never block legitimate bookings

This builds on the spam blocker DI infrastructure from PR #24040 by
adding the actual integration into the booking flow and implementing
the decoy response mechanism to avoid revealing spam detection to
malicious actors.

Related: #24040
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Do checks in paralle

* Fix leaking host name in title

* Reduce expoiry time localstorage

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-14 11:36:51 +00:00
Rajiv Sahal 09ee39a3d8 feat: upcoming bookings atom (#24010)
* init: upcoming bookings atom

* add comments

* fix: better naming

* fixup

* fix: use `usePrefetch` hook

* add comment- for myself

* chore: add changesets

* fix: ignore isTeamEvent prop if we have teamId

* chore: update docs

* chore: implement PR feedback

* refactor: remove all unnecessary props

* update fetch bookings count
2025-10-14 12:37:37 +02:00
Anik Dhabal Babu 243012e82f fix: update resend inviation to follow auto accept (#24447) 2025-10-14 10:13:58 +00:00
emrysal d96c807505 chore: release v5.7.12 2025-10-14 09:57:19 +00:00
iqram magdon-ismailandAnik Dhabal Babu dac1069181 refactor: change the description of JellyPhone in Update config.json (#24340)
* Update config.json

modifying the description of jellyphone

* Update config.json

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-14 09:25:07 +00:00
Udit TakkarandCarinaWolli 06d6c180d1 feat: report booking (#24324)
* feat: report booking

* refactor: improvements

* test: add unit test

* test: add unit test

* chore

* refactor: feedback

* refactor: feedback

* refactor: feedback

* fix: use string

* fix: schema

* chore: improvements

* refactor: create service

* fix: udate test

* fix: feedback

* fix: schema

* fix: type

* fix: type

* refactor: address feedback

* refactor: move to new file

* refactor: move to new file

* chor: remove

* fix UserRepository import

* fix type of bookingUid

* fix: import path

* fix: remove cancellation

* chore: duplicate

* fix: tests

* refactor: feedback

* chore: remove table from here

* fix: types

* fix: types

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-10-14 09:23:31 +01:00
Syed Ali Shahbaz a2bee76da6 feat: Add spam blocker DI structure (#24040)
* --init

* --

* replace old structure with new DI

* fix type

* --

* moving stuff around

* moving stuff around again

* minor clean up

* --

* resolve conflict

* clea up

* old schema clean up

* further clean up

* removing unwanted merged responsibilities

* --

* improve DI and SOLID

* some type fixes

* --1

* clean up --cont

* fix DI in facade for test

* more fix

* fix

* checking

* o.o

* fix import

* fix failing test --2

* fix failing test --3

* fix failing test --4

* normalization use

* introduce facade container injection

* uniform async telemetry spans

* further improvements

* replace prismock with repo mocks

* ensure we don't pass prisma outside of repo

* fix import

* remove try catch from repo calls

* async await fixes

* using deps pattern

* more clean up and fixes

* more clean up

* address feedback --1

* separation of concern

* clean up

* test clean up

* feedback --2

* remove extra fetch

* remove await

* migrate _post test from prismock

* fix type

* --

* fix tokens path

* rename AuditRepo

* test --1

* update _post to integration test

* fix test

* fix test

* test fix maybe?

* --

* feedback

* feedback

* fixes

* more feedback

* NIT

* use sentry and logger imports as planned

* assertion in test

* add missing test case

* add tests for controllers and services

* NITs

* fix domain normalisation
2025-10-14 10:16:18 +03:00
52ecea964d fix: add tests for embed (#23561)
* fix: add tests for embed

* update

* fix test

* fix: use immediate interpolation for cancel button link

- Change from delayed evaluation (${...}) to immediate interpolation (${...})
- Remove unnecessary fallback value and complex expression
- Remove frame.goto() from cancelBookingThroughEmbed as iframe already at cancel page
- Remove unused page parameter from selectFirstAvailableTimeSlotNextMonth
- This aligns with working pattern from line 294 and avoids parser issues with complex expressions + query params

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* chore: fix formatting in testUtils

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: read popupCancelUid from URL parameter instead of copying rescheduleUid

The cancel button was using the wrong booking UID because it was copying from
popupRescheduleUid instead of reading from the URL parameter. This caused the
embed iframe to never appear when clicking the cancel button, resulting in test
timeouts.

The test navigates to /?popupCancelUid=<booking_uid> which should be read by
the JavaScript, just like popupRescheduleUid is read from its URL parameter.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-13 15:33:30 -03:00
Anik Dhabal BabuandUdit Takkar f9b294cfc2 fix: email and phone field validation (#24432)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-10-13 17:05:11 +00:00
e5f14c9316 feat: form submitted no event booked workflow trigger #2 (#23716)
* refactor: improve _scheduleWorkflowReminders readability and add missing booking trigger events

- Extract complex conditional logic into helper functions (isImmediateTrigger, isTimeBased, shouldProcessWorkflow)
- Add missing workflow trigger events with immediate execution logic
- Update test workflows to use different actions (EMAIL_ATTENDEE, SMS_ATTENDEE) for better differentiation
- Fix translation function mock in confirm.handler.test.ts using mockNoTranslations utility
- Maintain existing functionality while improving code maintainability

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* only show customt emplate for form triggers

* filter outside scheduleWorkflowReminder

* fix type check

* chore: add more tests

* test: add comprehensive unit tests for handleMarkNoShow with webhook and workflow coverage

- Create handleMarkNoShow.test.ts following confirm.handler.test.ts pattern
- Add expectBookingNoShowUpdatedWebhookToHaveBeenFired utility function
- Test both webhook and workflow triggers for BOOKING_NO_SHOW_UPDATED
- Cover attendee/host no-show scenarios, multiple attendees, and error cases
- All 6 unit tests pass with proper mocking of external dependencies

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* Revert "test: add comprehensive unit tests for handleMarkNoShow with webhook and workflow coverage"

This reverts commit 764299220279f0c012392dec24d3150246bfc4ad.

* fix: add new workflow triggers to api/v2

* update swagger docs

* fix: e2e

* fix type check

* fix tests, add test for before after events

* fix unit tests

* revert confirm.handler.test

* fix: unit tests

* dummy form variables

* add routing forms to active on dropdown

* add migration file

* Ui fixes for variables dropdown

* remove other translation keys

* review fixes

* allow routing forms for activeOn

* use repository function to get routing forms

* remove unnecessary code

* adjust logic in update handler

* add triggers to api v2

* remvoe unused file

* rename to getAcitveOnOptions handler

* remove routingFormOptions handler

* clean up getActiveOnOptions

* refactor WorkflowService

* remove logs

* remove unused

* fix: type check

* fix: missed before after events for recurring

* fix: calendarEvent handleMarkNoShow

* fix error message

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* don't query disabled routing forms

* create tasker function

* add tasker code

* move isFormTrigger function

* small adjustments + todo comments

* remove email to host action for form triggers

* throw trpc error if email to host is added as step

* fix dialog on how to use form responses as variables

* remove add variable dropdown for form triggers

* remove form workfows in event workflows tab

* improvements for workflow logic on form submission

* review fixes

* base setup for seperate schedule functions (evt and form)

* add missing BOOKING_PAID workflow trigger

* fix pathname

* fix: test for BOOKING_REQUESTED

* fix activeOn ids

* pass hideBranding and smsReminderNumber

* adjustments to reminderScheduler

* create empty scheduelForForm functions

* pass locale and timezone with form user

* pass formData instead of responses

* pass timeFormat and locale

* reusable function for email sending and reminder creation

* implement scheduleEmailReminderForForm

* remove added editor field from merge conflict

* don't support cal.ai action with form triggers

* throw bad request if form trigger and cal.ai is combined

* add tests for scheduleFormWorkflows

* add form submission tests

* remove form response varibe info

* clean up workflow actions

* fixes for getting template options

* pass triggerType to getAllWorkflows

* move reusable logic to scheduleSMSReminder

* add formdata to param type

* type fixes for text reminder managers

* implement scheduleSMSReminderForForm

* fix import

* fix isAuthorizedToAddActiveOnIds

* disble whatsapp action

* implement triggerFormSubmittedNoEventWorkflow

* code clean up

* Merge branch 'devin/1755107037-add-workflow-triggers' into feat/routing-form-workflow-triggers

* fix type errors

* remove async from getSubmitterEmail

* fix type errors

* revert cal.ai changes

* fix type error

* add sublogger

* code clean up

* fix type errors

* remove label for attendee whatsapp action

* code clean up

* fixes saving teams on org workflows

* fix type error

* code improvements for activeOn ids

* Revert "code improvements for activeOn ids"

This reverts commit 0a3590a4e2ce541b17d63483ad86ed458795a6a3.

* improve variable name

* fix unit tests

* small fixes

* type fixes

* remove unused translation keys

* fix merge conflict issues

* code clean up

* remove SMS action support

* remove more SMS code

* add missing imports

* set custom template for form action

* type fixes

* fix tasker endpoint

* fix duplicate check

* fix workfows.test.ts

* use repository funciton to getHideBranding

* code clean up

* fix hasDuplicateSubmission

* code clean up

* select only needed properties

* remove repository functions

* Revert "remove repository functions"

This reverts commit 7aa47b1c59c9abd7f964ebf26f746934c53a44f4.

* add scheduleWorkflows function

* Revert "add scheduleWorkflows function"

This reverts commit fe5db4fe3b65e2743c95475d585300cab98beed7.

* move type to /types

* Revert "move type to /types"

This reverts commit 91e0152154594b3772a801a426260068a8ccea54.

* revert changes causing type errors

* remove import

* remove unused import

* Revert "remove unused import"

This reverts commit 1916768c875ea5d0ac5598ccb8f9c796c5622dc9.

* revert changed from attempt to fix type errors

* pass object to gt all workflows

* fix isAuthorized check

* trigger filtering

* remove form submitted no event booked code

* remove form submitted no event from schema

* remove more code

* remove test

* fixes

* add getSubmitterEmail function

* add trigger

* small fixes

* add missing workflow DTOs

* small fixes

* use activeOnWithChildren

* fix active on when switching trigger type

* remove add variable dropdown

* add getAllWorkflowsFromRoutingForm to WorkflowService

* fix error caused by undefined evt

* fix type error

* fix type error

* fix tests

* code clean up

* final fixes and clean up

* remove console.log

* remove template text form from triggers

* add routing form repoditory function

* fix bug with key

* fix test

* add missing trigger in update-workflow.input.ts

* ForEvt and ForForm function for aiPhoneCallManager

* chore: add support for form workflows on api v2

* fixup! chore: add support for form workflows on api v2

* use only repository functions in update handler

* move all prisma queries from list.handler

* review suggestions

* chore: handle workflows api v2

* chore: handle workflows api v2, split in 2 endpoints

* fix workflow step creation

* remove connect agent and fixes types

* add type to workflow

* chore: use workflow type in apiv2 WorkflowsOutputService

* update worklfow type on update

* chore: use workflow type in apiv2 WorkflowsOutputService

* fix template body for torm trigger

* some UI fixes for email subject/body

* resetting email body when changing form triggers

* use type field to query workflows

* clean up all old active on values

* remove responseId from all funciton calls

* remove undefined from updateTemplate

* refactor: split routing form and event-type workflows code

* refactor: split routing form and event-type workflows code

* fix template  text when adding action

* chore: don't rename WorkflowActivationDto to avoid ci blocking

* refine update schedule to use only allowed actions

* fix type error

* don't allow whatsapp action with form trigger

* fix type error

* return early if activeOn array is empty

* fix: from step type in BaseFormWorkflowStepDto

* fixup! fix: from step type in BaseFormWorkflowStepDto

* api v2 updates

* move all prisma calls to repository (service/workflows.ts)

* use FORM_TRIGGER_WORKFLOW_EVENTS for form queries

* use userRepository

* use FORM_TRIGGER_WORKFLOW_EVENTS in isFormTrigger

* code clean up

* code clean up

* use repository functions in formSubmissionValidation.ts

* add back trpc  import

* fix agent repository functions

* remove unsued import

* fixes for offset api v2

* add missing responseId

* fix failing test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: amit@cal.com <samit91848@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-13 16:13:56 +00:00
Hariom Balhara bed76beb2f fix: Layout shift in inline embed caused due to showing embed before it was really ready (#24427) 2025-10-13 12:29:31 -03:00
Benny Joo ff38d6c7db refactor: Remove circular deps between @calcom/lib and @calcom/features [1] (#24399)
* add eslint config

* migrate autoLock to features

* migrate teamService to features

* migrate userCreationService

* migrate insights services to features

* migrate ProfileRepository

* update imports

* migrate filter segmen tests

* migrate filter segment repository

* migrate getBusyTimes

* migrate getLocaleFromRequest

* refactor csvUtils

* make filename clearer

* migrate getLuckyUser integration test

* migrate autoLock test to features

* wip

* refactors

* migrate useBookerUrl

* migrate more

* wip

* Migrate eventTypeRepository

* membership repository

* update imports

* update imports

* migrate

* move organization repository

* update imports

* update imports

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix tests

* fix type checks

* fix

* fix

* migrate

* update imports

* fix tests

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix
2025-10-13 12:01:02 -03:00
1dc20e3aec refactor: usePrefetch hook (#24123)
* init: refactor usePrefetch hook to make it readable

* fix: move over logic to determine prefetch next month into its own function

* update parameters

* fix: better naming

* fix: type check

* test: add comprehensive test coverage for usePrefetch utility functions

- Add tests for areDifferentValidMonths: validates month comparison logic with edge cases
- Add tests for isLastWeekOfMonth: covers week boundaries and date edge cases
- Add tests for isMonthViewPrefetchEnabled: tests time-based prefetch logic with mocked time
- Add tests for getPrefetchMonthCount: validates conditional month count logic for different layouts
- Add tests for isPrefetchNextMonthEnabled: integration tests for orchestration function

All tests use vitest framework with 51 test cases covering key scenarios and edge cases.
Tests follow existing patterns from Cal.com codebase and use integration approach.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: implement coderabbit feedback

* fix: tests

* fix: use isoWeek plugin from day to maintain consistency

* fix: type errors

* fix: dont use isoWeek from dayjs

* revert isoWeek import for dayjs

* add helper function

* fix: bring back the orginal logic we had in usePrefetch but in a simplified way

* remove unused logic

* test: update tests for usePrefetch refactoring

- Add tests for new isMonthChange helper function
- Update isPrefetchNextMonthEnabled tests to match new signature
- Tests now use pre-calculated month values instead of date strings

All 39 tests passing locally

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-13 22:51:50 +09:00
44a3a9eabb feat: form submitted workflow triggers #1 (#23704)
* feat: add 5 new workflow triggers for booking events

- Add BOOKING_REJECTED, BOOKING_REQUESTED, BOOKING_PAYMENT_INITIATED, BOOKING_PAID, BOOKING_NO_SHOW_UPDATED to WorkflowTriggerEvents enum
- Update workflow constants to include new trigger options
- Implement workflow trigger logic for booking rejected and requested events
- Add translations for new workflow triggers following {enum}_trigger format
- Generate updated Prisma types for new schema changes

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: type check, remove as any

* feat: add workflow trigger for BOOKING_REQUESTED in handleNewBooking.ts

- Add WorkflowTriggerEvents import to handleNewBooking.ts
- Implement workflow trigger logic for BOOKING_REQUESTED in else block
- Filter workflows by BOOKING_REQUESTED trigger and call scheduleWorkflowReminders
- Use proper calendar event object construction without type casting
- Add error handling for workflow reminder scheduling

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: resolve type errors in workflow trigger implementations

- Add proper database includes for user information in handleConfirmation.ts
- Fix ExtendedCalendarEvent type structure with correct hosts mapping
- Add missing properties to calendar event objects in handleMarkNoShow.ts
- Ensure all workflow triggers follow proper type patterns

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* feat: add workflow test configurations for new booking triggers

- Add workflow configurations for BOOKING_REQUESTED and BOOKING_PAYMENT_INITIATED in fresh-booking.test.ts
- Add workflow configuration for BOOKING_REJECTED in confirm.handler.test.ts
- Enable previously skipped confirm.handler.test.ts
- Remove workflow test assertions temporarily until triggers are fully functional
- Maintain webhook test coverage while adding workflow test infrastructure

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* fix: add missing mockSuccessfulVideoMeetingCreation import to confirm.handler.test.ts

- Import mockSuccessfulVideoMeetingCreation from bookingScenario utils
- Add mock call to BOOKING_REJECTED workflow test case
- Resolves ReferenceError that was causing unit test CI failure

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* add new triggers

* refactor: improve _scheduleWorkflowReminders readability and add missing booking trigger events

- Extract complex conditional logic into helper functions (isImmediateTrigger, isTimeBased, shouldProcessWorkflow)
- Add missing workflow trigger events with immediate execution logic
- Update test workflows to use different actions (EMAIL_ATTENDEE, SMS_ATTENDEE) for better differentiation
- Fix translation function mock in confirm.handler.test.ts using mockNoTranslations utility
- Maintain existing functionality while improving code maintainability

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* only show customt emplate for form triggers

* filter outside scheduleWorkflowReminder

* fix type check

* chore: add more tests

* test: add comprehensive unit tests for handleMarkNoShow with webhook and workflow coverage

- Create handleMarkNoShow.test.ts following confirm.handler.test.ts pattern
- Add expectBookingNoShowUpdatedWebhookToHaveBeenFired utility function
- Test both webhook and workflow triggers for BOOKING_NO_SHOW_UPDATED
- Cover attendee/host no-show scenarios, multiple attendees, and error cases
- All 6 unit tests pass with proper mocking of external dependencies

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* Revert "test: add comprehensive unit tests for handleMarkNoShow with webhook and workflow coverage"

This reverts commit 764299220279f0c012392dec24d3150246bfc4ad.

* fix: add new workflow triggers to api/v2

* update swagger docs

* fix: e2e

* fix type check

* fix tests, add test for before after events

* fix unit tests

* revert confirm.handler.test

* fix: unit tests

* dummy form variables

* add routing forms to active on dropdown

* add migration file

* Ui fixes for variables dropdown

* remove other translation keys

* review fixes

* allow routing forms for activeOn

* use repository function to get routing forms

* remove unnecessary code

* adjust logic in update handler

* add triggers to api v2

* remvoe unused file

* rename to getAcitveOnOptions handler

* remove routingFormOptions handler

* clean up getActiveOnOptions

* refactor WorkflowService

* remove logs

* remove unused

* fix: type check

* fix: missed before after events for recurring

* fix: calendarEvent handleMarkNoShow

* fix error message

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* don't query disabled routing forms

* create tasker function

* add tasker code

* move isFormTrigger function

* small adjustments + todo comments

* remove email to host action for form triggers

* throw trpc error if email to host is added as step

* fix dialog on how to use form responses as variables

* remove add variable dropdown for form triggers

* remove form workfows in event workflows tab

* improvements for workflow logic on form submission

* review fixes

* base setup for seperate schedule functions (evt and form)

* add missing BOOKING_PAID workflow trigger

* fix pathname

* fix: test for BOOKING_REQUESTED

* fix activeOn ids

* pass hideBranding and smsReminderNumber

* adjustments to reminderScheduler

* create empty scheduelForForm functions

* pass locale and timezone with form user

* pass formData instead of responses

* pass timeFormat and locale

* reusable function for email sending and reminder creation

* implement scheduleEmailReminderForForm

* remove added editor field from merge conflict

* don't support cal.ai action with form triggers

* throw bad request if form trigger and cal.ai is combined

* add tests for scheduleFormWorkflows

* add form submission tests

* remove form response varibe info

* clean up workflow actions

* fixes for getting template options

* pass triggerType to getAllWorkflows

* move reusable logic to scheduleSMSReminder

* add formdata to param type

* type fixes for text reminder managers

* implement scheduleSMSReminderForForm

* fix import

* fix isAuthorizedToAddActiveOnIds

* disble whatsapp action

* implement triggerFormSubmittedNoEventWorkflow

* code clean up

* Merge branch 'devin/1755107037-add-workflow-triggers' into feat/routing-form-workflow-triggers

* fix type errors

* remove async from getSubmitterEmail

* fix type errors

* revert cal.ai changes

* fix type error

* add sublogger

* code clean up

* fix type errors

* remove label for attendee whatsapp action

* code clean up

* fixes saving teams on org workflows

* fix type error

* code improvements for activeOn ids

* Revert "code improvements for activeOn ids"

This reverts commit 0a3590a4e2ce541b17d63483ad86ed458795a6a3.

* improve variable name

* fix unit tests

* small fixes

* type fixes

* remove unused translation keys

* fix merge conflict issues

* code clean up

* remove SMS action support

* remove more SMS code

* add missing imports

* set custom template for form action

* type fixes

* fix tasker endpoint

* fix duplicate check

* fix workfows.test.ts

* use repository funciton to getHideBranding

* code clean up

* fix hasDuplicateSubmission

* code clean up

* select only needed properties

* remove repository functions

* Revert "remove repository functions"

This reverts commit 7aa47b1c59c9abd7f964ebf26f746934c53a44f4.

* add scheduleWorkflows function

* Revert "add scheduleWorkflows function"

This reverts commit fe5db4fe3b65e2743c95475d585300cab98beed7.

* move type to /types

* Revert "move type to /types"

This reverts commit 91e0152154594b3772a801a426260068a8ccea54.

* revert changes causing type errors

* remove import

* remove unused import

* Revert "remove unused import"

This reverts commit 1916768c875ea5d0ac5598ccb8f9c796c5622dc9.

* revert changed from attempt to fix type errors

* pass object to gt all workflows

* fix isAuthorized check

* trigger filtering

* remove form submitted no event booked code

* remove form submitted no event from schema

* remove more code

* remove test

* fixes

* add getSubmitterEmail function

* add missing workflow DTOs

* small fixes

* use activeOnWithChildren

* fix active on when switching trigger type

* remove add variable dropdown

* add getAllWorkflowsFromRoutingForm to WorkflowService

* fix error caused by undefined evt

* fix type error

* fix type error

* fix tests

* code clean up

* remove console.log

* remove template text form from triggers

* add routing form repoditory function

* fix bug with key

* add missing trigger in update-workflow.input.ts

* ForEvt and ForForm function for aiPhoneCallManager

* chore: add support for form workflows on api v2

* fixup! chore: add support for form workflows on api v2

* use only repository functions in update handler

* move all prisma queries from list.handler

* review suggestions

* chore: handle workflows api v2

* chore: handle workflows api v2, split in 2 endpoints

* fix workflow step creation

* remove connect agent and fixes types

* add type to workflow

* chore: use workflow type in apiv2 WorkflowsOutputService

* update worklfow type on update

* chore: use workflow type in apiv2 WorkflowsOutputService

* fix template body for torm trigger

* some UI fixes for email subject/body

* resetting email body when changing form triggers

* use type field to query workflows

* clean up all old active on values

* remove responseId from all funciton calls

* remove undefined from updateTemplate

* refactor: split routing form and event-type workflows code

* refactor: split routing form and event-type workflows code

* fix template  text when adding action

* chore: don't rename WorkflowActivationDto to avoid ci blocking

* refine update schedule to use only allowed actions

* fix type error

* don't allow whatsapp action with form trigger

* fix type error

* return early if activeOn array is empty

* fix: from step type in BaseFormWorkflowStepDto

* fixup! fix: from step type in BaseFormWorkflowStepDto

* move all prisma calls to repository (service/workflows.ts)

* use FORM_TRIGGER_WORKFLOW_EVENTS for form queries

* use userRepository

* use FORM_TRIGGER_WORKFLOW_EVENTS in isFormTrigger

* code clean up

* code clean up

* add back trpc  import

* fix agent repository functions

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: amit@cal.com <samit91848@gmail.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-13 12:20:47 +02:00
chauhan_s c0c52750b6 docs: add example and improve tabs prop documentation in event type settings (#24393) 2025-10-13 10:18:46 +00:00
3bcaf0ec22 fix: move team credits to org on upgarde (#24386)
* move credits from team to org

* add test

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-10-13 09:30:22 +00:00
Anik Dhabal BabuandDevin AI b881e025f6 fix: Standardize email field editable to system-but-optional (#24416)
Change email booking field's editable property from 'system' to
'system-but-optional' across all code paths. This allows email field
to be optional when phone field is required instead.

- Updated systemBeforeFieldEmail in API v2024_06_14 transformers
- Fixed explicit override in API v2024_04_15 service
- Updated test utility to match production behavior
- Ensures consistency with validation logic that requires either
  email OR phone to be visible and required

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-13 09:19:59 +00:00
sean-brydon 35d140e0a7 feat: PBAC - opt-in for organizations. (#24424)
* WIP UI for opt in pbac

* Remove header

* Opt in plus route invaldiation

* Use dialog upgrade tip approach

* Add i18n + animation

* Format

* Address @designer man feedback

* Fix type errors

* Add i18n to opt in view settings header + add comments for svg

* remvoe comments
2025-10-13 09:31:53 +01:00
Anik Dhabal Babu 5fd55cbfc3 fix: unable to cancel a seated event as an host (#24426) 2025-10-13 07:38:19 +00:00
18c546a171 fix: pass cancellation reason for seated event cancellations in API v2 (#24409)
* fix: pass cancellation reason for seated event cancellations in API v2

- Add cancellationReason field to CancelSeatedBookingInput_2024_08_13 type
- Update transformInputCancelSeatedBooking to use provided cancellationReason
- Fix pre-existing ESLint warnings (no-prototype-builtins) in isRescheduleSeatedBody and isCancelSeatedBody
- Fixes issue where API v2 throws 'cancellation reason required' error even when reason is provided
- Resolves validation error for hosts canceling seated events via API v2

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Update input.service.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-13 07:19:34 +00:00
Carina WollendorferandCarinaWolli b01ceb427d add videoCallUrl to zapier payload (#24403)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-10-13 06:02:03 +00:00
Rajiv Sahal eae2711f21 chore: update docs to make sure to inform users to pass in cal-api-version header (#24364)
Post release / release (push) Canceled after 0s
2025-10-10 11:00:27 +00:00
emrysal fac956b761 chore: release v5.7.11 2025-10-10 10:54:23 +00:00
b286244aab fix: api v2 logic for slots reservation endpoint (#23222)
* init logic for handling reservation for round robin event

* remove unused comments

* add function to get already reserved slots

* fixup: add correct logic for round robin slots reservation

* fixup: implement PR feedback

* fixup: update logic to handle fixed and non fixed round robin hosts

* update slots repository

* fixup: implement PR feedback

* fixup: implement PR feedback

* add tests for round robin slot reservation with non fixed hosts

* add tests for round robin slot reservation with fixed and non fixed hosts

* fix: implement PR feedback

* fix: e2e test

* fix: move validateRoundRobinSlotAvailability to core libraries

* fix: merge conflicts

* fix: merge conflicts

* update slots.ts for platform libraries

* fix: import logic from platform libraries

* cleanup

* fix: import path

* fix: missing import

* fix: test code and handle error thrown

---------

Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-10 12:35:21 +02:00
emrysal c46f824e3f chore: release vv5.7.11 2025-10-10 10:31:11 +00:00
Benny Joo dbe55f0804 refactor: Break videoClient into two separate files in app-store and features (#23992)
* getVideoAdapters

* fix
2025-10-10 07:11:46 -03:00
Hariom BalharaandVolnei Munhoz 3bcce02b92 chore: [Booking flow refactor - 2] Integrate Booking services (#23156)
* Integrate booking services

* Fix imports

---------

Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-10-09 18:21:55 -03:00
Anik Dhabal Babu 2a23911a5b fix: extra 30-minute buffer was added to 60-minute slots without it being set (#24087)
* fix: 30 min buffer added on 60 min slots

* update

* fix test

* Update restrictionSchedule.test.ts

* addressed test

* Update getSchedule.test.ts
2025-10-09 18:37:52 +01:00
sean-brydonandcoderabbitai[bot] 5aa24c8472 fix: event-type permissions (#24318)
* New permission function

* Update permission check service to have fall backs

Update event type create permission procedure to also have org heigharchy

* Update get eventType handler to use new procedure

* Type check

* Type fix

* Update packages/features/pbac/lib/event-type-permissions.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix type errorr

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-09 12:30:12 -03:00
Benny Joo 8277ce934b fix: ESLint config in app-store and features (#24387)
* make eslint config in app-store

* remove the one in features
2025-10-09 14:09:23 +00:00
Benny Joo bb68cd73ef refactor: circular deps between app store and lib [6] (#23971)
* move delegation credential repository to features

* mv credential repository to features

* update imports

* mv

* fix

* fix

* fix

* fix

* fix

* update imports

* update imports

* update eslint rule

* fix

* fix

* mv getConnectedDestinationCalendars

* fix import errors

* mv getCalendarsEvents

* remove getUsersCredentials

* wip

* revert eslint rule change for now

* fix type checks

* fix

* format

* cleanup

* fix

* fix

* fix

* fix

* fix tests

* migrate getUserAvailability

* migrate

* fix tests

* fix type checks

* fix

* fix

* migrate crmManager

* update imports

* migrate raqbUtils to appstore

* migrate getLuckyUser to features

* migrate findTeamMembersMatchingAttributeLogic to appstore

* update imports

* fix

* fix

* fix test

* fix unit tests

* fix

* fix

* add eslint config
2025-10-09 14:02:12 +00:00
Rajiv Sahal 445b307972 fix: week view and column view slots not fetching at end of month bug (#24374)
* fix: dont pick date value from url, use selectedDate value from booker store instead

* fix: replace month count logic with usePrefectch hook

* intialise booker layout as week view
2025-10-09 13:56:59 +01:00
Calcom BotandLingo.dev d2d86a4079 feat: update translations via @LingoDotDev (#24383)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-10-09 21:43:34 +09:00
chauhan_s 7601cc2194 fix: PER_ACTIVE_USER Plan should be able to access everything above SCALE (#24352)
* Update managed-organizations.billing.service.ts

* test: add plan restriction check for managed organization creation

* test: add pay-per-user plan validation for managed organization creation

* refactor: extract test setup to helpers

* refactor: move helper functions below beforeAll for better test organization
2025-10-09 09:26:22 -03:00
Udit TakkarandCarina Wollendorfer aa48e72c12 feat: inbound calls in cal ai (#23890)
* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types

* feat: add inbound calls

* chore: formatting

* chore

* feat: finish inbound call

* chore: formatting

* fix: update bug

* fix: types

* refactor: Agent Configuration Sheet (#23930)

* refactor: agent configuration sheet

* chore: use default phone numbre

* refactor: improvements

* refactor: improvements

* fix: types

* fix: feedback

* chore:

* fix: feedback

* fix: prompt

* fix: review

* fix: review

* refactor: class

* refactor: class

* refactor: rename

* Update apps/web/public/static/locales/en/common.json

* Update apps/web/public/static/locales/en/common.json

* chore: update set value

* fix: remove index

* fix: type error

* fix: update tetss

* fix: use logger

* refactor: don't use static

* fix: type

* fix: schema

* refactor:

---------

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2025-10-09 11:40:37 +01:00
Hariom BalharaandDevin AI bec49ef417 fix: provide meetingStartTime for test preview to prevent 'Meeting start time is required' crash (#24379)
Post release / release (push) Canceled after 0s
* fix: provide meetingStartTime for test preview to prevent RR timestamp error

When Round Robin timestamp basis is set to START_TIME, the system requires
a meeting start time to calculate the interval for load balancing. Test
Preview doesn't have a real meeting time since it's just simulating the
routing logic.

This fix provides the current time (new Date()) as the meetingStartTime
when calling getOrderedListOfLuckyUsers in test preview mode. This allows
the Round Robin calculation to proceed using the current interval for
realistic ordering while still being in preview mode.

Fixes the 'Meeting start time is required' error that occurs when users
click Test Preview on routing forms with Round Robin timestamp basis set
to START_TIME.

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* add comment

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-09 08:58:57 +00:00
Kartik LabhshetwarandDevanshu Sharma c13aa69565 fix: improve cross button alignment and spacing in FormBuilder Options (#24247)
* fix: improve cross button alignment and spacing in FormBuilder Options

* fix: revert eslint errors

---------

Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
2025-10-09 08:18:19 +00:00
emrysal 1470adb159 chore: release v5.7.10 2025-10-09 08:17:36 +00:00
emrysal bf89991eef chore: release v5.9.10 2025-10-09 00:22:21 +00:00
iqram magdon-ismail 4dfab874e0 refactor: update JellyPhone icon (#24341)
change the icon for jellyphone
2025-10-08 14:38:54 +00:00
Joe Au-Yeung 4303fb8726 feat: Salesforce - add urql/retry-exchange (#24302)
* Add .env variables

* Add `urql/exchange-retry`

* Add retry mechanic to graphql client

* Only add retries if .env variables are set

* Remove console.log
2025-10-08 14:03:40 +00:00
64f811ed0b feat: show organization username in impersonation banner (#24313)
- Update ImpersonatingBanner to use orgAwareUsername field from session
- Falls back to regular username for non-organization users
- Uses existing session data without additional queries

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-08 11:31:59 +00:00
4d51873140 feat: remove Cal.ai tab from navigation while preserving URL access (#23894)
Co-authored-by: peer@cal.com <peer@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-07 20:38:05 +00:00
3c0fc2e88b fix: reschedule issue when limited booking is enabled in the event settings. (#23717)
* fix

* fix fix

* cleanup

* Update useBookings.ts

* Update store.ts

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-07 19:23:43 +00:00
c702da0334 feat: Add team billing tables (#24148)
* Init billing tables

* Create `IBillingRepository` types

* Create billing repositories

* Create billingRepositoryFactory

* Eslint fix - remove unused organizationOnboarding

* internal-team-billing create saveTeamBilling method using repositories

* On new teams write to team billing table

* On new org write to org billing table

* Change fields to organizationId

* Add todo comment

* Revert "Change fields to organizationId"

This reverts commit bbb2e5dfa6b4c20a8a395f5730848a492cd70d68.

* test: add comprehensive tests for team billing tables

- Fix credit-service.test.ts Prisma mock to export prisma object
- Replace any types with proper TypeScript types in credit-service.test.ts
- Add unit tests for PrismaTeamBillingRepository covering record creation, enum casting, and error handling
- Add unit tests for PrismaOrganizationBillingRepository with same coverage
- Add unit tests for BillingRepositoryFactory to verify correct repository selection
- Add unit tests for InternalTeamBilling.saveTeamBilling() method testing delegation to correct repositories
- All 53 tests pass with TZ=UTC yarn test
- Type checking passes with yarn type-check:ci --force

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* refactor: update saveTeamBilling tests to mock repository interface

- Replace prismaMock usage with BillingRepositoryFactory mock
- Mock IBillingRepository interface instead of Prisma directly
- Follow repository mocking pattern from handleResponse.test.ts
- All tests passing (53 total)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Remove log statement

* Remove repository tests

* Address feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-07 14:25:31 -04:00
Bhavya Bhardwaj 92169eb0d2 fix: resolve AI assistant button overlap and mobile padding on Teams page (#24286)
* Fix padding in UpgradeTip component

Adjusted padding in UpgradeTip component.

* Adjust bottom positioning of main navigation component

* Adjust bottom positioning for main navigation
2025-10-07 23:11:39 +05:30
kusiewicz 3d74357e96 fix: polish sign-in translation (#24263) 2025-10-07 23:06:07 +05:30
Parship Chowdhury 6593291d00 Proper error handling in PrismaAppRepository.findAppStore with Sentry logging (#24212)
Signed-off-by: Parship Chowdhury <i.am.parship@gmail.com>
2025-10-07 21:23:27 +05:30
Kartik LabhshetwarandKartik Saini c48fb44a8d fix: make empty screen template grid mobile responsive (#24259)
* fix: make empty screen template grid mobile responsive

* refactor: adjust EmptyScreen layout classes for responsive grid

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-10-07 21:19:58 +05:30
Peer Richelsen e7c908bc80 feat: framer app (#24204)
* added framer app

* new 1.jpeg

* Update packages/app-store/framer/config.json
2025-10-07 15:12:22 +00:00
Peer RichelsenandRodrigo Ehlers ad35e19f8e feat: fonio.ai app (#23874)
* added fonio

* small hitpay update

* added fonio screenshots

* added description

* fix: rename 1.jpg -> 1.jpeg in fonio-ai app

---------

Co-authored-by: Rodrigo Ehlers <rodrigoehlers@outlook.com>
2025-10-07 14:42:29 +00:00
Keith Williams 3fc8c6c84e chore: Remove unused next dependency in @calcom/ui (#24311)
* chore: Remove unused Next.js package

* update yarn.lock
2025-10-07 01:34:53 +00:00
emrysal da7aeb4a21 chore: release v5.7.9
Post release / release (push) Canceled after 0s
2025-10-06 23:57:19 +00:00
Keith Williams 6197a2a5c5 chore: Upgrade Next.js to 15.5.4 (#24307) 2025-10-06 21:39:26 +00:00
Syed Ali ShahbazandAlex van Andel de186b95c1 fix: create missing migration for dropping obsolete indexes (#24304)
* Create migration.sql

* Drop index if exists, otherwise do nada

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-06 21:33:00 +00:00
Syed Ali Shahbaz 6b24513073 Update how-to-setup-api-in-a-local-instance.mdx (#24300) 2025-10-06 17:39:55 +00:00
Kinbaum 55ea18128a fix: timeZone variable name does not match webhook payload (#24279) 2025-10-06 22:49:28 +05:30
Calcom BotandLingo.dev d5557fa512 feat: update translations via @LingoDotDev (#24301)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-10-06 12:59:10 -03:00
Hariom BalharaandDevin AI 9c97b2aa6d feat: add usernameInOrg field to webhook organizer payload for organization users (#23246)
* feat: add usernameInOrg field to webhook organizer payload for organization users

- Add usernameInOrg field to CalendarEventBuilder organizer interface
- Update handleNewBooking to pass organizerOrganizationProfile.username as usernameInOrg
- Include usernameInOrg in webhook payload generation (sendPayload.ts)
- Add webhook form variable for usernameInOrg with translation
- Update Person type to include usernameInOrg field
- Add test case for organization user webhook verification
- Maintain backward compatibility by keeping existing username field unchanged

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* feat: add usernameInOrg to additional webhook sending locations

- Update handleCancelBooking.ts to include usernameInOrg in organizer payload
- Update confirm.handler.ts to include usernameInOrg for booking confirmations
- Update getBooking.ts to include usernameInOrg in payment-related webhooks
- Maintain backward compatibility with existing username field
- All webhook sending locations now include organization profile username

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fixes

* Add subteam event test for usernameInOrg

* fix eslitn issues

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-06 19:51:04 +05:30
sean-brydonandClaude 1e226a40d1 Add next-auth-options.ts to Foundation code owners (#24295)
Added packages/features/auth/lib/next-auth-options.ts to CODEOWNERS for the Foundation team to ensure proper review and oversight of authentication configuration changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-06 11:55:58 +00:00
Hariom Balhara bbe46eaa7d Restrict the length of emails as per RFC (#24269) 2025-10-06 10:22:58 +00:00
sean-brydon 7799b191ec feat: botid enabled on api/book/event api route (#24207)
* wip

* WIP

* restore event

* testing without instrument client

* Add conditional for botID init

* Bump BotID version + pass in header

* botID yarn lock changes

* feat: Add feature flag checks + tidy up into service

* rely on env var also

* use eventType repo instead of passing in prisma

* remove slug from audit

* rename botId feature to botid

* add unit tests for bot service
2025-10-06 11:16:13 +01:00
Anik Dhabal Babu f3269a3ddf fix: contentType is added in worng format (#24284) 2025-10-06 06:29:54 +00:00
emrysal a4be822636 chore: release v5.7.8
Post release / release (push) Canceled after 0s
2025-10-04 14:20:17 +00:00
Syed Ali Shahbaz 7cd8dbf7d8 chore: Watchlist schema update (#24246)
* watchlist schema update

* changes addressed

* no backfill audit

* fix type

* fix flow of migration

* fix err

* type err fix

* add if exists check in migration
2025-10-04 01:44:37 +01:00
654a865007 refactor: Salesforce getContacts (#24235)
* lint fixes

* Create getContactOrLeadFromEmail method

* Use getContactOrLeadFromEmail in getContacts

* Move normal getContact query

* fix: correct return type in getContactOrLeadFromEmail and add search mock

- Fix getContactOrLeadFromEmail to return single ContactRecord instead of array
- Add conn.search() implementation to salesforceMock for integration tests
- Ensure id field is always string with proper fallbacks for AccountId and Id
- Fix Owner.Email to use undefined instead of null in mock

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* test: add comprehensive tests for getContactOrLeadFromEmail method

- Add 6 new unit tests covering all key scenarios
- Test contact lookup, lead fallback, and preference logic
- Test both roundRobinSkipFallbackToLeadOwner and createEventOnLeadCheckForContact code paths
- Add search mock support to mockConnection in beforeEach
- All 34 tests passing, type-check clean

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Implement change to error from #24090

* Address feedback

* Type fix

* test: update SOQL query expectations to include Account.OwnerId

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-03 14:53:00 -04:00
Alex van AndelandDevin AI 409a0277fb fix: Resolve BillingPlan tree-shaking issue causing runtime error (#24229)
* fix: Convert BillingPlan enum to const object to prevent webpack tree-shaking

TypeScript enums compile to IIFEs which can be incorrectly tree-shaken by webpack
when 'sideEffects: false' is set in package.json. Converting to a const object
with 'as const' avoids the IIFE pattern while maintaining full type safety.

This fixes the 'TRPCError: BillingPlan is not defined' error that occurred in
the hasTeamPlan tRPC handler.

Follows the existing CHECKOUT_SESSION_TYPES pattern in the same file.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Re-export BillingPlan from billing-plans to prevent tree-shaking

The issue was a module initialization order problem. When BillingPlan was
imported from constants.ts into billing-plans.ts and used inside the
BillingPlanService class, webpack's tree-shaker (with sideEffects: false)
couldn't properly track the value dependency across the package boundary.

By re-exporting BillingPlan from the same module that exports
BillingPlanService, we ensure the constant is bundled together with the
class that uses it, preventing tree-shaking.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* revert: Restore BillingPlan enum format in constants.ts

The const object conversion didn't fix the tree-shaking issue. The real
fix is re-exporting BillingPlan from billing-plans.ts to ensure it's
part of the same module as BillingPlanService.

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Add BillingPlan as private static member to prevent tree-shaking

By making BillingPlan a private static member of BillingPlanService, webpack
now sees it as part of the class definition rather than just used inside
methods. This creates a strong reference that prevents webpack's tree-shaker
from removing the enum initialization IIFE when 'sideEffects: false' is set.

With the previous approach where BillingPlan was only imported and used inside
methods, webpack's static analysis couldn't properly track the enum usage
across package boundaries (@calcom/features -> @calcom/trpc), causing it to
incorrectly determine the enum initialization was unused code.

Fixes the TRPCError: BillingPlan is not defined runtime error.

Thread: https://calendso.slack.com/archives/C08LT9BLEET/p1759420015428149
Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Clean up BillingPlan references and add explanatory comment

- Remove unnecessary re-export statement
- Use direct BillingPlan references instead of BillingPlanService.BillingPlan
- Add detailed comment explaining webpack tree-shaking workaround
- Keep import from constants.ts and private static member for webpack reference

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Remove Slack reference from comment and restore static usage

- Remove Slack URL from explanatory comment
- Restore BillingPlanService.BillingPlan usage throughout class methods
- This static member usage is essential for webpack to track the enum reference

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Fix BillingPlan issue by finding root cause

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-03 16:37:45 +01:00
Anik Dhabal Babu 7adab1f65f fix: event not showing up on outlook through ics file (#24249) 2025-10-03 13:52:25 +00:00
Calcom BotandLingo.dev 3b92c86582 feat: update translations via @LingoDotDev (#24248)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-10-03 12:42:14 +00:00
Devanshu Sharma de195a1c0f feat: add email filtering to team memberships endpoint (#23923)
* Controller Layer updates.

* adding email filtering and pagination to team memberships endpoint..

* Minor enhancements.

* Improve addressed.

* refactor: update team memberships input to handle comma-separated emails

- Replace array format with comma-separated string handling
- Add proper email validation with BadRequestException
- Remove ArrayMaxSize constraint for better flexibility
- Update API documentation and examples
- Align with codebase patterns from get-managed-users.input.ts

* Morgan suggestions addressed.

* More improvements......
2025-10-03 18:09:47 +05:30
an_ifrah24andDevanshu Sharma d7d2487f6d fix: hydration error warning in scheduleListItem component (#24240)
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
2025-10-03 17:52:32 +05:30
sean-brydon 3e31945157 Fix nits (#24244) 2025-10-03 11:03:07 +00:00
Lauris Skraucis c11814c342 fix: managed user timeZone validation (#24226)
* fix: managed user timeZone validation

* fix: managed user timeZone validation

* fix: managed user timeZone validation
2025-10-03 08:23:54 +00:00
Syed Ali Shahbaz 60e3244088 Migrate watchlist severity to action(#24195) 2025-10-03 11:18:14 +04:00
Rajiv Sahal a1ac5f36f0 feat: add atoms section inside developing guides (#24220) 2025-10-02 21:59:43 +05:30
Lauris SkraucisandMorgan 6f38d40613 refactor: dont allow scheduling team event type without hosts (#24206)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-02 15:58:42 +00:00
Lauris Skraucis 6b7d22de3f refactor: fail breaking change check on error only (#24221) 2025-10-02 14:42:49 +00:00
Anik Dhabal Babu 2f763dceda fix: Getting an unauthorized error when accessing the workflow tab for a child-managed event (#24219)
* Update get.handler.ts

* fix: Ignore userIds form filter segment if no permission

* add tests

* Update booking-filters.e2e.ts

* Update booking-filters.e2e.ts

* fix test

* fix: got unautorized error when viewing workflows

* fix
2025-10-02 13:38:21 +00:00
Benny Joo 96468c4083 refactor: move @calcom/lib/di folder to @calcom/features (#24199)
* mv di folder

* update imports

* fix

* fix

* fix test
2025-10-02 08:12:06 -03:00
sean-brydonandBenny Joo 858d52563f feat: pbac - org pages check update permissions (#24164)
* pbac - org pages check update permissions

* restore permision service

* fix type check

* more type fixes

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2025-10-02 20:04:21 +09:00
7505b3b271 feat: add missing sensitive fields to redactSensitiveData (#24121)
- Add private_key, encrypted_credentials, tenant_id, client_email, serviceAccountKey to SENSITIVE_FIELDS array
- Add comprehensive test cases for delegation credential sensitive fields
- Prevents logging of sensitive delegation credential data including private keys

Fixes security issue where delegation credential sensitive fields were not being redacted from logs

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-01 20:26:58 -03:00
Calcom BotandLingo.dev 758dc88b55 feat: update translations via @LingoDotDev (#24203)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-10-01 23:24:17 +00:00
Udit Takkar 9be418dc65 chore: update description (#24189) 2025-10-01 23:35:41 +05:30
Volnei Munhoz 2ac310456e fix: Selected calendar delegation credentials (#24190)
* Fix selected calendar delegation credentials
2025-10-01 14:20:36 +00:00
ff264d6f7a fix: allow team with same slug for diff cases (#24029)
* fix: aalow team with slug for diff cases

* addressed review

* fix type error

* update test

* addressed review

* fix test

* Update team.ts

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-10-01 14:04:20 +00:00
8019c414e1 chore: CSRF protect forgot-password functionality (#22361)
* chore: CSRF protect forgot-password functionality

* feat: implement conditional sameSite cookie setting for CSRF tokens

- Use WEBAPP_URL to determine secure cookie settings
- Set sameSite to 'none' for HTTPS environments to support cross-origin scenarios
- Fall back to 'lax' for HTTP development environments
- Follows patterns from PRs #23439 and #23556

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* update

* change

* NIT

* minor

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: unknown <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-10-01 13:38:29 +00:00
chauhan_s a3fbe3731e feat: add host validation for team event types (#24170)
* feat: add host validation for team event types

* refactor: remove hosts validator in favor of documentation-based validation approach

* fix: remove HostsOrAssignAllValidator from event type update inputs

* docs: improve clarity of hosts and assignAllTeamMembers field descriptions in event type inputs
2025-10-01 16:15:40 +05:30
sean-brydonandcoderabbitai[bot] e3742dbc66 fix: Always enforce one owner with pbac (#24144)
* Always enforce one owner

* updates from merge

* remove redudant eslint rules

* Update packages/features/pbac/services/pbac-role-manager.service.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-10-01 11:06:18 +01:00
Rajiv SahalandMorgan 83bf717d6d fix: customReplyEmailTo feedback (#23738)
* fix: move validateRoundRobinSlotAvailability to core libraries

* fix: implement PR feedback

* fix: merge conflicts

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-10-01 15:32:32 +05:30
Peer RichelsenandDevin AI 7fcdaa1c46 feat: add created_at field display to admin user edit page (#23805)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-01 09:58:20 +00:00
Kartik LabhshetwarandKartik Saini a8154f9405 feat(ui/api-keys): add confirmation dialog for API key deletion (#24118)
* feat(api-keys): add confirmation dialog for API key deletion

* fix: changed text color to subtle

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-10-01 09:56:55 +00:00
chauhan_sandLauris Skraucis 52a5afeba5 fix: different calendar hosts (#24000)
* fis: pass the missing `platformClientId` to `handleNewBooking` in api/v2

* Update formatCalendarEvent.ts

* only add the externald in case of same calendar, otherwise add if from the .ics file sent in email

* Revert "fis: pass the missing `platformClientId` to `handleNewBooking` in api/v2"

This reverts commit 030ac0f0981c1135d4973fbdafa62d58e8985831.

* fix: alow the host change logic to run for collective envets as well

* fix: run the changedOrganizer logic for both collective and round-robin events

* Update handleNewBooking.ts

* fix: failing unit test

---------

Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
2025-10-01 12:15:34 +03:00
Anik Dhabal Babu 43cc40d7fe fix: add permissions to workflows (#24192) 2025-10-01 06:53:08 +00:00
Hariom Balhara 42a98f000e fix: 405 method not allowed error for queuedFormResponseCleanup (#24191) 2025-10-01 04:55:48 +00:00
Joe Au-Yeung f003ef935b Remove safeStringify from graphql errors (#24188) 2025-10-01 09:50:15 +05:30
Volnei Munhoz e2b2a184c8 fix: Calendar Cache sync page (#24182)
* fix

* fix calendar sync page
2025-09-30 17:10:51 +01:00
Calcom BotandLingo.dev 094595c435 feat: update translations via @LingoDotDev (#24178)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-30 13:51:13 +00:00
Benny Joo 4118a86c0d refactor: do a permission check in removeHostsFromEventTypes trpc handler (#24176) 2025-09-30 13:30:12 +00:00
sean-brydon 928d6f3821 chore: PBAC routingform entity permissions to favour pbac (#24130)
* Remove routingform entity permissions to favour pbac

* push typo

* fix types

* update returns

* Remove unused function

* nits

* fix hariom feedback

* fix correct write permissions
2025-09-30 18:55:43 +05:30
Benny Joo b2ade568c8 refactor: more pbac replacements (#24135)
Post release / release (push) Canceled after 0s
* getUserConnectedApps

* create teams

* use permission check in team deletion

* team read

* revert

* publish handler

* wip

* revert

* wip

* wip
2025-09-30 13:11:02 +00:00
27820ce897 feat: auto-accept team invitations for existing users (#24091)
* feat: auto-accept team invitations for existing users

- Change email button text from 'View Invitation' to 'Accept Invite'
- Implement auto-accept flow when clicking email CTA
- Update TeamService.inviteMemberByToken to support auto-acceptance
- Add new autoAcceptInvite tRPC endpoint for handling auto-acceptance
- Update invitation link generation to include autoAccept parameter
- Handle both team and organization invitation scenarios
- Maintain payment/billing flow integration with TeamBilling.updateQuantity
- Preserve backward compatibility with existing manual flow
- Update all locale files with new 'Accept Invite' button text

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* revert: locale changes except English

- Keep only English 'Accept Invite' translation
- Revert all other locale files to original 'View Invitation' translations
- Maintain core auto-accept invitation functionality

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* simplify: remove autoAccept parameter and make auto-acceptance default

- Remove autoAccept parameter from TeamService.inviteMemberByToken
- Always auto-accept invitations for existing users clicking email links
- Remove autoAccept logic from teams server-page.tsx
- Remove autoAccept=true from invitation URLs
- Delete autoAcceptInvite handler and schema files
- Remove autoAcceptInvite endpoint from tRPC router
- Simplify invitation flow to match new user pattern

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: update teamService test to expect auto-accepted memberships

- Change expectation from accepted: false to accepted: true
- Update test description to reflect auto-accept behavior
- Fix TypeScript type casting to use Pick<TeamRepository, 'deleteById'>
- Aligns with new default auto-acceptance for team invitations

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* Update utils.ts

* fix type error

* delete token

* add prisma transaction

* update

* update param

* test: fix mock objects in teamService tests with realistic data

- Fix duplicate property assignments in mock user objects
- Use proper email format (user@example.com) for email fields
- Use proper username format (testuser) for username fields
- Fix logic error in acceptInvitationByToken (|| to &&)
- Add autoAccept parameter to resendInvitation.handler.ts
- All 16 tests passing with proper TypeScript types

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* test: add e2e tests for team invitation auto-accept flow

- Add test for existing user auto-accepting team invitation via email link
- Add test for error handling when wrong user tries to use invitation link
- Verify proper user identity validation and database state changes
- Follow existing e2e test patterns with browser context isolation
- Fix ESLint warnings: replace conditional with assertion and remove unused browser parameter

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix

* fix

* fix: update team owner creation in e2e tests to include proper names

- Fix email subject mismatch in auto-accept invitation tests
- Team owners now created with explicit names instead of undefined
- Matches pattern used in other working team invitation tests

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: update organization invitation test helper to match new auto-accept link format

- Change expectExistingUserToBeInvitedToOrganization to look for 'teams?token' instead of 'settings/team'
- Fixes 'Invite link not found' error in organization booking e2e test
- Aligns with auto-accept invitation URL changes that use /teams?token= format
- Fix eslint disable comment for playwright rule

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* address coderrabit review

* fix failing test

* addressed review

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-30 13:07:21 +00:00
emrysal fea7e66996 chore: release v5.7.7 2025-09-30 12:57:27 +00:00
sean-brydon 474d1571ae Remove checkAdminOrOwner from settings layout client (#24162) 2025-09-30 12:08:05 +01:00
Rajiv Sahal 2ef627b87e fix: css issue for 12/24 styles (#24141) 2025-09-30 08:38:17 +00:00
sean-brydon 2dfb82b623 Bring back correct routing form teams (#24158) 2025-09-30 08:37:16 +00:00
sean-brydon ccd7fdfd52 refactor role manage (#24146) 2025-09-30 08:35:26 +01:00
Keith Williams f92e59ed34 chore: Update yarn.lock (#24153) 2025-09-30 02:19:30 +00:00
Keith WilliamsandDevin AI d29477349a test: replace prismaMock with BookingRepository mock in checkBookingLimits tests (#24152)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-29 23:34:20 +00:00
Alex van Andel 259e480baa chore: Handle stripe refunds slightly differently to reduce hard errors (#24150)
* chore: Handle stripe refunds slightly differently to reduce hard errors

* Remove 'Received and discarded' error when a credential is not found for a triggered subscription

* Fix handling of no credential found (do show in stripe debugger)

* Minimal overhaul of delete handling

* Fix doc typo
2025-09-29 23:07:08 +00:00
Benny Joo 0055dd1142 perf: dynamically import sentry in Next.js api routes' wrapper (#23710)
* dynamically import sentry in nextjs api routes wrapper

* refactor

* same for pages router

* fixes

* address feedback

* refactor

* address feedback
2025-09-30 02:13:50 +05:30
Volnei Munhoz 61c44780f0 chore: Optional skip warnings for lint-staged (#24102)
* add optional skip warnings

* remove test changes

* allow underscore variables pattern being ignored by eslint (#24103)
2025-09-29 19:51:18 +00:00
Calcom BotandLingo.dev 9710d3b15c feat: update translations via @LingoDotDev (#23991)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-29 19:23:59 +00:00
sean-brydon 04cefebd75 add permissions.canUpdateOrganization to show/hide items in org navbar (#24142) 2025-09-29 15:11:39 +00:00
Amit Sharma dbd927c002 fix: intercom zindex (#24096) 2025-09-29 11:43:11 -03:00
e6b2116a2b feat: Calendar Cache and Sync (#23876)
* feat: calendar cache and sync - wip

* Add env.example

* refactor on CalendarCacheEventService

* remove test console.log

* Fix type checks errors

* chore: remove pt comment

* add route.ts

* chore: fix tests

* Improve cache impl

* chore: update recurring event id

* chore: small improvements

* calendar cache improvements

* Fix remove dynamic imports

* Add cleanup stale cache

* Fix tests

* add event update

* type fixes

* feat: add comprehensive tests for new calendar subscription API routes

- Add tests for /api/cron/calendar-subscriptions-cleanup route (9 tests)
- Add tests for /api/cron/calendar-subscriptions route (10 tests)
- Add tests for /api/webhooks/calendar-subscription/[provider] route (11 tests)
- Add missing feature flags for calendar-subscription-cache and calendar-subscription-sync
- All 30 tests pass with comprehensive coverage of authentication, feature flags, error handling, and service instantiation

Tests cover:
- Authentication scenarios (API key validation, Bearer tokens, query parameters)
- Feature flag combinations (cache/sync enabled/disabled states)
- Success and error handling (including non-Error exceptions)
- Service instantiation with proper dependency injection
- Provider validation for webhook endpoints

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* feat: add comprehensive tests for calendar subscription services, repositories, and adapters

- Add unit tests for CalendarSubscriptionService with subscription, webhook, and event processing
- Add unit tests for CalendarCacheEventService with cache operations and cleanup
- Add unit tests for CalendarSyncService with Cal.com event filtering and booking operations
- Add unit tests for CalendarCacheEventRepository with CRUD operations
- Add unit tests for SelectedCalendarRepository with calendar selection management
- Add unit tests for GoogleCalendarSubscriptionAdapter with subscription and event fetching
- Add unit tests for Office365CalendarSubscriptionAdapter with placeholder implementation
- Add unit tests for AdaptersFactory with provider management and adapter creation
- Fix lint issues by removing explicit 'any' type casting and unused variables
- All tests follow Cal.com conventions using Vitest framework with proper mocking

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix: improve calendar-subscriptions-cleanup test performance by adding missing mocks

- Add comprehensive mocks for defaultResponderForAppDir, logger, performance monitoring, and Sentry
- Fix slow test execution (933ms -> <100ms) caused by missing dependency mocks
- Ensure consistent test performance across different environments

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* Fix tests

* Fix tests

* type fix

* Fix coderabbit comments

* Fix types

* Fix test

* Update apps/web/app/api/cron/calendar-subscriptions/route.ts

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Fixes by first review

* feat: add database migrations for calendar cache and sync fields

- Add CalendarCacheEventStatus enum with confirmed, tentative, cancelled values
- Add new fields to SelectedCalendar: channelId, channelKind, channelResourceId, channelResourceUri, channelExpiration, syncSubscribedAt, syncToken, syncedAt, syncErrorAt, syncErrorCount
- Create CalendarCacheEvent table with foreign key to SelectedCalendar
- Add necessary indexes and constraints for performance and data integrity

Fixes database schema issues causing e2e test failures with 'column does not exist' errors.

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* only google-calendar for now

* docs: add Calendar Cache and Sync feature documentation

- Add comprehensive feature overview and motivation
- Document feature flags with SQL examples
- Include SQL examples for enabling features for users and teams
- Reference technical documentation files

Addresses PR #23876 documentation requirements

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* docs: update calendar subscription README with comprehensive documentation

- Undo incorrect changes to main README.md
- Update packages/features/calendar-subscription/README.md with:
  - Feature overview and motivation
  - Environment variables section
  - Complete feature flags documentation with SQL examples
  - SQL examples for enabling features for users and teams
  - Detailed architecture documentation

Addresses PR #23876 documentation requirements

Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>

* fix docs

* Fix test to available calendars

* Fix test to available calendars

* add migration and sync boilerplate

* fix typo

* remove double log

* sync boilerplate

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-09-29 14:26:14 +00:00
Udit Takkar 855a02091f chore: update tooltip text (#24143) 2025-09-29 11:20:28 -03:00
Volnei MunhozandDevin AI 358434429e feat: add booking flags for skipAvailabilityCheck, skipEventLimitsCheck, skipCalendarSyncTaskCreation (#24122)
- Add three optional boolean flags to BookingHandlerInput interface
- Implement conditional logic to skip availability checks when skipAvailabilityCheck is true
- Implement conditional logic to skip event limits checks when skipEventLimitsCheck is true
- Implement conditional logic to skip calendar sync when skipCalendarSyncTaskCreation is true
- Add comprehensive tests for all three flags and combined scenarios
- Maintain backward compatibility with default false values
- Fix linting issues (unused variables and expressions)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-29 14:02:31 +00:00
sean-brydonandhbjORbj b00061d85e chore: Add addMembersToTeams logic from 24099 (#24140)
* Add addMembersToTeams logic from 24099

* remove import

---------

Co-authored-by: hbjORbj <sldisek783@gmail.com>
2025-09-29 12:54:35 +00:00
Udit Takkarandsean-brydon 022f08c05e feat: add 10 minute cooldown in instant meetings (#24119)
* feat: add 10 minute

* feat: add 10 minute

* chore: change name

* chore: change name

---------

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-09-29 16:03:03 +04:00
emrysal 6ff5c8ce5f chore: release v5.7.6
Post release / release (push) Canceled after 0s
2025-09-29 11:22:43 +00:00
Lauris Skraucis 3be7fb9dd8 fix: v2 create org user with time zone (#24133)
* fix: tzdata undefined import

* refactor: capitalize org user timezone

* test: org user creation with time zone
2025-09-29 11:12:18 +00:00
Benny Joo 72dd970b6e refactor: use permission check service in /organizations endpoints (#24099)
* getUserConnectedApps

* create teams

* use permission check in team deletion

* team read

* revert

* publish handler

* wip
2025-09-29 11:07:19 +00:00
sean-brydon f4d09ece43 chore: (PBAC) readonly eventTypes (#24131)
* Chore(PBAC): readonly eventTypes

* Set readonly value
2025-09-29 11:06:55 +00:00
sean-brydonandEunjae Lee 239e6085ba feat: pbac - private teams (#23998)
* Add permission + migration for listMembersPrivate + depends on lsitMember

* Add legacy list members PBAC private logic

* Add checks in team pages + handler

* add list memeber checks for private orgs

* Add permision visibility scope to loading permissions

* getMembers handler

* fix fallback permission

* Verify private teams work with private org

* Apply suggestion from @eunjae-lee

Co-authored-by: Eunjae Lee <hey@eunjae.dev>

* Remove and private scope function and add param to old

---------

Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2025-09-29 11:30:54 +01:00
sean-brydon b17eab3aeb chore: Use enums instead of hardcoded strings (#24132)
* Use enums instead of hardcoded strings

* use membership role
2025-09-29 10:57:36 +01:00
752f7fcde0 refactor: replace checkAdminOrOwner with team.create permission in teams page (#24116)
* refactor: replace checkAdminOrOwner with team.create permission in teams page

- Replace role-based access control with PBAC using team.create permission
- Follow PBAC refactoring guide pattern for server-side permission checking
- Use permission-specific variable naming (canCreateTeam)
- Maintain existing TeamsListing component interface

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: implement permissions object pattern for TeamsListing

- Replace isOrgAdmin prop with permissions object containing canCreateTeam
- Follow PBAC refactoring guide pattern for UI components
- Update TeamsListing component to use permissions.canCreateTeam
- Maintain existing functionality while improving code structure
- All type checking and linting verification passed

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use different method

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-09-29 14:11:42 +05:30
f6b061f787 fix: update handler to not delete banner (#24106)
* Fix update handler to not delete banner

* code cleanup

* add banner-upload.e2e

* fix: add slug fallback in banner-upload e2e test

- Use org.slug as fallback when requestedSlug is undefined
- Addresses GitHub comment about guarding against undefined slug
- Prevents test failures when requestedSlug is not set
- Fix ESLint warnings: remove unnecessary escape characters and unused variable

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* test: add banner preservation test for profile updates

- Verify that updating organization profile without banner changes preserves existing banner
- Ensures update handler doesn't overwrite banner when undefined is passed
- Addresses user request to test banner preservation during profile saves

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* remove banner e2e wip

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-29 09:31:49 +01:00
Eunjae LeeandDevin AI cc8a1290ee docs: add comprehensive DataTable usage guide (#24107)
* docs: add comprehensive DataTable usage guide

- Document DataTableProvider, DataTableWrapper, and DataTable components
- Cover filter system with all filter types and operators
- Explain segment system (system vs user segments)
- Document pagination modes (infinite vs standard)
- Include real-world usage examples from UserListTable, BookingsListingView, MemberList
- Add TypeScript types reference and best practices

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: update DataTable guide to recommend standard pagination

- De-emphasize virtualized rendering and infinite mode
- Position standard pagination as the recommended approach
- Document known issues with infinite loading mode
- Reorder pagination section to prioritize standard mode
- Update best practices to recommend standard pagination

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add missing DataTable guide topics

- Document getFacetedUniqueValues for faceted filters with real examples
- Add useSegments prop requirement for filter segment enablement
- Enhance server-side filtering documentation with comprehensive patterns
- Include examples from useFacetedUniqueValues and useInsightsRoutingParameters

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add missing DataTable guide topics

- Document getFacetedUniqueValues for faceted filters with real examples
- Add useSegments prop requirement for filter segment enablement
- Enhance server-side filtering documentation with comprehensive patterns
- Include examples from useFacetedUniqueValues and useInsightsRoutingParameters
- Correct server-side vs client-side filtering rationale

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: enhance DataTable guide with troubleshooting and testing

- Remove duplicate Key Hooks section (lines 783-803)
- Add visual ASCII diagrams for architecture and component hierarchy
- Add comprehensive troubleshooting section with 7 common issues and solutions
- Add testing patterns section with Vitest examples and best practices
- Update table of contents to include new sections
- Maintain existing high-quality documentation standards

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* remove some sections

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-29 07:59:55 +00:00
Eunjae LeeandDevin AI b7cf893169 refactor: replace checkAdminOrOwner with PBAC availability.read permission (#24115)
- Replace role-based check with PermissionCheckService
- Use availability.read permission with OWNER/ADMIN fallback roles
- Maintain existing privacy logic for organizations
- Follow established PBAC pattern from bookings implementation

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-29 07:59:23 +00:00
Lauris Skraucis 1458cacdbb fix: v2 api event type splitName booking field (#24111)
* fix: v2 api event type splitName booking field

* fix: test
2025-09-29 09:19:24 +02:00
github-actions[bot] a48a1bd5d8 chore: version packages (#24062)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-27 14:12:00 +00:00
Kartik Labhshetwar 1acd0a14ba improve: improve mobile layout for API keys settings and dialog (#24114) 2025-09-27 12:14:52 +05:30
Lauris Skraucis 6c9ac7636b docs: v2 disabled input (#24071)
* docs: v2 disabled input

* Delete apps/api/v2/swagger/documentation.json
2025-09-26 18:23:21 +00:00
Amit Sharma d261a23dbc fix: Bunch of fixes and minor changes throughout the app (#23356)
* Bunch of fixes and minor changes throughout the app

* remove logs

* fix: e2e

* fix: e2e

* fix: more e2e and design

* revert insights upgrade change
2025-09-26 12:25:49 +00:00
sean-brydonandcoderabbitai[bot] 8b7947a172 fix: remove legacy logic into legacy service (#24095)
* fix: remove legacy logic into legacy service

* Update packages/features/pbac/services/role-management.factory.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-26 11:56:44 +00:00
Keith Williams 89789b1e3b chore: Update CODEOWNERS to use @calcom/API team for API changes (#24100) 2025-09-26 11:46:03 +00:00
Eunjae LeeandDevin AI 43dd24c480 refactor: migrate TeamEventTypeForm to use PBAC instead of isTeamAdminOrOwner (#24034)
* refactor: migrate TeamEventTypeForm to use PBAC instead of isTeamAdminOrOwner

- Replace isTeamAdminOrOwner prop with permissions.canCreateEventType
- Move permission checks to server-side using PermissionCheckService
- Use eventType.create permission string as specified in PBAC guide
- Update all parent components: CreateEventTypeDialog, event-types-view, CreateEventTypePlatformWrapper
- Follow existing PBAC patterns from event-types-listing-view.tsx
- Maintain backward compatibility with role-based fallback

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: implement proper server-side PBAC permission checks

- Add eventType.create permission checks to TRPC teams.get handler
- Add PBAC permission checks to platform /organizations/{orgId}/teams/me endpoint
- Update all three components to use server-side permission data instead of client-side async calls
- Add canCreateEventTypes property to platform team types
- Maintain backward compatibility with role-based fallbacks
- Remove unused imports and variables

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: update client components to use server-side PBAC permission data

- Update event-types-view.tsx to use team.canCreateEventTypes from server
- Update CreateEventTypeDialog.tsx to use team.canCreateEventTypes with fallback
- Update CreateEventTypePlatformWrapper.tsx to use team.canCreateEventTypes with fallback
- Remove hardcoded permission values and role-based checks
- Maintain backward compatibility with existing role-based logic as fallback

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* apply correct PBAC for event type creation

* revert unexpected changes

* clean up

* address feedback

* fix type error

* clean up

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-26 13:40:27 +02:00
Udit Takkar ae6b1d402a feat: add create invite link endpoint (#24073)
* feat: add create invite link endpoint

* tests: add e2e test

* chore: feeback

* chore: feeback

* chore; udate summary

* chore; udate summary

* chore: deelte swagger
2025-09-26 10:24:44 +00:00
Rajiv SahalandVolnei Munhoz 3054ad33b2 feat: add docs for calendar view atom (#24049)
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-09-26 09:49:28 +00:00
a4dbb1a90b refactor: replace isTeamAdminOrOwner with PBAC team.listMembers permission (#24006)
* refactor: replace isTeamAdminOrOwner with PBAC team.listMembers permission

- Add canListMembers prop to BookingsProps interface
- Implement server-side permission check using PermissionCheckService
- Handle organization vs team context as specified
- Use ADMIN/OWNER fallback roles for backward compatibility
- Replace user?.isTeamAdminOrOwner check in bookings column filter
- Fix React Hook dependency arrays for ESLint compliance

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: wrap canListMembers in permissions object and simplify server logic

- Wrap canListMembers in permissions object for future extensibility
- Simplify server-side logic to only use getTeamIdsWithPermission
- Remove unused imports (prisma, MembershipRole)
- Address user feedback on PR #24006

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: add comment explaining canListMembers UI logic

- Clarify that teamIdsWithPermission.length > 0 check is for UI purposes
- Actual accurate filtering happens server-side for filter values

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add e2e test for member filter visibility

- Verify that users with the MEMBER role cannot see the member filter
- Test creates team with ADMIN and MEMBER users
- Confirms UI correctly reflects PBAC permissions
- Address user feedback on PR #24006

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct e2e test team member creation pattern

- Replace invalid teamId property with hasTeam and teammates pattern
- Fix TypeScript error in booking-filters.e2e.ts
- Resolve CI type check failure

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix e2e test

* remove booking.read permission from member

* add guide

* update

* resource scope

* fix markdown

* update usage

* update guide

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-09-26 06:26:20 -03:00
689150d78a fix(ui/auth): align email focus ring with password/username (#23885)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-09-26 07:39:01 +00:00
Benny JooandMorgan fba096f23d refactor: use permission service for team delete trpc endpoint (#24077)
* refactor: use permission service for team delete trpc endpoint

* add safety check

* throw forbidden

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-09-26 08:09:23 +01:00
AnshumancanrockandAnik Dhabal Babu 7d5a3391f1 fix: hydration issue ( Step 3 is not visible for all analytics apps ) (#24089)
* booking cancellation reason overflow fix

* apps-prod-issue

* resolve Step 3 blank screen in app installation flow in production

* resolve resolve Step 3 blank screen in app installation flow in production

* Update step-view.tsx

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-26 07:07:24 +00:00
Rajiv Sahal dcef99bf49 fix: update org billing portal service to handle platform orgs (#24088) 2025-09-26 05:56:25 +00:00
Anshumancanrock 805fcc22a5 booking cancellation reason overflow fix (#24072) 2025-09-26 03:34:03 +00:00
Volnei Munhoz c5b7da8ffd disable tui (#24076) 2025-09-25 20:16:20 +00:00
Anik Dhabal Babu 97f1f7b130 chore: add content type to ics file (#24069)
* chore: add content type into ics file

* Update generateIcsFile.ts
2025-09-25 18:44:21 +00:00
Alex van Andel 0ac460fce3 chore: when performing read operations we should use Promise.all, not $transaction (#24084) 2025-09-25 17:56:10 +00:00
Alex van Andel 82dfca8272 chore: Add createdAt default to eventtype table and remove extension (#24075) 2025-09-25 17:32:11 +00:00
Eunjae LeeandDevin AI d1c5576d4f feat: add availability and ooo permissions to PBAC registry (#24081)
* feat: add availability and ooo permissions to PBAC registry

- Add Availability and OutOfOffice resources to Resource enum
- Add CRUD permissions for both resources with empty scope arrays
- Create migration to seed admin_role with all CRUD permissions
- Create migration to seed member_role with read-only permissions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add i18n entries for availability and ooo permissions

- Add pbac_resource_availability and pbac_resource_out_of_office resource names
- Add description entries for all CRUD operations on both resources
- Follow existing PBAC i18n pattern for consistency

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-25 16:55:35 +00:00
Morgan 7090e3ed60 chore: remove atoms e2e for now (#24085)
* chore: remove atoms e2e for now

* fixup! chore: remove atoms e2e for now

* fixup! fixup! chore: remove atoms e2e for now
2025-09-25 17:12:10 +01:00
Volnei Munhoz 9926fd2e79 restore npm run all (#24080) 2025-09-25 14:48:02 +00:00
Benny Joo 7793cb20d1 Revert "perf: Replace isTeamMember util with an index DB call (#24066)" (#24078)
This reverts commit 8ed0fb6a07.
2025-09-25 14:35:12 +00:00
Benny Joo 8ed0fb6a07 perf: Replace isTeamMember util with an index DB call (#24066)
* Remove isTeamMember

* updates

* revert

* better
2025-09-25 12:55:14 +00:00
emrysal f5a1222fc5 chore: release v5.7.5
Post release / release (push) Canceled after 0s
2025-09-25 11:59:47 +00:00
Lauris Skraucisandcal.com 2b892296b0 feat: CI job to detect breaking api v2 changes (#24028)
* refactor: move swagger to src/swagger

* refactor: standalone swagger generation script

* refactor: generate only 1 swagger file

* feat: github action checking breaking changes

* chore: ensure openapi file is formatted

* chore: run breaking change check on label

* chore: have only 1 swagger file

* fix: run breaking changes check on workflow call

* refactor: pr breaking jobs dependency

* fix: copy swagger module

* refactor: add check-label as dep

* refactor: breaking changes check part of v2 e2e workflow

* refactor: run breaking changes before e2e

* chore: add vapid env keys to workflow

* chore: add CI_JWT_SECRET to e2e api v2

* chore: add NODE_ENV

---------

Co-authored-by: cal.com <morgan@cal.com>
2025-09-25 14:49:07 +03:00
Eunjae LeeandDevin AI f796802ed3 feat: add fallbackRoles parameter to getTeamIdsWithPermissions method (#24042)
* feat: add fallbackRoles parameter to getTeamIdsWithPermissions method

- Add fallbackRoles parameter to method signature in interface and implementation
- Implement second query for teams without PBAC where user has fallback roles
- Combine and deduplicate results from both PBAC-enabled and fallback role teams
- Supports fallback to role-based permissions when PBAC is disabled
- Fix linting issue in getUserMemberships method by replacing include with select

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix usages

* revert some change

* fix unit tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-25 11:10:41 +01:00
Lauris Skraucis b2ac227877 fix: add missing api v2 swagger DTOs (#24065) 2025-09-25 09:10:27 +00:00
sean-brydon f0aec4efdc fix border appearing in shell (#24003) 2025-09-25 09:07:01 +00:00
Benny Joo 8d7cdf9d3b refactor: use permission check service for isTeamAdmin (#24026)
* saml

* addGuests.handler.ts

* rename canAccess to canAccessOrganization and use organization.read

* update usages

* team update handler

* team member invite

* event type update

* remove isTeamAdmin util

* updateInternalNotesPresets

* setInviteExpiration

* event type update

* deleteInvite

* createInvite

* team publish

* fixes

* final

* address feedback

* update test
2025-09-25 08:54:16 +01:00
2ed0380e4f feat: adds user plan info in useHasPaidPlan for intercom (#23790)
* feat: adds user plan info in `useHasPaidPlan` for intercom

* add to support api route

* Update constants.ts

* sql migration to backfill plans and create/change plans on upgrade/downgrade/create of teams and orgs

* fix: breaking unit tests

* test: add comprehensive tests for billing plan service and team/org flows

- Add unit tests for BillingPlanService.getUserPlanByMemberships() covering all plan determination scenarios
- Add tests for team creation handler verifying TEAMS vs ORGANIZATIONS plan assignment
- Add tests for hasTeamPlan handler integration with BillingPlanService
- Add tests for MembershipRepository.findAllMembershipsByUserIdForBilling() data fetching
- Add tests for InternalTeamBilling upgrade/downgrade flows with proper mocking
- All tests follow existing vitest patterns with proper Prisma and service mocking
- Covers both self-serve and platform billing scenarios with comprehensive edge cases

Co-Authored-By: amit@cal.com <samit91848@gmail.com>

* Revert "test: add comprehensive tests for billing plan service and team/org flows"

This reverts commit 58e511f15caf8757c3ec45f6d026caf96ee1a75e.

* fix: make `BillingPlanService` instantiable and use `TeamRepository`

* Revert "fix: make `BillingPlanService` instantiable and use `TeamRepository`"

This reverts commit ae1ff8f15b725566b828864a217d8d0e308b520f.

* revert to runtime calculations. review fixes

* remove uneccessary changes and logs

* review fixes

* review fixes

* fix: type check

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-25 13:00:19 +05:30
Morgan 752cfa6bf9 chore: reduce atoms bundle size prisma types (#24001)
* chore: use kysely types instead of prisma types in atoms

* fixup! chore: use kysely types instead of prisma types in atoms

* fixup! Merge branch 'main' into reduce-atoms-bundle-size-prisma-types
2025-09-25 08:06:16 +05:30
Rajiv Sahal f11c4dd7ec fix: platform billing portal (#23975)
* fix: check if team is platform or not when sending billingPortalUrl

* update team repository

* fix: pass teamId explicitely for platform team

* fix: coderabbit feedback

* fix: merge conflicts

* fix: merge conflicts

* fix: make sure we pass in the correct subsciption id

* fix: implement PR feedback
2025-09-24 20:07:46 +00:00
Keith WilliamsandDevin AI 386f60ca6d refactor: replace prismaMock with BookingRepository mock in checkDurationLimits tests (#24050)
- Replace prismaMock. mocks with BookingRepository.getTotalBookingDuration mocks
- Update return values from [{ totalMinutes: X }] to X to match repository method signature
- Follow existing repository mocking pattern used in other test files
- All tests pass with the new mocking approach

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-24 19:41:54 +00:00
Volnei Munhoz e98f279f64 add react checks for features (#24054) 2025-09-24 18:45:45 +00:00
Eunjae LeeandDevin AI fe190f20f3 refactor: replace isTeamAdminOrOwner with PBAC permissions (#24037)
* refactor: replace isTeamAdminOrOwner with PBAC permissions

- Remove isTeamAdminOrOwner from team-members-view.tsx, rely on server-side permissions
- Replace role checks in addMembersToEventTypes.handler.ts with eventType.update permission
- Follow PBAC refactoring guide patterns for consistent permission checking
- Fix TypeScript any type usage and unused variable warnings

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* use enum

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-24 13:46:24 +00:00
Volnei MunhozandAlex van Andel 96855ea391 chore: upgrade eslint 9 (#24002)
* add eslint package

* upgrade lint

* remove linting for generated files from trpc

* ts imports

* add missing features lint script

* enable turbo ui

* reference workspace deps correctly

* fixes

* Fix eslint test

* Fix eslint test

* npm run all back

* fix e2e

* fix e2e

* fix e2e

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-09-24 22:20:49 +09:00
Eunjae Lee 57150d992e fix: make createdById at Watchlist nullable (#24033) 2025-09-24 07:55:27 -03:00
8b75bf347f feat: add BillingCacheService with 1-hour TTL for team subscription data (#23934)
* feat: add BillingCacheService with 1-hour TTL for team subscription data

- Create BillingCacheService following CalendarsCacheService pattern
- Use teamId-based cache keys with 1-hour TTL (3,600,000 ms)
- Integrate caching into getBillingData method in BillingService
- Add cache invalidation to all webhook handlers:
  - handleStripeSubscriptionDeleted
  - handleStripePaymentSuccess
  - handleStripePaymentFailed
  - handleStripePaymentPastDue
  - handleStripeCheckoutEvents
- Add cache invalidation to cancelTeamSubscription method
- Add RedisModule import to billing module
- Add BillingCacheService to billing module providers
- Add findTeamByPlatformBillingId method to OrganizationsRepository for cache invalidation

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: implement BillingServiceCachingProxy pattern

- Extract IBillingService interface with all public methods
- Create BillingServiceCachingProxy that implements caching logic
- Remove all caching logic from original BillingService
- Simplify cache invalidation using billing.id = team.id
- Update module to use proxy with proper dependency injection
- Update controller to inject proxy interface
- Remove unused BillingService import from controller

This follows the proxy pattern requested in PR feedback, separating
caching concerns from core billing logic for better maintainability.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: add e2e for billing check

* chore: eslint rule for blocking importing features from appstore, lib, prisma (#23832)

* eslint rule

* improve

* fix

* improve msg

* chore: fix any types set by devin

* fix: add mising expect in test

* refactor: move cache methods into BillingServiceCachingProxy

- Remove BillingCacheService abstraction as suggested by @keithwillcode
- Move cache methods directly into proxy as private methods
- Update proxy to inject RedisService directly
- Move BillingData type to interface for better type safety
- Remove BillingCacheService from module providers
- Delete unused billing-cache.service.ts file

This simplifies the architecture by removing unnecessary abstraction
and follows standard caching proxy patterns.

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: test and legacy starter

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-09-24 07:36:02 -03:00
Eunjae LeeandDevin AI 788fbdbe5e refactor: implement PBAC for team member listing in listSimpleMembers handler (#24005)
* refactor: implement PBAC for team member listing

- Replace membership-based team filtering with getTeamIdsWithPermission
- Use team.listMembers permission for access control
- Maintain fallback to original logic when PBAC fails
- Add comprehensive PBAC refactoring guide for future use

Fixes team fetching logic to use Permission-Based Access Control
while preserving existing functionality and privacy checks.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: move PBAC refactoring guide to packages/features/pbac/

Move the PBAC refactoring guide to the appropriate location within
the PBAC feature package for better organization and discoverability.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: remove unnecessary try-catch wrapper

The getTeamIdsWithPermission method already handles all errors internally
and returns an empty array instead of throwing exceptions, making the
try-catch wrapper redundant. Simplified to use direct fallback logic
based on empty array return.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: simplify PBAC implementation

- Remove flawed fallback logic that assumed empty array meant PBAC failure
- Use direct string 'team.listMembers' instead of PermissionMapper
- Remove unused imports (PermissionMapper, Resource, CustomAction)
- Empty array from getTeamIdsWithPermission is legitimate (no permissions)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: simplify PBAC refactoring guide

- Reduce from 260 to 87 lines by removing bloated content
- Focus on core pattern: direct permission strings, no fallback logic
- Align with actual PR implementation
- Remove verbose theoretical sections and complex patterns

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-24 08:56:03 +00:00
b2239374bc fix: Remove team members as org admin (#24020)
* Fallback to org admin

* Prevent accidental privilege escalation as code changes in the future

* When org admin, we don't actually need to do the db query

* Use findMany and Map to drill down permission adjustments

* Exclude .MEMBER from overriding role, we likely don't want to demote

* refactor logic

* Add tests for services/factories + removeHandler

* fix type check

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Sean Brydon <sean@cal.com>
2025-09-24 09:33:31 +01:00
Alex van Andel 77c61abef8 remove @id from BookingTimeStatusDenormalized for Prisma .16 support (#24024) 2025-09-24 06:45:33 +00:00
c2472cc05a feat: add createdAt and updatedAt fields to EventType model (#23949)
* feat: add createdAt and updatedAt fields to EventType model

- Add timestamp fields to EventType schema with backward compatibility
- Update all EventType select statements across API v1, v2, and tRPC
- Update platform API output types to include timestamp fields
- Generate migration for existing database records
- Fix test files to handle new timestamp fields properly

The timestamp fields are added as optional (DateTime?) to ensure backward
compatibility - existing EventType records will have null values for these
fields, while new records will automatically get timestamps.

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: remove @default(now()) from EventType createdAt to prevent existing records from getting current timestamp

- Remove @default(now()) from createdAt field in schema to ensure backward compatibility
- Create migration that only drops DEFAULT constraint without updating existing records
- Existing EventType records will keep null timestamps
- New records will get timestamps via application logic

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: add createdAt and updatedAt timestamps to all EventType creation locations

- Update all seed scripts to set timestamps for new EventType records
- Ensure consistency across all EventType creation patterns
- Maintain backward compatibility with nullable timestamp fields

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: add timestamps to remaining EventType creation locations in test files

- Update integration test files to include createdAt and updatedAt
- Ensure consistency across all EventType creation patterns
- Complete comprehensive update of all EventType creation locations

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* add migration

* few left

* feat: implement Prisma extension for automatic EventType timestamps

- Create eventTypeTimestampsExtension to automatically set createdAt and updatedAt
- Handle both eventType.create and eventType.createMany operations
- Revert all manual timestamp setting from application code
- Extension only sets timestamps if not already provided
- Maintains backward compatibility - existing records keep null timestamps
- New records get automatic timestamps via Prisma extension
- Follows existing Cal.com extension patterns and architecture

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* feat: remove hardcoded timestamp settings from test files

- Remove manual createdAt/updatedAt settings from routing forms controller test
- Remove manual timestamp settings from event types repository fixture
- Prisma extension now handles timestamps automatically for all EventType operations

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* update

* Update event-type.output.ts

* fix test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-09-24 06:59:46 +01:00
emrysal 608fe1c586 chore: release v5.7.4
Post release / release (push) Canceled after 0s
2025-09-24 05:21:33 +00:00
Syed Ali Shahbaz 4413295b27 feat: Add spam block schema and migration (#23996)
* schema

* fix migration

* --

* optional org

* --

* remove prisma level relation

* --

* rename

* remove redundant key

* --
2025-09-24 03:50:25 +01:00
Anik Dhabal Babu bcc433ba9a fix: reschedule flow is broken for seated booking (#23987)
* fix: reschedule flow is broken for seated booking

* Update BookingListItem.tsx

* Update

* tweak
2025-09-23 22:05:08 +01:00
sean-brydon 2ba571d230 Attach org to impersonation return (#24012) 2025-09-23 18:34:16 +00:00
Hariom BalharaandAnik Dhabal Babu 4a0a1ef053 fix: Update documentation as per code (#23994)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-23 23:13:00 +05:30
Udit Takkar 7e882eedf8 fix: remove booking question after workflow deletion (#23901)
* fix: remove booking question after workflow deletion

* fix
2025-09-23 15:58:56 +00:00
sean-brydonandcoderabbitai[bot] 224e606439 feat: pbac org billing (#23709)
* refactor layout to not check session

* add actions for orgs + org admins

* update types on actions to be correctly non nullable

* Add tests for utils

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* restore lock file

* add permission check action for org authentication managment

* WIP BRANCH

* Git merge fix conflicts

* Fix imports

* intro to pbac team billing

* restore log

* refactor to be a billing portal factory service

* fix merge conflict

* Fix merge conflicts

* Passing test with non hardcoded vars

* fix migration

* Wip

* remove layout permision checks

* Fix type check

* remove logs

* improve error handling and logs

* Fix nits

* nits

* Use push instead of slice for billing tab

* Add permissions to memo

* Fix credits handlers to use PBAC also

* fix imports

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-23 14:01:21 +01:00
Morgan 14b3344a41 fix: optional auth guard only secret provided (#23977) 2025-09-23 08:22:45 +00:00
Hariom Balhara a538ba64d2 Add validation tests (#23833) 2025-09-23 04:45:47 +00:00
Adarsh Singh b3bfad7fea fix(ui): Correct phone number dropdown position in RTL layouts (#23964)
* fix(ui): correct phone input dropdown position in RTL

* chore: Remove explanatory comments per review
2025-09-23 01:22:06 +00:00
emrysal f80b45e36a chore: release v5.7.3
Post release / release (push) Canceled after 0s
2025-09-23 00:52:24 +00:00
f3d60b141f fix: resolve 404 error when rescheduling seated event bookings (#23956)
* fix: skip select field validation for existing responses during reschedule

- Modify hasRequiredBookingFieldsResponses to detect reschedule context
- Skip validation for select, multiselect, checkbox, and radio fields during reschedule to preserve existing responses
- Fixes validation error when rescheduling bookings with select field responses that may no longer match current field options

Resolves issue where reschedule operations fail with 'Value Travel, Adventure & Wildlife is not valid for type select for field Niche-project' error

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: skip frontend validation for existing select field responses during reschedule

- Revert backend changes in bookings.service.ts as the issue is frontend-only
- Add reschedule detection in getBookingResponsesSchema.ts preprocess function
- Skip option validation for select, radio, multiselect, and checkbox fields during reschedule
- Preserves existing booking responses that may no longer match current field options
- Fixes error 'Value Travel, Adventure & Wildlife is not valid for type select for field Niche-project' during slot selection

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: extend reschedule validation skip to handle multiemail fields like guests

- Add reschedule-aware logic to multiemail validation in getBookingResponsesSchema.ts
- Skip validation for existing multiemail responses during reschedule to avoid type mismatch errors
- Fixes 'Value is not valid for type text for field guests' error during slot selection
- Complements existing fix for select/radio field validation during reschedule

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: disable guests field inputs for seated events

- Disable type SelectField for guests field in seated events
- Disable identifier InputField for guests field in seated events
- Add validation to prevent saving guests field changes for seated events
- Pass seatsEnabled prop from EventAdvancedTab to FormBuilder
- Use condition: seatsEnabled && formFieldType === 'multiemail' && fieldForm.getValues('name') === 'guests'
- Fix linting warnings: remove unused variable and add missing dependency

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Update getBookingResponsesSchema.ts

* Update FormBuilder.tsx

* Update FormBuilder.tsx

* update

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-22 23:44:46 +00:00
5463dc261c fix: prevent external CSS from breaking Cal.com embed (#22778)
* fix: added block display to .cal-embed

* fixed the iframe color-scheme to unset and bg transparent

* removed forced CSS

* changes reverted from iframe

* Add comments and remove background transparent as it is still not needed

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-09-22 19:10:06 +00:00
github-actions[bot] 55df0e3c9d chore: version packages (#23927)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-22 14:41:51 +00:00
sean-brydonandMorgan 730aab3e3d fix: always check team.parentID even if no membership (#23976)
* fix: always check team.parentID even if no membership

* refactor permission handling in create event type handler

* remove hasMembership

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-09-22 12:19:06 +00:00
Rajiv Sahal 63740c02c7 feat: calendar view atom v1 (#23840)
* fix: refactor

* add `isMonthViewProp` to header

* feat: init v1 for calendar view atom

* test breaking toggle buttons

* fix: make sure week start is always sunday for calendar view atom

* fixup

* fix: remove extra comments

* fix: add calendar view page in examples app

* chore: add changesets

* fix: coderabbit feedback

* fixup
2025-09-22 12:17:33 +00:00
Hariom Balhara c5942bcfcd Fix nan prefetch in platform (#23913) 2025-09-22 12:41:22 +03:00
Calcom BotandLingo.dev c4547c51a2 feat: update translations via @LingoDotDev (#23767)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-20 10:12:41 -03:00
Anik Dhabal Babu cf89046ede fix: few more e2e flakes (#23966) 2025-09-20 17:17:01 +05:30
chauhan_sandAnik Dhabal Babu d5d44fb64b fix: remove platform client ID from attendee list when adding team members as attendee in a team event (#23866)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-20 09:28:27 +00:00
David Johnson 4bb092c345 docs: Updated getting started process (#23920)
* Updated gettintg started process

* updated the common errors and added an advanced section to link to the docker repo
2025-09-20 09:26:18 +00:00
Morgan e1f7e94e36 fix: org admins can manage team even-types (#23953)
* fix: org admins can manage team even-types

* fix: org admins can manage team even-types
2025-09-19 21:16:26 +01:00
AnshumancanrockandDevanshu Sharma 2e9d5f7df1 fix: loading spinner appears in top-left corner during Round Robin setup (#23823)
* fix

* fix

* fix

* fix

* fix

* fixed

* fix

* Update globals.css

---------

Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
2025-09-19 19:30:03 +00:00
Morgan 8c943e8817 chore: documentation of event-type bookingRequiresAuthentication (#23942)
* chore: incomplete documentation of event-type bookingRequiresAuthentication setting

* fixup! chore: incomplete documentation of event-type bookingRequiresAuthentication setting
2025-09-19 18:06:32 +00:00
Morgan 56821553fe chore: do not log whole error stack in getConnectedCalendars (#23951) 2025-09-19 17:57:52 +00:00
Amit SharmaandAnik Dhabal Babu b512ceb217 fix: sender name/id missing in workflows (#23950)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-19 17:32:56 +00:00
cfeb18de3f feat: Billing page redesign plus credits (#23908)
* manage billing section

* wip billing credits

* WIP

* WIP

* Download expense log

* credit worth

* skeleton fixes

* add org tip

* add teams tip

* restore service

* type check

* type check

* fix types

* additional credits

* fix progress bar

* add dashed prop

* match new designs

* hide area with no monthly credits

* fix i18n

* show current balance label

* Update apps/web/modules/settings/billing/billing-view.tsx

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* spacing + monthly credits not showing additional

* Remove additional credits from monthly calculations

* feat: replace add members redirect with invite modal in billing settings

- Replace Button href with onClick handler to open MemberInvitationModal
- Add MemberInvitationModalWithoutMembers import and state management
- Maintain existing team/org context support
- Follow established modal usage patterns from other components
- Fix lint error by using undefined instead of empty arrow function

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* Remove redudant vars from method

* fix type check

---------

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-19 16:18:42 +00:00
Eunjae LeeandDevin AI b407be933d feat: add date and time columns to insights CSV exports (#23771)
* feat: add ISO timestamp columns to booking CSV exports

- Add createdAt_iso, startTime_iso, endTime_iso columns to getCsvData() method
- Use .toISOString() format for new columns: 2025-09-09T13:03:55+02:00
- Keep existing timestamp columns unchanged to avoid breaking changes
- Addresses user request for parseable timestamp format in CSV downloads

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add ISO timestamp columns to routing CSV exports

- Add ISO format columns for createdAt, bookingCreatedAt, bookingStartTime, bookingEndTime
- Preserve original timestamp format to avoid breaking changes
- Complete implementation for both /insights and /insights/routing pages

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: replace ISO columns with timezone-aware date/time columns

- Replace _iso columns with separate _date and _time columns
- Use user timezone for proper date/time conversion
- Add timezone parameter to CSV export methods
- Maintain backward compatibility with original timestamp format
- Date format: YYYY-MM-DD, Time format: HH:mm:ss

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve TypeScript type compatibility issues

- Fix WhereForTeamOrAllTeams type compatibility in routing-events.ts
- Restructure conditional object creation to ensure required properties
- Clean up merge conflict remnants from previous rebase

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix: use user profile timezone for CSV exports instead of browser timezone

- Modified rawData endpoint to use ctx.user.timeZone instead of input.timeZone
- Removed timeZone field from bookingRepositoryBaseInputSchema
- Updated useInsightsBookingParameters to remove timeZone property
- Fixed RecentNoShowGuestsChart to use useDataTable for timezone access
- Resolves timezone discrepancy where CSV exports showed incorrect time values

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: use user profile timezone for CSV exports instead of browser timezone"

This reverts commit 6356657bd0c503f41349c8d1463bb4dd427b1a2c.

* default columns are formatted as iso

* address feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-19 16:16:54 +00:00
Eunjae Lee 4e1920471d fix: remove page permission check for /insights (#23945)
* fix: remove page permission check for /insights

* add e2e test
2025-09-19 16:04:33 +00:00
Eunjae LeeandAlex van Andel 6ee752aed8 feat: add index [startTime, endTime] for BookingDenormalized (#23944)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-09-19 15:21:23 +00:00
Eunjae LeeandDevin AI a1922efab5 feat: make orgId optional for user and team scopes in /insights and /insights/routing (#23912)
* feat: make orgId optional for user and team scopes in InsightsRoutingBaseService

- User scope authorization only checks formUserId and formTeamId IS NULL
- Team scope now supports standalone teams without organizations
- Add validation logic to return NOTHING_CONDITION if team belongs to org but no orgId provided
- Add comprehensive test coverage for null/undefined orgId scenarios in both scopes
- Aligns schema with actual usage patterns and supports teams without organizations

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: extend orgId optional support to InsightsBookingBaseService

- Make orgId optional for user and team scopes in InsightsBookingBaseService
- Update InsightsBookingServicePublicOptions type to allow orgId: number | null
- Add validation logic for team scope to handle missing orgId
- Add comprehensive test coverage for null/undefined orgId scenarios
- Fix type casting issues in test file
- Maintains backward compatibility while supporting teams without organizations

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct authorization logic for optional orgId in team scope

- Skip isOwnerOrAdmin check for team scope when orgId is null (standalone teams)
- Maintain security for org scope and team scope with orgId
- Fixes integration test failures for null orgId test cases

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use != null instead of !== undefined for orgId checks

- Properly handle both null and undefined orgId values in authorization logic
- Fix integration test failures where null orgId was incorrectly triggering isOwnerOrAdmin check
- Ensure team scope with null orgId skips ownership validation for standalone teams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: always validate team membership for team scope

- Remove orgId condition from isOwnerOrAdmin check for team scope
- Ensure both standalone teams and org-based teams require ownership validation
- Maintain orgId validation logic in buildTeamAuthorizationCondition methods

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use nullish() for orgId schema validation

- Change from .optional() to .nullish() to allow both null and undefined
- Fixes schema validation when tests pass orgId: null
- Resolves authorization logic returning NOTHING_CONDITION for valid cases

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: replace isOwnerOrAdmin with PBAC checkPermission in insights services

- Replace isOwnerOrAdmin method in InsightsBookingBaseService with checkPermission from PermissionCheckService
- Replace isOwnerOrAdmin method in InsightsRoutingBaseService with checkPermission from PermissionCheckService
- Use permission 'insights.read' with fallback roles MembershipRole.OWNER and MembershipRole.ADMIN
- Maintain same method signature and behavior while leveraging PBAC system

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up types

* add comment

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-19 14:13:21 +00:00
Benny Joo 76332a759b refactor: circular deps between app store and lib [5] (#23936)
* getBulkEventTypes

* 2 eventtypes related utils to features

* locationsResolver

* checkForEmptyAssignment

* mv defaultEvents to features

* update imports

* PrismaAppRepository

* mv currencyConversions from appstore to lib

* useAppsData

* videoClient

* analytics files

* fix

* mv

* prettier

* use named import
2025-09-19 10:16:56 -03:00
emrysal dfdda8a5b8 chore: release v5.7.2
Post release / release (push) Canceled after 0s
2025-09-19 11:45:35 +00:00
Amit Sharma 286ee6b1bd fix: disable intercom while being impersonated (#23935) 2025-09-19 10:32:24 +00:00
Benny Joo ef8b0fa41c chore: eslint rule for blocking importing features from appstore, lib, prisma (#23832)
* eslint rule

* improve

* fix

* improve msg
2025-09-19 08:05:53 +00:00
7fbeeae25b fix: event type not found 400 and other (#23904)
* fix: various fixes specifically to event-types

* Revamp error handling a little; highly flawed

* fix: Test cases that depended on defaultResponder behaviour

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-09-18 18:56:00 +00:00
Anik Dhabal Babu 5cf0553199 fix: fix few e2e flakes (#23926) 2025-09-18 14:57:15 -03:00
Lauris Skraucis 4f114ef8d3 fix: EventTypeSettings Checkbox booking field label (#23891) 2025-09-18 17:14:06 +00:00
Anik Dhabal BabuandDevin AI a9d6fbd14d fix: resolve blank form in analytics app installation step 3 (#23924)
- Add mounted state to ensure component renders after hydration
- Fix hydration mismatch between server and client rendering
- Ensure ConfigureStepCard renders properly on initial load in production

Fixes the issue where GTM analytics app configuration form appears blank
on step 3 until page refresh.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-18 17:11:02 +00:00
Eunjae Lee 3e1629add9 chore: compare values in DateTargetSelector (#23916) 2025-09-18 17:10:14 +00:00
f1ac0642d1 fix: correct route pattern and assertions in duplicate API calls E2E test (#23287)
- Fix route pattern from **/api/trpc/viewer.slots.getSchedule** to **/api/trpc/slots/getSchedule**
- Remove permissive assertions that allowed tests to pass with 0 API calls
- Tests now properly fail when duplicate getSchedule calls are detected
- Addresses issue where E2E tests weren't catching duplicate API calls on main branch

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-09-18 17:09:45 +00:00
4689775a1f chore: Skip static file copy if not required (#23903)
* chore: Skip static file copy if not required

* feat: Replace MD5 hash checks with Turborepo caching for static file copying

- Add copy-app-store-static Turborepo task with proper inputs/outputs
- Remove manual MD5 hash calculation logic that was causing performance issues
- Update package.json scripts to use Turborepo task
- Addresses Keith's feedback about using Turborepo cache instead of manual checks

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Add copy-app-store-static script to package.json for Turborepo task execution

- Add missing script definition in apps/web/package.json
- Enables Turborepo to properly execute the static file copying task
- Fixes 'No tasks were executed' issue by providing the command to run

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: Remove skipped jobs from required check failure condition

- Allow conditional E2E jobs to be skipped without failing the required check
- Maintain failure detection for actual job failures and cancellations
- Apply fix consistently to both pr.yml and all-checks.yml workflows

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* Revert "fix: Remove skipped jobs from required check failure condition"

This reverts commit 429f0506d009eaae7fa88be6db077681d5124f2a.

* Only write new logs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-09-18 16:44:06 +00:00
Benny Joo 4011733271 refactor: remove @calcom/features dependency from @calcom/prisma (#23820) 2025-09-18 16:40:39 +00:00
Keith Williams f41aa234d7 test: Skip broken atom E2E test (#23925) 2025-09-18 13:11:36 -03:00
a44a3e5b84 feat: add Webhook resource to PBAC system with permission enforcement (#23614)
* feat: add Webhook resource to PBAC system with permission enforcement

- Add Webhook resource to PBAC permission registry with CRUD actions
- Implement PBAC permission checks in webhook handlers (create, edit, delete)
- Add webhook permission translations to common.json
- Use PermissionCheckService with fallback roles [ADMIN, OWNER] for team webhooks
- Maintain backward compatibility when PBAC is disabled
- Follow same pattern as workflow PBAC implementation from PR #22845

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: implement PBAC permission filtering in webhook list handler

- Add PermissionCheckService to filter team webhooks by webhook.read permission
- Only show webhooks from teams where user has proper permissions
- Maintain backward compatibility with fallback to all team memberships

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* add migration for default roles

* new forUserMethod

* update webhook repository

* fix UI showing/hiding webhooks for webhoo.create teams

* WIP pbac procedure migratoin + tests

* add more roles to get fallback

* permissions in cmponents instead of readOnly

* passPermissions to list item

* push instant events logic

* Git merge

* wip teamId accessable refactor

* fix delete handler

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-18 07:37:45 -03:00
Hariom Balhara 98a075d062 handle NaN != NaN prefetch (#23910) 2025-09-18 11:34:03 +01:00
Eunjae LeeandDevin AI bdc3cb9d6e feat: allow to choose dateTarget for /insights (startTime by default) (#23752)
* feat: allow to choose dateTarget for /insights (startTime by default)

* feat: add timestamp selector for insights date filtering

- Add TimestampFilter component with Start Time/Created At options
- Extend useInsightsBookingParameters hook with timestamp selection
- Update all insight components to use dateTarget parameter
- Add i18n translations for new UI strings
- Position selector next to DateRangeFilter as requested

Addresses user request to add select box next to date range filter
allowing users to choose between startTime (default) and createdAt
for displaying booking metrics on the Insights page.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename TimestampFilter to DateTargetSelector with nuqs URL state

- Rename TimestampFilter component to DateTargetSelector
- Implement nuqs hook in InsightsPageContent for URL state management
- Update useInsightsBookingParameters to return dateTarget from URL state
- Add dateTarget field to insightsRoutingServiceInputSchema and related types
- Simplify individual insight components to use insightsBookingParams directly
- Remove manual timestampTarget destructuring from all components
- Update all tRPC routing service calls to include dateTarget parameter
- All TypeScript checks now pass successfully

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update styles

* fix inconsistency

* feat: replace Select with Command component and rename filter ID

- Replace Select with Command + Popover for compact width and wider dropdown
- Add descriptive option labels with translations
- Change filter ID from 'createdAt' to 'timestamp' across all components
- Maintain URL state management with nuqs
- Fix ESLint warning for missing dependency in useEffect

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: revert routing components to use createdAt filter ID

- Keep timestamp filter ID change scoped only to main insights page
- Routing components should continue using createdAt as filter ID
- Only insights-view.tsx and related booking hooks use timestamp

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* update styles

* fix trpc router

* refactor timestamp column for insights booking service

* fix

* update text

* rename and clean up

* fix endDate in DateRangeFilter

* fix type errors

* fix startTime filter and type errors

* provide default date range

* add completed to getMembersStatsWithCount

* add unit tests

* fix type error

* address feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-18 11:32:50 +01:00
Rajiv SahalandAlex van Andel 616e4c4908 chore: add stale time for billing check (#23907)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-09-18 09:47:08 +00:00
emrysal eaf695824b chore: release v5.7.1
Post release / release (push) Canceled after 0s
2025-09-18 09:20:19 +00:00
sean-brydon 69a76f7fb7 fix: reassign PBAC role before deleting (#23889) 2025-09-18 08:30:56 +00:00
Anik Dhabal Babu d70fa46260 fix: event startTime is in utc (#23905) 2025-09-18 05:15:32 +00:00
Anik Dhabal Babu efba58a36a fix: users still get updated email when reassign event after disabling standard emails (#23906)
* fix: users still get updated email

* Update yarn.lock

* update
2025-09-18 05:13:04 +00:00
Benny Joo b3a28dca25 refactor: circular deps between app store and lib [4] (#23829)
* mv team queries to features from lib

* update imports

* same

* wip

* move event manager test

* calendar manager to features from lib

* update imports

* update imports

* fix

* mv getEventTypeById

* fix

* fix

* remove

* fix type check error

* fix tests

* fix tests

* fix
2025-09-18 01:42:40 +01:00
Anik Dhabal Babu 3b471f0e25 fix: one e2e flake visible in ci (#23897)
* fix: e2e flake visible in ci

* fix
2025-09-17 21:25:53 +05:30
Anwar SadathandAnik Dhabal Babu aac5fa3537 fix: Showing 0 in onboard members to team screen (#23882)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-17 15:19:59 +00:00
Anwar SadathandAnik Dhabal Babu 134f7e591e fix: Bookings unconfirmed count not getting updated in left sidebar badge (#23886)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-17 15:14:39 +00:00
5bb2bc3ba4 fix: resolve JSON parsing error in Stripe subscription endpoint (#23892)
* fix: resolve JSON parsing error in Stripe subscription endpoint

- Fix 'Unexpected end of JSON input' error during premium username upgrade
- Replace res.status(404).end() with proper JSON response
- Add descriptive error message for missing userId or intentUsername parameters
- Ensure consistent JSON response format across all error paths

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add proper session handling to Stripe subscription endpoint

- Import getServerSession from @calcom/features/auth/lib/getServerSession
- Use getServerSession({ req }) to properly populate user session
- Fix session validation that was causing 'Unexpected end of JSON input' error
- Ensure subscription endpoint handles sessions consistently with other Cal.com API endpoints

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-17 15:03:16 +00:00
Anik Dhabal Babu bb6f5cca93 fix: Zod error caused by number-type responses (#23804)
* fix: getting zoderror due to number type responses

* update

* fix lint erro
2025-09-17 15:01:21 +00:00
Anik Dhabal BabuandDevin AI 81bd8033a9 fix: resolve hydration mismatch in analytics app installation (#23877)
- Wrap ConfigureStepCard content with NoSSR component
- Prevents blank step 3 configuration page in production
- Fixes hydration mismatch between server and client rendering
- Ensures analytics apps (GTM, Fathom, GA4) installation works properly
- Uses Cal.com's established NoSSR pattern for client-side only rendering

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-17 20:09:28 +05:30
Hariom Balhara c2a44e9319 fix api-v2 tests (#23896) 2025-09-17 14:32:39 +00:00
Hariom BalharaandDevin AI 39917ebfa6 fix: Alternate reschedule behaviour for past bookings - Don't allow new booking (#23736)
* fix: Past booking redirect

* fix: rename ENV_PAST_BOOKING_RESCHEDULE_CHANGE to ENV_PAST_BOOKING_RESCHEDULE_CHANGE_TEAM_IDS for clarity

- Renamed environment variable to better reflect that it contains comma-separated team IDs
- Updated all references in constants.ts, implementation file, tests, and turbo.json
- Addresses PR comment feedback about misleading variable name

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-17 12:47:45 +01:00
Anwar SadathandAnik Dhabal Babu 9ee06b410e fix: Teams list not getting refreshed after adding a new team (#23881)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-17 10:09:37 +00:00
76ced2d3b8 feat: event type pbac (#22618)
* fix members page crash with pbac feature flag

* invite member to org backend

* update org permissions

* feat: org profile update settings

* org general page

* remove redudant me call

* privacy page

* add attributes to pbac

* dync + sso on organization permissions

* add tests for resource-permission util

* pass permissions to attributes\

* restore invite members

* update org update and attribute backends

* fix type errors

* fix orgId

* fix types attempt two

* fix types attempt two

* fix type error

* show/hide team event types based on eventType.read permission

* fix dupe string in i18n

* fix tests

* fix team-dsync

* update session to use profile

* use profile metadata to get orgRolew

* fix dsync

* fix typing

* Event type create pbac check

* fix the readonly permission check. WIP

* refactor getUserEventTypes

* fix test

* add generate util for update

* update router to use new generator function for pbac procedures

* update transform utils

* fix members being able to update on UI

* fix allSettled

* fix fallback permissions

* fix permission logic

* fix compare memebrship type error

* fix unit test error

* fix manage test error

* fix nested permissions

* filter based on canView permission in getUserEventGroups

* Update packages/trpc/server/routers/viewer/eventTypes/utils/EventTypeGroupFilter.test.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix tests

* fix tests

* feat: Adding workflow permission checks inside of eventTypes (#23038)

* add permission checks for workflows

* wip getall active workflows

* check eventType.update permission on activiating workflow on event type

* pass permissions to context and use context in client

* remove local parsePermissionString and use registery

* Use new scoped function

* default scope to orgs

* use object values for workflow permissions

* fix type errors

* Fix permission traversal + fix all state caluclation

* fix eventType group to use permissions.canRead

* fix: update failing PBAC unit tests and resolve ESLint warnings

- Fix getUserEventGroups test: MEMBER role should not have update permissions in fallback scenario
- Fix EventTypeGroupFilter test: add missing canRead property to mock permissions map
- Replace 'as any' type assertions with proper 'as unknown as' type assertions to resolve ESLint warnings

Both tests now pass and align with PBAC permission model where MEMBER role has read-only access to event types.

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* add pbac to _heavy router

* Merge main

* restore versions

* Parallelizable members query

* fix nits

* fix create

* Restore lock file

* Fix import from merge artifact

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-17 10:25:30 +01:00
Rajiv Sahal eaa1ad6578 feat: e2e tests for Connect atoms (#23433)
* e2e tests for apple connect atom

* update globalEnv for turbo.json

* update pages for tests

* update playwright config so we can use env variables inside tests

* update packages

* update variable names

* update playwright config

* fix: import variables from env instead of separate files

* update env variables for atoms e2e yml
2025-09-17 11:20:38 +02:00
Rajiv Sahal f9095d298d update env variables (#23883) 2025-09-17 08:21:39 +00:00
HichemandKartik Saini fd87954048 feat: show refresh and back button is app mode (#23838)
* Change display mode from 'standalone' to 'minimal-ui'

this shows the refresh and back button for easier navigation ux

* Update display settings in site.webmanifest

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-09-17 12:53:35 +05:30
Morgan be249a94de chore: add auth strategy test only x-cal-client-id (#23872) 2025-09-17 09:05:10 +02:00
59582cf8f5 fix: unable to add or edit user from admin page and add tests (#23871)
* fix

* Update UserForm.tsx

* test: add e2e tests for admin user creation and editing

- Add test for successful user creation via /settings/admin/users/add
- Add test for successful user editing via /settings/admin/users/{id}
- Tests verify form submission, API responses, and database changes
- Follow Cal.com e2e testing patterns with admin authentication
- Use Playwright for end-to-end form interaction testing

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* Update admin-users.e2e.ts

* Update admin-users.e2e.ts

* update

* tweak

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-16 23:47:56 +05:30
Udit Takkar 5c70060992 feat: voice and language support in cal.ai (#23865)
* feat: lang support

* fix: type errors

* feat: select voice agent

* refactor: address feedback

* refactor: address feedback

* refactor: missing import

* fix: types
2025-09-16 20:15:11 +05:30
Lauris Skraucis ae7f8f1653 feat: v2 show hidden attendees for authenticated requests (#23868)
* refactor: return attendees when fetching all bookings

* refactor: v2 show hidden attendees for authenticated requests

* chore: regenerate docs

* chore: add test
2025-09-16 19:57:42 +05:30
Eunjae LeeandDevin AI 4d0458b0e8 feat: add client-side auth protection to routing forms pages (#23743)
* feat: add client-side auth protection to routing forms pages

- Create RoutingFormsShell component with useRedirectToLoginIfUnauthenticated hook
- Wrap form-edit, route-builder, and incomplete-booking pages with RoutingFormsShell
- Ensures consistent auth behavior during client-side navigation
- Maintains existing server-side auth protection
- Fix ESLint warnings: replace 'any' types with 'unknown' types and add eslint-disable for restricted imports

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: clean up RoutingFormsShell implementation

- Remove unused isPublic parameter from RoutingFormsShell component
- Keep only essential client-side authentication protection functionality
- Fix remaining ESLint warnings to allow commit to pass

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* remove unnecessary hook

* use shell at layout

* rename component

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-16 10:39:42 -03:00
55e6682832 feat: Custom Fields OR Add-Ons with a fee associated (#19997)
* feat: Addons to bookings

* Add tests

* Add tests

* Fix price field not shown immediately after enabling payment for an event

* Add support for all currencies in addons and fix type errors

* Address review comments

* Add tests to cover all input types

* Address cubic-dev-ai comments

* Remove openapi.json from git tracking

* Revert changes

* Revert unrelated linter/formatter changes

* Address cubic-dev-ai comments

* Addres cubic-dev-ai comment

* Update to use test id instead of hardcoded label

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Address coderabbits review comments

* Fix failing unit test

* some fixes...

* Fix tests

* Fix import

* Move handlePayment test file to appropriate location

* Fix test

---------

Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: amrit <iamamrit27@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devanshu Sharma <devanshusharma658@gmail.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
2025-09-16 21:33:23 +09:00
Morgan 65448c017f chore: use local platform libraries instead of npm package (#23834)
* chore: use local platform libraries instead of npm package

* chore: use local platform libraries instead of npm package

* chore: use local platform libraries instead of npm package

* chore: use local platform libraries instead of npm package

* chore: use local platform libraries instead of npm package
2025-09-16 15:00:51 +03:00
Anik Dhabal Babu e9fd23d0d3 fix: unable to add users from the admin page (#23869) 2025-09-16 10:59:21 +00:00
Hariom Balhara badc857bcd Move modules to moduleLoader format (#23740) 2025-09-16 10:58:23 +00:00
Eunjae Lee 7fe80dd3dd Revert "feat: implement generalized navigation permission system with PBAC (#23706)" (#23867)
This reverts commit 34b62f7516.
2025-09-16 11:17:08 +01:00
Udit Takkar 5feca13cfb fix: phone number cancel billing (#23854)
* fix: phone number billing bug

* fix: phone number billing bug

* fix: use raw code

* fix: use zod

* chore: update test

* fix: double cancel

* fix: double cancel

* fix: double cancel

* fix: chore update

* fix: schema
2025-09-16 15:39:32 +05:30
Hariom BalharaandDevin AI f267cd9cd9 fix: change no-restricted-imports to @typescript-eslint/no-restricted-imports for allowTypeImports support (#23860)
The allowTypeImports option is only supported by @typescript-eslint/no-restricted-imports,
not the standard ESLint no-restricted-imports rule. This fixes the configuration error:
'Configuration for rule no-restricted-imports is invalid: allowTypeImports should NOT have additional properties'

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-16 10:00:53 +00:00
Morgan e8c2d4fa95 chore: add build platform libs in api v2 github actions (#23862) 2025-09-16 09:07:47 +00:00
Morgan 7e415b4542 fix: eslint no-restricted-imports app-store rule (#23845) 2025-09-15 22:40:01 +05:30
emrysal 43f4caaba4 chore: release v5.7.0
Post release / release (push) Canceled after 0s
2025-09-15 16:22:52 +00:00
Udit TakkarandAlex van Andel 0c2ba81269 fix: phone number billing bug (#23851)
* fix: phone number billing bug

* fix: phone number billing bug

* fix: use raw code

* fix: use zod

* chore: update test

* Remove newline.

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-09-15 17:17:05 +01:00
Morgan 3aca339c95 fix: catch HttpError in getRoutedUrl (#23844)
* fix: catch HttpError in getRoutedUrl

* fixup! fix: catch HttpError in getRoutedUrl
2025-09-15 14:34:43 +00:00
sean-brydonandAlex van Andel 41553f6c01 feat: PBAC remove dogfood for safe checking (#23846)
* Remove dogfood for safe checking

* chore: Remove now redundant test cases

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2025-09-15 14:57:11 +01:00
Eunjae Lee 3661860433 docs: add search tools priority (#23843) 2025-09-15 13:57:25 +01:00
Keith Williams f0210d06ea chore: Upgrade prisma-kysely (#23825) 2025-09-15 13:44:31 +01:00
Rajiv Sahal fcfb8cc9a3 fix: update validation for billing check endpoint (#23842) 2025-09-15 11:57:58 +00:00
88391c7942 fix: Handle account user lookup fields for queued form responses (#23811)
* Add constants for queued response id query string

* Ignore eslint - app store imports

* Return `routingFormResponseId` or `queuedFormResponseId` from URL params

* Pass routingForm params to `getTeamMemberEmailForResponseOrContact`

* Handle getting form responses for queued form responses

* Type fix

* add test

* Add tests

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-09-15 11:16:50 +00:00
Eunjae Lee e9c6af562e docs: update knowledge base regarding auth checks in page (#23672) 2025-09-15 09:33:06 +00:00
Lauris Skraucis 18bac4a063 feat: v2 toggle transcription settings (#23836) 2025-09-15 09:13:22 +00:00
0332118724 feat: add e2e tests for insights charts (#23777)
* feat: add e2e tests for insights ChartCard components

- Test that all ChartCard components render with expected titles
- Test graceful handling of TRPC call failures
- Test ChartCard rendering for organization users
- Wait for page load and TRPC calls before checking chart presence
- Use text-based selectors to find ChartCard titles in h2 elements
- Remove page.waitForTimeout() calls to comply with ESLint rules

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up e2e tests

* fix titles

* still render charts if no data

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2025-09-15 11:00:00 +02:00
Eunjae LeeandDevin AI 34b62f7516 feat: implement generalized navigation permission system with PBAC (#23706)
* feat: implement generalized navigation permission system with PBAC

- Create NavigationPermissionsProvider context for server-side permission data
- Add checkNavigationPermissions utility using PermissionCheckService
- Update main navigation layout to check permissions server-side
- Enhance useShouldDisplayNavigationItem for generalized permission filtering
- Support permission mapping for insights, workflows, routing, teams, members
- Use unstable_cache for performance optimization
- Replace insights-specific logic with scalable PBAC-based system

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: correct flag check logic in useShouldDisplayNavigationItem

- Only return false when flag is explicitly false
- Allow navigation permission checks to run when flags are truthy
- Fixes bug where truthy flags would short-circuit permission checks

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve linting errors in embed-core files

- Replace forbidden non-null assertion with null check in embed.ts
- Replace 'any' type with 'unknown' in embed.test.ts
- Replace non-null assertion with proper null check in EmbedElement.test.ts
- Remove unused variable declaration

These are pre-existing linting issues unrelated to navigation permissions feature.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: resolve server-client boundary issue in NavigationPermissionsProvider

- Add 'use client' directive to NavigationPermissionsProvider.ts
- Replace JSX syntax with React.createElement to fix TypeScript compilation
- Create NavigationPermissionsWrapper.tsx as client component bridge
- Update layout.tsx to use wrapper instead of provider directly
- Ensure proper separation between server-side permission checking and client-side context consumption

This fixes the architectural issue where useContext was being used in server components.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* Revert "fix: resolve linting errors in embed-core files"

This reverts commit 4f481bae576376c9f9177215f7872c8bf7132894.

* refactor: simplify NavigationPermissionsProvider approach

- Remove NavigationPermissionsWrapper.tsx (revert to simpler approach)
- Rename NavigationPermissionsProvider.ts to .tsx for JSX support
- Update layout.tsx to use NavigationPermissionsProvider directly
- Keep 'use client' directive for proper server-client boundary handling
- Maintain all navigation permission functionality with cleaner architecture

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* return true for no team situation

* fix: prevent hidden navigation items from reappearing via stored expansion state

- Modified usePersistedExpansionState hook to accept shouldDisplay parameter
- Clear stored expansion state for items that shouldn't be displayed
- Prevent state persistence for items without permissions
- Updated both NavigationItem and MobileNavigationMoreItem components
- Use safe sessionStorage import from @calcom/lib/webstorage

Fixes bug where clicking 'Workflows' would restore 'Insights' menu visibility
even when user lacks insights permissions due to sessionStorage state restoration.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: add sessionStorage to webstorage module and export NavigationItemName type

- Added sessionStorage wrapper to @calcom/lib/webstorage with safe error handling
- Export NavigationItemName type from NavigationPermissionsProvider for proper type access
- Resolves TypeScript compilation errors in navigation permission system

These changes enable the collapsible menu state bug fix to compile properly.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: improve separation of concerns in usePersistedExpansionState hook

- Remove shouldDisplay parameter from usePersistedExpansionState hook
- Move state clearing logic for hidden items to NavigationItem component level
- Add setIsExpanded to useEffect dependency arrays to fix ESLint warnings
- Maintain bug fix functionality while improving code design
- Better separation between expansion state management and display permissions

This addresses user feedback about inappropriate coupling between concerns.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix provider

* fix unstable_cache

* refactor: move navigation permission checks to client-side with tRPC

- Replace server-side unstable_cache permission checks with client-side tRPC query
- Add getNavigationPermissions query to PBAC router
- Update NavigationPermissionsProvider to use tRPC with loading states
- Remove server-side checkNavigationPermissions function
- Improve initial page load performance by deferring permission checks

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: centralize navigation item definitions to eliminate repetition

- Create NAVIGATION_ITEMS_CONFIG as single source of truth for navigation items
- Auto-generate NAVIGATION_PERMISSION_MAP from centralized config
- Update Navigation.tsx to use centralized definitions for teams, routing, workflows, insights
- Fix import issues in NavigationPermissionsProvider.tsx
- Eliminate hardcoded repetition of navigation item properties across codebase

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* clean up permissions

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-15 10:55:51 +02:00
Eunjae LeeandDevin AI da1863069d feat: sort bookingUserId options alphabetically on the /insights/routing page (#23791)
* feat: sort bookingUserId options alphabetically in insights routing faceted values

- Add .sort((a, b) => a.label.localeCompare(b.label)) to bookingUserId options
- Makes user dropdown more human-friendly with alphabetical ordering
- Follows existing sorting pattern used in FilterSegmentSelect.tsx
- Fix ESLint warning by replacing Table<any> with Table<unknown>

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use generic type parameter instead of unknown in Table type

- Replace Table<unknown> with <TData>(_: Table<TData>) to fix CI type errors
- Maintains type safety while avoiding ESLint any type warning
- Allows hook to work with any table type through generic parameter

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-15 09:53:30 +01:00
Joe Au-YeungandHariom Balhara 31270ca86b feat: Write same metadata to Stripe for booking payment and no show fee payment (#23634)
* Add `findBookingById` to `BookingRepository`

* Create `generateMetadata` to Stripe `PaymentService`

* `create` method to use `generateMetadata`

* Remove unused trpc endpoint

* Pass booking id to chargeCard method

* Use generateMetadata in chargeCard method

* Remove unused stripeAppKeys

* Add error handling if booking doesn't contain attendee

* Rename  to

* Return attendees in a consistent order

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-09-15 14:20:05 +05:30
Morgan 7e876e3457 fix: use class CreateDelegationCredentialInput instead of type for api v2 (#23831) 2025-09-15 07:59:30 +00:00
Peer Richelsen cbfd991ab7 chore: small cal.ai updates (#23827)
* Update page.tsx

* fixed close button

* typo

* fixed i18n cal.ai
2025-09-14 20:21:56 +01:00
emrysal d7cd185da1 chore: release v5.6.20
Post release / release (push) Canceled after 0s
2025-09-14 17:52:38 +00:00
Udit Takkar 416504240c feat: call history V1 (#23761)
* feat: call history

* chore

* refactor: move to insights

* fix: types

* chore: improvements

* fix: memberhsip logic

* chore: improvements

* fix: update types

* fix: type errors

* fix: type errors
2025-09-14 12:04:47 -03:00
cfadd2e892 feat: cal ai promo design (#23651)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-09-14 12:00:12 -03:00
Benny JooandDevin AI 3aab13b4da refactor: circular deps between app store and lib [3] (#23742)
* getEnabledAppsFromCredentials

* wip

* wip

* mv more

* fix: update test mocking for PrismockClient in processPaymentRefund.test.ts

- Replace prismaMock with prismock for proper PrismockClient usage
- Update mock data structure to include required fields (id, userId, teamId, etc.)
- Create app and credential records separately to handle PrismockClient limitations
- Replace 'as any' type casting with vi.mocked() for proper type safety
- Adjust test expectations to match PrismockClient's actual return structure
- Add proper cleanup in beforeEach hook for both credential and app records

Fixes failing unit tests after migration from packages/lib to packages/features/bookings/lib/payment

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* publish platform libraries

* fix import

* bump version

* fix apiv2

* publish platform-libraries

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-14 11:24:16 -03:00
Benny JooandDevin AI 76bba1ca05 refactor: remove circular dependency between appstore and trpc (#23768)
* mv PaymentPage to web

* mv 2 more components to web

* refactor

* update imports

* mv

* revert

* fix

* fix

* update

* migrate relevant test too

* move setup components to web from appstore

* move wipemycalother

* mv

* fix typechecks

* mv more routing forms components

* fix

* fix

* fix

* fix: resolve type errors in SingleForm.tsx after migration

- Updated SingleFormComponentProps type to include enriched form properties
- Added proper typing for user, team, nonOrgUsername, nonOrgTeamslug, userOrigin, teamOrigin
- Fixes type errors that occurred after migrating SingleForm.tsx from packages/app-store/routing-forms/components/
- Resolves both SingleForm.tsx and TestForm.tsx type errors

Co-Authored-By: benny@cal.com <sldisek783@gmail.com>

* delete

* refactors

* fix

* fix

* fix

* remove usage of trpc client from OmniInstallAppButton.tsx

* fix test

* import only type

* fix test

* remove trpc package from appstore package.json

* remove remaining trpc usage

* update test

* fix type checks

* fix errors

* fix

* make it error

* nit

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-14 12:51:05 +00:00
Eunjae Lee 06fcea4116 docs: update insights chart dev guide for Prisma v6 (#23793) 2025-09-13 12:48:49 +00:00
Benny Joo a7fecaf578 fix: platform library export-verifyEmailCodeUnAuthenticated (#23814)
* fix apiv2

* fix import
2025-09-13 08:16:04 -03:00
Anik Dhabal Babu 639940d1bf fix: couldn't get adapter issue for few apps (#23813)
* fix: couldn't get adapter issue for few apps

* Update videoClient.ts
2025-09-13 10:35:30 +00:00
d7397d4563 fix: managed event types inherit team hideBranding setting (#23562)
* fix: managed event types inherit team hideBranding setting

- Add getParentTeamForBranding helper to query parent team data
- Update shouldHideBrandingForEvent to use parent team when eventType.team is null
- Ensures CTA 'create your own booking link with Cal' respects team branding settings
- Follows existing pattern used by eventType.team?.id ?? eventType.parent?.teamId

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* chore: update yarn.lock dependencies

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Get parent event type team branding

* Use data from getEventTypeFromDB

* Undo yarn.lock changes

* Undo yarn.lock changes from latest main

* Address code commit

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-13 08:35:23 +01:00
Udit Takkar cf07621de7 fix: make cal ai div clickable (#23807) 2025-09-12 20:16:40 +00:00
Syed Ali Shahbaz 110615b509 chore: add webhook architecture skeleton (#23247)
* add migration guide and dto

* add factory

* add notifier

* add repo

* add services

* coderabbit review --1

* coderabbit review --2

* coderabbit review --3

* further improvement

* --

* fix

* bookingWebhookFactory consideration and type fixes

* cleanup

* fix types

* DI part1

* DI --part 2

* remove migrationGuide as we're WIP

* using evyweb for DI -- 1

* DI --final

* separate func instead of private class

* adds a todo migration file

* adjust structure

* address feedback

* remove todo_migrate

* --1

* fix type

* address feedback

* add TODO comment

* address requested changes --1

* address feedback --2

* restructure as per feedback

* rename camelcase
2025-09-12 20:02:50 +00:00
Udit Takkar 3915348d03 feat: support web calls in webhook (#23788)
* feat: support web calls in webhook

* fix: test

* chore: formating

* fix: type error

* chore: improvements

* chore: improvements
2025-09-12 19:04:19 +00:00
Neha Prasadandunknown 5230694e2c fix: dynamic adapter imports not working in self-hosted instances (#23784)
* export const CalendarServiceMap

* fix: resolve linting issues in video and calendar adapter fixes

- Remove unused isCalendarService function
- Fix any type usage in getCalendar
- Add eslint-disable for necessary app-store imports in videoClient
- Maintain architectural separation while fixing core functionality

* revert

---------

Co-authored-by: unknown <adhabal2002@gmail.com>
2025-09-12 19:02:17 +00:00
Benny Joo 68f2fc9174 perf: remove trpc basecamp3 router (#23785)
* remove trpc basecamp3 router

* update

* define business logic in appstore package

* cleaner

* cleaner code

* refactor

* use zod

* cleaner

* update
2025-09-12 15:32:50 -03:00
a63802dea7 feat: redirect authenticated users from signup page (#23766)
* feat: redirect authenticated users from signup page

- Add session check in signup getServerSideProps
- Redirect to redirect parameter if present, otherwise to root
- Follows existing authentication patterns in codebase

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix test

* fix test

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: unknown <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-12 23:36:00 +05:30
Carina WollendorferandCarinaWolli 2be388373f fix: adjust free monthly credits for orgs (#23798)
* add org monthly credits env variable

* use fallback for env variable

* remove comment

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-09-12 17:47:13 +00:00
Anik Dhabal Babu a62c74f79e fix: make cancellation reason mandatory when cancelledBy param is set to host email (#23764)
* fix: make cancelllation Reason mandatory when cancelledBy set as the host

* update

* tweak

* show error message
2025-09-12 18:28:24 +01:00
Rajiv Sahal 1a8b5d145f fix: api v2 typing issues (#23786)
* fix: move validateRoundRobinSlotAvailability to core libraries

* fix: imports

* fix: update CreateCalendarCredentialsInput DTO

* cleanup
2025-09-12 18:27:56 +01:00
Lauris Skraucis 794c99239a fix: processWorkflowStep format cal event (#23802)
* fix: processWorkflowStep format cal event

* chore: update platform libraries
2025-09-12 18:27:37 +01:00
Benny Joo 1fee90322d refactor: move app-store dependent seed files from prisma to scripts (#23799)
* move seed.ts

* update package.json

* wip

* revert
2025-09-12 18:27:20 +01:00
Anik Dhabal Babu ee70111c45 fix: RateLimit verify email and fix (#23718)
* fix: RateLimit verify email

* update

* client chnages

* type error

* fix

* add test

* Update event-types.e2e.ts

* minor update

* Update event-types.e2e.ts

* fix test

* handle it in api v2
2025-09-12 18:27:05 +01:00
Lauris Skraucis 79169de8d8 fix: updating managed user email (#23794) 2025-09-12 18:26:52 +01:00
Morgan 74288b0ecb fix: OptionalApiAuthGuard when only client id is provided (#23783) 2025-09-12 12:16:52 +03:00
Udit Takkar a977fb4970 feat: add number to call in web call (#23769) 2025-09-12 12:16:39 +03:00
79a09362c9 refactor: remove circular dependency between prisma and app-store packages (#23475)
* refactor: remove circular dependency between prisma and app-store packages

- Replace EventTypeAppMetadataSchema with z.record(z.any()).optional() pattern
- Remove appDataSchemas import from packages/prisma/zod-utils.ts
- Add null checks in consuming packages for flexible validation
- Fix test file that no longer needs @ts-expect-error directive

This breaks the circular dependency while maintaining all functionality
by moving strict validation to the business logic layer where operations
actually happen, following existing patterns in the codebase.

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: remove EventTypeAppMetadataSchema exports from prisma package

- Remove EventTypeAppMetadataSchema and eventTypeAppMetadataOptionalSchema exports from prisma/zod-utils.ts
- Update all importing files to use local z.record(z.any()).optional() schemas
- Replace type annotations with Record<string, any> where appropriate
- Maintain validation functionality while breaking circular dependency
- All TypeScript compilation now passes without errors

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* refactor: complete removal of EventTypeAppMetadataSchema from remaining files

- Update handleSeats/createNewSeat.ts to use local schema
- Update payment handlers to use local schemas
- Update eventTypes update handler to use local schema
- All files now define their own validation instead of importing from prisma
- Circular dependency completely eliminated

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: resolve TypeScript compilation errors

- Remove duplicate z import from handleConfirmation.ts
- Remove duplicate appDataSchemas import from update.handler.ts
- Fix index signature errors in handlePayment.ts by using appData variable consistently
- All type checks now pass successfully

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add type casting for appSlug in eventTypeService

- Cast appSlug as keyof typeof apps to resolve index signature error
- Maintains type safety while allowing dynamic property access

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix

* remove

* make zod-utils.ts in app-store

* update imports

* fix

* fix

* fix

* revert unrelated change

* update imports

* fix

* fix

* revert

* fix

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: hbjORbj <sldisek783@gmail.com>
2025-09-12 05:57:09 -03:00
Alex van Andel 94a50086e6 Instead of type casting user.id, coerce string to number (#23781) 2025-09-12 02:46:07 +01:00
emrysal 18ba54522c chore: release v5.6.19
Post release / release (push) Canceled after 0s
2025-09-11 23:29:05 +00:00
Alex van Andel 5483597a5b Revert "fix: Don’t allow hosts to cancel a booking without providing a reason through v1 (#23647)"
This reverts commit 3c72d7aaa0.
2025-09-12 00:13:02 +01:00
Alex van Andel 4ed0901957 fix: prisma client binary cannot be found on vercel (#23772) 2025-09-11 23:18:39 +01:00
Eunjae LeeandDevin AI dbbf3ae2a2 fix: extract Prisma.sql queries for $queryRaw calls with Prisma.sql parameters (Prisma v6 upgrade) (#23779)
* fix: extract Prisma.sql queries for  calls with Prisma.sql parameters

- Extract SQL queries to separate Prisma.sql variables before passing to
- Fix PrismaPhoneNumberRepository.ts findManyWithUserAccess and findPhoneNumbersFromUserId methods
- Fix PrismaAgentRepository.ts multiple methods with whereCondition parameters
- Fix PermissionRepository.ts checkRolePermissions and getTeamIdsWithPermissions methods
- Fix virtual-queues.ts getUserRelevantTeamRoutingForms method
- Fix tasker/repository.ts hasNewerScanTaskForStepId method
- Add missing Prisma imports where needed
- Fix lint warnings: replace any with JsonValue and use explicit select for permissions
- Skip primitive parameter cases as instructed
- Compatible with Prisma v6 requirements

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* revert unnecessary changes

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-11 23:18:12 +01:00
Eunjae Lee c3985e3efb fix: including Prisma.sql for Prisma v6 upgrade (#23775) 2025-09-11 23:16:12 +01:00
c28eb90928 chore: Upgrade prisma to 6.7.0 (#21264)
* chore: Upgrade prisma to 6.7.0

* Build fixes

* type fixes

Signed-off-by: Omar López <zomars@me.com>

* Update schema.prisma

* Patching

* Revert "Update schema.prisma"

This reverts commit 47d8618bf89ef4d007b30084df766f17281e21a1.

* Revert "Patching"

This reverts commit a1d2e3040e71690a44d4324db95d73b4d68c6adb.

* Revert schema changes

Signed-off-by: Omar López <zomars@me.com>

* WIP

Signed-off-by: Omar López <zomars@me.com>

* Update getPublicEvent.ts

* Update imports

Signed-off-by: Omar López <zomars@me.com>

* Update gitignore

Signed-off-by: Omar López <zomars@me.com>

* update remaining imports

Signed-off-by: Omar López <zomars@me.com>

* Delete .cursor/config.json

* Discard changes to packages/features/eventtypes/lib/getPublicEvent.ts

* Update _get.ts

* Update user.ts

* Update .gitignore

* update

* Update WorkflowStepContainer.tsx

* Update next-auth-custom-adapter.ts

* Update getPublicEvent.ts

* Update workflow.ts

* Update next-auth-custom-adapter.ts

* Update next-auth-options.ts

* Update bookingScenario.ts

* fix missing imports

* upgrades prismock

Signed-off-by: Omar López <zomars@me.com>

* patches prismock

Signed-off-by: Omar López <zomars@me.com>

* Update reschedule.test.ts

* Update prisma.ts

* patch prismock

Signed-off-by: Omar López <zomars@me.com>

* fix enums imports

Signed-off-by: Omar López <zomars@me.com>

* Revert "Update prisma.ts"

This reverts commit 64edcf8db54171ff4456c209d563b5d431d99619.

* Revert "patch prismock"

This reverts commit e95819113dc9d88e7130947aa120cd42710977c8.

* fix patch

* Fix test that overrun the boundary, it shouldn't test too much

* Move prisma import to changeSMSLockState

* Bring back broken test without illegal imports

* Merge with main and fix filter hosts by same round robin host

* Fixed buildDryRunBooking fn tests

* Fix and move ooo create or update handler test

* Fix packages/features/eventtypes/lib/isCurrentlyAvailable.test.ts

* Fix packages/trpc/server/routers/viewer/organizations/listMembers.handler.test.ts

* Mock @calcom/prisma

* Fix: verify-email.test.ts

* fix: Moved WebhookService test and fixed default import mock

* Fix: Added missing prisma mock, handleNewBooking uses that of course

* We're not testing createContext here

* fix: Prisma mock fix for listMembers.test.ts

* More fixes to broken testcases

* Forgot to remove borked test

* Prevent the need to mock a lot of dependencies by moving out buildBaseWhereCondition to its own file

* Temporarily skip getCalendarEvents, needs a rewrite

* Fix: turns out you can access protected in testcases

* fix further mocks

* Added packages/features/insights/server/buildBaseWhereCondition.ts, types

* Always great to have a mock and then not use it

* And one less again.

* fix: confirm.handler.test, didn't mock prisma

* fix: Address minor nit by @eunjae & fix ImpersonationProvider test

* Updated isPrismaAvailableCheck that doesn't crash on import

* fix: Get Prisma directly from the client, it usually involves the Validator and does not need 'local' inclusion

* Add zod-prisma-types without the generator enabled (commented out)

* Uncomment and see what happens

* Change method of import as imports did not work in Input Schemas

* Remove custom 'zod' booking model, it does not belong with Prisma

* Fix all other global Model imports

* Rewrite most schema includes AND remove barrel file

* Add bookingCreateBodySchema to features/bookings

* Flurry of type fixes for compatibility with new zod gen

* Refactor out the custom prisma type createEventTypeInput

* Work around nullable eventTypeLocations

* HandlePayment type fix

* More fixes, final fix remaining is CompleteEventType

* Should fix a bunch more booking related type errors

* Missed one

* Some props missing from BookingCreateBodySchema

* Fix location type in handleChildrenEventTypes

* Little bit hacky imo but it works

* Final type error \o/

* Forgot to include Prisma

* Do not include zod-utils in booker/types

* Oops, was already including Booker/types

* Fix membership type, also disallow updating createdAt/updatedAt, make part of patch/post

* Fix api v1 type errors

* Fix EventTypeDescription typings

* Remove getParserWithGeneric, use userBodySchema with UserSchema

* use centralized timeZoneSchema

* Implement feedback by @zomars

* Couple of WIP pushes

* Fix tests

* Type fixes in `handleChildrenEventTypes` test

* Try and parse metadata before use

* Change zod-prisma-types configuration for optimal performance

* Fix prisma validator error in `prisma/selects/credential`

* Disable seperate relations model, hits a bug

* Import absolute - this makes rollup work in @platform/libraries

* Attempt at removing resolutions override

* Refactor using `Prisma.validator` to `satisfies`

* Build atoms using @calcom/prisma/client

* Build atoms using @calcom/prisma/client

* fixes

* Update eventTypeSelect.ts

* Adjust `eventTypeMetaDataSchemaWithUntypedApps` from `unknown` to `record(any)`

* `EventTypeDescription` rely on `descriptionAsSafeHTML` instead of `description`

* Add `seatsPerTimeSlot` to event type public select

* Fix typing in `users-public-view` getServerSide props

* Add missing `schedulingType` to prop

* chore: bump platform libraries

* Function return type is illegal, not sure how this passed eslint (#21567)

* Merged with main

* Update updateTokenObject.ts

* Update handleResponse.ts

* Update index.ts

* Update handleChildrenEventTypes.ts

* Update booking-idempotency-key.ts

* Update WebhookService.test.ts

* Update events.test.ts

* Update queued-response.test.ts

* Update events.test.ts

* Update getRoutedUrl.test.ts

* fix: type checks

Signed-off-by: Omar López <zomars@me.com>

* fixes

Signed-off-by: Omar López <zomars@me.com>

* chore: bump platform libraries

* Update yarn.lock

* more fixes

Signed-off-by: Omar López <zomars@me.com>

* fixes

Signed-off-by: Omar López <zomars@me.com>

* biuld fixes

* chore: bump platform libraries

* Update conferencing.repository.ts

* Update conferencing.repository.ts

* Update getCalendarsEvents.test.ts

* Update vite.config.js

* chore: bump platform libraries

* Update users.ts

* Discard changes to docs/api-reference/v2/openapi.json

* Update vite.config.ts

* updated platform libraries

* Update get.handler.test.ts

* Update get.handler.test.ts

* Update schema.prisma

* Discard changes to docs/api-reference/v2/openapi.json

* Update next-auth-custom-adapter.ts

* Update team.ts

* Flurry of type fixes

* Fix majority of insight related type errors

* Type fixes for unlink of account

* Make user nullable again

* Fixed a bunch of unit tests and one type error

* Attempted mock fix

* Attempted fix for Attribute type

* Ensure default import becomes prisma, but not direct usage

* Import default as prisma in prisma.module

* Add attributeOption to attribute type

* Fix calcom/prisma mock

* Refactor Prisma client imports to @calcom/prisma/client

Updated all imports from '@prisma/client' to '@calcom/prisma/client' across tests and repository files for consistency and to use the correct Prisma client package. This change improves maintainability and ensures the correct client is referenced throughout the codebase.

* Undo removal of max-warnings=0 to get main to merge

* Remove unit tests for e2e fixtures, provide new prisma mock

* Mock @calcom/prisma in event manager

* Mock @calcom/prisma in event manager

* Add correct format even with --no-verify

* Mock prisma in CalendarManager

* Add mock for permission-check.service

* Better injection in PrismaApiKeyRepository imports

* More mock fixes :)

* Fix listMembers.handler.test

* Fix User import

* Appropriately adjust all types to be imported as types, there were a lot of types imported as normal deps

* Why was this a thing?

* Strictly speaking; Not using prismock anymore

* Ditched patch file for prismock

* Fix output.service.ts platform type imports, need concrete for plainToClass

* Better typing and tests for unlinkConnectedAccount.handler

* Small type fix

* Disable calendar cache tests as they are dependent on prismock

* chore: bump platform lib

* getRoutedUrl test remove of unused import

* Extract select to external const on getEventTypesFromDB

* Direct select of userSelect from selects/user

* fix type error from merging 23653

* Fixed integration tests by removing hardcoded values that were possible due to mocking, but as its now directly hitting the db no longer

* fix: vite config atoms prisma client type location

* revert: example app prisma client

* revert: example app prisma client

* bump platform libs

* fix: use class instead of type for DI of PlatformBookingsService

* update platform libs

* remove unused variable

* chore: generate prisma client for api v2

* fix: api v2 e2e

* fix: atoms e2e

* fix: atoms e2e

* fix: atoms e2e

* fix: api v2 e2e

* fix: tsconfig apiv2 enums

* publish libraries

* Simplify check for existence teamId

---------

Signed-off-by: Omar López <zomars@me.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
2025-09-11 15:27:50 +01:00
Amit Sharma a55d56f260 fix: Intercom not opening with openSupport param (#23755)
* fix: Intercom not opening with openSupport param

* remove logs

* remove unused
2025-09-11 18:11:42 +05:30
1d25265c56 feat: workflows v3 UI (#22772)
* early UI refresher of workflows using v3 designs. needs tons of testing, might have broken

* Delete .claude/settings.local.json

* fix: bunch of design fixes, merge conflict fixes

* fix: e2e and type-check

* fix: await button click

* review fixes

* code rabbit fixes

* fix styles in variables dropdown

* fix text truncate

* fix: unit tests

* fix: unit tests

* chore: add missing i18n

* review fixes

* review fixes

* fix testing info message

* move timeSectionText up

* fix which team does this apply to info message

* disable set up agent button with read only

* fix: cal.ai breaking on mobile screen

---------

Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-09-11 17:01:42 +05:30
emrysal 65f6689025 chore: release v5.6.18
Post release / release (push) Canceled after 0s
2025-09-11 10:33:13 +00:00
Hariom Balhara 92005b93c3 All handleNewBooking tests import from getNewBookingHandler (#23741) 2025-09-11 06:58:16 -03:00
Anik Dhabal Babu 0a7e573117 fix: scdules reset to default (#23759) 2025-09-11 04:58:30 +00:00
Anik Dhabal Babu 943c1a3c03 fix: events not removed from the previous host calendar due to wrong credentials usage (#23756)
* fix: events not removed from the previous host claendar

* fix test

* Update roundRobinManualReassignment.test.ts
2025-09-11 04:03:50 +00:00
Benny Joo 9156848503 refactor: circular deps between app store and lib [2] (#23734)
* mv getDefaultLocations

* fix

* 2 more utils

* update imports

* fix

* move getConnectedApps

* move handlePaymentSuccess

* update imports

* fix import

* publish platform libraries
2025-09-10 23:18:59 -03:00
emrysal 2e6ad8be9a chore: release v5.6.17
Post release / release (push) Canceled after 0s
2025-09-10 23:17:01 +00:00
Calcom BotandLingo.dev 1aca18324d feat: update translations via @LingoDotDev (#23753)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-10 21:38:05 +05:30
Udit TakkarandPeer Richelsen a8a3e48465 feat: add web phone call for cal ai (#23527)
* feat: add web phone call for cal ai

* fix: web call

* refactor: improvements

* chore

* refactor: web call improvements

* chore: error message

* refactor: improvements

* fix: err

* refactor: feedback and improvements

* fix: type errors

* refactor: hasAvailable

* chore: use orgid

* fix: types

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2025-09-10 12:41:10 -03:00
Volnei Munhoz 2e96600529 Revert "fix(workflows): hide organizer email in workflow emails (#23525)" (#23739)
This reverts commit 7f200df1ac.
2025-09-10 11:49:38 +00:00
Hariom Balhara b9074aeb81 Better ioctopus type-safety (#23541) 2025-09-10 17:10:25 +05:30
Udit Takkar 13add03479 chore: update vitest (#23732) 2025-09-10 16:59:25 +05:30
Hariom Balhara bb2dcc51c6 Ignore requests from bot for headless router (#23733) 2025-09-10 16:59:04 +05:30
RomitandKartik Saini 8f82e78597 fix: loading skeleton is rendered even when no attributes filter is selected (#23656)
* fix

* fix tests

* fix tests

* test fidx

* chore

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-09-10 16:57:56 +05:30
Eunjae LeeandDevin AI 34d2a13080 fix: move admin permission check to server-side to prevent flash (#23517)
- Move permission validation from AdminLayoutAppDirClient.tsx (client) to layout.tsx (server)
- Add server-side redirect using next/navigation redirect() function
- Remove client-side useEffect permission check to eliminate flash
- Follow same pattern as organizations layout for consistent auth handling
- Users without admin role are redirected to /settings/my-account/profile before any content renders

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-10 11:15:37 +01:00
Eunjae LeeandDevin AI 6066ed206b fix: Fix booking count discrepancy between KPI cards and trends chart (#23619)
* fix: correct booking count in EventTrendsChart by restructuring SQL query

- Replace JOIN-based query with CTE approach to count distinct bookings
- Separate booking stats from guest stats to prevent duplicate counting
- Preserve no-show guest functionality with LEFT JOIN
- Ensure EventTrendsChart 'Created' sum matches BookingKPICards 'events_created'

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: use positional GROUP BY references to resolve PostgreSQL error

- Replace column expressions in GROUP BY with positional references (1, 2, 3)
- Fixes PostgreSQL error 42803 caused by parameter resolution in CTE queries
- Maintains the same query logic while avoiding column reference conflicts

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* address feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-10 11:13:29 +01:00
d30d2792cd fix: hide notes (#22061)
* fix: hide notes

* test: re-enable confirmHandler tests and add tests for hide notes fix

* fix: replace deprecated getDate with hardcoded dates for timezone safety

* fix: hide notes test

* refactor: move test from trpc to web package

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
2025-09-10 10:51:41 +01:00
ba50268634 feat: support auto create agent (#23493)
* feat: support auto create agent

* feat: add prompts

* chore: add number to call

* fix typo

---------

Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2025-09-10 08:42:39 +00:00
Benny Joo 4ca78f46df chore: bump platform libraries version (#23730) 2025-09-10 08:37:17 +00:00
Eunjae LeeandAnik Dhabal Babu 3a7ca0246c docs: add knowledge base against unnecessary Day.js usage (#23719)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-10 09:54:48 +02:00
Vansh GilhotraandAnik Dhabal Babu 2cc8b1c2af fix: Use db-deploy instead of db-migrate for yarn dx in non-interactive environments (#23253)
Fixes the issue where 'yarn dx' fails in non-interactive environments
(CI/CD, Docker, automated scripts) by changing Turbo dependencies:

- @calcom/prisma#db-seed: db-migrate → db-deploy
- @calcom/prisma#dx: db-migrate → db-up

This ensures that non-interactive 'prisma migrate deploy' is used
instead of interactive 'prisma migrate dev', allowing yarn dx to
work correctly in automated environments.

Resolves: Cal.com App Store performance optimization - yarn dx failure

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-10 06:46:46 +00:00
Lauris Skraucis a2d0cbfe5b chore: v2 dont allow mixing platform teams/users with non-platform (#20296)
* chore: v2 dont allow mixing platform teams/users with non-platform

* chore: finish main merge

* test: e2e

* refactor: simplify can add user to team logic

* refactor: fetch only needed oauth data

* refactor: cleanup
2025-09-09 21:24:18 +02:00
PallavandKartik Saini d65c0753ef conventional left aligned dropdown (#23643)
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-09-09 16:02:43 +00:00
github-actions[bot] 76bd90b228 chore: version packages (#23714)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-09 15:23:30 +00:00
Benny Joo d908403a99 refactor: circular deps between app store and lib [1] (#23653)
* move dailyApiFetcher.ts to app store package

* update imports

* bookingLocationService

* revert

* move findFieldValueByIdentifier

* wip

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* move to features package

* update imports

* update imports

* move

* fix typechecks

* move getCalendarLinks

* mv event test
2025-09-09 14:38:29 +00:00
Amit SharmaandUdit Takkar 0fe775962f fix: intercom showing on cal video page (#23713)
* feat: support auto create agent

* fix: intercom showing on cal.video page

* Revert "feat: support auto create agent"

This reverts commit 084319c419b3baa44a3a82c0a2d79a4242a64d4d.

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2025-09-09 14:28:59 +00:00
Calcom BotandLingo.dev 412a6992c7 feat: update translations via @LingoDotDev (#23715)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-09 11:04:39 -03:00
Rajiv Sahal cfd1992733 feat: add customReplyToEmail for EventTypeSettings atom (#23686)
* init: endpoint for fetching verified emails

* fix: enable custom reply to email in frontend

* init endpoint to add verified emails

* add verified emails option for platform in frontend

* fixup: move useGetVerifiedEmails hook to correct folder

* update atoms module

* fixup: teamId should be string

* add methond to fetch team member emails

* update logic to fetch and add emails

* fixup: append client id with email

* fixup: pass teamId for fetching verified emails

* fixup: simplify check for existing emails

* fix: cleanup comments

* fix: implement code rabbit feedback

* fix: add translations

* fixup: update transaltions

* fix: update logic for addVerifiedEmail

* add changesets

* fix: implement PR feedback
2025-09-09 16:52:28 +03:00
RomitandAnik Dhabal Babu e86d6169ba fix (#23705)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2025-09-09 19:05:17 +05:30
sean-brydonandcoderabbitai[bot] a379bd2b52 fix: org layout authentication (#23707)
* refactor layout to not check session

* add actions for orgs + org admins

* update types on actions to be correctly non nullable

* Add tests for utils

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* restore lock file

* rename _actions to actions

* update tests to be mocked

* restore lock

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-09 22:27:00 +09:00
Eunjae LeeandDevin AI 1137047606 feat: add PBAC permission checks to insights (#23592)
* feat: add PBAC permission checks to insights

- Add layout-level protection for insights pages with session.user.org.id check
- Add API-level protection for insights tRPC endpoints using insightsPbacProcedure
- Enhance routing form insights with PBAC team filtering
- Use insights.read permission with OWNER/ADMIN fallback roles
- Replace all userBelongsToTeamProcedure with insightsPbacProcedure in insights router
- Fix lint issues: remove unused variables and functions, fix non-null assertion

Implements Permission-Based Access Control (PBAC) for insights functionality following the same patterns as event type PBAC implementation from PR #22618.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: clean up unused imports in routing-forms

- Remove unused isFormCreateEditAllowed import
- Remove unused TRPCError import
- Change MembershipRole to type import for better tree-shaking

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* address feedback

* clean up permission check

* revert unnecessary changes

* fix procedure

* allow MEMBER for insights

* support teams not under orgs

* fix type error

* revert unnecessary changes

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-09 14:26:20 +01:00
Lauris Skraucis ad4cf0cc3a fix: v2 hidden event types (#23584)
* fix: return hidden event types only if owner auth provided

* chore: add tests

* chore: remove optional chaining when defined
2025-09-09 13:23:50 +02:00
RomitandKartik Saini e7d2e0dc2f fix: Prevent loading of dashboard GTM container on booking success page (#22620)
* moved bookings folder

* removed test

---------

Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-09-09 16:31:07 +05:30
Alex van Andel aa51218428 perf: move to disable prisma client extension inference (#23692)
* perf: move to disable prisma client extension inference

* Prisma doesn't like it when you pass Record<string, unknown>

* API v1 type fixes

* Missed one

* Fix unit test fail due to faulty expect

* Assigning to prisma InputJsonValue/Array must be done as object, not interface

* Fix @calcom/web ts error, teams not defined

* Run eslint formatter

* fixed the routingFormHelpers file causing a failing app store e2e test
2025-09-09 10:56:58 +00:00
Yadong (Adam) Zhang 38bc5fb71e chore(apps/web): add Scan for React performance issues and eliminate slow renders in web app (#23696)
* chore: add Scan for React performance issues and eliminate slow renders in web app

* chore(apps/web): always install latest `react-scan`.
2025-09-09 10:50:44 +00:00
411516ddb9 fix: duplicate event created in attendee calendar due to incorrect icalUid (#23658)
* chre: update reassigment to delete old events

* fix

* Update yarn.lock

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: unknown <adhabal2002@gmail.com>
2025-09-09 10:29:14 +00:00
Morgan c6c17ac388 fix: delegated credentials timezone outlook (#23700) 2025-09-09 11:25:48 +01:00
emrysal 6838133865 chore: release v5.6.16
Post release / release (push) Canceled after 0s
2025-09-09 10:21:58 +00:00
Calcom BotandLingo.dev 4b2bb2271a feat: update translations via @LingoDotDev (#23703)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-09 06:47:06 -03:00
20b7ac8c0d feat: implement tiered Intercom chat system replacing Plain (#23285)
* feat: implement tiered Intercom chat system replacing Plain

- Add TieredIntercomChat component with customer tier detection
- Add IntercomContactForm for free users using Intercom API
- Add /api/intercom-conversation endpoint for free user support
- Update UserDropdown to use tiered chat logic
- Replace Plain chat with Intercom in app providers
- Remove all Plain chat components and related files
- Use useHasPaidPlan hook for customer tier detection

Paying customers see Intercom widget, free users see contact form
that creates conversations via Intercom API.

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: add missing environment variables to turbo.json globalEnv

- Add NEXT_PUBLIC_WEBAPP_URL, NEXT_PUBLIC_WEBSITE_URL, NEXT_PUBLIC_STRIPE_PUBLIC_KEY
- Add NEXT_PUBLIC_IS_E2E, NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE_MONTHLY
- Add NEXT_PUBLIC_BOOKER_NUMBER_OF_DAYS_TO_LOAD, NEXT_PUBLIC_STRIPE_CREDITS_PRICE_ID
- Resolves turbo/no-undeclared-env-vars ESLint errors blocking commits

Co-Authored-By: peer@cal.com <peer@cal.com>

* fix: resolve linting errors in platform examples base package

- Fix prettier/prettier formatting (quotes and comma)
- Add underscore prefix to unused variables
- Resolves CI failure in @calcom/base#lint check

Co-Authored-By: peer@cal.com <peer@cal.com>

* remove plain usage

* placement fixes

* fix: pop closing immediately issue

* stuff

* proper error and additional user info

* add key to .env.example and remove unused plain route

* fix conversation route

* refactor intercom dynamic provider

* code rabbit fixes

* feat: introduce tiered support feature flag

* fix: type check

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-09 18:20:22 +09:00
Calcom BotandLingo.dev ca7c432728 feat: update translations via @LingoDotDev (#23699)
Co-authored-by: Lingo.dev <support@lingo.dev>
2025-09-09 08:49:09 +00:00
SomandHariom Balhara 3b966191e3 fix: prevent footer doubling with CSS position absolute for grid layouts (#23368)
* fix: prevent footer doubling with CSS position absolute for grid layouts

* fix: use :host selector for Shadow DOM compatibility in footer doubling fix

* Add better comments and updae playground to be ab le to test it

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-09-09 08:13:15 +00:00
a7889984a0 fix: design improvements for log in screen for cal video (#22359)
* fix: design improvements for log in screen for cal video

Signed-off-by: bandhan-majumder <bandhanmajumder16@gmail.com>

* fix: type

Signed-off-by: bandhan-majumder <bandhanmajumder16@gmail.com>

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* add: light mode

* Update videos-single-view.tsx

* add suggestions 

added padding change and removed hard coded values

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* Update apps/web/modules/videos/views/videos-single-view.tsx

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* Update common.json

* Update videos-single-view.tsx

* remove isLoggedin from LogInOverlayProps

* type fix

* screen flash fixed

* rabbit suggestions

* rabbit suggestions

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* flakey test

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* Update videos-single-view.tsx

* add: deps

* coderabbit

---------

Signed-off-by: bandhan-majumder <bandhanmajumder16@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
2025-09-09 07:44:29 +00:00
Anik Dhabal Babu 3c72d7aaa0 fix: Don’t allow hosts to cancel a booking without providing a reason through v1 (#23647)
* fix: hosts is cancelling booking through apiV1

* tweak
2025-09-09 05:30:51 +00:00
Romit ece0030978 fix (#23685) 2025-09-09 04:20:20 +00:00
Anik Dhabal Babu a26a769119 fix: send awaiting payment email only to the current seat (#23630) 2025-09-09 03:50:24 +00:00
Anik Dhabal Babu 3313de1eec fix: change internal note preset fkey to cascade (#23613) 2025-09-09 03:13:31 +00:00
Anik Dhabal Babu 7a6e16631b fix: guests are not adding when reschedule booking (#23620)
* fix: guests are not adding when reschedule booking

* Update addGuests.handler.ts

* add types
2025-09-09 03:12:41 +00:00
Anik Dhabal Babu ce4d71ba2e fix: workflow attach ics file is in base64 format (#23680) 2025-09-09 03:11:34 +00:00
300cd31efb chore: redis cache for calendars in api v2 (#23622)
* chore: implement redis cache for calendars api v2

* fixup! chore: implement redis cache for calendars api v2

* fixup! fixup! chore: implement redis cache for calendars api v2

* fix leverage genetic type of redis.get

* refactor: address supalarry's PR feedback

- Create CalendarsCacheService to separate cache responsibilities
- Rename cache methods to be more descriptive (getConnectedAndDestinationCalendarsCache, setConnectedAndDestinationCalendarsCache)
- Remove unused redisService injection from CalendarsController
- Move all cache-related functionality to dedicated service

Addresses comments 9, 10, and 11 from supalarry on PR #23622

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* refactor: address supalarry's latest PR feedback

- Remove redundant deleteConnectedAndDestinationCalendarsCache from CalendarsService
- Update controller to directly inject and use CalendarsCacheService
- Extract TTL constant and remove manual JSON.stringify in cache service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update IcsFeedService to use CalendarsCacheService directly

- Inject CalendarsCacheService into IcsFeedService constructor
- Replace calendarsService.deleteCalendarCache with calendarsCacheService.deleteConnectedAndDestinationCalendarsCache
- Completes the refactoring to eliminate all old cache method references

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: update destination-calendars and selected-calendars services to use CalendarsCacheService directly

- Inject CalendarsCacheService in both service constructors
- Replace calendarsService.deleteCalendarCache calls with calendarsCacheService.deleteConnectedAndDestinationCalendarsCache
- Add CalendarsCacheService to module providers for proper dependency injection
- Completes migration of all cache method references to use dedicated cache service

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* chore: use CalendarsCacheService

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-09-08 21:21:55 +00:00
Rajiv Sahal f5bb734441 fix: platform onboarding (#23581)
* fix: platform onboarding

* chore: better function naming

* fix: implement PR feedback
2025-09-08 19:04:33 +00:00
emrysal e33560ef82 chore: release v5.6.15
Post release / release (push) Canceled after 0s
2025-09-08 12:44:40 +00:00
devin-ai-integration[bot]andmorgan@cal.com 84f34b2244 feat: add 5000ms staleTime to useConnectedCalendars hook (#23674)
- Add staleTime: 5000 to useQuery configuration in useConnectedCalendars
- Prevents unnecessary refetches for 5 seconds after data becomes stale
- Improves performance by reducing redundant API calls

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
2025-09-08 12:19:22 +00:00
Benny Joo 086bae03d3 refactor: move a constant to a dedicated file in App store package (#23671)
* define DailyLocationType in app-store/locations.ts

* update imports
2025-09-08 08:38:46 -03:00
4a0a429774 refactor: Migrate getRoutedUrl from @calcom/lib to @calcom/features (#23666)
* mkdir

* update imports

* chore: update platform libraries

---------

Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
2025-09-08 11:28:22 +00:00
Benny Joo c4142ab4e7 refactor: Move handlePayment to Features Package (#23670)
* mv

* update imports
2025-09-08 07:32:29 -03:00
Benny Joo 95f8046db9 refactor: Error code - remove circular dep between app store <-> lib (#23669)
* remove stripe.types.ts

* use stripe-error defined in packages/lib

* refactor
2025-09-08 07:31:28 -03:00
Lauris Skraucis d8a87e9f04 fix: v2 seated bookings (#23514)
* fix: email manage link missing seat uid

* fix: toggle seated booking attendees

* fix: email manage link seat uid

* chore: update platform libraries
2025-09-08 09:50:36 +00:00
Keith Williams 86dcd6f0ff perf: Create 'heavy' eventTypes router (#23664)
* perf: Create 'heavy' eventTypes router

* Fixing type checks

* Fixing platform libraries imports
2025-09-08 08:24:30 +00:00
Anik Dhabal Babu 411a14dd3d fix: unit test flakiness (#23668)
* fix: unit test flakyness

* Update CalendarService.test.ts
2025-09-08 03:47:40 +00:00
Benny Joo 03bc8db64a refactor: Remove StripeService from @calcom/lib and define it in @calcom/trpc (#23655)
* remove packages/lib/server/stripe

* simplify metadata

* define business logic directly in trpc handler
2025-09-08 02:02:56 +00:00
Benny Joo fe7fd8bc79 chore: add an eslint rule to warn importing trpc package in app store package (#23665) 2025-09-08 10:36:34 +09:00
Benny Joo 92eb41c117 refactor: Migrate trpc routers in App store package to Trpc package (#23536)
* migrate trpc routers in app package to trpc package

* delete

* delete

* delete

* fix

* fix

* fix

* format

* format

* fix

* fix

* fix

* fix

* remove unused file

* fix

* fix

* wip
2025-09-07 22:17:33 -03:00
Benny Joo a1fca56aac refactor: Remove App Store's Type Dependency on Trpc Package (#23640)
* remove trpc type interface

* refactors

* refactors
2025-09-08 00:59:51 +00:00
2331 changed files with 76943 additions and 54751 deletions
+58
View File
@@ -318,3 +318,61 @@ dates.map((date) => dayjs.utc(date).add(1, "day").format());
// ✅ Best - Use native Date when possible
dates.map((date) => new Date(date.valueOf() + 24 * 60 * 60 * 1000));
```
## Next.js App Directory: Authorisation Checks in Pages
This can include checking session.user exists or session.org etc.
### TL;DR:
Don’t put permission checks in layout.tsx! Always put them directly inside your page.tsx or relevant server components for every restricted route.
### Why Not to Use Layouts for Permission Checks
* Layouts don’t intercept all requests: If a user navigates directly or refreshes a protected route, layout checks might be skipped, exposing sensitive content.
* APIs and server actions bypass layouts: Sensitive operations running on the server can’t be guarded by checks in the layout.
* Risk of data leaks: Only page/server-level checks ensure that unauthorized users never get protected data.
### ✅ How To Secure Routes (The Right Way)
* Check permissions inside page.tsx or the actual server component.
* Perform all session/user/role validation before querying or rendering sensitive content.
* Redirect or return nothing to unauthorized users, before running restricted code.
### 🛠️ Example: Page-Level Permission Check
```tsx
// app/admin/page.tsx
import { redirect } from "next/navigation";
import { getUserSession } from "@/lib/auth";
export default async function AdminPage() {
const session = await getUserSession();
if (!session || session.user.role !== "admin") {
redirect("/"); // Or show an error
}
// Protected content here
return <div>Welcome, Admin!</div>;
}
```
### 🧠 Key Reminders
* Put permission guards in every restricted page.tsx.
* Never assume layouts are secure for guarding data.
* Validate users before any sensitive queries or rendering.
## Avoid using Dayjs if you don’t need to be strictly tz aware.
When doing logic like Dayjs.startOf(".."), you can instead use date-fns' `startOfMonth(dateObj)` / `endOfDay(dateObj)`;
When doing logic that depends on Browser locale, use i18n.language (prefer to deconstruct) like: `const { i18n: { language } } = useLocale();`, in combination with built-in Intl.
Note that with Date, you’re dealing with System time, so it’s not suited to everywhere (such as in the Booker, where instead we’ll likely migrate to Temporal) - but in most cases the above are suitable.
The main reason for doing so is that Dayjs uses a useful, but highly risky plugin system, which has led us to create `@calcom/dayjs` - this is heavy however, because it pre-loads ALL plugins, including locale handling. It’s a non-ideal solution to a problem that unfortunately exists due to Dayjs.
+1 -1
View File
@@ -7,7 +7,7 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@calcom/platform-libraries"],
"ignore": ["@calcom/platform-libraries", "@calcom/api-v2"],
"privatePackages": {
"version": false,
"tag": false
+5
View File
@@ -0,0 +1,5 @@
---
"@calcom/atoms": minor
---
This PR adds ability to display bookings of a user event for calendar view atom
+17 -8
View File
@@ -103,19 +103,14 @@ NEXT_PUBLIC_INTERCOM_APP_ID=
# Secret to enable Intercom Identity Verification
INTERCOM_SECRET=
# Intercom api token for free users
INTERCOM_API_TOKEN=
# Posthog Config
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=
# plain.com config
PLAIN_API_KEY=
PLAIN_API_URL=https://api.plain.com/v1
PLAIN_HMAC_SECRET_KEY=
NEXT_PUBLIC_PLAIN_CHAT_ID=
PLAIN_CHAT_HMAC_SECRET_KEY=
NEXT_PUBLIC_PLAIN_CHAT_EXCLUDED_PATHS=
# Dub Config
@@ -149,6 +144,12 @@ GOOGLE_WEBHOOK_TOKEN=
# Optional URL to override for tunelling webhooks. Defaults to NEXT_PUBLIC_WEBAPP_URL.
GOOGLE_WEBHOOK_URL=
# Token to verify incoming webhooks from Microsoft Calendar
MICROSOFT_WEBHOOK_TOKEN=
# Optional URL to override for tunelling webhooks. Defaults to NEXT_PUBLIC_WEBAPP_URL.
MICROSOFT_WEBHOOK_URL=
# Inbox to send user feedback
SEND_FEEDBACK_EMAIL=
@@ -208,6 +209,7 @@ NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN=0
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE=
STRIPE_TEAM_MONTHLY_PRICE_ID=
NEXT_PUBLIC_STRIPE_CREDITS_PRICE_ID=
ORG_MONTHLY_CREDITS=
STRIPE_TEAM_PRODUCT_ID=
# It is a price ID in the product with id STRIPE_ORG_PRODUCT_ID
STRIPE_ORG_MONTHLY_PRICE_ID=
@@ -265,6 +267,9 @@ NEXT_PUBLIC_CLOUDFLARE_SITEKEY=
NEXT_PUBLIC_CLOUDFLARE_USE_TURNSTILE_IN_BOOKER=
CLOUDFLARE_TURNSTILE_SECRET=
# 0 = false, 1=true
NEXT_PUBLIC_VERCEL_USE_BOTID_IN_BOOKER=
# Set the following value to true if you wish to enable Team Impersonation
NEXT_PUBLIC_TEAM_IMPERSONATION=false
@@ -477,3 +482,7 @@ DATABASE_CHUNK_SIZE=
# Service Account Encryption Key for encrypting/decrypting service account keys
# You can use: `openssl rand -base64 24` to generate one
CALCOM_SERVICE_ACCOUNT_ENCRYPTION_KEY=
SALESFORCE_GRAPHQL_DELAY_MS=500
SALESFORCE_GRAPHQL_MAX_DELAY_MS=2000
SALESFORCE_GRAPHQL_MAX_RETRIES=3
-9
View File
@@ -1,9 +0,0 @@
node_modules
apps/api/v2/dist
packages/platform/**/dist/*
**/**/node_modules
**/**/.next
**/**/public
packages/prisma/zod
apps/web/public/embed
packages/ui/components/icon/dynamicIconImports.tsx
-23
View File
@@ -1,23 +0,0 @@
// This configuration only applies to the package manager root.
/** @type {import("eslint").Linter.Config} */
module.exports = {
extends: ["./packages/config/eslint-preset.js"],
plugins: ["import"],
rules: {
"import/no-cycle": ["warn", { maxDepth: Infinity }],
},
overrides: [
{
files: ["packages/lib/**/*.{ts,tsx,js,jsx}", "packages/prisma/**/*.{ts,tsx,js,jsx}"],
rules: {
"no-restricted-imports": [
"warn",
{
paths: ["@calcom/app-store"],
patterns: ["@calcom/app-store/*"],
},
],
},
},
],
};
+2 -1
View File
@@ -1,5 +1,5 @@
/**/package.json @calcom/Foundation
/apps/api/**/* @calcom/Platform @calcom/Foundation
/apps/api/**/* @calcom/API
/apps/ui-playground/**/* @calcom/Consumer @calcom/Foundation
/apps/web/**/layout.tsx @calcom/Consumer @calcom/Foundation
/apps/web/lib/csp.ts @calcom/Foundation
@@ -23,6 +23,7 @@
/packages/app-store/office365calendar/**/* @calcom/Foundation
/packages/app-store/zohocalendar/**/* @calcom/Foundation
/packages/embeds/**/* @calcom/Foundation
/packages/features/auth/lib/next-auth-options.ts @calcom/Foundation
/packages/features/bookings/lib/**/* @calcom/Foundation
/packages/lib/getAggregatedAvailability.ts @calcom/Foundation
/packages/lib/getUserAvailability.ts @calcom/Foundation
+1 -7
View File
@@ -74,14 +74,8 @@ jobs:
uses: ./.github/workflows/e2e-embed-react.yml
secrets: inherit
e2e-atoms:
name: Tests
needs: [lint, build, build-atoms, build-api-v2]
uses: ./.github/workflows/e2e-atoms.yml
secrets: inherit
required:
needs: [lint, type-check, unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store, e2e-atoms]
needs: [lint, type-check, unit-test, integration-test, build, build-api-v1, build-api-v2, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
if: always()
runs-on: buildjet-2vcpu-ubuntu-2204
steps:
+20 -3
View File
@@ -1,4 +1,4 @@
name: E2E
name: Check breaking changes and run E2E
on:
workflow_call:
env:
@@ -23,6 +23,10 @@ env:
STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }}
STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }}
SLOTS_CACHE_TTL: ${{ secrets.CI_SLOTS_CACHE_TTL }}
NEXT_PUBLIC_VAPID_PUBLIC_KEY: ${{ secrets.NEXT_PUBLIC_VAPID_PUBLIC_KEY }}
VAPID_PRIVATE_KEY: ${{ secrets.VAPID_PRIVATE_KEY }}
JWT_SECRET: ${{ secrets.CI_JWT_SECRET }}
NODE_ENV: ${{ vars.CI_NODE_ENV }}
jobs:
e2e:
timeout-minutes: 20
@@ -68,13 +72,26 @@ jobs:
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-db
- name: Generate Swagger
working-directory: apps/api/v2
run: yarn generate-swagger
- name: Check breaking changes
uses: oasdiff/oasdiff-action/breaking@main
with:
base: https://raw.githubusercontent.com/calcom/cal.com/refs/heads/main/docs/api-reference/v2/openapi.json
revision: docs/api-reference/v2/openapi.json
fail-on: ERR
- name: Run Tests
working-directory: apps/api/v2
run: |
yarn test:e2e
yarn workspace @calcom/platform-libraries build && yarn test:e2e
EXIT_CODE=$?
echo "yarn test:e2e command exit code: $EXIT_CODE"
echo "yarn workspace @calcom/platform-libraries build && yarn test:e2e command exit code: $EXIT_CODE"
exit $EXIT_CODE
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v4
+2
View File
@@ -13,6 +13,8 @@ env:
ATOMS_E2E_API_URL: ${{ secrets.ATOMS_E2E_API_URL }}
ATOMS_E2E_ORG_ID: ${{ secrets.ATOMS_E2E_ORG_ID }}
ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED: ${{ secrets.ATOMS_E2E_OAUTH_CLIENT_ID_BOOKER_EMBED }}
ATOMS_E2E_APPLE_ID: ${{ secrets.ATOMS_E2E_APPLE_ID }}
ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE: ${{ secrets.ATOMS_E2E_APPLE_CONNECT_APP_SPECIFIC_PASSCODE }}
DATABASE_DIRECT_URL: ${{ secrets.CI_DATABASE_URL }}
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
with:
repo-token: ${{ secrets.EQUITY_BEE_TEAM_LABELER_ACTION_TOKEN }}
organization-name: calcom
ignore-labels: "admin, app-store, ai, authentication, automated-testing, billing, bookings, caldav, calendar-apps, ci, console, crm-apps, dba, devops, docs, documentation, emails, embeds, event-types, i18n, impersonation, manual-testing, ui, performance, ops-stack, organizations, public-api, routing-forms, seats, self-hosted, teams, webhooks, workflows, zapier"
ignore-labels: "admin, app-store, ai, api, authentication, automated-testing, billing, bookings, caldav, calendar-apps, ci, console, crm-apps, dba, devops, docs, documentation, emails, embeds, event-types, i18n, impersonation, manual-testing, ui, performance, ops-stack, organizations, public-api, routing-forms, seats, self-hosted, sre, teams, webhooks, workflows, zapier"
apply-labels-from-issue:
runs-on: ubuntu-latest
+2 -10
View File
@@ -195,13 +195,6 @@ jobs:
uses: ./.github/workflows/e2e-embed-react.yml
secrets: inherit
e2e-atoms:
name: Tests
needs: [changes, check-label, build, build-atoms, build-api-v2]
if: ${{ needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-atoms.yml
secrets: inherit
analyze:
name: Analyze Build
needs: [build]
@@ -211,7 +204,7 @@ jobs:
merge-reports:
name: Merge reports
if: ${{ !cancelled() && needs.check-label.outputs.run-e2e == 'true' && needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
needs: [changes, check-label, e2e, e2e-embed, e2e-embed-react, e2e-app-store, e2e-atoms]
needs: [changes, check-label, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
uses: ./.github/workflows/merge-reports.yml
secrets: inherit
@@ -255,8 +248,7 @@ jobs:
e2e-api-v2,
e2e-embed,
e2e-embed-react,
e2e-app-store,
e2e-atoms,
e2e-app-store
]
if: always()
runs-on: buildjet-2vcpu-ubuntu-2204
+1 -1
View File
@@ -21,4 +21,4 @@ jobs:
working-directory: apps/api/v2
run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn test
yarn workspace @calcom/platform-libraries build && yarn test
+2 -1
View File
@@ -66,7 +66,8 @@ tsconfig.tsbuildinfo
.turbo
# Prisma generated files
packages/prisma/zod/*.ts
packages/prisma/client/*
packages/prisma/zod/**/*.ts
packages/prisma/enums
# Builds
-1
View File
@@ -1 +0,0 @@
20
-1
View File
@@ -16,5 +16,4 @@ public
packages/prisma/zod
packages/prisma/enums
apps/web/public/embed
apps/api/v2/swagger/documentation.json
packages/ui/components/icon/dynamicIconImports.tsx
View File
+2
View File
@@ -0,0 +1,2 @@
undecided:
- calcom-monorepo
View File
View File
View File
View File
View File
View File
View File
+2
View File
@@ -0,0 +1,2 @@
undecided:
- calcom-monorepo
View File
+3
View File
@@ -0,0 +1,3 @@
undecided:
- calcom-monorepo
- "@calcom/app-store"
View File
+2
View File
@@ -0,0 +1,2 @@
undecided:
- "@calcom/prisma"
View File
View File
View File
+2
View File
@@ -0,0 +1,2 @@
undecided:
- calcom-monorepo
View File
+3
View File
@@ -0,0 +1,3 @@
undecided:
- calcom-monorepo
- "@calcom/prisma"
View File
+10
View File
@@ -13,6 +13,16 @@
- `yarn test <filename> -- --integrationTestsOnly` - Run integration tests
- `yarn e2e <filename> --grep "<testName>"` - Run specific E2E test
## Tool Preferences
### Search Tools Priority
Use tools in this order of preference:
1. **ast-grep** - For AST-based code searches (if available)
2. **rg (ripgrep)** - For fast text searches
3. **grep** - As fallback for text searches
## 📚 Detailed Documentation
- **[.agents/README.md](.agents/README.md)** - Complete development guide
+3
View File
@@ -13,5 +13,8 @@
"connect": "^3.7.0",
"http": "^0.0.1-security",
"http-proxy-middleware": "^2.0.6"
},
"devDependencies": {
"@calcom/eslint-config": "workspace:*"
}
}
+3
View File
@@ -0,0 +1,3 @@
import { nextJsConfig } from "@calcom/eslint-config/next-js";
export default nextJsConfig;
+2 -8
View File
@@ -1,20 +1,14 @@
import { captureException as SentryCaptureException } from "@sentry/nextjs";
import type { NextMiddleware } from "next-api-middleware";
import { redactError } from "@calcom/lib/redactError";
export const captureErrors: NextMiddleware = async (_req, res, next) => {
try {
// Catch any errors that are thrown in remaining
// middleware and the API route handler
await next();
} catch (error) {
console.error(error);
SentryCaptureException(error);
const redactedError = redactError(error);
if (redactedError instanceof Error) {
res.status(400).json({ message: redactedError.message, error: redactedError });
return;
}
res.status(400).json({ message: "Something went wrong", error });
res.status(500).json({ message: "Something went wrong" });
}
};
@@ -4,7 +4,7 @@ import type { NextApiResponse, NextApiRequest } from "next";
import { createMocks } from "node-mocks-http";
import { describe, it, expect, vi } from "vitest";
import { handleAutoLock } from "@calcom/lib/autoLock";
import { handleAutoLock } from "@calcom/features/ee/api-keys/lib/autoLock";
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
import { HttpError } from "@calcom/lib/http-error";
@@ -19,7 +19,7 @@ vi.mock("@calcom/lib/checkRateLimitAndThrowError", () => ({
checkRateLimitAndThrowError: vi.fn(),
}));
vi.mock("@calcom/lib/autoLock", () => ({
vi.mock("@calcom/features/ee/api-keys/lib/autoLock", () => ({
handleAutoLock: vi.fn(),
}));
@@ -30,7 +30,7 @@ describe("rateLimitApiKey middleware", () => {
query: {},
userId: testUserId,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(res._getStatusCode()).toBe(401);
@@ -43,7 +43,7 @@ describe("rateLimitApiKey middleware", () => {
query: { apiKey: "test-key" },
userId: testUserId,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockResolvedValueOnce({
limit: 100,
remaining: 99,
@@ -51,6 +51,7 @@ describe("rateLimitApiKey middleware", () => {
});
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(checkRateLimitAndThrowError).toHaveBeenCalledWith({
@@ -74,15 +75,14 @@ describe("rateLimitApiKey middleware", () => {
success: true,
};
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockImplementationOnce(
({ onRateLimiterResponse }: { onRateLimiterResponse: (response: RatelimitResponse) => void }) => {
onRateLimiterResponse(rateLimiterResponse);
}
);
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(res.getHeader("X-RateLimit-Limit")).toBe(rateLimiterResponse.limit);
@@ -96,10 +96,11 @@ describe("rateLimitApiKey middleware", () => {
query: { apiKey: "test-key" },
userId: testUserId,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockRejectedValue(new Error("Rate limit exceeded"));
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(res._getStatusCode()).toBe(429);
@@ -121,6 +122,7 @@ describe("rateLimitApiKey middleware", () => {
};
// Mock rate limiter to trigger the onRateLimiterResponse callback
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockImplementationOnce(
({ onRateLimiterResponse }: { onRateLimiterResponse: (response: RatelimitResponse) => void }) => {
onRateLimiterResponse(rateLimiterResponse);
@@ -131,6 +133,7 @@ describe("rateLimitApiKey middleware", () => {
vi.mocked(handleAutoLock).mockResolvedValueOnce(true);
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(handleAutoLock).toHaveBeenCalledWith({
@@ -158,6 +161,7 @@ describe("rateLimitApiKey middleware", () => {
};
// Mock rate limiter to trigger the onRateLimiterResponse callback
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockImplementationOnce(
({ onRateLimiterResponse }: { onRateLimiterResponse: (response: RatelimitResponse) => void }) => {
onRateLimiterResponse(rateLimiterResponse);
@@ -168,6 +172,7 @@ describe("rateLimitApiKey middleware", () => {
vi.mocked(handleAutoLock).mockRejectedValueOnce(new Error("No user found for this API key."));
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(handleAutoLock).toHaveBeenCalledWith({
@@ -195,6 +200,7 @@ describe("rateLimitApiKey middleware", () => {
};
// Mock rate limiter to trigger the onRateLimiterResponse callback
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(checkRateLimitAndThrowError as any).mockImplementationOnce(
({ onRateLimiterResponse }: { onRateLimiterResponse: (response: RatelimitResponse) => void }) => {
onRateLimiterResponse(rateLimiterResponse);
@@ -235,6 +241,7 @@ describe("rateLimitApiKey middleware", () => {
);
// @ts-expect-error weird typing between middleware and createMocks
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await rateLimitApiKey(req, res, vi.fn() as any);
expect(res._getStatusCode()).toBe(429);
+1 -1
View File
@@ -1,6 +1,6 @@
import type { NextMiddleware } from "next-api-middleware";
import { handleAutoLock } from "@calcom/lib/autoLock";
import { handleAutoLock } from "@calcom/features/ee/api-keys/lib/autoLock";
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
import { HttpError } from "@calcom/lib/http-error";
+89 -63
View File
@@ -1,19 +1,42 @@
import prismock from "../../../../../tests/libs/__mocks__/prisma";
/**
* Unit Tests for verifyApiKey middleware
*
* These tests verify the middleware logic without touching the database.
* All dependencies (repositories, utilities) are mocked.
*/
import type { Request, Response } from "express";
import type { NextApiRequest, NextApiResponse } from "next";
import { createMocks } from "node-mocks-http";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ILicenseKeyService } from "@calcom/ee/common/server/LicenseKeyService";
import LicenseKeyService from "@calcom/ee/common/server/LicenseKeyService";
import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys";
import LicenseKeyService, { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService";
import { PrismaApiKeyRepository } from "@calcom/lib/server/repository/PrismaApiKeyRepository";
import type { IDeploymentRepository } from "@calcom/lib/server/repository/deployment.interface";
import prisma from "@calcom/prisma";
import { MembershipRole, UserPermissionRole } from "@calcom/prisma/enums";
import { ApiKeyService } from "@calcom/lib/server/service/ApiKeyService";
import { UserPermissionRole } from "@calcom/prisma/enums";
import { isAdminGuard } from "../utils/isAdmin";
import { isLockedOrBlocked } from "../utils/isLockedOrBlocked";
import { ScopeOfAdmin } from "../utils/scopeOfAdmin";
import { verifyApiKey } from "./verifyApiKey";
vi.mock("@calcom/lib/server/service/ApiKeyService", () => ({
ApiKeyService: vi.fn(),
}));
vi.mock("@calcom/lib/server/repository/PrismaApiKeyRepository", () => ({
PrismaApiKeyRepository: vi.fn(),
}));
vi.mock("../utils/isAdmin", () => ({
isAdminGuard: vi.fn(),
}));
vi.mock("../utils/isLockedOrBlocked", () => ({
isLockedOrBlocked: vi.fn(),
}));
vi.mock("@calcom/lib/crypto", () => ({
symmetricDecrypt: vi.fn().mockReturnValue("mocked-decrypted-value"),
symmetricEncrypt: vi.fn().mockReturnValue("mocked-encrypted-value"),
@@ -32,17 +55,29 @@ afterEach(() => {
});
const mockDeploymentRepository: IDeploymentRepository = {
getLicenseKeyWithId: vi.fn().mockResolvedValue("mockLicenseKey"), // Mocked return value
getLicenseKeyWithId: vi.fn().mockResolvedValue("mockLicenseKey"),
getSignatureToken: vi.fn().mockResolvedValue("mockSignatureToken"),
};
describe("Verify API key", () => {
describe("Verify API key - Unit Tests", () => {
let service: ILicenseKeyService;
let mockApiKeyService: ApiKeyService;
beforeEach(async () => {
service = await LicenseKeyService.create(mockDeploymentRepository);
vi.spyOn(service, "checkLicense");
vi.spyOn(LicenseKeySingleton, "getInstance").mockResolvedValue(service as LicenseKeyService);
mockApiKeyService = {
verifyKeyByHashedKey: vi.fn(),
} as unknown as ApiKeyService;
vi.mocked(ApiKeyService).mockImplementation(() => mockApiKeyService);
vi.mocked(PrismaApiKeyRepository).mockImplementation(() => ({} as unknown as PrismaApiKeyRepository));
vi.mocked(isAdminGuard).mockReset();
vi.mocked(isLockedOrBlocked).mockReset();
});
it("should throw an error if the api key is not valid", async () => {
@@ -98,22 +133,25 @@ describe("Verify API key", () => {
query: {
apiKey: "cal_test_key",
},
prisma,
});
const hashedKey = hashAPIKey("test_key");
await prismock.apiKey.create({
data: {
hashedKey,
user: {
create: {
email: "admin@example.com",
role: UserPermissionRole.ADMIN,
locked: false,
},
},
vi.mocked(mockApiKeyService.verifyKeyByHashedKey).mockResolvedValue({
valid: true,
userId: 1,
user: {
role: UserPermissionRole.ADMIN,
locked: false,
email: "admin@example.com",
},
});
vi.mocked(isAdminGuard).mockResolvedValue({
isAdmin: true,
scope: ScopeOfAdmin.SystemWide,
});
vi.mocked(isLockedOrBlocked).mockResolvedValue(false);
const middleware = {
fn: verifyApiKey,
};
@@ -139,40 +177,25 @@ describe("Verify API key", () => {
query: {
apiKey: "cal_test_key",
},
prisma,
});
const hashedKey = hashAPIKey("test_key");
await prismock.apiKey.create({
data: {
hashedKey,
user: {
create: {
email: "org-admin@acme.com",
role: UserPermissionRole.USER,
locked: false,
teams: {
create: {
accepted: true,
role: MembershipRole.OWNER,
team: {
create: {
name: "ACME",
isOrganization: true,
organizationSettings: {
create: {
isAdminAPIEnabled: true,
orgAutoAcceptEmail: "acme.com",
},
},
},
},
},
},
},
},
vi.mocked(mockApiKeyService.verifyKeyByHashedKey).mockResolvedValue({
valid: true,
userId: 2,
user: {
role: UserPermissionRole.USER,
locked: false,
email: "org-admin@acme.com",
},
});
vi.mocked(isAdminGuard).mockResolvedValue({
isAdmin: true,
scope: ScopeOfAdmin.OrgOwnerOrAdmin,
});
vi.mocked(isLockedOrBlocked).mockResolvedValue(false);
const middleware = {
fn: verifyApiKey,
};
@@ -198,22 +221,25 @@ describe("Verify API key", () => {
query: {
apiKey: "cal_test_key",
},
prisma,
});
const hashedKey = hashAPIKey("test_key");
await prismock.apiKey.create({
data: {
hashedKey,
user: {
create: {
email: "locked@example.com",
role: UserPermissionRole.USER,
locked: true,
},
},
vi.mocked(mockApiKeyService.verifyKeyByHashedKey).mockResolvedValue({
valid: true,
userId: 3,
user: {
role: UserPermissionRole.USER,
locked: true,
email: "locked@example.com",
},
});
vi.mocked(isAdminGuard).mockResolvedValue({
isAdmin: false,
scope: ScopeOfAdmin.SystemWide,
});
vi.mocked(isLockedOrBlocked).mockResolvedValue(true);
const middleware = {
fn: verifyApiKey,
};
+13 -24
View File
@@ -3,21 +3,15 @@ import type { NextMiddleware } from "next-api-middleware";
import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService";
import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys";
import { IS_PRODUCTION } from "@calcom/lib/constants";
import { PrismaApiKeyRepository } from "@calcom/lib/server/repository/PrismaApiKeyRepository";
import { DeploymentRepository } from "@calcom/lib/server/repository/deployment";
import prisma from "@calcom/prisma";
import { ApiKeyService } from "@calcom/lib/server/service/ApiKeyService";
import { prisma } from "@calcom/prisma";
import { isAdminGuard } from "../utils/isAdmin";
import { isLockedOrBlocked } from "../utils/isLockedOrBlocked";
import { ScopeOfAdmin } from "../utils/scopeOfAdmin";
// Used to check if the apiKey is not expired, could be extracted if reused. but not for now.
export const dateNotInPast = function (date: Date) {
const now = new Date();
if (now.setHours(0, 0, 0, 0) > date.setHours(0, 0, 0, 0)) {
return true;
}
};
// This verifies the apiKey and sets the user if it is valid.
export const verifyApiKey: NextMiddleware = async (req, res, next) => {
const deploymentRepo = new DeploymentRepository(prisma);
@@ -32,24 +26,19 @@ export const verifyApiKey: NextMiddleware = async (req, res, next) => {
const strippedApiKey = `${req.query.apiKey}`.replace(process.env.API_KEY_PREFIX || "cal_", "");
const hashedKey = hashAPIKey(strippedApiKey);
const apiKey = await prisma.apiKey.findUnique({
where: { hashedKey },
include: {
user: {
select: { role: true, locked: true, email: true },
},
},
});
if (!apiKey) return res.status(401).json({ error: "Your API key is not valid." });
if (apiKey.expiresAt && dateNotInPast(apiKey.expiresAt)) {
return res.status(401).json({ error: "This API key is expired." });
// Use service layer for API key verification
const apiKeyRepo = new PrismaApiKeyRepository(prisma);
const apiKeyService = new ApiKeyService({ apiKeyRepo });
const result = await apiKeyService.verifyKeyByHashedKey(hashedKey);
if (!result.valid) {
return res.status(401).json({ error: result.error });
}
if (!apiKey.userId || !apiKey.user)
return res.status(404).json({ error: "No user found for this API key." });
// save the user id in the request for later use
req.userId = apiKey.userId;
req.user = apiKey.user;
req.userId = result.userId!;
req.user = result.user!;
const { isAdmin, scope } = await isAdminGuard(req);
const userIsLockedOrBlocked = await isLockedOrBlocked(req);
+68
View File
@@ -0,0 +1,68 @@
import type { Prisma } from "@calcom/prisma/client";
export const eventTypeSelect = {
id: true,
title: true,
slug: true,
length: true,
hidden: true,
position: true,
userId: true,
teamId: true,
scheduleId: true,
eventName: true,
timeZone: true,
periodType: true,
periodStartDate: true,
periodEndDate: true,
periodDays: true,
periodCountCalendarDays: true,
requiresConfirmation: true,
recurringEvent: true,
disableGuests: true,
hideCalendarNotes: true,
minimumBookingNotice: true,
beforeEventBuffer: true,
afterEventBuffer: true,
schedulingType: true,
price: true,
currency: true,
slotInterval: true,
parentId: true,
successRedirectUrl: true,
description: true,
locations: true,
metadata: true,
seatsPerTimeSlot: true,
seatsShowAttendees: true,
seatsShowAvailabilityCount: true,
bookingFields: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
customInputs: {
select: { id: true, label: true, required: true, options: true, type: true, placeholder: true },
},
hashedLink: {
select: { link: true },
},
team: {
select: { slug: true },
},
hosts: {
select: {
userId: true,
isFixed: true,
scheduleId: true,
},
},
owner: {
select: { username: true, id: true },
},
children: {
select: {
id: true,
userId: true,
},
},
} satisfies Prisma.EventTypeSelect;
+9 -1
View File
@@ -1,9 +1,17 @@
import type { NextApiRequest } from "next";
import { sentrySpan } from "@calcom/features/watchlist/lib/telemetry";
import { checkIfEmailIsBlockedInWatchlistController } from "@calcom/features/watchlist/operations/check-if-email-in-watchlist.controller";
export async function isLockedOrBlocked(req: NextApiRequest) {
const user = req.user;
if (!user?.email) return false;
return user.locked || (await checkIfEmailIsBlockedInWatchlistController(user.email));
return (
user.locked ||
(await checkIfEmailIsBlockedInWatchlistController({
email: user.email,
organizationId: null,
span: sentrySpan,
}))
);
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { z } from "zod";
import { _ApiKeyModel as ApiKey } from "@calcom/prisma/zod";
import { ApiKeySchema as ApiKey } from "@calcom/prisma/zod/modelSchema/ApiKeySchema";
export const apiKeyCreateBodySchema = ApiKey.pick({
note: true,
+3 -3
View File
@@ -1,11 +1,11 @@
import { z } from "zod";
import { emailSchema } from "@calcom/lib/emailSchema";
import { _AttendeeModel as Attendee } from "@calcom/prisma/zod";
import { AttendeeSchema } from "@calcom/prisma/zod/modelSchema/AttendeeSchema";
import { timeZone } from "~/lib/validations/shared/timeZone";
export const schemaAttendeeBaseBodyParams = Attendee.pick({
export const schemaAttendeeBaseBodyParams = AttendeeSchema.pick({
bookingId: true,
email: true,
name: true,
@@ -31,7 +31,7 @@ const schemaAttendeeEditParams = z
export const schemaAttendeeEditBodyParams = schemaAttendeeBaseBodyParams.merge(schemaAttendeeEditParams);
export const schemaAttendeeCreateBodyParams = schemaAttendeeBaseBodyParams.merge(schemaAttendeeCreateParams);
export const schemaAttendeeReadPublic = Attendee.pick({
export const schemaAttendeeReadPublic = AttendeeSchema.pick({
id: true,
bookingId: true,
name: true,
+5 -4
View File
@@ -1,16 +1,17 @@
import { z } from "zod";
import { _AvailabilityModel as Availability, _ScheduleModel as Schedule } from "@calcom/prisma/zod";
import { denullishShape } from "@calcom/prisma/zod-utils";
import { AvailabilitySchema } from "@calcom/prisma/zod/modelSchema/AvailabilitySchema";
import { ScheduleSchema } from "@calcom/prisma/zod/modelSchema/ScheduleSchema";
export const schemaAvailabilityBaseBodyParams = /** We make all these properties required */ denullishShape(
Availability.pick({
AvailabilitySchema.pick({
/** We need to pass the schedule where this availability belongs to */
scheduleId: true,
})
);
export const schemaAvailabilityReadPublic = Availability.pick({
export const schemaAvailabilityReadPublic = AvailabilitySchema.pick({
id: true,
startTime: true,
endTime: true,
@@ -19,7 +20,7 @@ export const schemaAvailabilityReadPublic = Availability.pick({
days: true,
// eventTypeId: true /** @deprecated */,
// userId: true /** @deprecated */,
}).merge(z.object({ success: z.boolean().optional(), Schedule: Schedule.partial() }).partial());
}).merge(z.object({ success: z.boolean().optional(), Schedule: ScheduleSchema.partial() }).partial());
const schemaAvailabilityCreateParams = z
.object({
@@ -1,7 +1,7 @@
import { _BookingReferenceModel as BookingReference } from "@calcom/prisma/zod";
import { denullishShape } from "@calcom/prisma/zod-utils";
import { BookingReferenceSchema } from "@calcom/prisma/zod/modelSchema/BookingReferenceSchema";
export const schemaBookingReferenceBaseBodyParams = BookingReference.pick({
export const schemaBookingReferenceBaseBodyParams = BookingReferenceSchema.pick({
type: true,
bookingId: true,
uid: true,
@@ -11,7 +11,7 @@ export const schemaBookingReferenceBaseBodyParams = BookingReference.pick({
deleted: true,
}).partial();
export const schemaBookingReferenceReadPublic = BookingReference.pick({
export const schemaBookingReferenceReadPublic = BookingReferenceSchema.pick({
id: true,
type: true,
bookingId: true,
@@ -22,7 +22,7 @@ export const schemaBookingReferenceReadPublic = BookingReference.pick({
deleted: true,
});
export const schemaBookingCreateBodyParams = BookingReference.omit({ id: true, bookingId: true })
.merge(denullishShape(BookingReference.pick({ bookingId: true })))
export const schemaBookingCreateBodyParams = BookingReferenceSchema.omit({ id: true, bookingId: true })
.merge(denullishShape(BookingReferenceSchema.pick({ bookingId: true })))
.strict();
export const schemaBookingEditBodyParams = schemaBookingCreateBodyParams.partial();
+25 -25
View File
@@ -1,15 +1,13 @@
import { z } from "zod";
import {
_AttendeeModel,
_BookingModel as Booking,
_EventTypeModel,
_PaymentModel,
_TeamModel,
_UserModel,
} from "@calcom/prisma/zod";
import { extendedBookingCreateBody } from "@calcom/features/bookings/lib/bookingCreateBodySchema";
import { iso8601 } from "@calcom/prisma/zod-utils";
import { extendedBookingCreateBody } from "@calcom/prisma/zod/custom/booking";
import { AttendeeSchema } from "@calcom/prisma/zod/modelSchema/AttendeeSchema";
import { BookingSchema as Booking } from "@calcom/prisma/zod/modelSchema/BookingSchema";
import { EventTypeSchema } from "@calcom/prisma/zod/modelSchema/EventTypeSchema";
import { PaymentSchema } from "@calcom/prisma/zod/modelSchema/PaymentSchema";
import { TeamSchema } from "@calcom/prisma/zod/modelSchema/TeamSchema";
import { UserSchema } from "@calcom/prisma/zod/modelSchema/UserSchema";
import { schemaQueryUserId } from "./shared/queryUserId";
@@ -72,17 +70,16 @@ export const schemaBookingEditBodyParams = schemaBookingBaseBodyParams
.merge(schemaBookingEditParams)
.omit({ uid: true });
const teamSchema = _TeamModel.pick({
const teamSchema = TeamSchema.pick({
name: true,
slug: true,
});
export const schemaBookingReadPublic = Booking.extend({
eventType: _EventTypeModel
.pick({
title: true,
slug: true,
})
eventType: EventTypeSchema.pick({
title: true,
slug: true,
})
.merge(
z.object({
team: teamSchema.nullish(),
@@ -91,7 +88,7 @@ export const schemaBookingReadPublic = Booking.extend({
.nullish(),
attendees: z
.array(
_AttendeeModel.pick({
AttendeeSchema.pick({
id: true,
email: true,
name: true,
@@ -100,17 +97,15 @@ export const schemaBookingReadPublic = Booking.extend({
})
)
.optional(),
user: _UserModel
.pick({
email: true,
name: true,
timeZone: true,
locale: true,
})
.nullish(),
user: UserSchema.pick({
email: true,
name: true,
timeZone: true,
locale: true,
}).nullish(),
payment: z
.array(
_PaymentModel.pick({
PaymentSchema.pick({
id: true,
success: true,
paymentOption: true,
@@ -140,3 +135,8 @@ export const schemaBookingReadPublic = Booking.extend({
rescheduledBy: true,
createdAt: true,
});
export {
bookingCreateSchemaLegacyPropsForApi,
bookingCreateBodySchemaForApi,
} from "@calcom/features/bookings/lib/bookingCreateBodySchema";
@@ -1,8 +1,8 @@
import { z } from "zod";
import { _DestinationCalendarModel as DestinationCalendar } from "@calcom/prisma/zod";
import { DestinationCalendarSchema } from "@calcom/prisma/zod/modelSchema/DestinationCalendarSchema";
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendar.pick({
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendarSchema.pick({
integration: true,
externalId: true,
eventTypeId: true,
@@ -38,7 +38,7 @@ export const schemaDestinationCalendarEditBodyParams = schemaDestinationCalendar
schemaDestinationCalendarEditParams
);
export const schemaDestinationCalendarReadPublic = DestinationCalendar.pick({
export const schemaDestinationCalendarReadPublic = DestinationCalendarSchema.pick({
id: true,
integration: true,
externalId: true,
@@ -1,10 +1,10 @@
import { _EventTypeCustomInputModel as EventTypeCustomInput } from "@calcom/prisma/zod";
import { EventTypeCustomInputSchema } from "@calcom/prisma/zod/modelSchema/EventTypeCustomInputSchema";
export const schemaEventTypeCustomInputBaseBodyParams = EventTypeCustomInput.omit({
export const schemaEventTypeCustomInputBaseBodyParams = EventTypeCustomInputSchema.omit({
id: true,
});
export const schemaEventTypeCustomInputPublic = EventTypeCustomInput.omit({});
export const schemaEventTypeCustomInputPublic = EventTypeCustomInputSchema.omit({});
export const schemaEventTypeCustomInputBodyParams = schemaEventTypeCustomInputBaseBodyParams.strict();
+5 -69
View File
@@ -6,12 +6,12 @@ import {
MIN_EVENT_DURATION_MINUTES,
} from "@calcom/lib/constants";
import slugify from "@calcom/lib/slugify";
import { _EventTypeModel as EventType, _HostModel } from "@calcom/prisma/zod";
import { customInputSchema, eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import { EventTypeSchema } from "@calcom/prisma/zod/modelSchema/EventTypeSchema";
import { HostSchema } from "@calcom/prisma/zod/modelSchema/HostSchema";
import { Frequency } from "~/lib/types";
import { jsonSchema } from "./shared/jsonSchema";
import { schemaQueryUserId } from "./shared/queryUserId";
import { timeZone } from "./shared/timeZone";
@@ -24,7 +24,7 @@ const recurringEventInputSchema = z.object({
tzid: timeZone.optional(),
});
const hostSchema = _HostModel.pick({
const hostSchema = HostSchema.pick({
isFixed: true,
userId: true,
scheduleId: true,
@@ -35,7 +35,7 @@ export const childrenSchema = z.object({
userId: z.number().int(),
});
export const schemaEventTypeBaseBodyParams = EventType.pick({
export const schemaEventTypeBaseBodyParams = EventTypeSchema.pick({
title: true,
description: true,
slug: true,
@@ -117,67 +117,3 @@ const schemaEventTypeEditParams = z
.strict();
export const schemaEventTypeEditBodyParams = schemaEventTypeBaseBodyParams.merge(schemaEventTypeEditParams);
export const schemaEventTypeReadPublic = EventType.pick({
id: true,
title: true,
slug: true,
length: true,
hidden: true,
position: true,
userId: true,
teamId: true,
scheduleId: true,
eventName: true,
timeZone: true,
periodType: true,
periodStartDate: true,
periodEndDate: true,
periodDays: true,
periodCountCalendarDays: true,
requiresConfirmation: true,
recurringEvent: true,
disableGuests: true,
hideCalendarNotes: true,
minimumBookingNotice: true,
beforeEventBuffer: true,
afterEventBuffer: true,
schedulingType: true,
price: true,
currency: true,
slotInterval: true,
parentId: true,
successRedirectUrl: true,
description: true,
locations: true,
metadata: true,
seatsPerTimeSlot: true,
seatsShowAttendees: true,
seatsShowAvailabilityCount: true,
bookingFields: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
}).merge(
z.object({
children: z.array(childrenSchema).optional().default([]),
hosts: z.array(hostSchema).optional().default([]),
locations: z
.array(
z.object({
link: z.string().optional(),
address: z.string().optional(),
hostPhoneNumber: z.string().optional(),
type: z.any().optional(),
})
)
.nullable(),
metadata: jsonSchema.nullable(),
customInputs: customInputSchema.array().optional(),
link: z.string().optional(),
hashedLink: z
.array(z.object({ link: z.string() }))
.optional()
.default([]),
bookingFields: eventTypeBookingFields.optional().nullable(),
})
);
+12 -5
View File
@@ -1,19 +1,24 @@
import { z } from "zod";
import { MembershipRole } from "@calcom/prisma/enums";
import { _MembershipModel as Membership, _TeamModel } from "@calcom/prisma/zod";
import { stringOrNumber } from "@calcom/prisma/zod-utils";
import { MembershipSchema } from "@calcom/prisma/zod/modelSchema/MembershipSchema";
import { TeamSchema } from "@calcom/prisma/zod/modelSchema/TeamSchema";
import { schemaQueryIdAsString } from "~/lib/validations/shared/queryIdString";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
export const schemaMembershipBaseBodyParams = Membership.omit({});
export const schemaMembershipBaseBodyParams = MembershipSchema.omit({});
const schemaMembershipRequiredParams = z.object({
teamId: z.number(),
});
export const membershipCreateBodySchema = Membership.omit({ id: true })
export const membershipCreateBodySchema = MembershipSchema.omit({
id: true,
createdAt: true,
updatedAt: true,
})
.partial({
accepted: true,
role: true,
@@ -26,11 +31,13 @@ export const membershipCreateBodySchema = Membership.omit({ id: true })
...v,
}));
export const membershipEditBodySchema = Membership.omit({
export const membershipEditBodySchema = MembershipSchema.omit({
/** To avoid complication, let's avoid updating these, instead you can delete and create a new invite */
teamId: true,
userId: true,
id: true,
createdAt: true,
updatedAt: true,
})
.partial({
accepted: true,
@@ -43,7 +50,7 @@ export const schemaMembershipBodyParams = schemaMembershipBaseBodyParams.merge(
schemaMembershipRequiredParams
);
export const schemaMembershipPublic = Membership.merge(z.object({ team: _TeamModel }).partial());
export const schemaMembershipPublic = MembershipSchema.merge(z.object({ team: TeamSchema }).partial());
/** We extract userId and teamId from compound ID string */
export const membershipIdSchema = schemaQueryIdAsString
+2 -2
View File
@@ -1,6 +1,6 @@
import { _PaymentModel as Payment } from "@calcom/prisma/zod";
import { PaymentSchema } from "@calcom/prisma/zod/modelSchema/PaymentSchema";
export const schemaPaymentPublic = Payment.pick({
export const schemaPaymentPublic = PaymentSchema.pick({
id: true,
amount: true,
success: true,
+3 -3
View File
@@ -1,10 +1,10 @@
import { z } from "zod";
import { _ReminderMailModel as ReminderMail } from "@calcom/prisma/zod";
import { ReminderMailSchema } from "@calcom/prisma/zod/modelSchema/ReminderMailSchema";
export const schemaReminderMailBaseBodyParams = ReminderMail.omit({ id: true }).partial();
export const schemaReminderMailBaseBodyParams = ReminderMailSchema.omit({ id: true }).partial();
export const schemaReminderMailPublic = ReminderMail.omit({});
export const schemaReminderMailPublic = ReminderMailSchema.omit({});
const schemaReminderMailRequiredParams = z.object({
referenceId: z.number().int(),
+5 -4
View File
@@ -1,11 +1,12 @@
import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { _ScheduleModel as Schedule, _AvailabilityModel as Availability } from "@calcom/prisma/zod";
import { AvailabilitySchema } from "@calcom/prisma/zod/modelSchema/AvailabilitySchema";
import { ScheduleSchema } from "@calcom/prisma/zod/modelSchema/ScheduleSchema";
import { timeZone } from "./shared/timeZone";
const schemaScheduleBaseBodyParams = Schedule.omit({ id: true, timeZone: true }).partial();
const schemaScheduleBaseBodyParams = ScheduleSchema.omit({ id: true, timeZone: true }).partial();
export const schemaSingleScheduleBodyParams = schemaScheduleBaseBodyParams.merge(
z.object({ userId: z.number().optional(), timeZone: timeZone.optional() })
@@ -17,12 +18,12 @@ export const schemaCreateScheduleBodyParams = schemaScheduleBaseBodyParams.merge
export const schemaSchedulePublic = z
.object({ id: z.number() })
.merge(Schedule)
.merge(ScheduleSchema)
.merge(
z.object({
availability: z
.array(
Availability.pick({
AvailabilitySchema.pick({
id: true,
eventTypeId: true,
date: true,
@@ -1,28 +1,22 @@
import z from "zod";
import { _SelectedCalendarModel as SelectedCalendar } from "@calcom/prisma/zod";
import { SelectedCalendarSchema } from "@calcom/prisma/zod/modelSchema/SelectedCalendarSchema";
import { schemaQueryIdAsString } from "./shared/queryIdString";
import { schemaQueryIdParseInt } from "./shared/queryIdTransformParseInt";
export const schemaSelectedCalendarBaseBodyParams = SelectedCalendar;
export const schemaSelectedCalendarBaseBodyParams = SelectedCalendarSchema;
export const schemaSelectedCalendarPublic = SelectedCalendar.omit({});
export const schemaSelectedCalendarPublic = SelectedCalendarSchema.omit({});
export const schemaSelectedCalendarBodyParams = schemaSelectedCalendarBaseBodyParams
.partial({
.pick({
integration: true,
externalId: true,
userId: true,
})
.omit({
// id will be set by the database
id: true,
// No eventTypeId support in API v1
eventTypeId: true,
/** No watch related fields support in API v1 */
watchAttempts: true,
unwatchAttempts: true,
maxAttempts: true,
.partial({
userId: true,
});
export const schemaSelectedCalendarUpdateBodyParams = schemaSelectedCalendarBaseBodyParams
+3 -3
View File
@@ -1,8 +1,8 @@
import { z } from "zod";
import { _TeamModel as Team } from "@calcom/prisma/zod";
import { TeamSchema } from "@calcom/prisma/zod/modelSchema/TeamSchema";
export const schemaTeamBaseBodyParams = Team.omit({ id: true, createdAt: true }).partial({
export const schemaTeamBaseBodyParams = TeamSchema.omit({ id: true, createdAt: true }).partial({
hideBranding: true,
metadata: true,
pendingPayment: true,
@@ -28,6 +28,6 @@ const schemaOwnerId = z.object({
export const schemaTeamCreateBodyParams = schemaTeamBodyParams.merge(schemaOwnerId).strict();
export const schemaTeamReadPublic = Team.omit({});
export const schemaTeamReadPublic = TeamSchema.omit({});
export const schemaTeamsReadPublic = z.array(schemaTeamReadPublic);
+4 -4
View File
@@ -1,9 +1,9 @@
import { z } from "zod";
import { checkUsername } from "@calcom/features/profile/lib/checkUsername";
import { emailSchema } from "@calcom/lib/emailSchema";
import { checkUsername } from "@calcom/lib/server/checkUsername";
import { _UserModel as User } from "@calcom/prisma/zod";
import { iso8601 } from "@calcom/prisma/zod-utils";
import { UserSchema } from "@calcom/prisma/zod/modelSchema/UserSchema";
import { isValidBase64Image } from "~/lib/utils/isValidBase64Image";
import { timeZone } from "~/lib/validations/shared/timeZone";
@@ -68,7 +68,7 @@ const usernameSchema = z
});
// @note: These are the values that are editable via PATCH method on the user Model
export const schemaUserBaseBodyParams = User.pick({
export const schemaUserBaseBodyParams = UserSchema.pick({
name: true,
email: true,
username: true,
@@ -151,7 +151,7 @@ export const schemaUserCreateBodyParams = schemaUserBaseBodyParams
.strict();
// @note: These are the values that are always returned when reading a user
export const schemaUserReadPublic = User.pick({
export const schemaUserReadPublic = UserSchema.pick({
id: true,
username: true,
name: true,
+3 -3
View File
@@ -1,9 +1,9 @@
import { z } from "zod";
import { WEBHOOK_TRIGGER_EVENTS } from "@calcom/features/webhooks/lib/constants";
import { _WebhookModel as Webhook } from "@calcom/prisma/zod";
import { WebhookSchema } from "@calcom/prisma/zod/modelSchema/WebhookSchema";
const schemaWebhookBaseBodyParams = Webhook.pick({
const schemaWebhookBaseBodyParams = WebhookSchema.pick({
userId: true,
eventTypeId: true,
eventTriggers: true,
@@ -38,7 +38,7 @@ export const schemaWebhookEditBodyParams = schemaWebhookBaseBodyParams
.partial()
.strict();
export const schemaWebhookReadPublic = Webhook.pick({
export const schemaWebhookReadPublic = WebhookSchema.pick({
id: true,
userId: true,
eventTypeId: true,
+7
View File
@@ -1,5 +1,6 @@
const { withAxiom } = require("next-axiom");
const { withSentryConfig } = require("@sentry/nextjs");
const { PrismaPlugin } = require("@prisma/nextjs-monorepo-workaround-plugin");
const plugins = [withAxiom];
@@ -14,6 +15,12 @@ const nextConfig = {
"@calcom/prisma",
"@calcom/trpc",
],
webpack: (config, { isServer }) => {
if (isServer) {
config.plugins = [...config.plugins, new PrismaPlugin()];
}
return config;
},
async headers() {
return [
{
+12 -10
View File
@@ -10,7 +10,7 @@
"build": "next build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
"dev": "PORT=3003 next dev",
"lint": "eslint . --ignore-path .gitignore",
"lint": "eslint .",
"lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix",
"start": "PORT=3003 next start",
"docker-start-api": "PORT=80 next start",
@@ -18,18 +18,20 @@
"type-check:ci": "tsc-absolute --pretty --noEmit"
},
"devDependencies": {
"@calcom/tsconfig": "*",
"@calcom/types": "*",
"@calcom/eslint-config": "workspace:*",
"@calcom/tsconfig": "workspace:*",
"@calcom/types": "workspace:*",
"node-mocks-http": "^1.11.0"
},
"dependencies": {
"@calcom/app-store": "*",
"@calcom/dayjs": "*",
"@calcom/emails": "*",
"@calcom/features": "*",
"@calcom/lib": "*",
"@calcom/prisma": "*",
"@calcom/trpc": "*",
"@calcom/app-store": "workspace:*",
"@calcom/dayjs": "workspace:*",
"@calcom/emails": "workspace:*",
"@calcom/features": "workspace:*",
"@calcom/lib": "workspace:*",
"@calcom/prisma": "workspace:*",
"@calcom/trpc": "workspace:*",
"@prisma/nextjs-monorepo-workaround-plugin": "^6.16.1",
"@sentry/nextjs": "^9.15.0",
"bcryptjs": "^2.4.3",
"memory-cache": "^0.2.0",
+1 -1
View File
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import type { Ensure } from "@calcom/types/utils";
import { apiKeyPublicSchema } from "~/lib/validations/api-key";
+1 -1
View File
@@ -1,4 +1,3 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { v4 } from "uuid";
@@ -6,6 +5,7 @@ import { generateUniqueAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { apiKeyCreateBodySchema, apiKeyPublicSchema } from "~/lib/validations/api-key";
+1 -1
View File
@@ -1,9 +1,9 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaAttendeeReadPublic } from "~/lib/validations/attendee";
+1 -1
View File
@@ -1,7 +1,7 @@
import type { NextApiRequest } from "next";
import { z } from "zod";
import { getUserAvailabilityService } from "@calcom/lib/di/containers/GetUserAvailability";
import { getUserAvailabilityService } from "@calcom/features/di/containers/GetUserAvailability";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import {
schemaBookingEditBodyParams,
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaBookingReferenceReadPublic } from "~/lib/validations/booking-reference";
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import {
schemaBookingCreateBodyParams,
@@ -1,7 +1,7 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import { getAccessibleUsers } from "~/lib/utils/retrieveScopedAccessibleUsers";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
@@ -34,7 +34,14 @@ async function authMiddleware(req: NextApiRequest) {
where: { id: userId },
select: {
email: true,
bookings: true,
bookings: {
where: {
id,
},
select: {
id: true,
},
},
},
});
@@ -102,8 +102,11 @@ export async function getHandler(req: NextApiRequest) {
const booking = await prisma.booking.findUnique({
where: { id },
include: {
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
attendees: true,
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
user: true,
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
payment: true,
eventType: expand.includes("team") ? { include: { team: true } } : false,
},
@@ -1,11 +1,11 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import {
getRecordingsOfCalVideoByRoomName,
getDownloadLinkOfCalVideoByRecordingId,
} from "@calcom/lib/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { RecordingItemSchema } from "@calcom/prisma/zod-utils";
import type { PartialReference } from "@calcom/types/EventManager";
@@ -63,6 +63,7 @@ export async function getHandler(req: NextApiRequest) {
const booking = await prisma.booking.findUnique({
where: { id },
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
include: { references: true },
});
@@ -1,11 +1,11 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import {
getTranscriptsAccessLinkFromRecordingId,
checkIfRoomNameMatchesInRecording,
} from "@calcom/lib/videoClient";
} from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { PartialReference } from "@calcom/types/EventManager";
@@ -61,6 +61,7 @@ export async function getHandler(req: NextApiRequest) {
const checkIfRecordingBelongsToBooking = async (bookingId: number, recordingId: string) => {
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
include: { references: true },
});
@@ -1,8 +1,8 @@
import type { NextApiRequest } from "next";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/features/conferencing/lib/videoClient";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import { getAllTranscriptsAccessLinkFromRoomName } from "@calcom/lib/videoClient";
import prisma from "@calcom/prisma";
import type { PartialReference } from "@calcom/types/EventManager";
@@ -44,6 +44,7 @@ export async function getHandler(req: NextApiRequest) {
const booking = await prisma.booking.findUnique({
where: { id },
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
include: { references: true },
});
+1 -1
View File
@@ -1,9 +1,9 @@
import type { Prisma, Booking } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma, Booking } from "@calcom/prisma/client";
import { withMiddleware } from "~/lib/helpers/withMiddleware";
import { buildWhereClause } from "~/lib/utils/bookings/get/buildWhereClause";
+8 -6
View File
@@ -1,7 +1,7 @@
import type { NextApiRequest } from "next";
import { getRegularBookingService } from "@calcom/features/bookings/di/RegularBookingService.container";
import getBookingDataSchemaForApi from "@calcom/features/bookings/lib/getBookingDataSchemaForApi";
import handleNewBooking from "@calcom/features/bookings/lib/handleNewBooking";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
@@ -239,15 +239,17 @@ async function handler(req: NextApiRequest) {
}
try {
return await handleNewBooking(
{
bookingData: req.body,
const regularBookingService = getRegularBookingService();
return await regularBookingService.createBookingForApiV1({
bookingData: req.body,
bookingMeta: {
userId,
hostname: req.headers.host || "",
forcedSlug: req.headers["x-cal-force-slug"] as string | undefined,
},
getBookingDataSchemaForApi
);
bookingDataSchemaGetter: getBookingDataSchemaForApi,
});
} catch (error: unknown) {
const knownError = error as Error;
if (knownError?.message === ErrorCode.NoAvailableUsersFound) {
@@ -1,10 +1,10 @@
import type { NextApiRequest } from "next";
import type { UserWithCalendars } from "@calcom/lib/getConnectedDestinationCalendars";
import { getConnectedDestinationCalendarsAndEnsureDefaultsInDb } from "@calcom/lib/getConnectedDestinationCalendars";
import type { UserWithCalendars } from "@calcom/features/calendars/lib/getConnectedDestinationCalendars";
import { getConnectedDestinationCalendarsAndEnsureDefaultsInDb } from "@calcom/features/calendars/lib/getConnectedDestinationCalendars";
import { UserRepository } from "@calcom/features/users/repositories/UserRepository";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import { UserRepository } from "@calcom/lib/server/repository/user";
import prisma from "@calcom/prisma";
import { extractUserIdsFromQuery } from "~/lib/utils/extractUserIdsFromQuery";
@@ -3,7 +3,8 @@ import type { NextApiRequest } from "next";
import { OAuth2UniversalSchema } from "@calcom/app-store/_utils/oauth/universalSchema";
import { symmetricDecrypt } from "@calcom/lib/crypto";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaCredentialPatchParams, schemaCredentialPatchBody } from "~/lib/validations/credential-sync";
@@ -71,7 +72,7 @@ async function handler(req: NextApiRequest) {
userId,
},
data: {
key,
key: key as unknown as Prisma.InputJsonValue,
},
select: {
id: true,
@@ -6,7 +6,8 @@ import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
import { symmetricDecrypt } from "@calcom/lib/crypto";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import { schemaCredentialPostBody, schemaCredentialPostParams } from "~/lib/validations/credential-sync";
@@ -92,7 +93,7 @@ async function handler(req: NextApiRequest) {
data: {
userId,
appId: appSlug,
key,
key: key as unknown as Prisma.InputJsonValue,
type: appMetadata.type,
},
select: credentialForCalendarServiceSelect,
@@ -80,7 +80,13 @@ export async function patchHandler(req: NextApiRequest) {
const { query } = req;
const { id } = schemaQueryIdParseInt.parse(query);
const data = schemaEventTypeCustomInputEditBodyParams.parse(req.body);
const result = await prisma.eventTypeCustomInput.update({ where: { id }, data });
const result = await prisma.eventTypeCustomInput.update({
where: { id },
data: {
...data,
options: data.options === null ? [] : data.options,
},
});
return { event_type_custom_input: schemaEventTypeCustomInputPublic.parse(result) };
}
+1 -1
View File
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaEventTypeCustomInputPublic } from "~/lib/validations/event-type-custom-input";
+5 -1
View File
@@ -92,7 +92,11 @@ async function postHandler(req: NextApiRequest) {
}
const data = await prisma.eventTypeCustomInput.create({
data: { ...body, eventType: { connect: { id: eventTypeId } } },
data: {
...body,
options: body.options === null ? [] : body.options,
eventType: { connect: { id: eventTypeId } },
},
});
return {
@@ -1,12 +1,15 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import type { z } from "zod";
import { getCalendarCredentialsWithoutDelegation, getConnectedCalendars } from "@calcom/lib/CalendarManager";
import {
getCalendarCredentialsWithoutDelegation,
getConnectedCalendars,
} from "@calcom/features/calendars/lib/CalendarManager";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { PrismaClient } from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import {
@@ -1,6 +1,9 @@
import type { NextApiRequest } from "next";
import { getCalendarCredentialsWithoutDelegation, getConnectedCalendars } from "@calcom/lib/CalendarManager";
import {
getCalendarCredentialsWithoutDelegation,
getConnectedCalendars,
} from "@calcom/features/calendars/lib/CalendarManager";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
@@ -1,8 +1,7 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
@@ -66,4 +65,4 @@ async function checkPermissions(req: NextApiRequest) {
throw new HttpError({ statusCode: 403, message: "Forbidden" });
}
export default defaultResponder(deleteHandler);
export default deleteHandler;
+15 -15
View File
@@ -1,11 +1,10 @@
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import { MembershipRole } from "@calcom/prisma/enums";
import { schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { eventTypeSelect } from "~/lib/selects/event-type";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
import { checkPermissions as canAccessTeamEventOrThrow } from "~/pages/api/teams/[teamId]/_auth-middleware";
@@ -49,15 +48,13 @@ export async function getHandler(req: NextApiRequest) {
const eventType = await prisma.eventType.findUnique({
where: { id },
include: {
customInputs: true,
hashedLink: { select: { link: true } },
team: { select: { slug: true } },
hosts: { select: { userId: true, isFixed: true } },
owner: { select: { username: true, id: true } },
children: { select: { id: true, userId: true } },
},
select: eventTypeSelect,
});
if (!eventType) {
throw new HttpError({ statusCode: 404, message: "Event type not found" });
}
await checkPermissions(req, eventType);
const link = eventType ? getCalLink(eventType) : null;
@@ -74,9 +71,12 @@ export async function getHandler(req: NextApiRequest) {
eventType.scheduleId = user.defaultScheduleId;
}
// TODO: eventType when not found should be a 404
// but API consumers may depend on the {} behaviour.
return { event_type: schemaEventTypeReadPublic.parse({ ...eventType, link }) };
return {
event_type: {
...eventType,
link,
},
};
}
type BaseEventTypeCheckPermissions = {
@@ -100,4 +100,4 @@ async function checkPermissions<T extends BaseEventTypeCheckPermissions>(
throw new HttpError({ statusCode: 403, message: "Forbidden" });
}
export default defaultResponder(getHandler);
export default getHandler;
@@ -1,14 +1,14 @@
import { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import type { z } from "zod";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import { Prisma } from "@calcom/prisma/client";
import { SchedulingType } from "@calcom/prisma/enums";
import { eventTypeSelect } from "~/lib/selects/event-type";
import type { schemaEventTypeBaseBodyParams } from "~/lib/validations/event-type";
import { schemaEventTypeEditBodyParams, schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { schemaEventTypeEditBodyParams } from "~/lib/validations/event-type";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
import ensureOnlyMembersAsHosts from "~/pages/api/event-types/_utils/ensureOnlyMembersAsHosts";
@@ -210,6 +210,7 @@ export async function patchHandler(req: NextApiRequest) {
hosts = [],
bookingLimits,
durationLimits,
locations,
/** FIXME: Updating event-type children from API not supported for now */
children: _,
...parsedBody
@@ -217,8 +218,10 @@ export async function patchHandler(req: NextApiRequest) {
const data: Prisma.EventTypeUpdateArgs["data"] = {
...parsedBody,
teamId: parsedBody.teamId === null ? undefined : parsedBody.teamId,
bookingLimits: bookingLimits === null ? Prisma.DbNull : bookingLimits,
durationLimits: durationLimits === null ? Prisma.DbNull : durationLimits,
locations: locations === null ? Prisma.DbNull : locations,
};
if (hosts) {
@@ -232,8 +235,8 @@ export async function patchHandler(req: NextApiRequest) {
};
}
await checkPermissions(req, parsedBody);
const eventType = await prisma.eventType.update({ where: { id }, data });
return { event_type: schemaEventTypeReadPublic.parse(eventType) };
const eventType = await prisma.eventType.update({ where: { id }, data, select: eventTypeSelect });
return { event_type: eventType };
}
async function checkPermissions(req: NextApiRequest, body: z.infer<typeof schemaEventTypeBaseBodyParams>) {
@@ -246,4 +249,4 @@ async function checkPermissions(req: NextApiRequest, body: z.infer<typeof schema
await checkTeamEventEditPermission(req, body);
}
export default defaultResponder(patchHandler);
export default patchHandler;
+4 -11
View File
@@ -2,10 +2,10 @@ import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import type { PrismaClient } from "@calcom/prisma";
import { schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { eventTypeSelect } from "~/lib/selects/event-type";
import { schemaQuerySlug } from "~/lib/validations/shared/querySlug";
import { schemaQuerySingleOrMultipleUserIds } from "~/lib/validations/shared/queryUserId";
@@ -54,14 +54,7 @@ async function getHandler(req: NextApiRequest) {
userId: shouldUseUserId ? { in: userIds } : undefined,
slug: slug, // slug will be undefined if not provided in query
},
include: {
customInputs: true,
hashedLink: { select: { link: true } },
team: { select: { slug: true } },
hosts: { select: { userId: true, isFixed: true } },
owner: { select: { username: true, id: true } },
children: { select: { id: true, userId: true } },
},
select: eventTypeSelect,
});
// this really should return [], but backwards compatibility..
if (data.length === 0) new HttpError({ statusCode: 404, message: "No event types were found" });
@@ -69,7 +62,7 @@ async function getHandler(req: NextApiRequest) {
event_types: (await defaultScheduleId<(typeof data)[number]>({ eventTypes: data, prisma, userIds })).map(
(eventType) => {
const link = getCalLink(eventType);
return schemaEventTypeReadPublic.parse({ ...eventType, link });
return { ...eventType, link };
}
),
};
+13 -8
View File
@@ -1,12 +1,13 @@
import { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import { prisma } from "@calcom/prisma";
import { Prisma } from "@calcom/prisma/client";
import { MembershipRole } from "@calcom/prisma/enums";
import { schemaEventTypeCreateBodyParams, schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { eventTypeSelect } from "~/lib/selects/event-type";
import { schemaEventTypeCreateBodyParams } from "~/lib/validations/event-type";
import { canUserAccessTeamWithRole } from "~/pages/api/teams/[teamId]/_auth-middleware";
import checkParentEventOwnership from "./_utils/checkParentEventOwnership";
@@ -265,14 +266,17 @@ import ensureOnlyMembersAsHosts from "./_utils/ensureOnlyMembersAsHosts";
* description: Authorization information is missing or invalid.
*/
async function postHandler(req: NextApiRequest) {
const { userId, isSystemWideAdmin, body } = req;
const { userId: ctxUserId, isSystemWideAdmin, body } = req;
const {
hosts = [],
bookingLimits,
durationLimits,
locations,
/** FIXME: Adding event-type children from API not supported for now */
children: _,
// if userId is not passed, we will use the userId from the context
userId = ctxUserId,
...parsedBody
} = schemaEventTypeCreateBodyParams.parse(body || {});
@@ -282,6 +286,7 @@ async function postHandler(req: NextApiRequest) {
users: !!parsedBody.teamId ? undefined : { connect: { id: userId } },
bookingLimits: bookingLimits === null ? Prisma.DbNull : bookingLimits,
durationLimits: durationLimits === null ? Prisma.DbNull : durationLimits,
locations: locations === null ? Prisma.DbNull : locations,
};
await checkPermissions(req);
@@ -291,8 +296,8 @@ async function postHandler(req: NextApiRequest) {
await checkUserMembership(req);
}
if (isSystemWideAdmin && parsedBody.userId && !parsedBody.teamId) {
data = { ...parsedBody, users: { connect: { id: parsedBody.userId } } };
if (isSystemWideAdmin && userId && parsedBody.teamId === undefined) {
data = { ...parsedBody, users: { connect: { id: userId } } };
}
await checkTeamEventEditPermission(req, parsedBody);
@@ -302,10 +307,10 @@ async function postHandler(req: NextApiRequest) {
data.hosts = { createMany: { data: hosts } };
}
const eventType = await prisma.eventType.create({ data, include: { hosts: true } });
const eventType = await prisma.eventType.create({ data, select: eventTypeSelect });
return {
event_type: schemaEventTypeReadPublic.parse(eventType),
event_type: eventType,
message: "Event type created successfully",
};
}
@@ -1,8 +1,8 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { membershipIdSchema, schemaMembershipPublic } from "~/lib/validations/membership";
@@ -1,9 +1,9 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import {
membershipEditBodySchema,
@@ -43,7 +43,13 @@ export async function patchHandler(req: NextApiRequest) {
const { query } = req;
const userId_teamId = membershipIdSchema.parse(query);
const data = membershipEditBodySchema.parse(req.body);
const args: Prisma.MembershipUpdateArgs = { where: { userId_teamId }, data };
const args: Prisma.MembershipUpdateArgs = {
where: { userId_teamId },
data: {
...data,
updatedAt: new Date(),
},
};
await checkPermissions(req);
+1 -1
View File
@@ -1,9 +1,9 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaMembershipPublic } from "~/lib/validations/membership";
import {
+2 -5
View File
@@ -1,9 +1,9 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { membershipCreateBodySchema, schemaMembershipPublic } from "~/lib/validations/membership";
@@ -25,10 +25,7 @@ import { membershipCreateBodySchema, schemaMembershipPublic } from "~/lib/valida
async function postHandler(req: NextApiRequest) {
const data = membershipCreateBodySchema.parse(req.body);
const args: Prisma.MembershipCreateArgs = {
data: {
createdAt: new Date(),
...data,
},
data,
};
await checkPermissions(req);
+1
View File
@@ -46,6 +46,7 @@ export async function paymentById(
if (safeQuery.success && method === "GET") {
const userWithBookings = await prisma.user.findUnique({
where: { id: userId },
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
include: { bookings: true },
});
await prisma.payment
+5 -1
View File
@@ -75,7 +75,11 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
export async function getHandler(req: NextApiRequest) {
const { query } = req;
const { id } = schemaQueryIdParseInt.parse(query);
const data = await prisma.schedule.findUniqueOrThrow({ where: { id }, include: { availability: true } });
const data = await prisma.schedule.findUniqueOrThrow({
where: { id },
// eslint-disable-next-line @calcom/eslint/no-prisma-include-true
include: { availability: true },
});
return { schedule: schemaSchedulePublic.parse(data) };
}
+1 -1
View File
@@ -1,10 +1,10 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { z } from "zod";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaSchedulePublic } from "~/lib/validations/schedule";
import { schemaQuerySingleOrMultipleUserIds } from "~/lib/validations/shared/queryUserId";
+1 -1
View File
@@ -1,10 +1,10 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server/defaultResponder";
import prisma from "@calcom/prisma";
import type { Prisma } from "@calcom/prisma/client";
import { schemaCreateScheduleBodyParams, schemaSchedulePublic } from "~/lib/validations/schedule";

Some files were not shown because too many files have changed in this diff Show More