Commit Graph
16251 Commits
Author SHA1 Message Date
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3e29904d7d test: add tests for __reloadInitiated behavior to ensure correct bookerViewed vs bookerReloaded events (#27379)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 14:35:18 -03:00
Carina WollendorferGitHubcarina@cal.com <c.wollendorfer@me.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>CarinaWolli
06f4b25080 fix: update routing form identifier hint text with learn more link (#27837)
* fix: update routing form identifier hint text with learn more link

Co-Authored-By: carina@cal.com <c.wollendorfer@me.com>

* UI improvements

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-02-20 13:09:09 +01:00
DeepanshuandGitHub 79fc0c8437 fix: toolbar dropdown toggle (#28097) 2026-02-20 11:20:38 +00:00
a2b25fa615 fix: prevent deselecting active option in booker layout toggle (#27748)
* fix: prevent deselecting active option in ToggleGroup

Radix UI's single-type ToggleGroup allows deselection by default,
calling onValueChange("") when the active item is clicked.

Fix by converting to controlled mode with proper dual-mode support:
- Controlled (value prop): parent owns state, component just filters
  empty values from onValueChange. Parent can still reject changes.
- Uncontrolled (defaultValue prop): internal useState prevents
  deselection by only updating state for non-empty values.

* Update ToggleGroup.tsx

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-02-20 10:41:54 +00:00
Volnei MunhozGitHubunknown <>Claude Opus 4.6Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
14c151be76 fix: add CSRF protection to OAuth callback via HMAC-signed nonce (#28083)
* fix: add CSRF protection to OAuth callback via HMAC-signed nonce

The OAuth state parameter was used only for passing application data
(returnTo, teamId) with no cryptographic binding to the user session.
An attacker could authorize their own account on a provider, capture the
authorization code, and trick a logged-in user into visiting the callback
URL to link the attacker's account to the victim's Cal.com profile.

Changes:
- encodeOAuthState: generate a random nonce and HMAC-sign it with
  NEXTAUTH_SECRET + userId, injecting both into the OAuth state
- decodeOAuthState: verify the HMAC on callback using timingSafeEqual;
  skip verification when nonce is absent (backwards compatible with apps
  that don't yet use encodeOAuthState)
- Stripe callback: replace raw state.returnTo redirect with
  getSafeRedirectUrl to prevent open redirect, remove redundant
  getReturnToValueFromQueryState, add missing return on access_denied

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make CSRF nonce verification mandatory with allowlist for exempt apps

Makes nonce/HMAC verification mandatory by default in decodeOAuthState,
preventing attackers from bypassing CSRF protection by omitting nonce
fields from the state parameter.

Apps not yet migrated to encodeOAuthState (stripe, basecamp3, dub,
webex, tandem) are explicitly allowlisted and pass their slug to
decodeOAuthState to skip verification.

Addresses review feedback (identified by cubic) about the conditional
check being trivially bypassable.

Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 10:35:01 +00:00
Hariom BalharaGitHubunknown <>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1aae57daae refactor(booking-audit): discriminated union for displayFields and i18n param support (#27373)
* feat: Add infrastructure for no-show audit integration

- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys

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

* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types

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

* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema

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

* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED

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

* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService

- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService

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

* fix: Add data migration step for deprecated no-show enum values

Addresses Cubic AI review feedback (confidence 9/10): The migration now
includes an UPDATE statement to convert existing records using the
deprecated 'host_no_show_updated' or 'attendee_no_show_updated' enum
values to the new unified 'no_show_updated' value before the type cast.
This prevents migration failures if any existing data uses the old values.

Co-Authored-By: unknown <>

* fix: Use CASE expression in USING clause for enum migration

Fixes PostgreSQL error 'unsafe use of new value of enum type' by avoiding
the ADD VALUE statement and instead using a CASE expression in the ALTER
TABLE USING clause to convert deprecated enum values (host_no_show_updated,
attendee_no_show_updated) to the new unified value (no_show_updated) during
the type conversion.

Co-Authored-By: unknown <>

* fix: Replace hardcoded color with semantic text-success class

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

* fix: Remove color class completely from display fields

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

* feat: Add valuesWithParams support for translatable complex field values

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

* refactor(booking-audit): use discriminated union for displayFields and update consumers

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

* fix: add explicit return type to getBookingHistoryHandler to bust stale tRPC build cache

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

* refactor: replace $t() nested interpolation with separate translation keys and add translationsWithParams tests

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-20 14:34:12 +05:30
12e95a1f47 feat: Add meta pixel conversion events (#25638)
* feat(meta-pixel): add trackingEvent to zod schema

* fix: do not allow trackingEvent to be optional

* feat(meta-pixel): add trackingEvent selection dropdown to UI

* feat(meta-pixel): add trackingEvent to Event Type App Data

* fix(meta-pixel): implement history API hook for SPA conversion tracking

* fix(meta-pixel): check for cancel in URL and prevent Re-wrapping of pushState

* Update EventTypeAppSettingsInterface.tsx

* fix: make trackingEvent optional in zod schema to fix type-check

---------

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-20 00:17:42 +05:30
Peer RichelsenGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Dhairyashileunjae@cal.com <hey@eunjae.dev>Dhairyashil Shinde
60b6086221 feat: add keyboard shortcuts and tooltips to booking slideover buttons (#27428)
* feat: add keyboard shortcuts and tooltips to booking slideover buttons

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

* fix: remove duplicate useBookingLocation import and fix import ordering

- Removed duplicate import of useBookingLocation from non-existent
  @calcom/web/modules/bookings/hooks/useBookingLocation path
- Fixed import ordering to satisfy biome organizeImports rules
- Removed unnecessary code comment
- Original feature by @PeerRich via Devin AI

Co-Authored-By: unknown <>

* use same style arrows for both button and remove bydefault focus from them

* fix join button tooltip hover

* fix: disable keyboard shortcuts when overlays/dialogs are open on BookingDetailsSheet

Co-Authored-By: unknown <>

* fix: use focus-based detection instead of selector-based overlay detection for keyboard shortcuts

Co-Authored-By: unknown <>

* fix: allow keyboard shortcuts when focus is on sheet ancestors

Co-Authored-By: unknown <>

* fix: use capture phase for keyboard handler to prevent Enter from activating focused buttons

Co-Authored-By: unknown <>

* fix: allow shortcuts when focus is on page elements outside any Radix portal

Co-Authored-By: unknown <>

* fix: handle calendar event clicks in onInteractOutside to prevent sheet close/reopen

Co-Authored-By: unknown <>

* fix: stop arrow key propagation to prevent Radix dropdown from opening during booking navigation

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

* fix: always stop arrow key propagation when sheet is active, even at first/last booking

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

* refactor: extract keyboard handler into testable utility with tests

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

* fix: resolve type errors in keyboard handler config and test mocks

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

* test: add e2e tests for booking sheet keyboard shortcuts

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

* fix: replace text= locators with data-testid selectors in e2e tests

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

* made 3 fixes: Fix 1 — Stabilize handleNext/handlePrevious/handleClose with useCallback
In BookingDetailsSheet.tsx, all three handler functions were plain arrow functions recreated on every render, causing the useEffect to tear down and re-attach the document keydown listener unnecessarily. Wrapped all three in useCallback with proper dependency arrays (the Zustand store functions they call).
Fix 2 — data-booking-list-item verified (no change needed)
Confirmed that data-booking-list-item is rendered on BookingListItem.tsx and data-booking-calendar-event is rendered on Event.tsx. The onInteractOutside handler in the final merged state correctly checks both selectors. No code change required.
Fix 3 — Removed dead code from JoinMeetingButton
Reverted JoinMeetingButton back to a plain function component:
Removed forwardRef wrapping (no caller passes a ref)
Removed showTooltip prop (unused — tooltip is handled by the parent BookingDetailsSheet)
Removed ref prop from the inner Button
Removed unused Tod forwardRef imports

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2026-02-19 22:32:43 +05:30
Syed Ali ShahbazGitHubali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Hariom Balhara
5d65df9c05 chore: migrate booking requested webhook trigger (#27546)
* init

* wiring up

* fix type

* feat: implement DI pattern for webhook producer in API v2

- Export IWebhookProducerService and getWebhookProducer from platform-libraries
- Add WEBHOOK_PRODUCER token and useFactory provider in RegularBookingModule
- Inject webhookProducer in RegularBookingService and pass to base class

This follows the composition root pattern where only the NestJS module
knows about getWebhookProducer(), and all consumers depend only on the
IWebhookProducerService interface via constructor injection.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* test: migrate BOOKING_REQUESTED tests to new webhook architecture

- Remove failing BOOKING_REQUESTED tests from fresh-booking.test.ts (4 tests)
- Remove failing BOOKING_REQUESTED tests from reschedule.test.ts (2 tests)
- Remove failing BOOKING_REQUESTED test from collective-scheduling.test.ts (1 test)
- Replace WebhookTaskConsumer.test.ts with placeholder (constructor changed)
- Create new webhook architecture test suite:
  - producer/WebhookTaskerProducerService.test.ts (14 tests)
  - consumer/WebhookTaskConsumer.test.ts (8 tests)
  - consumer/triggers/booking-requested.test.ts (8 tests)

The new test suite is organized by trigger type for extensibility as more
triggers are migrated to the producer/consumer pattern.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* test: remove paid events BOOKING_REQUESTED test (moved to new architecture)

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* wrap webhook in own try-catch

* wire datafetcher

* fix

* fix v2

* fix circular dependency

* --

* merge-conflict-resolve

* mreg-conflict-resolve

* remove early return

* test: add integration tests for BOOKING_REQUESTED webhook producer invocation

Cover all 8 scenarios verifying the booking flow correctly invokes
the webhook producer for BOOKING_REQUESTED:

1. Basic confirmation → queueBookingRequestedWebhook called
2. Booker-is-organizer + confirmation → still called
3. Confirmation threshold NOT met → not called (BOOKING_CREATED instead)
4. Confirmation threshold IS met → called
5. Paid event + confirmation → called after payment succeeds
6. Reschedule + confirmation (non-organizer) → called (not BOOKING_RESCHEDULED)
7. Reschedule + confirmation (organizer) → not called (BOOKING_RESCHEDULED instead)
8. Collective scheduling + confirmation → called

Adds reusable MockWebhookProducer helper in @calcom/testing for
extendable use as more webhook triggers migrate to the new architecture.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix bug

* fix conditional check

* remove unnecessary comment

* add missing expect

* remove empty test

* clean up

* tasker config

* --

* fix missing metadata

* remove faulty if else

* test: add payload content verification tests for BOOKING_REQUESTED webhook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* remove unnecessary tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
2026-02-19 20:21:26 +04:00
Peer RichelsenGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
66ce20245c docs: declare credentials and environment variables in calcom-api skill (#28047)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 14:32:41 +00:00
Lauris SkraucisGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c321a6c07a feat: owner can test non accepted OAuth client (#27525)
* refactor: combine exchange and refresh into token endpoint

* refactor: controller error handling

* refactor: use snake_case

* refactor: use snake_case

* refactor: use snake case

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: token endpoint accepts application/x-www-form-urlencoded

* refactor: flat token response data

* refactor: error structure

* refactor: client_id in the body

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient endpoint to use proper REST API error format instead of OAuth token error format (confidence 9/10)
- Add missing space after comma in error format string in token.input.pipe.ts (confidence 9/10)
- Support both camelCase and snake_case inputs in authorize endpoint for backward compatibility (confidence 10/10)
- Restore legacy /exchange and /refresh endpoints alongside new /token endpoint for backward compatibility (confidence 10/10)
- Add OAuth2TokensResponseDto for legacy endpoint wrapped responses
- Add OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput for legacy endpoints

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Log errors when status code >= 500 in handleClientError (confidence 9/10)
- Add Cache-Control: no-store and Pragma: no-cache headers to legacy /exchange and /refresh endpoints (confidence 9/10)

Co-Authored-By: unknown <>

* docs

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit 39cc4aa3ebb9e59a171541d7010398425995ed89.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 97bf593186db04c0859f9ca30950c9e3e524019d.

* docs

* fix: address Cubic AI review feedback on OAuth2 endpoints

- Fix getClient to use handleClientError instead of handleTokenError (confidence 10)
- Restore legacy /exchange and /refresh endpoints for backward compatibility (confidence 9)
- Fix RFC 6749 error format: use human-readable messages in error_description (confidence 9)
- Fix errorDescription in OAuthService to use OAUTH_ERROR_REASONS mapping (confidence 9)

Co-Authored-By: unknown <>

* fix: address additional Cubic AI feedback on OAuth2 endpoints

- Fix security issue: Replace 'CALENDSO_ENCRYPTION_KEY is not set' with generic 'Internal server configuration error' message (confidence 10/10)
- Fix backward compatibility: Create OAuth2LegacyTokensDto with camelCase properties for legacy /exchange and /refresh endpoints (confidence 9/10)
- Skipped: RFC 6749 error field issue (confidence 8/10, below threshold)

Co-Authored-By: unknown <>

* e2e

* Revert "fix: address additional Cubic AI feedback on OAuth2 endpoints"

This reverts commit a080e93f07aaf5a7dcf81fe605012cb7ebcdc192.

* Revert "fix: address Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 04986a16c981521ca97069152457bf521a9ee45f.

* fix: re-apply Cubic AI review feedback on OAuth2 endpoints

- Restore OAuth2LegacyExchangeInput and OAuth2LegacyRefreshInput classes
- Restore legacy /exchange and /refresh endpoints in OAuth2Controller
- Restore OAuth2LegacyTokensDto and OAuth2TokensResponseDto classes
- Restore OAUTH_ERROR_DESCRIPTIONS mapping in oauth2-error.service.ts
- Restore OAUTH_ERROR_REASONS lookup in OAuthService.ts mapErrorToOAuthError
- Fix encryption_key_missing error to not expose internal env var name

Addresses Cubic AI feedback with confidence >= 9/10:
- Comment 32 (9/10): Legacy endpoints and input classes
- Comment 34 (9/10): Error description mapping in OAuthService
- Comment 35 (10/10): OAUTH_ERROR_DESCRIPTIONS in error service

Skipped (confidence < 9/10):
- Comment 33 (8/10): getClient handleTokenError vs handleClientError

Co-Authored-By: unknown <>

* Revert "fix: re-apply Cubic AI review feedback on OAuth2 endpoints"

This reverts commit 416bef9c931d9a7ed78c65a70a3425550d61b151.

* delete unused file

* fix: e2e tests

* address cubic review

* fix: address Cubic AI review feedback on OAuth2 exception filter

- Fix header case sensitivity: use lowercase 'x-request-id' instead of 'X-Request-Id' since Express lowercases all request headers
- Redact request body in error logs to prevent exposing sensitive OAuth2 credentials like client_secret, password, and refresh_token

Co-Authored-By: unknown <>

* docs: api v2 oauth controller docs

* chore: remove authorize endpoint

* feat: owner can test non accepted OAuth client

* fix: remove sensitive data from OAuth2 exception logs

Remove Authorization header and userEmail from error logs in
OAuth2HttpExceptionFilter to avoid logging sensitive information.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fix: e2e

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 08:11:46 -03:00
0eb2c15b39 fix: handle JSON string name field from URL prefill for firstAndLastName variant (#28039)
* fix: handle JSON string name field from URL prefill for firstAndLastName variant

* refactoring logic

* improve test coverage

* remove unnecessary comment

---------

Co-authored-by: Maks Pikov <mixelburg@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-19 05:14:51 +05:30
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9d29055808 feat: replace admin API settings page with link to API docs (#28046)
* feat: replace admin API settings page with link to API docs

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

* chore: remove unused AdminAPIView component

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

* feat: rename admin API tab to API Docs

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 17:12:24 -05:00
74f3608b42 fix: Billings page reorganised (#28053)
* billings page reorganised

* Update redirect-apps.generated.ts

* small border update

* udpate for organization billing page

---------

Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-18 21:50:38 +00:00
Dhairyashil ShindeGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9bfa4165b9 fix: prevent sending raw errors in responses (#24282)
* fix: prevent sending raw errors in responses

* correct already existing typo

* style: fix import ordering per biome lint

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-19 02:43:14 +05:30
8a96a45424 feat: update translations via @LingoDotDev (#27639)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-02-18 16:32:10 -03:00
DeepanshuandGitHub 0787c4890e fix: add toggle in workflow form (#27983) 2026-02-18 18:39:11 +01:00
Eunjae LeeandGitHub 51e902f03e chore: pause syncing rules to devin (#28041)
* chore: pause syncing rules to devin

* Revert "chore: pause syncing rules to devin"

This reverts commit dd0e55322fe079b62207c9a4b58c9d24ce1c0dda.

* disable temporarily
2026-02-18 16:35:45 +00:00
9b1bf29ecf chore: remove stale Vitest workspace TODO (#27667)
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-18 14:50:58 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ad65fbbd81 fix: change URL prefill behavior to skip only invalid fields (#26982)
* fix: change URL prefill behavior to skip only invalid fields

Previously, when prefilling booking form fields from URL query parameters,
if any single field failed validation, all prefilling was skipped and an
empty object was returned.

This change modifies the behavior so that only invalid fields are skipped,
while valid fields are still prefilled. The implementation:

- Adds validateSingleFieldForPrefill() to validate individual fields
- Adds parseFieldByField() to collect valid fields when full parse fails
- Modifies getBookingResponsesPartialSchema to use field-by-field parsing
  as a fallback when full schema validation fails
- Logs which specific fields were skipped and why

This improves user experience by preserving valid prefill data even when
some fields have invalid values.

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

* refactor: reduce code duplication in partial prefill validation

Simplify the implementation by integrating field-by-field error handling
directly into the existing preprocess() function instead of using separate
helper functions.

Changes:
- Remove validateSingleFieldForPrefill() and parseFieldByField() functions
- Simplify getBookingResponsesPartialSchema to directly use preprocess()
- Add try-catch wrapper in preprocess() when isPartialSchema=true
- Continue processing other fields even if one fails during preprocessing
- Log skipped fields with reasons at debug level

This reduces code duplication while maintaining the same behavior of
skipping only invalid fields during URL prefill.

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

* fixes

* refactor: rename getRefinedValue to superRefineField and add edge case tests

- Rename getRefinedValue to superRefineField for clarity
- Remove duplicate multiselect test block
- Add test for empty object name field during partial prefill
- Add test for invalid URL format during partial prefill
- Add test for null responses during partial prefill

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

* Simplifu

* Simplif more

* Enhance booking responses schema tests to validate required fields and name variants. Updated error handling for empty names and added tests for first and last name requirements. Refactored schema validation logic to improve clarity and maintainability.

* fix types

* test: add test for email validation behavior during partial prefill

Documents that email validation is relaxed to z.string() during partial prefill,
consistent with phone field behavior where partial values like '+91' are accepted.
This addresses Cubic AI feedback (confidence 9/10) to verify email handling.

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

* fix

* Add tests: packages/features/bookings/lib/getBookingResponsesSchema.test.ts

Generated by Paragon from proposal for PR #26982

* Revert "Add tests: packages/features/bookings/lib/getBookingResponsesSchema.test.ts"

This reverts commit fc2b7ad7ca8099bc4f68e97b383ea16b41cdd772.

* Simplify

* fix: sanitize partial prefill log to avoid exposing user input data

Replaced raw Zod issues array in console.warn with a count of
validation errors to prevent sensitive user data from being logged.

Issue identified by cubic (confidence 9/10).

Co-Authored-By: unknown <>

* fix

* Remove throw Error

* Refactor booking responses schema tests to use helper functions for assertions

- Introduced `expectResponsesToBe` and `expectParsingToFail` helper functions to streamline test assertions.
- Replaced direct assertions with these helper functions for improved readability and maintainability.
- Removed redundant error handling code to simplify test logic.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 20:01:23 +05:30
Peer RichelsenGitHubpeer@cal.com <peer@cal.com>peer@cal.com <peer@cal.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Hariom BalharaSyed Ali Shahbaz
eef47ddefd feat: add duplicate functionality for managed event types (#26792)
* feat: add duplicate functionality for managed event types

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

* feat: add disclaimer and redirect for managed event type duplication

- Add info alert disclaimer in duplicate modal for managed event types
- Pass schedulingType to duplicate dialog via query params
- Redirect to assignment tab after duplicating managed event types
- Add translation key for managed event type duplicate disclaimer

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

* test: add tests for managed event type duplication

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

* refactor: replace PrismaMock unit test with Prisma integration test for duplicate handler (#27973)

* refactor: replace PrismaMock unit test with Prisma integration test for duplicate handler

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: re-throw TRPCErrors in duplicate handler catch block and assert specific error codes in tests

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <1780212+hariombalhara@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-02-18 16:49:23 +04:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
8908a66c23 fix: allow booking rejection via GET for email clients that do not support forms (#28029)
* fix: allow booking rejection via GET for email clients that do not support forms

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

* Refactor test cases for GET handler in route.test.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 17:23:42 +05:30
Alex van AndelGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
a78a3ffe39 refactor: optimize team booking limits query with in-app filtering (#28021)
Replace 3 sequential queries (with expensive attendee email IN clauses)
with 2 parallel queries using indexed eventType.teamId filtering and
in-application user filtering with Sets for O(1) lookups.

Fix managed events booking-limit behavior: managed bookings now only
match by organizer userId (not attendee email), preserving the original
query semantics where managed bookings used userId-only matching.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-18 11:47:30 +00:00
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Udit Takkar
a6a428c8cb feat: make actionSource required with ValidActionSource type across booking handlers (#27869)
* feat: make actionSource required with ValidActionSource type across booking handlers

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

* fix: update getAuditActionSource to return ValidActionSource, default to SYSTEM

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

* fix: revert getAuditActionSource, handleSeats, RegularBookingService back to ActionSource

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

---------

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>
2026-02-18 07:34:25 -03:00
Pasquale VitielloandGitHub 217c6e6a76 chore: re-pull coss-ui components (#28032) 2026-02-18 10:08:35 +00:00
Rajiv SahalGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
b1eb5a2809 feat: api v2 POST booking attendees endpoint (#27759)
* feat: add booking attendee endpoint

* chore: add attendee added email for add guests handler

* cleanup

* fix: restore BookingPbacGuard to prevent IDOR vulnerability in booking attendees endpoint

Co-Authored-By: unknown <>

* chore: implement review feedback, add a core service for booking attendees endpoint

* chore: implement PR feedback

* fix: dont reuse add guests handler instead add logic to add attendee function

* fix: revert previous changes

* chore: implement cubic feedback

* fix: e2e tests

* fix: e2e tests

* fix: remove convertTRPCErrorToErrorWithCode not needed

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 20:46:18 +00:00
Anirban SinghaandGitHub bd5d94a4ba fix: localize remaining hardcoded strings in PayPal setup (#27908)
* chore: add en locale key-value for paypal setup

* fix: add translation function for paypal setup

* chore: avoid merge conflicts
2026-02-17 17:36:45 +00:00
3cfe295ed5 Commit 1 (#28011)
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-17 16:51:21 +00:00
20dcef6680 fix: validate schedule title input to block invalid characters (#27818)
* fix(availability): validate schedule title input to block invalid characters

* fix: add english translation for invalid_characters_in_name

* fix(schedule): allow Unicode characters in schedule name validation

* fix(schedule): update validation message to match regex

* fix: tsconfig target

* fix(schedule): add required validation in NewScheduleButton using translation

* fix(schedule): allow ASCII apostrophe in schedule name validation

* Update ScheduleListItem.tsx

* fix: remove unused @ts-expect-error directives

* fix: remove tsconfig target change

* Revert "fix: remove tsconfig target change"

This reverts commit d4992caf9b71cdfe32ac9db9a509128548097a30.

* Revert "fix: remove unused @ts-expect-error directives"

This reverts commit 913eda500aeccdd67b15cf1898f6db376bf3dda9.

* fix: update validation regex to support unicode characters

* fix: remove es6 from tsconfig

* Update NewScheduleButton.tsx

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-02-17 22:12:38 +05:30
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>Joe Au-YeungDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Udit Takkar
11b65b295b test: add missing negation operator tests for TEXT, NUMBER, and compound rules (#27690)
* Fix exclusion filter - include all team members

* Fix display when members aren't saved in the DB

* Update tests

* test: add missing negation operator tests for TEXT, NUMBER, and compound rules

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

* fix: revert non-intentional changes to AddMembersWithSwitch.tsx

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

---------

Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
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>
2026-02-17 15:45:36 +00:00
+3
Syed Ali ShahbazGitHubali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>hackice20YashMorganDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
4c73695d3a fix: refresh slots on timezone change for booker timezone restrictions (#27491)
* fix: refresh slots on timezone change for booker timezone restrictions

* refactor: use useMemo for timezone change detection

* revert: remove unnecessary formatting changes

* feat: add timezone refresh for platform components

Add timezone change detection and slot refresh to BookerPlatformWrapper
and EventTypeCalendarViewComponent to handle restriction schedules with
useBookerTimezone enabled.

* refactor: extract timezone slot refresh logic into reusable hook

* Update packages/platform/atoms/calendar-view/EventTypeCalendarViewComponent.tsx

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

* Update packages/platform/atoms/calendar-view/EventTypeCalendarViewComponent.tsx

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

* fix

* fix: prevent unnecessary getSchedule calls when useBookerTimezone is disabled

* fix: add timezone fields to BookerEvent type

* fix: add missing properties to BookerEvent and BookerEventProfile types

* trying to fix type errors

* Add restrictionScheduleId and useBookerTimezone fields

* fix: correct import path for useBookerTime hook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: explicitly include restrictionScheduleId and useBookerTimezone in getPublicEvent return

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* chore: trigger fresh CI build

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: cast event.data to BookerEvent for timezone fields access

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: address review feedback for timezone slot refresh

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: add explicit return type to event handler to ensure type propagation

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: extract useStableTimezone hook and remove dead timezone detection code

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: hackice20 <yashkam431@gmail.com>
Co-authored-by: Yash <116657771+hackice20@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 07:46:40 -03:00
Raihanullah ShamsiandGitHub ab4eff1fe1 fix: translate hardcoded 'mins' on payment page (#27998) 2026-02-17 09:26:25 +00:00
Rajiv SahalGitHubrajiv@cal.com <sahalrajiv6900@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
38b43f75ba refactor: remove circular dependencies from CalendarView atom (#27850)
* fix: decouple large calendar from features

* fix: move calendar to features since this is the better approach

* chore: move OOO slots to features

* feat: add DefaultOutOfOfficeSlot fallback for calendar OOO rendering

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

* chore: cleanup unused LargeCalendar component

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-17 08:14:33 +00:00
Hariom BalharaandGitHub 9603831def refactor: update BookingHistory component to use date-fns for timestamp formatting (#27851)
Replaced dayjs with date-fns for better performance and consistency in date handling. Added Tooltip for displaying formatted timestamps and improved search functionality by translating field labels and values. Cleaned up code for better readability.
2026-02-17 13:22:16 +05:30
+5
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Udit Takkar
2bc17313fd fix: deep link reschedule audit log to booking drawer history tab (#27709)
* fix: deep link reschedule audit log to booking drawer history tab

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

* fix: make booking drawer tab-agnostic for cross-tab deep links

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

* fix: use status-agnostic /bookings URL for audit log deep links

- Update audit service URLs from /bookings/upcoming?uid=... to /bookings?uid=...
- Add /bookings/page.tsx redirect that routes to /bookings/upcoming preserving query params
- Update tests to expect new URL format

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

* fixes

* refactor: use client-side replaceState instead of server redirect for booking deep links

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

* fix: use router.replace instead of replaceState to update tab and booking list

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

* improvements

* refactor: extract deep link logic from BookingListContainer into usePreSelectedBooking hook

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

* fix: use proper BookingOutput status type in test helper

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

* fix: decouple getTabForBooking from BookingOutput type for simpler testing

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

* fix: accept Date | string for endTime in BookingForTabResolution interface

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

* refactor: eliminate initialBookingUid prop drilling and revert formatting-only changes

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

* fix: use AuditDeepLink wrapper to preserve target=_blank through ServerTrans cloneElement

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

* Improve code organization

* refactor: rename usePreSelectedBooking to useSwitchToCorrectStatusTab

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

* fix: push preSelectedBooking into store so drawer opens on direct navigation

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

* fixes

* fixes

* fixes

* fix

---------

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>
2026-02-17 13:20:06 +05:30
Syed Ali ShahbazGitHubali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>ali@cal.com <alishahbaz7@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3a7122d613 fix: revert assignmentReason breaking change in webhook payloads (#27891)
* fix: revert assignmentReason breaking change in webhook payloads

Remove the new { category, details } format from EventPayloadType to
maintain backward compatibility for webhook consumers. The new format
is stripped at all webhook payload construction sites by destructuring
assignmentReason out of CalendarEvent before spreading into the payload.

A sanitizeAssignmentReasonForWebhook function provides an additional
safety net in sendPayload itself. Emails and booking single view
continue to use the new format via CalendarEvent.

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: strip assignmentReason from handlePaymentSuccess webhook payload

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* fix: strip assignmentReason from triggerWebhooks and handleSeats webhook payloads

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

* refactor: use zod safeParse instead of type assertion in sanitizeAssignmentReasonForWebhook

Co-Authored-By: ali@cal.com <alishahbaz7@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-16 21:55:10 -03:00
21d28c9747 refactor: apply biome formatting to packages/trpc (#27928)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 12:46:42 -03:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f8a93414a5 chore: remove companion app (moved to calcom/companion) (#27957)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-16 10:08:24 -03:00
85e1ed3ab5 refactor: move cancel logic from inline onClick handler to dedicated function (#27972)
* refactor: move cancel booking logic into handleCancel function

* chore: remove unused comments per review feedback

---------

Co-authored-by: Deepanshu Verma <deepanshuverma186@email.com>
2026-02-16 09:46:42 +00:00
emrysal 4647333839 chore: release v6.2.0 2026-02-16 01:36:08 +00:00
Aritra DeyandGitHub 9d4cb08c55 fix: Correct hours-to-days conversion in convertToNewDurationType (#27964)
Signed-off-by: Aritra Dey <adey01027@gmail.com>
2026-02-15 21:01:00 +05:30
Peer RichelsenGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
773fab858f fix: hide bookings opt-in banner on mobile viewport (#27965)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-15 14:24:21 +00:00
ea0c92a267 fix: use maxLength parameter in truncateOnWord instead of hardcoded value (#27961)
Signed-off-by: Aritra Dey <adey01027@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-02-15 09:51:53 +00:00
Dhairyashil ShindeandGitHub 2abefc412c update version (#27952) 2026-02-14 14:36:43 +00:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9d4b12b8d3 fix: lazy-load companion iframe to avoid requests on every page visit (#27946)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-14 11:41:43 +01:00
Anik Dhabal BabuandGitHub c21281a55c preserve customReplyToEmail (#27941) 2026-02-13 18:09:39 +00:00
sean-brydonandGitHub f5a813f531 Revert "revert (#27933)" (#27938)
This reverts commit 227ed64b49.
2026-02-13 23:36:50 +05:30
Dhairyashil ShindeandGitHub fa53f54815 feat(companion): add configurable landing page (#27267)
* feat(companion): add configurable landing page feature

- Add useUserPreferences hook for persistent storage of landing page preference
- Add LandingPagePicker component for both iOS and Android/web platforms
- Update tabs index to redirect based on user preference
- Update bookings index to accept initial filter from URL params
- Add App Settings section in More screen with landing page selector
- Clear user preferences on logout for fresh state

* fix(companion): remove try-finally for React Compiler compatibility

* fix(companion): use router.replace for dynamic landing page redirect

Replace Redirect component with router.replace() to fix TypeScript
strict typing issue with expo-router's Href type for dynamic routes.

* fix(companion): use literal route strings for TypeScript strict typing

Use switch statement with literal route strings instead of dynamic
string variable to satisfy expo-router's strict Href type checking.

* working fix

* better css
2026-02-13 11:28:42 -03:00
Pedro CastroandGitHub f07bed1a2a chore(deps): bump axios to 1.13.5 (#27864)
* chore: bump axios to 1.13.5

* chore: bump axios in apps/api/v2

* chore: dedupe follow-redirects to 1.15.11
2026-02-13 22:08:49 +09:00
sean-brydonandGitHub 227ed64b49 revert (#27933) 2026-02-13 12:14:08 +00:00