Commit Graph
784 Commits
Author SHA1 Message Date
MorganGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
9ad8aa981a chore: deploy api v2 on vercel (#26735)
* chore: deploy api v2 on vercel

* fix: replace console.log with logger.log in Vercel handler

Address Cubic AI review feedback to use the logging framework
consistently instead of console.log in the serverless handler.

Co-Authored-By: unknown <>

* chore: enable esModuleInterop

* chore: deploy api v2 on vercel

* chore: deploy api v2 on vercel

* Update apps/api/v2/src/bootstrap.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fixup! Merge branch 'main' into deploy-api-v2-vercel

* Revert "chore: deploy api v2 on vercel"

This reverts commit 45c704a48e8396c46118069e1a25d8d7a5ee84be.

* chore: deploy api v2 on vercel

* fix: address Cubic AI review feedback in main.ts

- Replace console.log with logger.log for consistent logging
- Replace console.error with logger.error for consistent error logging
- Restore comma: true option in qs.parse to support comma-separated arrays

Co-Authored-By: unknown <>

* fix: remove comma: true from qs.parse to maintain backward compatibility

The main branch does not have comma: true in the query parser, so adding
it would be a breaking change for existing API consumers. Removing it to
maintain consistency with the current production behavior.

Co-Authored-By: unknown <>

* chore: deploy api v2 on vercel

* small fixes

* chore: add try catch around bootstrap.ts

* fix: use NestJS Logger and throw error instead of process.exit in bootstrap

- Replace console.error with logger.error for consistent logging
- Replace process.exit(1) with throw error to avoid breaking Vercel serverless instance reuse

Addresses Cubic AI review feedback (confidence 10/10 for both issues)

Co-Authored-By: unknown <>

* chore: try log redis url

* fix: sanitize REDIS_URL logging to avoid exposing credentials

Replace full REDIS_URL logging with a boolean check that only indicates
whether Redis is configured, without exposing the connection string.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* chore: remove unnecessary logs

* fix: prisma adapter

* chore: handle USE_POOL platform libraries

* fix: use JSON.stringify for Vite define value

Wrap usePool with JSON.stringify() to properly serialize the string value.
Without this, Vite injects the raw value as an identifier instead of a
string literal, breaking runtime behavior.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* fix: docker file builds

* fix: correct Dockerfile build order for platform packages

Reorder builds to match the dependency graph from dev:build script:
constants → enums → utils → types → libraries → trpc → api-v2

platform-libraries depends on the other platform packages, so they
must be built first.

Addresses Cubic AI review feedback (confidence 9/10)

Co-Authored-By: unknown <>

* fix: docker file builds

* chore: add docker build

* chore: upgrade nest/bull

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-13 11:31:21 -03:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
75d611c2e8 chore: Integrate creation/rescheduling booking audit for Recurring/regular booking/seated bookings (#26046)
* Integrate creation/rescheduling booking audit

* fix: add missing hostUserUuid to booking audit test data

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

* fix-ci

* feat: enhance booking audit with seat reference

- Added support for seat reference in booking audit actions.
- Updated localization for booking creation to include seat information.
- Modified relevant services to pass attendee seat ID during booking creation.

* fix: update test data to match schema requirements

- Add seatReferenceUid: null to default mock audit log data
- Add seatReferenceUid: null to multiple audit logs test case
- Convert SEAT_RESCHEDULED test data to use numeric timestamps instead of ISO strings

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

* Allow nullish seatReferenceUid

* feat: enhance booking audit to support rescheduledBy information

- Updated booking audit actions to include rescheduledBy details, allowing tracking of who rescheduled a booking.
- Refactored related services to accommodate the new rescheduledBy parameter in booking events.
- Adjusted type definitions and function signatures to reflect the changes in the booking audit context.

* Avoid possible run time issue

* Fix imoport path

* fix failing test due to merge from main\

* Pass useruuid

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 13:16:16 +00:00
5818da414b feat: update recording, transcript endpoint and add tests (#25771)
* feat: add tests and update endpoint

* chore: undo

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-13 09:54:23 -03:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>anik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9202028ab6 fix: resolve API v2 test flakes with cleanup and simplified slug (#26766)
* fix: resolve API v2 test flakes by using UUID-only slug

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

* fix: add beforeAll cleanup to prevent test flakes from leftover data

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 18:54:29 -03:00
Dhairyashil ShindeandGitHub e879c923ea feat(api): add bookingUrl field to event types API v2 response (#26195)
* feat(api): add bookingUrl field to event types API v2 response

Add a new bookingUrl field to EventTypeOutput_2024_06_14 that contains
the full, correct booking URL for each event type. This fixes the issue
where companion app and Chrome extension were hardcoding cal.com URLs
instead of using organization subdomains.

Changes:
- Add bookingUrl field to EventTypeOutput_2024_06_14 type definition
- Update repository to include organization data when fetching users
- Add buildBookingUrl method to compute URL using getOrgFullOrigin
- Include bookingUrl in getResponseEventType return object

The booking URL is computed using the first user's organization slug
(if any) to generate the correct subdomain URL (e.g., i.cal.com/keith/30min
for organization users instead of cal.com/keith/30min).

* fix: include organization data in getEventTypeByIdWithHosts

Update getEventTypeByIdWithHosts to use usersInclude to fetch
organization slug data, ensuring bookingUrl is computed correctly
for the GET /v2/event-types/{eventTypeId} endpoint.

* test: add unit tests and E2E assertions for bookingUrl field

* fix(api-v2): correct bookingUrl format for org users and fix double slashes

Fix issues with bookingUrl field in event types API v2 response:
- Remove trailing slashes from base URLs to prevent double slashes
- Use profile.username instead of user.username for organization users
  (profile contains clean username without org suffix)
- Include user profiles in repository queries to access profile data
- Create local org-domains utility to replace @calcom/features dependency
  which isn't available in API v2 runtime

Changes:
- Add apps/api/v2/src/lib/org-domains.ts with getOrgFullOrigin function
  adapted from @calcom/features/ee/organizations/lib/orgDomains
- Update event-types.repository.ts to include profiles in usersInclude
- Update buildBookingUrl() to prioritize profile data when available
- Update unit tests to cover organization user profile scenarios

Fixes:
- Double slashes in URLs (e.g., http://localhost:3000//user/slug)
- Incorrect username format for org users (e.g., owner1-acme instead
  of owner1)
- Missing organization subdomain in booking URLs (e.g., should be
  http://acme.localhost:3000/owner1/30min not
  http://localhost:3000/owner1-acme/30min)

* deslop ai code

* handle empty username in both code and write test for it, use select instead of include

* feat(api-v2): reuse core org domain logic for event type bookingUrl

Export getOrgFullOrigin and subdomainSuffix from @calcom/platform-libraries/organizations
to reuse existing core logic instead of duplicating it in API v2. This ensures consistency
across the codebase and reduces maintenance burden.

- Export getOrgFullOrigin and subdomainSuffix from platform-libraries/organizations
- Update output-event-types.service to import from @calcom/platform-libraries/organizations
- Remove duplicate org-domains.ts file from API v2
- Update test mocks to use platform-libraries import path
- buildBookingUrl method now uses core getOrgFullOrigin function

This addresses feedback to reuse core code rather than introducing duplicate logic.

* test(api-v2): exclude bookingUrl from output comparison in e2e test

* refactor(api-v2): reuse core logic for event type bookingUrl

Replace duplicated username/org extraction logic in buildBookingUrl with
core functions. Use getBookerBaseUrlSync from @calcom/platform-libraries/organizations
for base URL generation, and add enrichUserWithProfile method that follows
the same pattern as core's UserRepository.enrichUsersWithTheirProfiles.

The enrichment logic is applied synchronously since profiles are already
fetched by the repository, avoiding the need to make the service async.
This ensures consistency with core patterns while maintaining the existing
synchronous API contract.

- Replace getOrgFullOrigin with getBookerBaseUrlSync
- Add enrichUserWithProfile method following core enrichment pattern
- Simplify buildBookingUrl to use enriched user data
- Update tests to mock getBookerBaseUrlSync and verify enrichment flow

* trailing slash cubic comment

* address review comments

* address review comments 2

* better code

* Updated the test to give the user an organization

* address review comments again

* Revert "address review comments again"

This reverts commit 622ea3fc8dcd7f5c3113614afcfc86beadecca0e.

* allow both the full UserWithProfile and the partial EventTypeUser (from select queries) to use the same getUserMainProfile() method, eliminating code duplication without changing the performance-optimized repository queries.

* reveiw points
2026-01-12 14:57:17 -03:00
MorganandGitHub c7cd25b7d5 chore: api v2 esModuleInterop more imports (#26755) 2026-01-12 11:39:01 -03:00
MorganandGitHub 6840642cb7 chore: esModuleInterop: true api v2 tsconfig (#26752)
* chore: api v2 esModuleInterop

* chore: api v2 esModuleInterop
2026-01-12 11:24:08 -03:00
Dhairyashil ShindeandGitHub dd4e1ba11b fix: api v2 dev server error (#26748) 2026-01-12 13:33:48 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
77f59b1e4d chore: Integrate confirmation booking audit (#26523)
* chore: Integrate booking confirmation booking audit

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

* fix: Use BookingStatus type instead of string for booking.status

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

* Make booking-audit integration test utils reusable

* refactor: enhance handlePaymentSuccess to accept appSlug and actor identification

- Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext.
- Introduced getActor function to determine the actor based on appSlug and credentialId.
- Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters.
- Improved logging for missing credentialId in payment processing.
- Adjusted related schemas to ensure proper type handling for booking status and actor identification.

* fix: Correct import paths and getActor function call

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

* fix: Use ActorIdentification type instead of AuditActor in getActor

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

* fix: Add guard clause for undefined actor in fireBookingAcceptedEvent

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

* fix: Add actionSource to all confirm calls

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

* refactor: Integrate actor identification and action source updates across booking services

- Added `makeUserActor` to various booking service files to enhance actor identification.
- Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK".
- Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling.
- Improved error handling and logging for booking actions to enhance traceability.

* Remvoe formatting changes

* Add test

* refactor: Enhance booking confirmation tests and event handling

- Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings.
- Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings.
- Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability.
- Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections.

* fix tests

* refactor: Use confirmHandler directly in link and verify-booking-token routes

Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.

Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller

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

* fix ts errors due to merge frommain

* feat: introduce getAppActor utility for actor creation

This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic.

Changes:
- New file: packages/app-store/_utils/getAppActor.ts
- Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor
- Removed redundant actor creation code from these functions

* refactor: Update appSlug in payment success handlers to use appConfig.slug

This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code.

Changes:
- Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks.
- Adjusted a test case to reflect the new appSlug value for consistency.

* test: Enhance booking token verification and audit action tests

This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity.

Changes:
- Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error.
- Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`.
- Clarified comment in `actionSource.ts` regarding the schema for action sources.
- Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 08:17:26 -03:00
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c9bb03b602 chore: Integrate add guests booking audit (#26568)
* chore: Integrate add guests booking audit

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

* chore: Add actionSource parameter to support API_V2 audit logging

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

* refactor: update attendee audit action service to use new email schema

- Modified the `AttendeeAddedAuditActionService` to replace the old attendees schema with a new `emailSchema` for better validation.
- Adjusted the `addGuestsHandler` to pass the action source explicitly and updated the audit logging to reflect the new structure.
- Cleaned up the code for better readability and consistency.

* test: add happy path integration test for attendee added action

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 11:11:33 +00:00
Rajiv SahalandGitHub f7dee536d7 fix: dont import directly from @calcom/trpc or @calom/features (#26734) 2026-01-12 10:05:39 +00:00
0994050b0f fix(api): return original email without OAuth suffix in bookings (#25593)
* fix(api): remove OAuth client ID suffix from email in booking API responses

Fixes #25494 | Linear: CAL-6843

When managed users create or receive bookings, their emails were being returned with an internal OAuth client ID suffix (e.g., bob+cuid123@example.com). This suffix is used internally for user identification but should not be exposed in API responses.

Changes:
- Add cleanOAuthEmailSuffix() helper using CUID regex pattern
- Clean email suffix in hosts[], attendees[], bookingFieldsResponses.email, bookingFieldsResponses.guests[], and reassignedTo.email
- Pattern consistent with google-calendar.service.ts implementation

Affected output methods:
- getOutputBooking
- getOutputRecurringBooking
- getOutputSeatedBooking
- getOutputRecurringSeatedBooking
- getOutputReassignedBooking
- getHost

* refactor(api): preserve original email, add displayEmail field

Per team discussion, keep original email unchanged to avoid breaking changes for platform customers.
Add displayEmail field with CUID suffix removed for display purposes

* feat(api): add displayEmail to booking output DTOs

Add displayEmail property to BookingAttendee, BookingHost and ReassignedToDto for API documentation and type safety

* test(api): add e2e tests for displayEmail fields in managed user bookings

Add tests to verify that displayEmail fields correctly strip CUID suffix from OAuth managed user emails in booking API responses:

- Test host displayEmail returns email without CUID suffix
- Test attendee displayEmail returns email without CUID suffix
- Test bookingFieldsResponses.displayEmail returns clean email
- Test displayGuests array returns emails without CUID suffix

* false positive breaking change

* false positive breaking change

* test(api): update existing e2e tests to expect displayEmail field

* fix(api): add missing displayEmail to seated booking test assertions

The seated booking tests were missing displayEmail in the attendee
assertions for the second booking test and cancel-as-host test,
causing CI test failures

---------

Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-12 07:48:37 +00:00
3e7e376100 chore: Some minor fixes and follow up to #26446 (#26587)
* init

* DI and other improvements

* type fix

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-12 04:32:55 +00:00
MorganandGitHub 32ecb924d7 chore: USE_POOL env var for api v2 prisma pooling (#26622) 2026-01-10 09:10:38 +00:00
cal.com 71729813a9 Revert "chore: USE_POOL env var for api v2 prisma pooling"
This reverts commit a97092619f.
2026-01-09 17:59:10 +02:00
cal.com a97092619f chore: USE_POOL env var for api v2 prisma pooling 2026-01-09 17:55:25 +02:00
MorganGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
8666efa29d chore: enable/disable slots workers via env (#26621)
* chore: enable/disable slots workers via env

* fix: address Cubic AI review feedback

- Fix incorrect JSDoc comment for getSerializableContext method
- Remove debug console.log statement from slots controller
- Fix port suffix condition to preserve original behavior

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 15:03:13 +00:00
MorganandGitHub 02a334e072 chore: api v2 generate swagger only in dev (#26617) 2026-01-09 15:12:42 +02:00
MorganandGitHub 56b29b5df6 chore: rename app.ts to bootstrap.ts on api-v2 (#26604) 2026-01-09 09:56:27 +00:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
b6c243f1dd fix: improve cleanup for managed event types and fix flaky api v2 e2e test (#26602)
* fix: improve cleanup for managed event types in e2e tests

- Add deleteAllUserEventTypes method to EventTypesRepositoryFixture
- Update afterAll cleanup to delete user event types before deleting users
- This ensures child event types of managed event types are properly cleaned up
- Fixes flaky tests caused by incomplete cleanup between test runs
- Add explicit return types to fixture methods to satisfy lint rules
- Replace @ts-ignore with @ts-expect-error for better type safety

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

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-09 06:16:59 -03:00
Pedro CastroandGitHub d9aef5b6a6 fix: add URL validation for logo fields (#26522)
* fix(auth): add URL validation for organization logo fields

- Add URL validation utility for server-side fetched URLs
- Validate logo URLs in tRPC organization schema
- Validate logo URLs in API v2 team DTOs
- Add graceful fallback in logo route for invalid URLs
- Only allow HTTPS and image data URLs
- Add unit tests for URL validation

* fix: add missing IP range and type validation

- Add RFC 6598 CGNAT range (100.64.0.0/10) to blocked IPs
- Add @IsString() decorator before custom URL validators
- Add boundary tests for new IP range

* fix: address review feedback

   - Export validateUrlForSSRFSync via @calcom/platform-libraries
   - Fix nullable/optional order in Zod schema

* fix: block localhost hostname and explicit null check

- Add localhost to BLOCKED_HOSTNAMES for sync validation
- Use explicit null check (url == null) instead of falsy check

* fix: allow empty string in URL validation

* refactor: extract shared validation logic

- Extract validateUrlCore() to eliminate duplication between sync/async versions
- Add JSDoc to all exported functions for better discoverability
- Remove redundant comments that repeated function names
- Simplify existing comments to be more concise

* fix: reject empty strings in URL validator

Previously if (!url) allowed empty strings to bypass validation.
Now explicitly checks for null/undefined only
2026-01-08 22:03:54 +00:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>anik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ccff0045fc fix: Add email verification requirement for API v1 and v2 email updates (#24988)
* fix: Add email verification requirement for API v1 and v2 email updates

- API v2 (/v2/me): Implement email verification check when updating primary email
  - Store new email in metadata as emailChangeWaitingForVerification when verification is required
  - Send verification email using sendChangeOfEmailVerification
  - Allow immediate email change if new email is already a verified secondary email
  - Add hasEmailBeenChanged and sendEmailVerification flags to response
  - Add tests to verify email verification behavior
  - Add findVerifiedSecondaryEmail method to UsersRepository
  - Add PrismaFeaturesRepository to MeModule providers

- API v1 (/v1/users/{userId}): Implement same email verification logic
  - Check if email-verification feature flag is enabled
  - Store new email in metadata when verification is required
  - Send verification email for unverified email changes
  - Allow immediate change for verified secondary emails
  - Preserve existing API v1 response format

- Test fixtures: Add createSecondaryEmail method to UserRepositoryFixture

This fixes the vulnerability where users could update their primary email
without verification via API endpoints.

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

* update

* update

* refactor: Extract business logic to MeService and add platform-managed bypass

- Create MeService with all business logic extracted from MeController
- Update MeController to delegate to MeService (thin controller pattern)
- Add PrismaWorkerModule to MeModule imports to provide PrismaWriteService
- Add isPlatformManaged bypass: platform-managed users can update email without verification
- Fix test cleanup to use delete by ID instead of email to avoid failures when email changes
- Remove hasEmailBeenChanged and sendEmailVerification response flags per reviewer feedback
- Add comprehensive documentation to @ApiOperation describing email verification behavior
- Update tests to remove flag assertions

Addresses PR comments:
- supalarry: Extract logic to service layer
- supalarry: Allow platform-managed users to update email without verification
- supalarry: Remove response flags and document behavior in @ApiOperation instead
- cubic-dev-ai: Fix module dependency for PrismaFeaturesRepository
- cubic-dev-ai: Fix test cleanup issue

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

* docs: Simplify API operation description

Remove internal implementation details about metadata staging and shorten the description to focus on API consumer behavior.

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

* fix

* update

* update

* update

* remove comment

* addressed commit

* review addressed

* use repository

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 15:51:11 +00:00
MorganGitHubmorgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
dbc6b15ffc fix: time and timeUnit partial update workflows api v2 (#26503)
* test: add e2e test for workflow partial update time/timeUnit preservation

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

* fix: time and timeUnit partial update workflows api v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 09:26:55 -03:00
MorganGitHubmorgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ac3699dcb4 fix: set attendeeSeatId in evt for seated booking reschedule emails (#26498)
* fix: set attendeeSeatId in evt for seated booking reschedule emails

When an attendee reschedules a seated booking, the reschedule/cancel links
in emails were using bookingUid instead of seatUid after the first reschedule.
This was because evt.attendeeSeatId was not being set before sending the email.

This fix ensures that evt.attendeeSeatId is set to bookingSeat.referenceUid
so that the email links consistently use seatUid for seated bookings.

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

* test: add E2E test for seatUid preservation across multiple reschedules

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

* fix: use valid time slots within availability window for E2E test

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

* fix: make E2E test self-contained to avoid shared state issues

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

* fix: update E2E test to validate seatUid usability across reschedules

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-08 14:15:40 +02:00
Udit TakkarandGitHub 0d905a6c11 fix: add arrayLimit (#26542) 2026-01-07 14:23:38 +00:00
Dhairyashil ShindeandGitHub dcf10935de feat: add missing event type fields for advanced settings in api v2 (#25739)
* feat: api v2 add missing event type fields for advanced settings

Add 9 event type fields to API v2 that were available in tRPC but missing from the platform API:

- disableCancelling: disable cancelling for guests/organizer
- disableRescheduling: disable rescheduling for guests/organizer
- canSendCalVideoTranscriptionEmails: send Cal Video transcription emails
- autoTranslateInstantMeetingTitleEnabled: auto-translate instant meeting titles
- interfaceLanguage: preferred booking interface language
- allowReschedulingPastBookings: allow rescheduling past events
- allowReschedulingCancelledBookings: allow booking via reschedule link
- customReplyToEmail: custom reply-to email for confirmations
- showOptimizedSlots: optimize time slot arrangement

Updated output/input schemas, transformation services, and E2E tests.

* fix(api-v2): add proper OpenAPI types for nullable event type fields

Add explicit type and nullable properties to @ApiPropertyOptional decorators
for fields with `boolean | null` or `string | null` types. Without these,
Swagger was generating incorrect "type": "object" instead of the correct types.

Fixed fields:
- disableCancelling: type: Boolean, nullable: true
- disableRescheduling: type: Boolean, nullable: true
- interfaceLanguage: type: String, nullable: true
- allowReschedulingCancelledBookings: type: Boolean, nullable: true
- customReplyToEmail: type: String, nullable: true
- showOptimizedSlots: type: Boolean, nullable: true

* refactor: customReplyToEmail was intentionally excluded from this PR. The web UI
restricts this field to only allow the user's own verified emails via a
dropdown, but implementing the same validation in the API requires additional
business logic. This will be addressed in a separate PR with proper email
ownership validation.

* feat(api-v2): add validation for interfaceLanguage field

Add @IsIn validation to interfaceLanguage field to only accept supported
locales. This ensures API v2 matches the web UI behavior where users can
only select from a predefined dropdown of supported languages.

Changes:
- Add SUPPORTED_LOCALES constant to @calcom/platform-constants
- Add @IsIn([...SUPPORTED_LOCALES]) validation to create/update DTOs
- Add E2E tests for invalid locale rejection (400 error)
- Add cross-reference comments in i18n.json and api.ts to keep in sync

* docs(api): add default values to event type input field documentation

Added default value documentation to @DocsPropertyOptional decorators
for the new event type fields in API v2 (2024_06_14):

- disableCancelling: false
- disableRescheduling: false
- canSendCalVideoTranscriptionEmails: true
- autoTranslateInstantMeetingTitleEnabled: false
- allowReschedulingPastBookings: false
- allowReschedulingCancelledBookings: false
- showOptimizedSlots: false

This improves API documentation by clearly communicating default
values to API consumers in the OpenAPI spec.

* feat(api-v2): refactor event type settings to object types for future extensibility

- Convert disableRescheduling from boolean to object with disabled and minutesBefore properties
- Convert disableCancelling from boolean to object with disabled property
- Move canSendCalVideoTranscriptionEmails into CalVideoSettings as sendTranscriptionEmails
- Remove autoTranslateInstantMeetingTitleEnabled (Enterprise-only feature)
- Add DisableRescheduling_2024_06_14 and DisableCancelling_2024_06_14 input/output types
- Add transformation methods for new object types in input and output services
- Update E2E tests for new API contract

BREAKING CHANGE: disableRescheduling and disableCancelling now accept objects instead of booleans

* fix(api-v2): prevent clearing calVideoSettings when only sendTranscriptionEmails is provided

Only include calVideoSettings in transformed output if it has properties,
avoiding unintentional reset of existing settings during updates.
2026-01-07 16:03:01 +02:00
MorganGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Peer RichelsenVolnei Munhoz
61a932f8f5 feat: OAuth2 controller api v2 + refactor oAuth Trpc handlers (#25989)
* feat(api-v2): add OAuth2 controller skeleton for auth module

- Add new OAuth2 module under /auth with controller, service, repository, and DTOs
- Implement skeleton endpoints:
  - GET /v2/auth/oauth2/clients/:clientId - Get OAuth client info
  - POST /v2/auth/oauth2/clients/:clientId/authorize - Generate authorization code
  - POST /v2/auth/oauth2/clients/:clientId/exchange - Exchange code for tokens
  - POST /v2/auth/oauth2/clients/:clientId/refresh - Refresh access token
- Create input DTOs for authorize, exchange, and refresh operations
- Create output DTOs for client info, authorization code, and tokens
- Register OAuth2Module in endpoints.module.ts

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

* chore: add missing functions to platform libraries

* feat(api-v2): integrate OAuthService from platform-libraries into OAuth2 controller

- Add OAuthService export to platform-libraries
- Refactor OAuth2Service to use OAuthService.validateClient() and OAuthService.verifyPKCE()
- Remove duplicate local implementations of validateClient and verifyPKCE methods

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

* feat(api-v2): use local validateClient and verifyPKCE implementations

- Remove OAuthService export from platform-libraries (will be deprecated)
- Reimplement validateClient and verifyPKCE methods locally in OAuth2Service
- Use verifyCodeChallenge and generateSecret from platform-libraries directly

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

* refactor(api-v2): separate repositories for OAuth2, access codes, and teams

- Create AccessCodeRepository for access code Prisma operations
- Add findTeamBySlugWithAdminRole method to TeamsRepository
- Move generateAuthorizationCode, createTokens, verifyRefreshToken to OAuth2Service
- Update OAuth2Repository to only contain OAuth client operations
- Update OAuth2Module to import TeamsModule and provide AccessCodeRepository

Addresses PR review comments to properly separate concerns

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

* feat(api-v2): implement JWT token creation and verification for OAuth2

- Implement createTokens method using jsonwebtoken to sign access and refresh tokens
- Implement verifyRefreshToken method to verify JWT refresh tokens
- Add ConfigService injection for CALENDSO_ENCRYPTION_KEY access
- Import ConfigModule in OAuth2Module for dependency injection

Based on logic from apps/web/app/api/auth/oauth/token/route.ts and
apps/web/app/api/auth/oauth/refreshToken/route.ts

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

* fix: refactor and dayjs import fix

* feat(api-v2): add ApiAuthGuard to getClient endpoint and e2e tests for OAuth2

- Add @UseGuards(ApiAuthGuard) to getClient endpoint for authentication
- Add comprehensive e2e tests for all OAuth2 endpoints:
  - GET /v2/auth/oauth2/clients/:clientId
  - POST /v2/auth/oauth2/clients/:clientId/authorize
  - POST /v2/auth/oauth2/clients/:clientId/exchange
  - POST /v2/auth/oauth2/clients/:clientId/refresh
- Tests cover happy paths and error cases (invalid client, invalid code, etc.)

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

* chore(api-v2): hide OAuth2 endpoints from Swagger documentation

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

* hide endpoints from doc

* fix(api-v2): address PR feedback for OAuth2 controller

- Fix P0 critical bug: token_type field name mismatch in DecodedRefreshToken interface
- Add @Equals('authorization_code') validation to exchange.input.ts grantType
- Add @Equals('refresh_token') validation to refresh.input.ts grantType
- Add @IsNotEmpty() validation to get-client.input.ts clientId
- Add @Expose() decorators to all output DTOs for proper serialization
- Add security test assertion to verify clientSecret is not returned in response

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

* feat(api-v2): implement redirect behavior for OAuth2 authorize endpoint

- Update authorize endpoint to return HTTP 303 redirect with authorization code
- Add exact match validation for redirect URI (security requirement)
- Implement error handling with redirect to redirect URI and error query params
- Add state parameter support for CSRF protection
- Update e2e tests to verify redirect behavior (303 status, Location header, error redirects)

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

* refactor(api-v2): address PR feedback for OAuth2 authorize endpoint

- Make redirectUri a required input parameter (remove optional fallback)
- Move buildRedirectUrl and mapErrorToOAuthError to oauth2Service
- Add return statements to res.redirect() calls
- Simplify controller by delegating redirect URL building to service

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

* wip move code outside of api v2

* feat(oauth): wire up dependency injection for OAuthService and repositories

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

* refactor: oAuthService used in routes

* fix imports

* fix(api-v2): return 404 for invalid client ID instead of redirect in authorize endpoint

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

* fix(api-v2): fix E2E test URL paths and remove bootstrap() in authenticated section

- Remove bootstrap() call in authenticated section to match working test pattern
- Change URL paths from /api/v2/... to /v2/... in authenticated section
- Keep bootstrap() and /api/v2/... paths in unauthenticated section

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

* fix(api-v2): mock getToken from next-auth/jwt for E2E tests

- Add jest.mock for next-auth/jwt getToken function
- Mock returns null for unauthenticated tests
- Mock returns { email: userEmail } for authenticated tests
- Remove withNextAuth helper since ApiAuthGuard uses ApiAuthStrategy
  which calls getToken directly, not NextAuthStrategy

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

* fix tests and code review

* cleanup generate secrets

* cleanup controller

* chore: remove console.log from OAuthService.validateClient

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

* Update apps/web/app/api/auth/oauth/refreshToken/route.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix(api-v2): add bootstrap() to authenticated E2E tests and update URL paths to /api/v2/

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

* Merge remote-tracking branch 'origin/devin/oauth2-controller-skeleton-1765988792' and remove console.log from token route

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

* chore: remove dead code

* refactor

* refactor: generateAuthCode trpc handler and getClient trpc handler

* remove pkce check for refreshToken endpoint

* Update packages/trpc/server/routers/viewer/oAuth/getClient.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor: error handling

* refactor: error handling

* refactor: error handling

* remove console log

* provide redirectUri in generateAuthCodeHandler

* provide redirectUri in authorize view

* refactor: replace HttpError with ErrorWithCode in OAuth files

- Update OAuthService to use ErrorWithCode instead of HttpError
- Update mapErrorToOAuthError to check ErrorCode instead of status codes
- Update token/route.ts and refreshToken/route.ts to use ErrorWithCode
- Add ErrorWithCode export to platform-libraries
- Use getHttpStatusCode to map ErrorCode to HTTP status codes

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

* fix: update generateAuthCode handler to use ErrorWithCode instead of HttpError

The handler was still checking for HttpError in its catch block, but OAuthService
now throws ErrorWithCode. This caused the error messages to be lost and replaced
with 'server_error' instead of the specific error messages.

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

* fix: update OAuth2 controller to use ErrorWithCode instead of HttpError

The controller was still checking for HttpError in its catch blocks, but OAuthService
now throws ErrorWithCode. This caused all errors to return 500 Internal Server Error
instead of the correct HTTP status codes (400, 401, 404).

Also added getHttpStatusCode export to platform-libraries.

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

* fix: add explicit unknown type annotation to catch blocks in OAuth2 controller

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

* fix: change NotFoundException to HttpException in authorize endpoint

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

* fix: handle err with ErrorWithCode in authorize endpoint catch block

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

* fix: move errorWithCode

* fix: error code rfc

* fix: no need to handle errors there is a middleware

* refactor errors

* refactor errors

* refactor redirecturi and state from api

* refactor: address PR comments for OAuth2 controller

- Remove unused GetOAuth2ClientInput class
- Change API tag from 'Auth / OAuth2' to 'OAuth2'
- Move OAuthClientFixture to separate fixture file (oauth2-client.repository.fixture.ts)
- Add 'type' property to OAuth2ClientDto for confidential/public client type
- Rename 'clientId' to 'id' in OAuth2ClientDto (using @Expose mapping)
- Clean up duplicate provider declarations in oauth2.module.ts
- Update e2e tests to use new fixture and verify type property

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-07 08:05:21 -03:00
Hariom BalharaandGitHub ca32f04cc1 chore: Integrate booking cancellation audit (#26458)
## What does this PR do?
> **⚠️ Note: This PR does not enable booking audit in production.** The `BookingAuditTaskerProducerService` has an [`IS_PRODUCTION` guard](https://github.com/calcom/cal.com/blob/integrate-booking-creation-reschedule-audit/packages/features/booking-audit/lib/service/BookingAuditTaskerProducerService.ts#L106-L108) that skips audit task queueing in production environments. This allows the integration to be tested in development before enabling it in production.

Integrates audit logging for booking cancellations, following the pattern established in PR #26046 for booking creation/rescheduling audit.

- Related to #25125 (Booking Audit Infrastructure)

### Changes:
- Add audit logging for single booking cancellation via `onBookingCancelled`
- Add audit logging for bulk recurring booking cancellation via `onBulkBookingsCancelled`
- Pass `userUuid` and `actionSource` from webapp cancel route (WEBAPP)
- Pass `userUuid` and `actionSource` from API-v2 bookings service (API_V2)
- Create `getAuditActor` helper to derive actor from userUuid or create synthetic guest actor
- Add `getUniqueIdentifier` helper for generating unique actor identifiers
- Add warning log when `actionSource` is "UNKNOWN" for observability
- Add integration tests for booking cancellation audit

### Audit Data Captured:
- `cancellationReason` (simple string value)
- `cancelledBy` (simple string value)  
- `status` (old → new, e.g., "ACCEPTED" → "CANCELLED")

### Updates since last revision:
- Simplified `CancelledAuditActionService` schema: `cancellationReason` and `cancelledBy` are now stored as simple nullable strings instead of change objects (old/new), since cancellation is a one-time event where tracking previous values doesn't apply
- Added integration tests for cancelled booking audit in `booking-audit-cancelled.integration-test.ts`
- Added `getUniqueIdentifier` helper function in actor.ts for generating unique identifiers with prefixes

## Mandatory Tasks (DO NOT REMOVE)

- [x] I have self-reviewed the code (A decent size PR without self-review might be rejected).
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Cancel a single booking via the webapp - verify audit record is created with actor and actionSource="WEBAPP"
2. Cancel a single booking via API v2 - verify audit record is created with actionSource="API_V2"
3. Cancel all remaining bookings in a recurring series - verify bulk audit records are created with shared operationId
4. Cancel via unauthenticated cancel link - verify guest actor is created with synthetic email (prefixed with "param-" or "fallback-")
5. Run integration tests: `yarn test packages/features/booking-audit/lib/service/__tests__/booking-audit-cancelled.integration-test.ts`

## Human Review Checklist

- [ ] Verify `onBookingCancelled` and `onBulkBookingsCancelled` methods exist in `BookingEventHandlerService`
- [ ] Review the `getAuditActor` fallback logic - creates synthetic email with "fallback-" or "param-" prefix when no userUuid available
- [ ] Confirm the simplified schema for `cancellationReason`/`cancelledBy` (no longer tracking old→new) is intentional
- [ ] Note: Audit logging calls are awaited directly - if audit service fails, the cancellation will fail. Confirm this is the desired behavior.
- [ ] Verify `CancelledAuditDisplayData` type no longer includes `previousReason` and `previousCancelledBy` fields

---

Link to Devin run: https://app.devin.ai/sessions/42404e76a66946fe9e46fa07fb12e779
Requested by: @hariombalhara (hariom@cal.com)
2026-01-07 16:15:57 +05:30
701c4cdb76 perf: batch booking queries in output service (#25900)
Replace N sequential queries with single batch queries in:
- getOutputRecurringBookings
- getOutputRecurringSeatedBookings

Uses existing batch repository methods. Reduces database roundtrips
from O(n) to O(1) for recurring booking lookups

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-07 08:41:09 +00:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f4248bf20d feat: implement FeatureOptInService (#25805)
* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

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

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

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

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

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

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

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

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

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

* refactor: use team.isOrganization and clarify computeEffectiveState comment

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

* refactor: use MembershipRepository.findAllByUserId with isOrganization

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

* feat: add featureId validation using isOptInFeature type guard

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

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

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

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 16:55:53 +01:00
MorganGitHubmorgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
81b5d62f07 feat(api): add team event-types webhooks controller (#26449)
* feat(api): add team event-types webhooks controller

- Add TeamsEventTypesWebhooksController for managing webhooks on team event types
- Add IsTeamEventTypeWebhookGuard for authorization
- Add TeamEventTypeWebhooksService for business logic
- Register new controller in TeamsEventTypesModule
- Enable unsafeParameterDecoratorsEnabled in biome.json for NestJS support

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

* test(api): add e2e tests for team event-types webhooks controller

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

* fix(api): restrict team event-type webhooks to admins/owners only

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

* fix(api): use regular imports instead of type imports for DI and DTOs

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

* fix(api): use regular imports for DI in guard file

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

* fix: circular depndency in modules

* delete teams in test

* fix roles guard

* fix biome

* fix guard

* resolve type import

* resolve review feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-06 11:23:18 -03:00
Volnei MunhozandGitHub a1e5384859 Prefix node protocol (#26391) 2026-01-02 12:47:00 +00:00
Pedro CastroandGitHub 40dd546429 chore(deps): update dependencies and add version constraints (#26328)
* chore(deps): update dependencies and add version constraints

 - Update direct dependencies: body-parser, @nestjs/swagger, react-use, trigger.dev
 - Add resolutions for consistent dependency versions across the monorepo
 - Add packageExtensions to ensure compatible transitive dependency versions

* fix: upgrade rollup resolution from 3.29.5 to 4.22.4

 Rollup 3.x is incompatible with vite 5.x which requires rollup ^4.20.0.
 The previous resolution caused CI failures due to missing ./parseAst
 export

* fix: update axios resolution to 1.13.2

Align resolution with direct dependency in apps/api/v2.
Both versions include the fix, but 1.13.2 is newer and
avoids an unnecessary downgrade
2026-01-01 23:18:53 +00:00
Pedro CastroGitHubkeith@cal.com <keithwillcode@gmail.com>Keith WilliamsDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
128d15ea8f fix: ensure proper async handling in delegation credentials (#25898)
* fix: ensure proper async handling in ensureDefaultCalendars

Replace forEach(async...) with Promise.allSettled to ensure:
- Caller properly awaits completion
- Errors are captured and logged
- All users are processed even if some fail

Adds unit tests for ensureDefaultCalendars

* fix: use correct Jest assertion pattern for async test

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

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 19:30:26 +00:00
b08997b553 fix: remove debug logs and clean up verbose logging (#25896)
- Remove debug console.log statements in calendar and video adapter services
- Clean up verbose request/response logging in OAuth controllers
- Remove leftover debug prefixes

Ensure only necessary data is captured in observability systems

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-31 19:12:28 +00:00
Volnei MunhozandGitHub ed14219e44 upgrade typescript (#26347) 2025-12-31 13:32:55 -03:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
17224d9df3 ci: reduce e2e-api-v2 test overhead with caching and Jest optimizations (#26331)
* perf: increase E2E test shards from 4 to 6 for faster CI

Increase the number of parallel E2E test shards from 4 to 6 to reduce
overall CI wall-clock time. Each shard runs on a separate 4-vCPU runner
with 4 workers, so adding more shards increases total parallelism.

This should reduce E2E test time from ~3 minutes per shard to ~2 minutes
per shard by distributing tests across more parallel jobs.

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

* update

* fix

* update

* readd

* final update

* fix flake

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-31 10:19:09 -03:00
Volnei MunhozGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7c373ddad6 feat: Introduce biome (#25664)
* Configure biome

* Fix companion build

* fix: remove generated files from formatter ignore list to enable proper formatting

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

* fix: add explicit stripe dependency to @calcom/features to fix type resolution

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

* fix: rename const require to nodeRequire in generate-swagger.ts to avoid TypeScript reserved identifier conflict

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

* fix: add guard for document in makeBodyVisible to prevent test environment teardown errors

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

* fix: replace ESLint with Biome CLI in embed-code-generator.e2e.ts

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

* fix: address cubic review comments

- Fix invalid --reporter-path Biome CLI option by using shell redirection
- Fix packages/lib lint report filename (app-store.json -> lib.json)
- Add typescript-eslint and eslint back to companion for lint:react-compiler
- Add missing restricted import rules to biome.json:
  - packages/lib: add ../trpc/** and @trpc/server restrictions
  - packages/trpc: add ../apps/web/** restriction

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

* chore: regenerate companion bun.lock after adding eslint dependencies

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

* Remove remaining eslint things

* add tailwind directives

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 19:41:41 -03:00
Anik Dhabal BabuGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
96dc3b5cc6 fix: improve test isolation for managed event type e2e tests (#26283)
- Move managedEventTypeSlug generation inside beforeAll to ensure uniqueness across test runs
- Add deleteAllTeamEventTypes method to EventTypesRepositoryFixture
- Explicitly delete all team event types in afterAll before deleting teams

This fixes flaky tests in organizations-member-team-admin-event-types.e2e-spec.ts
where the managed event type creation was intermittently failing with 400 Bad Request.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 16:12:01 -03:00
Keith WilliamsGitHubkeith@cal.com <keithwillcode@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
55805f081d fix: add artifact handling for API v2 E2E tests (#26249)
* fix: add artifact handling for API v2 E2E tests

- Add jest-junit reporter to generate JUnit XML test results
- Update workflow to upload from correct path (apps/api/v2/test-results)
- Add if-no-files-found: ignore and retention-days: 30 for consistency

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

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 02:22:38 -03:00
Pedro CastroandGitHub ab512ea263 chore: bump package versions (#26211)
* chore: bump package versions

- @nestjs/common 10.4.20
- @nestjs/platform-express 10.4.20
- @jsforce/jsforce-node 3.10.10
- dompurify 3.3.1
- @dub/embed-react 0.0.18
- @dub/embed-core 0.0.18
- http-proxy-middleware 2.0.9
- action-download-artifact v6

* fix: align NestJS core packages to same version

Update @nestjs/core and @nestjs/testing to 10.4.20 to match
@nestjs/common and @nestjs/platform-express versions
2025-12-26 13:38:25 -03:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
44586c7dec chore: lock all package versions to match yarn.lock (#26204)
This commit pins all dependency versions in package.json files to exact
versions matching the yarn.lock file, removing ^ and ~ prefixes.

Changes:
- Locked 427 dependencies across 47 package.json files
- Versions now match exactly what is resolved in yarn.lock
- Ensures reproducible builds and prevents unexpected version drift

This change improves build reproducibility by ensuring that the versions
specified in package.json files match exactly what yarn.lock resolves to.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-26 11:54:30 -03:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
8befcced39 ci: shard API v2 E2E tests into 4 parallel jobs (#26183)
* ci: shard API v2 E2E tests into 4 parallel jobs

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

* check

* Fix typo in workflow name from 'Update' to 'Updatee'

* Rename workflow from 'PR Updatee' to 'PR Update'

* update

* test

* update

* fix

* update

* check

* remove

* revert

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-24 10:46:49 -03:00
Pedro CastroandGitHub 99b82c55d5 chore: update direct dependencies (#26172)
Updates:
- vite: 4.5.3→4.5.14, 5.4.6→5.4.21
- nodemailer: 6.7.8→7.0.11
- @playwright/test: 1.45.3→1.55.1
- next-auth: 4.22.1→4.24.13
- class-validator: 0.14.0→0.14.3
- dompurify: 3.2.3→3.3.1

Includes type fixes for next-auth adapter compatibility
2025-12-23 23:42:55 -03:00
cd6c5fe6df chore: remove unused dependencies (#26169)
* chore: remove unused dependencies

- Remove msw from apps/web (test was disabled with test.fixme)
- Remove integrations.e2e.ts (unused test file depending on msw)
- Remove jsforce from apps/api/v2 (never imported, salesforce uses @jsforce/jsforce-node)
- Remove rollup-plugin-node-builtins and vite-plugin-node-polyfills from atoms (never used)
- Remove fs/path/os aliases from atoms vite.config.ts

Resolves: #76, #118, #354 (partial), #356, #347, #266

* fix(companion): remove unused glob dependency

Glob was declared as devDependency but never imported in companion code
Resolves dependabot alerts #465, #460

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-23 21:38:38 -03:00
7847177e8b fix(api): accept avatar URLs and use email for user creation (#25629)
* fix(api): fix user creation with avatarUrl and username

- avatarValidator: accept URLs in addition to base64 images
- organizations-users-service: use email for user creation instead of username

The avatarValidator was incorrectly rejecting valid URLs even though the API documentation shows URL examples and all e2e tests use URLs.

The user creation was failing when username was provided because createNewUsersConnectToOrgIfExists requires a valid email, not username. The username is correctly applied via updateOrganizationUser after creation.

Fixes user creation endpoint POST /v2/organizations/{orgId}/users

* test(api): add tests for avatar validator fixes

  Add comprehensive test coverage for avatarValidator changes:

  - Unit tests: 18 scenarios covering valid/invalid URLs and base64 images
  - E2E tests: user creation with username + avatarUrl (URL and base64)
  - Security validation: reject unsafe protocols and malformed data
  - Error message verification for validation failures

  Addresses testing requirements from code review

* fix(api): enhance avatar validator security per code review

  - Reject HTTP URLs, accept only HTTPS for security and browser compatibility
  - Reject empty strings and whitespace (use null to reset avatar)
  - Update validation message to clarify HTTPS requirement
  - Add test coverage for new security restrictions

 Addresses security feedback from code review regarding mixed content vulnerabilities and clearer API semantics for avatar reset

* refactor(api): simplify avatarValidator null check

Remove redundant null/undefined check since @IsOptional decorator already skips validation for undefined values. Updated test mock to include @IsOptional to match real DTO usage

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-23 15:07:14 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
866c8c046d fix: create host records when team membership transitions to accepted via PATCH (#26138)
The PATCH endpoint for /v2/teams/:teamId/memberships/:membershipId had a bug
where host records for assignAllTeamMembers event types were not created when
a membership transitioned from accepted=false to accepted=true.

The bug was caused by incorrect operation ordering:
1. Update membership (first update)
2. Get current membership (gets already-updated state)
3. Update membership again (second update)
4. Check if transition happened (condition never fires)

Fixed by reordering to match the org-scoped controller pattern:
1. Get current membership BEFORE any updates
2. Update membership
3. Compare and call updateNewTeamMemberEventTypes if transition occurred

Also added an e2e test to verify host records are created when membership
transitions from accepted=false to accepted=true via PATCH.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-23 10:46:14 +00:00
Anik Dhabal BabuGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Syed Ali Shahbazcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
23920fe9ce fix: Org/team admin or owner should be marked as ‘no show’ in a member’s booking (#26009)
* fix: update tempOrgRediret on updating s
lug

* Update packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* refactor

* fix

* fix

* revert

* fix handle no show

* revert

* Remove metadata from organization query selection

Removed metadata selection from organization query.

* use repo

* update

* Update packages/features/bookings/lib/checkIfUserIsAuthorizedToManageBooking.ts

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* update

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2025-12-22 15:42:20 -03:00
Rajiv SahalandGitHub f9ff3248e5 feat: endpoint to update location for existing booking (#25367)
* feat: init endpoint to update booking location

* chore: update controller

* chore: DTOs for update location endpoint

* chore: add update booking method

* fix: refactor

* feat: service update booking location

* chore: update platform libraries

* chore: update exports

* chore: e2e tests for updating booking location endpoint

* chore: update e2e tests for updating booking location endpoint

* chore: update bookings module

* fixup

* chore: update configs

* fixup: revert changes

* chore: remove unused handlers

* fix: update inputs

* refactor: booking location service

* fixup

* revert: unnecessary changes

* chore: cleanup

* fix: e2e tests

* chore: implement cubic feedback

* chore: implement feedback

* fixup

* chore: more PR feedback
2025-12-22 09:25:00 +00:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
40883386f0 fix: address peer dependency issues across the monorepo (#26105)
MOVE:
- Move @next/third-parties from root to apps/web (only used there)
- Remove date-fns-tz from root, add date-fns and date-fns-tz to root deps

REMOVE:
- Remove sonner from packages/lib (not used there, already in apps/web)
- Remove next-seo from packages/ui (not used there, already in apps/web)
- Remove next-auth from apps/api/v2 (only used for User type in tests)

ADD peerDependencies:
- packages/ui: add react-dom
- packages/features: add react, react-dom, react-is, date-fns-tz, stripe, zod
- packages/platform/atoms: add react-dom
- packages/trpc: add next, react, react-dom

ADD dependencies:
- apps/web: add @next/third-parties, i18next, react-i18next
- apps/api/v2: add axios (required by @nestjs/axios)

FIX:
- apps/api/v2: replace next-auth User type with @calcom/prisma/client User

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-21 23:20:49 +00:00