Commit Graph
881 Commits
Author SHA1 Message Date
Eunjae LeeGitHubClaude Opus 4.5unknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
bf348ee209 refactor: migrate Icon to component icons from @coss/ui/icons (#27458)
* feat: add @coss/ui/icons package and migrate static icon usages

Create a new icon system in @coss/ui/icons that wraps lucide-react icons
with controlled props (size and className only). Migrate 44 component
files from <Icon name="xxx" /> to <XxxIcon /> pattern.

This is Phase 1 of the icon migration, covering only static icon names.
Dynamic icon usages (e.g., name={variable}) are skipped for now.

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

* refactor: migrate more static icons to @coss/ui/icons (batch 2)

Migrated 18 files from <Icon name="xxx" /> to <XxxIcon /> pattern:
- Event meta, insights, shell, user table bulk actions
- Webhooks, blocklist, form-builder, form components

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

* refactor: migrate more static icons to @coss/ui/icons (batch 3)

Migrated 7 files:
- CancelBooking, AddGuestsDialog, ChargeCardDialog
- ReassignDialog, RescheduleDialog
- Categories, Slider

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

* refactor: migrate more static icons to @coss/ui/icons (batch 4)

Migrated 6 files:
- Organizations: AboutOrganizationForm, PaymentStatusView, profile
- Workflows: CallDetailsSheet, SkeletonLoaderList, TimeTimeUnitInput

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

* refactor: migrate more static icons to @coss/ui/icons (batch 5)

Migrated 4 files:
- TwoFactorModalHeader
- App setups: alby, make, btcpayserver

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

* refactor: migrate static icons to @coss/ui/icons (batch 6)

- confirmDialog.tsx: clock icon
- ics-feedcalendar/Setup.tsx: trash, plus icons
- hitpay/Setup.tsx: info icon
- paypal/Setup.tsx: circle-alert icons

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

* refactor: migrate static icons to @coss/ui/icons (batch 7)

- webhook-edit-view.tsx: external-link icon
- webhook-new-view.tsx: external-link icon
- UserDropdown.tsx: chevron-down, user, settings, moon, map, circle-help, download, blocks, log-out icons
- TopNav.tsx: settings icon

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

* refactor: migrate static icons to @coss/ui/icons (batch 8)

- EmailInviteForm.tsx: x icon
- InviteOptions.tsx: mail, upload, link icons
- SkeletonLoader.tsx: search, clock, user icons
- Embed.tsx: sun, arrow-left icons
- CalendarSwitch.tsx: arrow-left, rotate-cw icons

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

* refactor: migrate static icons to @coss/ui/icons (batch 9)

- apps-view.tsx: search icon
- categories-view.tsx: arrow-left, arrow-right icons
- DatePicker.tsx: calendar icon
- EditLocationDialog.tsx: map-pin icon
- AppPage.tsx: circle-alert, book-open, external-link, mail, file, shield, flag icons

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

* refactor: migrate static icons to @coss/ui/icons (batch 10)

- LicenseSelection.tsx: loader, check icons
- AppConnectionItem.tsx: circle-alert, arrow-right icons
- oauth-client-form/index.tsx: info icons (x2)
- auth/error/page.tsx: x icon
- troubleshoot/layout.tsx: loader icon

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

* refactor: migrate static icons to @coss/ui/icons (batch 11)

- UpgradeTipWrapper.tsx: users, refresh-ccw, user-plus icons
- PbacOptInModal.tsx: shield-check, lock, users, shield icons
- AdvancedPermissionGroup.tsx: chevron-right, info icons

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

* refactor: migrate static icons to @coss/ui/icons (batch 12)

- AdminAppsList.tsx: pencil icon
- AvailableTimes.tsx: calendar-x-2 icon
- BookingDetailsSheet.tsx: external-link (x2), repeat icons
- BookingCalendarContainer.tsx: chevron-left, chevron-right icons

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

* refactor: migrate static icons to @coss/ui/icons (batch 13)

- videos-single-view.tsx: chevron-right icon
- TroubleshooterSidebar.tsx: arrow-left icon
- RuleBuilder.tsx: filter icon

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

* refactor: migrate static icons to @coss/ui/icons (batch 14)

- FieldMappingBuilder.tsx: arrow-right, link icons
- IntegrationAttributeSyncCard.tsx: key icon
- onboarding-view.tsx: loader icon

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

* refactor: migrate static icons to @coss/ui/icons (batch 15)

- team-profile-view.tsx: copy icon
- DateRangeFilter.tsx: check icon
- ColumnVisibilityButton.tsx: check icon

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

* refactor: migrate static Icon to @coss/ui/icons (batch 16)

- EventWorkflowsTab.tsx: lock
- event-types-listing-view.tsx: search
- onboarding-migrate-members-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, user-plus
- onboarding-migrate-teams-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, arrow-right, users
- EventAvailabilityTab.tsx: globe, user
- onboarding-teams-browser-view.tsx: arrow-left, arrow-right, rotate-cw, lock, ellipsis-vertical, check, arrow-right, users
- FormBuilder.tsx: mail, phone, arrow-up, arrow-down
- AIEventController.tsx: info
- EventTeamAssignmentTab.tsx: x

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

* refactor: migrate static Icon to @coss/ui/icons (batch 17)

- EventAdvancedTab.tsx: pencil, info
- HostLocations.tsx: triangle-alert, loader
- EventTypeLayout.tsx: loader
- Locations.tsx: x, corner-down-right, check
- EditWeightsForAllTeamMembers.tsx: upload, search, info, chevron-down
- WorkflowPage.tsx: pencil

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

* refactor: migrate static Icon to @coss/ui/icons (batch 18)

- TestPhoneCallDialog.tsx: phone
- WorkflowListPage.tsx: link
- UsersTable.tsx: building, lock
- TeamList.tsx: building, paintbrush, chart-line, user-plus, users, pencil
- bookings-single-view.tsx: chevron-left, check, calendar, x, external-link

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

* refactor: migrate static Icon to @coss/ui/icons (batch 19)

- TeamsListing.tsx: users, refresh-ccw, user-plus, mail, video, eye-off, info
- ConnectionInfo.tsx: clipboard
- IntercomContactForm.tsx: message-circle, loader, send

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

* fix: migrate static Icon to @coss/ui/icons in teams components

- EventTypesList.tsx: check → CheckIcon
- MemberInvitationModal.tsx: user, users, building → UserIcon, UsersIcon, BuildingIcon

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

* fix: migrate static Icon to @coss/ui/icons in workflow components

- ImportNumberDialog.tsx: info → InfoIcon
- VoiceSelector.tsx: user → UserIcon
- IncomingCallsTab.tsx: info, phone-incoming → InfoIcon, PhoneIncomingIcon
- PhoneNumberTab.tsx: loader, phone → LoaderIcon, PhoneIcon
- VoiceSelectionDialog.tsx: pause, play, user → PauseIcon, PlayIcon, UserIcon
- WebCallDialog.tsx: loader, phone, phone-off, triangle-alert, trash, message-circle → new icons (kept Icon import for dynamic mic icon)
- WorkflowDetailsPage.tsx: zap, arrow-right → ZapIcon, ArrowRightIcon
- AddActionDialog.tsx: info → InfoIcon

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

* fix: migrate static Icon to @coss/ui/icons in WorkflowStepContainer

- info → InfoIcon (2 instances)
- phone → PhoneIcon (2 instances)
- circle-help → CircleHelpIcon

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

* fix: migrate static Icon to @coss/ui/icons in data-table and org components

- attributes-list-view.tsx: tags → TagsIcon
- AddFilterButton.tsx: plus, eye-off → PlusIcon, EyeOffIcon
- BaseSelectFilterOptions.tsx: check → CheckIcon
- DataTable.tsx: arrow-up, arrow-down, check, chevrons-up-down, eye-off → new icons
- booking-dry-run-success-view.tsx: check → CheckIcon

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

* fix: migrate static Icon to @coss/ui/icons in username and routing components

- UsernameTextfield.tsx: check → CheckIcon
- PremiumTextfield.tsx: check, external-link → CheckIcon, ExternalLinkIcon (kept Icon for star with fill prop)
- Header.tsx (routing-forms): pencil, menu, waypoints → PencilIcon, MenuIcon, WaypointsIcon

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

* refactor: migrate Icon to component icons in routing-forms pages

Batch 25: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- Forms.tsx: file-text, shuffle, chart-bar, circle-check, mail, download → FileTextIcon, ShuffleIcon, ChartBarIcon, CircleCheckIcon, MailIcon, DownloadIcon
- FormEdit.tsx: chevron-down, menu → ChevronDownIcon, MenuIcon
- IncompleteBooking.tsx: globe → GlobeIcon

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

* refactor: migrate Icon to component icons in UI package

Batch 26: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- ProgressToast.tsx: file-down, x → FileDownIcon, XIcon
- showToast.tsx: check, info, x → CheckIcon, InfoIcon, XIcon
- InfoBadge.tsx: info → InfoIcon
- MeetingTimeInTimezones.tsx: globe → GlobeIcon
- InputError.tsx: info → InfoIcon
- ConfirmationDialogContent.tsx: circle-alert, check → CircleAlertIcon, CheckIcon
- CalendarSwitch.tsx: arrow-left, rotate-cw → ArrowLeftIcon, RotateCwIcon
- ArrowButton.tsx: arrow-up, arrow-down → ArrowUpIcon, ArrowDownIcon
- FileUploader.tsx: upload → UploadIcon (kept Icon for dynamic)
- Checkbox.tsx: check → CheckIcon
- EditableHeading.tsx: pencil → PencilIcon

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

* refactor: migrate Icon to component icons in UI and app-store packages

Batch 27: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- MultiEmail.tsx: x → XIcon (converted width to size)
- AppListCard.tsx: circle-alert → CircleAlertIcon
- SplitButton.tsx: chevron-down → ChevronDownIcon (kept Icon for dynamic)
- Calendar.tsx: chevron-left, chevron-right → ChevronLeftIcon, ChevronRightIcon
- AppDependencyComponent.tsx: check, circle-x, arrow-right → CheckIcon, CircleXIcon, ArrowRightIcon

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

* refactor: migrate Icon to component icons in form input components

Batch 28: Migrate static Icon usages to @coss/ui/icons components.

Files changed:
- TextField.tsx: info → InfoIcon (kept Icon for x with onClick)
- Input.tsx: eye, eye-off, search → EyeIcon, EyeOffIcon, SearchIcon

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

* fix: use @coss/ui/src/icons in packages with legacy moduleResolution

Packages like packages/ui and packages/app-store use a legacy moduleResolution
setting that doesn't support subpath exports. This changes the import path from
@coss/ui/icons to @coss/ui/src/icons for these packages.

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

* refactor: migrate Icon to component icons in UI form and editor components

Migrates static Icon usages:
- MultiOptionInput: x (2x), arrow-up, arrow-down
- components (select): check
- AddVariablesDropdown: chevron-down (3x)
- ToolbarPlugin: chevron-down

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

* refactor: migrate Icon to component icons in settings and platform atoms

Migrates static Icon usages:
- SettingsLayoutAppDirClient: chevron-down (2x), chevron-right (2x), arrow-left
- platform/atoms dialog: x
- platform/atoms toast: x

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

* fix: resolve @coss/ui/icons module resolution for legacy moduleResolution

Add typesVersions to @coss/ui package.json to help TypeScript resolve
subpath exports even with legacy moduleResolution: "node" setting.

Change imports from @coss/ui/src/icons to @coss/ui/icons to avoid
double-src path issue when Next.js applies import maps.

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

* fix: localize 'Select field type' fallback label in FormEdit

Address Cubic AI review feedback (confidence 9/10) by using t() for
the hardcoded 'Select field type' string to ensure proper i18n support.

Co-Authored-By: unknown <>

* fix: add typesVersions wildcards for @coss/ui subpath imports

Add lib/*, components/*, and hooks/* to typesVersions to support
legacy moduleResolution with all package subpath patterns.

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

* fix: resolve missing Icon references in settings and workflows

- Add Icon import for dynamic icon usages in SettingsLayoutAppDirClient
- Replace static Icon usages with component icons (InfoIcon, PhoneIcon)

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

* fix: resolve icon component type errors

- Add onClick prop support to IconProps
- Fix size prop type (use number instead of string)
- Rename local MailOpenIcon to MailOpenIconWrapper to avoid shadowing

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

* fix: add data-testid to icon components for test compatibility

- Add testId parameter to createIcon function
- Auto-generate data-testid for all icons (e.g., "check-icon", "search-icon")
- Remove outdated mock for @calcom/ui/components/icon in tests

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

* Update package.json

* Update package.json

* fix: migrate Icon to CalendarDaysIcon in videos-single-view.tsx

Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-12 14:30:27 +01:00
Alex van Andel abbc8bbb7b Revert "fix: availability page UI (#27825)"
This reverts commit 267686704d.
2026-02-10 13:05:50 +00:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
431fbe44fc refactor: decouple @calcom/features from @calcom/trpc/server (#27751)
* make GetPublicEventInput

* space

* mv feature flags router to trpc

* remove trpc imports

* wip

* mv OrgMembershipLookup to features

* fix

* fix

* update

* fix

* revert formatting-only changes to improve PR reviewability

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 09:28:37 -03:00
Udit TakkarGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
267686704d fix: availability page UI (#27825)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 09:06:21 +00:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
96bec9f7b9 refactor: Move repositories from @calcom/lib to @calcom/features domain folders (#27570)
* refactor: move repositories from lib to features domain folders

- Move HolidayRepository to features/holidays/repositories
- Move PrismaTrackingRepository to features/bookings/repositories
- Move PrismaBookingPaymentRepository to features/bookings/repositories
- Move PrismaRoutingFormResponseRepository to features/routing-forms/repositories
- Move PrismaAssignmentReasonRepository to features/assignment-reason/repositories
- Move VerificationTokenRepository to features/auth/repositories
- Move WorkspacePlatformRepository to features/workspace-platform/repositories
- Move DTO files to their respective feature domains
- Merge lib DestinationCalendarRepository into features version
- Merge lib SelectedCalendarRepository into features version
- Update all import paths across the codebase

This follows the vertical slice architecture pattern by organizing
repositories by domain rather than by technical layer.

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

* fix: update VerificationTokenService import path to new location

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

* fix: update test file imports to use new repository locations

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

* mv

* fix structure

* fix

* refactor: merge unit tests for SelectedCalendarRepository into single file

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 08:41:04 -03:00
Benny JooandGitHub e64fad8e34 refactor: remove 6 @calcom/trpc imports from packages/features (#27727)
* migrate booker layout selector

* move schedule hooks and types

* migrate feature opt in components

* migrate feedback dialog

* update

* migrate schedule hooks

* migrate useSegments

* update

* update import paths

* fix import paths

* mv useTimesForSchedule back to features

* fix
2026-02-07 09:05:09 -03:00
Rajiv SahalandGitHub 8a17ebc2ef feat: Troubleshooter atom (#27497) 2026-02-06 17:34:58 +02:00
sean-brydonandGitHub bb6b99d9b1 feat: move platform active billing logic to services (#27704)
* wip

* feat: migrate from v2

* format

* remove plan
2026-02-06 12:45:40 +00:00
MorganGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
295058d123 fix: use Object.prototype.hasOwnProperty.call for safe property checks (#27661)
The error 'TypeError: value.hasOwnProperty is not a function' can occur
when objects are created without the standard Object prototype (e.g., via
Object.create(null) or certain parsing methods). Using
Object.prototype.hasOwnProperty.call() is the safe way to check for
property existence on any object.

Fixed in:
- GetSlotsInputPipe (isById, isByUsernameAndEventTypeSlug, isByTeamSlugAndEventTypeSlug)
- CancelBookingInputPipe (isCancelSeatedBookingInput)
- CreateBookingInputPipe (isRecurringBookingInput, isInstantBookingInput)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 11:11:43 -03:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
357c2882ad refactor: apply biome formatting to several packages (#27439)
* refactor: apply biome formatting to Phase 1 packages

Packages formatted:
- packages/app-store-cli
- packages/config
- packages/dayjs
- packages/debugging
- packages/embeds/embed-react
- packages/embeds/embed-snippet
- packages/kysely
- packages/platform/constants
- packages/platform/utils
- packages/testing
- packages/tsconfig

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

* fix: restore non-null assertions in embed-snippet to fix type error

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

* fix: remove ESM import from CommonJS config file

Biome incorrectly added 'import process from node:process' to a CommonJS
file that uses require(). This breaks Jest which expects CommonJS syntax.
The process global is already available in Node.js without explicit import.

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

* refactor: exclude packages/embeds from Phase 1 formatting

Per user request, reverting all biome formatting changes in packages/embeds
to handle separately.

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

* fix: restore const enum for BookingLocations

Biome changed 'const enum' to 'enum' which is a semantic change.
Reverting to keep the PR purely formatting-only.

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 07:24:34 -03:00
Benny JooandGitHub 249065851b refactor: Break useCreateEventType hook into web-specific and platform-specific ones (#27522)
* migrate useCreateEventType hook to web

* fix

* fix

* fix import
2026-02-05 15:06:05 +05:30
Lauris SkraucisGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
bd25cba89c refactor: OAuth 2.0 endpoints (#27442)
* 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

* refactor: remove scope from docs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-05 10:16:15 +02:00
+1
Lauris SkraucisGitHubunknown <>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>lauris@cal.com <lauris.skraucis@gmail.com>lauris@cal.com <lauris.skraucis@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>Rajiv Sahal
fc602d3b03 feat: OAuth 2.0 support for atoms (#27158)
* fix: useOAuthClient support OAuth 2.0

* fix: cannot read properties of undefined (reading NEXT_PUBLIC_IS_E2E)

* fix: allow OAuth 2.0 token to connect gcal or ms calendar

* fix: allow OAuth 2.0 token to save gcal or ms calendar credentials

* refactor: dont set oauth id header for OAuth 2.0

* fix: calendar events not showing and emails not sent

* feat: CalOAuth2Provider

* chore: make OAuth 2.0 work in examples app

* chore: refresh OAuth 2.0 tokens

* docs: running examples app with oauth 2.0

* fix: remove sensitive console.log statements that leak secrets

Remove logging of:
- OAuth authorization codes (oauth2-user.ts)
- Token-bearing exchange responses (oauth2-user.ts)
- /me response data containing PII (oauth2-user.ts)
- OAuth2 refresh response with tokens (refresh.ts)
- Response payload with access tokens (_app.tsx)

Addresses Cubic AI review feedback for issues with confidence >= 9/10

Co-Authored-By: unknown <>

* docs: update readme

* fix: implemente cubic feedback

* fix: seed script import

* fix: seed script pkce

* fix: correct typos and SQLite capitalization in OAuth2 README (#27176)

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

* refactor: dont return name in public oauth endpoint

* docs: CalOAuthProvider

* chore: add NEXT_PUBLIC_IS_E2E constant to test

* docs: fix duplicated 'or' in Cal OAuth Provider documentation (#27177)

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

* revert: is e2e constant

* fix: typecheck

* refactor: example app users select

* update readme

* chore: update oauth atoms readme

* refactor: enable booking managed event types with user.username instead of profile.username

* fix: EventTypeSettings when viewing round robin

* test: add e2e tests for atoms-oauth2 controller

Co-Authored-By: lauris@cal.com <lauris.skraucis@gmail.com>

* fix: correct error message path in atoms-oauth2 e2e test

Co-Authored-By: lauris@cal.com <lauris.skraucis@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: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-02-04 12:54:15 +01:00
MorganandGitHub 49a2fcaf65 feat: allow users to provide custom apiUrl prop to BookerEmbed (#27576) 2026-02-04 17:53:03 +09:00
Rajiv SahalandGitHub efcbc3a07b fix: avatar URL breaking for team/orgs in BookerEmbed atom (#27424)
* fix: avatar URL breaking for team/orgs in booker embed

* fix: api v2 breaking because of type mismatch

* fix: atoms build

* chore: implement PR feedback
2026-02-03 17:19:48 +00:00
Pedro CastroandGitHub 51b3f5c74d Revert b3430c8efc: fix Atoms build failures on CI (#27575) 2026-02-03 15:39:46 +00:00
078b3935eb chore: update atoms retry mechanism (#27450)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-02-03 15:18:17 +05:30
+10
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>joe@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>
c0f6a1b088 feat: add redirect option for non-routed visits to event types (#27468)
* feat: add redirect option for non-routing form bookings

Add a new event type option that redirects to a custom URL when the booking
was not made through a routing form (no cal.routingFormResponseId or
cal.queuedFormResponseId query parameters).

Changes:
- Add redirectUrlOnNoRoutingFormResponse field to EventType schema
- Add UI toggle in Advanced tab to configure the redirect URL
- Implement redirect logic in bookingSuccessRedirect hook
- Add translations for new UI strings

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

* fix: add redirectUrlOnNoRoutingFormResponse to test builder

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

* fix: add redirectUrlOnNoRoutingFormResponse to BookerEvent type

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

* fix: add redirectUrlOnNoRoutingFormResponse to getPublicEventSelect

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

* fix: add redirect logic to getServerSideProps for non-routing form bookings

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

* fix: remove redirectUrlOnNoRoutingFormResponse from booking success flow

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

* fix: use 'in' operator for type narrowing on redirectUrlOnNoRoutingFormResponse

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

* fix: exclude redirectUrlOnNoRoutingFormResponse from test assertions

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

* fix: include redirectUrlOnNoRoutingFormResponse in test assertions and update description

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

* fix: add redirectUrlOnNoRoutingFormResponse to mockUpdatedEventType

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

* fix: remove redirect logic from instant meetings

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

* fix: add redirectUrlOnNoRoutingFormResponse to EventTypeRepository select

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

* fix: add redirectUrlOnNoRoutingFormResponse to form default values

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

* Reword string

* fix: bust tRPC cache for redirectUrlOnNoRoutingFormResponse

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

* fix: guard redirect when rescheduleUid or bookingUid is present

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

* fix: add redirectUrlOnNoRoutingFormResponse to dynamicEvent defaults

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

* fix: add bookingUid guard to team getServerSideProps redirect

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-02 15:48:23 -03:00
Benny JooGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
8c123ece25 refactor: move shared components from apps/web to packages/features (#27490)
* refactor: move shared components from apps/web to packages/features

Move components that don't require dependency injection:
- DisconnectIntegrationModal
- Booking components (Header, Section, TimeFormatToggle, PayIcon, Price)
- useInitializeWeekStart hook
- TeamEventTypeForm
- Event type components (AssignAllTeamMembers, BulkEditDefaultForEventsModal, etc.)
- Event type dialogs (HostEditDialogs, ManagedEventDialog)
- Location components (LocationInput, types)
- Tab components (EventLimitsTab, EventRecurringTab, etc.)

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

* refactor: update import paths to use @calcom/features

Update imports in apps/web and packages/platform/atoms to reference
the moved components from @calcom/features instead of @calcom/web.

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

* refactor: delete original files from apps/web/modules

Complete the file move by deleting the original files that were
copied to packages/features. This makes it a proper move instead
of a copy, reducing the PR size significantly.

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

* fix: update import paths to use @calcom/features for moved files

Update import paths in apps/web files that reference components
that were moved from apps/web/modules to packages/features:
- LearnMoreLink
- ChildrenEventTypeSelect
- AssignAllTeamMembers
- WeightDescription
- LocationCustomClassNames (types)

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

* fix: update additional import paths for moved components

Update import paths in apps/web files that reference components
moved from apps/web/modules to packages/features:
- AppList.tsx: BulkEditDefaultForEventsModal
- schedule-view.tsx: BulkUpdatParams type
- AddMembersWithSwitch.tsx: AssignAllTeamMembers, CheckedTeamSelect
- EventTypeWebWrapper.tsx: ChildrenEventType, ManagedEventDialog
- DefaultLocationSettings.tsx: LocationCustomClassNames, LocationInput
- Locations.tsx: LocationCustomClassNames, LocationInput

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

* fix: resolve circular dependency by adding isPlatform prop to Header

This fixes the circular dependency where @calcom/atoms (CalendarViewComponent)
was importing Header from @calcom/features, but Header was importing
useIsPlatform from @calcom/atoms.

The fix adds an isPlatform prop to the Header component so it no longer
needs to import useIsPlatform from @calcom/atoms. Callers now pass the
isPlatform value directly:
- atoms components pass isPlatform={true}
- web components pass the isPlatform prop they receive

Fix confidence: 9/10 (Cubic AI)

Co-Authored-By: unknown <>

* fix

* fix

* fix

* fix

* fix

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 10:25:41 -03:00
MorganGitHubmorgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
d29c8a4fa2 fix: add guest limits and rate limiting to booking-guests endpoint (#27494)
* fix: add guest limits and rate limiting to booking-guests endpoint

- Add ArrayMaxSize(10) validation to limit guests per request to 10
- Add aggressive rate limiting (5 requests/minute) via @Throttle decorator
- Add total guest limit check (max 30 guests per booking) to prevent abuse
- Update API documentation to reflect new limits

This prevents scammers from using the endpoint to send spam emails
to hundreds of guests through our system.

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

* docs: update openapi.json with guest limits and rate limiting info

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-02 11:49:25 +02:00
Benny JooGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
73f51920c5 refactor: move Booker hooks from packages/features to apps/web/modules (#27343)
* refactor: move Booker hooks from packages/features to apps/web/modules

Migrate the following Booker hooks:
- useOverlayCalendar
- useSkipConfirmStep
- useInitializeWeekStart
- useIsQuickAvailabilityCheckFeatureEnabled
- useDecoyBooking

These hooks are only imported by apps/web files, making them safe to move
without creating circular dependencies.

Part of the tRPC-driven UI migration from packages/features to apps/web/modules.

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

* fix: revert useIsQuickAvailabilityCheckFeatureEnabled move and fix import paths

- Reverted useIsQuickAvailabilityCheckFeatureEnabled.ts back to packages/features since it's imported by useSlots.ts in packages/features (would create circular dependency)
- Fixed import paths in useOverlayCalendar.ts to use @calcom/features paths
- Fixed import paths in useSkipConfirmStep.ts to use @calcom/features paths
- Updated Booker.tsx to import useIsQuickAvailabilityCheckFeatureEnabled from original location

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

* fix: use @calcom/web alias for hook imports to fix vitest resolution

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

* refactor

* migrate more hooks

* fix

* mv types

* fix

* fix

* fix

* fix

* revert: remove formatting-only changes to make PR easier to review

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

* fix

* fix

* fix

* revert: restore original import ordering in moved hooks

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

* fix imports

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* fix: add isBrowser guard to useSlotsViewOnSmallScreen hook

Address Cubic AI review feedback (confidence 9/10) by adding the isBrowser
guard to the useSlotsViewOnSmallScreen hook to follow the file's client-only
contract and avoid executing during SSR/prerendering.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-31 07:33:33 -03:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
b3430c8efc refactor: remove 10 trpc imports from features package by moving 16 tRPC-driven components to apps/web/modules (#27336)
* refactor: move Segment, BookerLayoutSelector, CreateLicenseKeyForm from packages/features to apps/web/modules

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

* fix: update relative imports to absolute paths in moved files

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

* refactor: move useBookingLocation and blocklist components from packages/features to apps/web/modules

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

* refactor: move EmbedTabs and embed hooks from packages/features to apps/web/modules

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

* fix

* migrate useBookerUrl

* migrate embed tabs

* fix

* fix

* fix

* mv ThemeLabel

* mv settings headers to webn

* update imports

* clean up

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-30 04:55:50 -03:00
Alex van AndelandGitHub 39f97e7326 chore: Reduce circular dependencies in tsconfig resoluttion (#27416) 2026-01-30 02:24:02 +00:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c7ee3984ef refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules (#27222)
* refactor: move feature-flags, calendars, and schedules components from packages/features to apps/web/modules

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

* fix

* fix

* fix

* fix: move DatePicker and DateOverrideInputDialog to apps/web/modules and update imports

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

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* rename

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* wip

* wip

* wip

* fix unit tests

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-29 16:41:44 +02:00
Lauris SkraucisGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Ryukemeister
3b2e3351c4 docs: api v2 and examples app setup (#27290)
* docs: api v2 and examples app setup

* docs: api v2 and examples app setup

* fix: address Cubic AI review feedback

- Fix env file path typo in README.md (apps/api/v2.env -> apps/api/v2/.env)
- Write generated secrets to file instead of logging to console
- Add .generated-secrets to gitignore
- Update README-PLATFORM.md to reflect new secret generation behavior

Co-Authored-By: unknown <>

* chore: update locale

* chore: update docs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
2026-01-29 11:18:23 +00:00
+3
Alex van AndelGitHubalex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>alex@cal.com <me@alexvanandel.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
c9bd18e866 chore: Disables syncing of calendarList on overlay calendar fetch (#27020)
* chore: Disables syncing of calendarList on overlay calendar fetch

* Unwrap ToggledConnectedCalendars

* Pick the right type for connectedCalendars

* further type amends

* Type fixes, tons of em

* Some further fixups consistent with what was before

* fix: resolve type incompatibility in getConnectedDestinationCalendars return type

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

* fix: update DestinationCalendarProps to accept tRPC handler return type

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

* fix: use generic type for DestinationCalendarProps to accept tRPC enriched types

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

* fix: simplify DestinationCalendarProps type for better compatibility

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

* fix: export ConnectedCalendar type for consistent type inference

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

* fix: use permissive type for connectedCalendars to accept tRPC enriched types

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

* fix: export ConnectedCalendar and ConnectedDestinationCalendars types from platform-libraries

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

* fix: update ConnectedCalendar type to use boolean | null for primary field

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

* Update ConnectedCalendarItem

* Undo some of Devins fixes, more fixes

* Fixup the destination calendar return type, historically not null

* Change init to undefined to deal with null

* Approach to connect selected calendars with the right credential

* This return type is used way too much everywhere, not refactoring

* Add the selectedCalendars to the type

* Actually fix overlay calendar

* set calendarsToLoad param as required

* Apply suggestion from @cubic-dev-ai[bot]

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

* Add new translation for 'Calendar Settings'

---------

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-28 14:20:19 -03:00
Volnei MunhozandGitHub 61dd7eb64c chore: Upgrade Next & React (#27332)
* upgrade next and react versions

* upgrade next and react versions

* upgrade next and react versions
2026-01-28 10:47:04 -03:00
Benny JooandGitHub 1a31f9136b refactor: Move integration attribute async components to /web (#27341)
* calendar switch

* wip

* wip

* wip

* fix
2026-01-28 10:44:18 -03:00
MorganGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Rajiv Sahal
bf39489899 feat: add token refresh lifecycle callbacks to CalProvider (#25203)
Add three new optional callbacks to CalProvider that enable users to react during the access token refresh lifecycle:
- onTokenRefreshStart: Called when token refresh begins
- onTokenRefreshSuccess: Called when token refresh succeeds
- onTokenRefreshError: Called when token refresh fails with error message

These callbacks are invoked in both token refresh locations:
1. Response interceptor (when API returns 498 status)
2. Initial access token validation

The callbacks are properly passed through the component hierarchy:
CalProvider -> BaseCalProvider -> useOAuthFlow hook

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-27 14:47:56 +05:30
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
0774a41119 refactor: move hooks and stores from packages/features to apps/web/modules (#27221)
* refactor: move booking-audit client components from packages/features to apps/web/modules

This is part of the larger effort to move tRPC-dependent UI components from packages/features to apps/web/modules to eliminate circular dependencies.

Changes:
- Move BookingHistory.tsx and BookingHistoryPage.tsx to apps/web/modules/booking-audit/components/
- Update imports in apps/web to use the new location

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

* refactor: move formbricks client from packages/features to apps/web/modules

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

* refactor: move hooks and stores from packages/features to apps/web/modules

- Move useAppsData hook from packages/features/apps/hooks to apps/web/modules/apps/hooks
- Move onboardingStore from packages/features/ee/organizations/lib to apps/web/modules/ee/organizations/lib
- Move useWelcomeModal hook from packages/features/ee/organizations/hooks to apps/web/modules/ee/organizations/hooks
- Move useAgentsData hook from packages/features/ee/workflows/hooks to apps/web/modules/ee/workflows/hooks
- Update all import paths in consuming files

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

* refactor: move onboardingStore test file to apps/web/modules

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 13:11:14 +00:00
Rajiv SahalandGitHub 9a927206bd feat: atoms enhancements (#27224) 2026-01-26 13:28:35 +01:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
15268bcfb4 refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules (#27227)
* refactor: move timezone-select, settings, and insights components from packages/features to apps/web/modules

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

* fix

* fix

* fix

* wip

* wip

* wip

* wip

* wip

* wip

* wip

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-26 12:05:18 +00:00
Udit TakkarGitHubunknown <>unknown <>unknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
0ad4367005 feat: Custom host location (#25916)
* chore: save progress

* chore:

* feat: add input dialog

* fix: type error

* feat: mass apply dialog

* test: per host location

* test: fix test

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Remove PII (address, phone number) from tracing logs in RegularBookingService.ts
- Constrain HostLocation.type to EventLocationType["type"] for compile-time validation

Co-Authored-By: unknown <>

* fix: translation

* refactor: improvements

* fix: correct grammar in custom host locations tooltip

Change 'custom host locations is enabled' to 'custom host locations are enabled' (plural subject requires plural verb).

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

Co-Authored-By: unknown <>

* refactor: improvements

* fix: auth

* fix: check

* refactor: improvements

* fix: address Cubic AI review feedback (confidence >= 9/10)

- Add scheduleId to newly created hosts in update.handler.ts to persist
  host-specific schedules during create operations
- Change host location deletion filter from !host.location to
  host.location === null to only delete when explicitly set to null
- Fix static-link per-host locations to use actual link instead of type
  in locationBodyString for bookingLocationService.ts

Co-Authored-By: unknown <>

* fix: preserve existing host scheduleId when not explicitly provided

Change scheduleId handling for existing hosts from 'host.scheduleId ?? null'
to 'host.scheduleId === undefined ? undefined : host.scheduleId' so that
when the client doesn't provide a scheduleId, the existing value is preserved
instead of being cleared to null.

Co-Authored-By: unknown <>

* fix; type erro

* fix; type erro

* fix; type erro

* refactor: move repository

* refactor: move repository

* fix: add singular/plural translations for location_applied_to_hosts

Addresses Cubic AI review feedback (confidence 9/10) to fix '1 hosts' rendering as '1 host' by using i18next plural format with _one and _other suffixes.

Co-Authored-By: unknown <>

* refactor: feedback

* fix: type err

* fix: use uuid in schema and remove attendee locaiton

* fix: type err

* fix: type err

* fix: validate eventTypeId as integer in massApplyHostLocation schema

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-23 11:18:43 -03:00
MorganandGitHub b9b7e50f5a refactor: platform billing jobs tasks constants (#27190) 2026-01-23 12:54:05 +00:00
MorganGitHubmorgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
51976b1eab feat: add rrHostSubsetIds to reschedule booking endpoint (#27135)
* feat: add rrHostSubsetIds to reschedule booking endpoint

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

* test: add e2e test for reschedule with rrHostSubsetIds

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

* chore: update openapi.json

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 17:44:26 +02:00
MorganGitHubmorgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f00f80ed26 chore: ensure default calendars with trigger.dev apiv2 (#27058)
* chore: ensure default calendars with trigger.dev apiv2

* test: add unit and e2e tests for CalendarsTasker integration

- Add unit tests for CalendarsTasker.dispatch when enableAsyncTasker is true
- Add e2e test to verify ensureDefaultCalendarsForUser is called when creating membership
- Mock CalendarsTasker and ConfigService in unit tests
- Test both async (Trigger.dev) and sync (Bull queue) paths
- Fix missing return types on helper functions in e2e tests
- Add *.spec.ts to biome test file exceptions for noExcessiveLinesPerFunction rule

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-21 16:03:30 +02:00
MorganGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c60addc528 feat: add PlatformOrganizationBillingTasker with sync and trigger.dev versions (#26803)
* feat: add PlatformOrganizationBillingTasker with sync and trigger.dev versions

- Create PlatformOrganizationBillingTasker extending Tasker base class
- Add sync tasker (PlatformOrganizationBillingSyncTasker) for synchronous execution
- Add trigger.dev tasker (PlatformOrganizationBillingTriggerTasker) for async execution
- Create trigger.dev task for incrementing subscription usage
- Add PlatformOrganizationBillingTaskService with business logic
- Add PlatformOrganizationBillingRepository for data access
- Add createSubscriptionUsageRecord method to StripeBillingService
- Follow BookingEmailAndSmsTasker pattern for consistency

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

* refactor: move repository methods per PR feedback

- Move findPlatformOrgByUserId to OrganizationRepository
- Create new PlatformBillingRepository for billing queries
- Remove PlatformOrganizationBillingRepository (consolidated)
- Update task service and trigger.dev task to use new repositories

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

* feat: add DI using @evyweb/ioctopus for platform billing tasker

- Create di/tasker/ directory following BookingEmailAndSmsTasker pattern
- Add tokens.ts with DI tokens for all billing tasker classes
- Add module files for PlatformBillingRepository, TaskService, SyncTasker, TriggerTasker, Tasker
- Add container files with getter functions
- Update trigger.dev task to use DI container instead of manual instantiation

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

* refactor: add select statement to PlatformBillingRepository.findByTeamId

Only select subscriptionId field since that's the only field used by the task service

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

* feat: add NestJS DI modules for platform billing tasker in API v2

- Add platform billing tasker exports to platform-libraries/organizations.ts
- Export IBillingProviderService type from platform-libraries
- Create StripeBillingProviderService wrapper implementing IBillingProviderService
- Create PrismaPlatformBillingRepository extending PlatformBillingRepository
- Create NestJS service wrappers for all platform billing tasker classes
- Create PlatformBillingTaskerModule with all providers and exports
- Update PlatformOrganizationBillingTaskService to use Pick<IBillingProviderService>

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

* feat: handle cancel and reschedule usage

* fix: restore IsUserInBillingOrg to billing module providers

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

* chore: add idempotency key

* fix: just log error]

* fix: logger and typo

* fix: address Cubic AI review feedback (high confidence issues)

- Fix grammar error: 'Delayed task are' -> 'Delayed tasks are' in PlatformOrganizationBillingSyncTasker.ts (3 occurrences)
- Re-throw error after logging in increment-usage.ts to enable trigger.dev retry mechanism

Co-Authored-By: unknown <>

* fix: remove duplicate code and use DI instead

* fix: remove orThrow on find first in findPlatformOrgByUserId

* refactor: prevent usage increment task from re-throwing errors

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-20 15:26:50 +09:00
MorganGitHubmorgan@cal.com <morgan@cal.com>unknown <>morgan@cal.com <morgan@cal.com>morgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
62216f2db6 feat: add CalendarsTasker with sync and trigger.dev versions (#26854)
* feat: add CalendarsTasker with sync and trigger.dev versions

This PR implements a CalendarsTasker following the same pattern as
PlatformOrganizationBillingTasker to replace the logic in
apps/api/v2/src/ee/calendars/processors/calendars.processor.ts

New files created:
- CalendarsTasker main orchestrator extending Tasker base class
- CalendarsSyncTasker for sync execution
- CalendarsTriggerTasker for async execution via trigger.dev
- CalendarsTaskService with business logic for ensuring default calendars
- trigger.dev task with queue config and retry settings
- DI modules using @evyweb/ioctopus
- NestJS DI modules for API v2

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

* fix: import and deasync

* style: format trigger.config.ts dirs array

Co-Authored-By: unknown <>

* refactor: move prisma query to UserRepository and set onboarding to true

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

* refactor: remove credential.key from UserRepository method

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-19 16:20:05 +02:00
2227d990b6 refactor: replace loggedInUsersTz with timeZone property in busy-times API (#25440)
* refactor: replace loggedInUsersTz with timeZone in busy-times API

- Add new timeZone parameter to CalendarBusyTimesInput
- Mark loggedInUsersTz as deprecated
- Update getBusyTimes endpoint to prioritize timeZone parameter
- Maintain backward compatibility with loggedInUsersTz
- Add validation to ensure at least one timezone parameter is provided
- Update API documentation with new parameter example

Fixes #25423

* fix: improve timezone validation in CalendarBusyTimesInput

- Use custom ValidatorConstraint instead of problematic ValidateIf
- Properly validate that at least one timezone parameter is provided
- Improve code quality and clarity

* fix: update DTOs for getBusyTimes

* cleanup

* fix: abstract normalize timezone logic into platform types util function

* chore: update e2e tests

* fixup

* fixup

---------

Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2026-01-19 09:22:19 +00:00
Rajiv SahalandGitHub adc4272545 fix: atoms issues (#26983)
* fix: missiing imports

* chore: add popover components for atoms

* chore: keep openapi spec up to date
2026-01-19 08:09:57 +00:00
GusGitHubunknown <>Claude Opus 4.5supalarryAnik Dhabal BabuRajiv SahalRyukemeisterDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
da143ae546 fix: availability unlockedFields initialisation for team-managed event types (#25666)
* Fix: availability unlockedFields initialisation for team-managed event types

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

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

* chore: init managed event type for local atoms testing

* chore: add changeset file

* chore: add tests

* fix: restore eslint-disable comments in managed-user.ts

Addresses review feedback from @anikdhabal to fix the eslint comment
issues where comments were accidentally replaced with whitespace.

Co-authored-by: gusdudey2k <45557946+gusdudey2k@users.noreply.github.com>
Co-Authored-By: unknown <>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-18 09:31:27 -03:00
Rajiv SahalGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1f28504db1 fix(api): add @ApiExtraModels for location types in OpenAPI spec (#26951)
The UpdateInputAddressLocation_2024_08_13 and related location types were
referenced via getSchemaPath() but not registered with @ApiExtraModels,
causing them to be missing from the generated OpenAPI spec.

This fix adds @ApiExtraModels decorator to the BookingLocationController
to register all location types used in the UpdateBookingLocationInput.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-17 00:22:19 +02:00
MorganandGitHub 9391b523e3 fix: rrHostsubsetIds not provided to mapBookingToMutationInput, atoms 2.3.1 (#26122) 2026-01-16 13:55:09 +00:00
Rajiv SahalGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
689ce1ec7f fix: rescheduled booking with multiple durations does not preserve the duration (API v2) (#26746)
* fix: make sure we dont implement directly from @calcom/features

* fix: preserve the original booking duration instead of using the default event type length

* chore: update tests

* fix: merge conflicts

* chore: revert linting changes

* chore: implement PR feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-16 13:53:50 +00:00
MorganGitHubmorgan@cal.com <morgan@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f5085af396 docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2 (#26899)
* docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2

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

* fixup! docs: improve beforeEventBuffer and afterEventBuffer descriptions in API v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 15:27:13 -03:00
Rajiv SahalandGitHub 568d9de160 chore: better error messages (#26890) 2026-01-15 18:28:54 +02:00
Keith WilliamsGitHubkeith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>keith@cal.com <keithwillcode@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3a8fe8c7af perf: convert services to factory functions and add TypeScript project references (#26117)
* perf(app-store): convert services to factory functions to narrow SDK type exports

This change converts CRM, Calendar, Payment, and Analytics services from
exporting classes to exporting factory functions that return interface types.
This prevents SDK types (HubSpot, Stripe, etc.) from leaking into the type
system when TypeScript emits .d.ts files.

Services modified:
- CRM: hubspot, salesforce, closecom, pipedrive-crm, zoho-bigin, zohocrm
- Calendar: all 13 calendar services
- Payment: stripe, paypal, alby, btcpayserver, hitpay, mock-payment-app
- Analytics: dub

Video adapters were audited and already use factory pattern.

WIP: Salesforce CRM service has a type error that needs fixing.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix(salesforce): add type assertion for appOptions in factory function

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

* fix: update remaining consumers to use factory functions

- getAnalytics.ts: call factory function instead of new
- getConnectedApps.ts: call factory function instead of new
- salesforce/CrmService.ts: fix type assertion with default value
- salesforce/routingForm/incompleteBookingAction.ts: use factory function
- salesforce/routingFormBookingFormHandler.ts: use factory function

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

* fix(salesforce): add SalesforceCRM interface for Salesforce-specific methods

- Create SalesforceCRM interface extending CRM with findUserEmailFromLookupField and incompleteBookingWriteToRecord methods
- Add createSalesforceCrmServiceWithSalesforceType factory function for internal Salesforce modules
- Update routing form files to use the new factory function with proper typing

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

* fix(salesforce): correct return type in SalesforceCRM interface

The findUserEmailFromLookupField method returns { email: string; recordType: RoutingReasons } | undefined,
not string | undefined. Updated the interface to match the actual implementation.

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

* fix: update all call sites to use factory functions

- Update calendar API add files to use factory functions (7 files)
- Update Google Calendar test files to use factory functions (3 files)
- Update Salesforce test files to use SalesforceCRM interface
- Add testMode parameter to createSalesforceCrmServiceWithSalesforceType
- Remove unused @ts-expect-error directive in bookingScenario.ts

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

* fix: add GoogleCalendar interface and update factory functions for service-specific methods

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

* fix: add type annotation to attendee parameter in google-calendar.e2e.ts

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

* fix: update selected-calendars/route.ts to use GoogleCalendar factory function

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

* fix: update remaining GoogleCalendarService call sites to use factory function

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

* fix: remove explicit type annotation in google-calendar.e2e.ts to fix type error

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

* fix: update test mocks to use factory function pattern for calendar and payment services

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

* fix: convert MockPaymentService to factory function in setupVitest.ts

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

* fix(api-v2): call calendar service factory functions instead of using new

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

* perf(trpc): add TypeScript project references to reduce build file count

- Add tsconfig.build.json to app-store with composite settings for declaration emit
- Add tsconfig.server.build.json to trpc with project references
- Add types and typesVersions to app-store package.json to redirect type resolution to dist-types
- Add build:types script to app-store for generating declarations
- Add dist-types to .gitignore

This reduces the tRPC build file count from 7,733 to 5,618 files (27% reduction)
by having TypeScript resolve to prebuilt .d.ts files instead of source files.

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

* fix(app-store): add fallback to typesVersions for CI compatibility

The typesVersions now prefers dist-types but falls back to source files
when dist-types don't exist. This fixes CI type-check failures while
still allowing the optimization when dist-types are built.

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

* Added build dependency for tRPC on app-store

* fix(app-store): exclude test directories from tsconfig.build.json

Exclude __tests__, __mocks__, and tests directories from the build
config to prevent test utility files (which import from outside rootDir)
from being included in the declaration emit.

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

* fix(turbo): add build:types task definition for app-store

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

* fix(turbo): remove circular build dependency between trpc and app-store

The build:types task for app-store transitively imports from @calcom/features,
which imports from @calcom/trpc. This creates a circular build dependency when
@calcom/trpc#build depends on @calcom/app-store#build:types.

Solution: Remove the turbo dependency. The typesVersions fallback pattern
['./dist-types/*', './*'] will use source files when dist-types/ doesn't exist,
and use prebuilt declarations when they do exist (for faster builds).

Also exclude dist-types from regular tsconfig.json to prevent 'Cannot write file'
errors when dist-types/ exists.

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

* refactor(app-store): rename dist-types to types for consistency

Rename the prebuilt TypeScript declarations folder from dist-types to types
to match the convention used by @calcom/trpc and other packages in the monorepo.

Updated files:
- tsconfig.build.json: declarationDir and exclude
- tsconfig.json: exclude
- package.json: typesVersions paths
- turbo.json: build:types outputs
- .gitignore: ignore path

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

* fix(api-v2): update ICS calendar test to mock factory function instead of class prototype

The IcsFeedCalendarService is now a factory function, not a class, so
jest.spyOn(IcsFeedCalendarService.prototype, 'listCalendars') no longer works.

Updated to use jest.spyOn(appStore, 'IcsFeedCalendarService').mockImplementation()
to mock the factory function return value instead.

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

* refactor(app-store): rename factory functions to Build* naming convention

- Rename Calendar factory functions from create*CalendarService to BuildCalendarService
- Rename CRM factory functions from create*CrmService to BuildCrmService
- Rename Payment factory functions from PaymentService to BuildPaymentService
- Rename Analytics factory function from createDubAnalyticsService to BuildAnalyticsService
- Update all index.ts re-exports to use new names
- Update all call sites throughout the codebase
- Update test mocks to use new factory function names

This makes it clear that these are factory functions, not class constructors.

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

* fix(app-store): update remaining CalendarService and PaymentService imports to Build* names

- Update api/add.ts files for applecalendar, caldavcalendar, exchange2013calendar, exchange2016calendar, exchangecalendar, ics-feedcalendar
- Update mock-payment-app index.ts to export BuildPaymentService
- Fix googlecalendar test import alias for createInMemoryDelegationCredentialForBuildCalendarService

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

* fix(tests): update payment service mocks to use BuildPaymentService

- Update setupVitest.ts to use BuildPaymentService instead of PaymentService
- Update handlePayment.test.ts mock to use BuildPaymentService

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

* refactor: address PR review comments - rename to Build* and remove unused code

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

* refactor: remove explanatory comments and fix indentation

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

* chore: update .gitignore to use *.tsbuildinfo pattern

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

* fix(api-v2): update IcsFeedCalendarService to BuildIcsFeedCalendarService in e2e test

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

* style: format CalendarService.test.ts

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

* Delete apps/ui-playground/next-env.d.ts

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-15 11:28:05 -03:00
2881961859 feat: add custom calendar reminder for Google Calendar events (#26078)
* feat: add custom calendar reminder for Google Calendar events

Allows users to set default reminder notifications (10, 30, or 60 minutes)
for events created via Cal.com bookings in Google Calendar. This addresses
the issue where Google Calendar's default reminders don't apply to
API-created events.

- Add customCalendarReminder field to DestinationCalendar model
- Create reminder selector UI in destination calendar settings
- Update GoogleCalendarService to apply custom reminders (popup + email)
- Add TRPC endpoint for updating reminder settings

* fix: address code review feedback

- Use z.union with literal values (10, 30, 60) for stricter schema validation
- Add localization for toast messages using t()
- Fix test data to use null for customCalendarReminder to match test intent

* fix: add customCalendarReminder to DestinationCalendar types

Update manually-defined DestinationCalendar types to include the new
customCalendarReminder field added in the previous commit. This fixes
type mismatches when passing Prisma-persisted destination calendars to
functions using these local type definitions.

* fix: update customCalendarReminder type in test to match Prisma schema

The customCalendarReminder field is defined as a non-nullable Int with
default value of 10 in the Prisma schema. Changed test value from null
to 10 to fix TS2345 type error.

* feat: add 'just in time' reminder option for Google Calendar events

- Add 0 (just in time) as a valid reminder option alongside 10, 30, 60 minutes
- Update TRPC schema to accept 0 as valid reminder value
- Add 'Just in time' option to reminder dropdown selector UI
- Add translation for 'just_in_time' key in English locale
- Include comprehensive test case for 0-minute (just in time) reminders
- Remove unused import from test file

This addresses reviewer feedback to provide flexible 'just in time' option that allows reminders to fire at exact event start time.

🤖 Generated with Claude Code

* fix: add customCalendarReminder to calendars service mock

- Add missing customCalendarReminder field to destination calendar mock
- Matches the Prisma schema requirement
- Fixes type error in calendars controller e2e test

* fix: add customCalendarReminder to destination calendars controller test

- Add missing customCalendarReminder field to mock destination calendar
- Matches Prisma schema requirement
- Fixes type error in destination-calendars controller e2e test

* fix: cast customCalendarReminder to ReminderMinutes type

- Add type cast for reminderValue to ensure type safety
- Use nullish coalescing (??) to preserve 0 as valid reminder value
- Ensures database number type is properly cast to ReminderMinutes union

* refactor: simplify translation logic in DestinationReminderSelector

- Remove conditional check for 'just_in_time' label
- Pass count parameter to all translations uniformly
- Translation function handles unused parameters gracefully

Addresses review feedback from @Khaan25

* refactor: make custom calendar reminder opt-in and use repository pattern

- Change default from 10 to null (opt-in feature)
- Add DestinationCalendarRepository to avoid direct Prisma usage
- Add 'Use default reminders' option to UI

* refactor: remove redundant migration file

The original migration already creates customCalendarReminder as nullable,
so this second migration to make it nullable is not needed.

* fix: type error for customCalendarReminder in destination calendar settings

* refactor: validate customCalendarReminder with Zod schema instead of type casting

* refactor: use instance methods in DestinationCalendarRepository

Changed from static to instance methods with getInstance() pattern as requested in review.

* refactor: replace singleton with DI for DestinationCalendarRepository

- Remove getInstance() singleton pattern
- Add DI tokens, module, and container
- Update GoogleCalendarService and tRPC handler to use DI

---------

Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-14 12:32:00 +01:00
+48 a7a8c78494 chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow (#24159)
* chore: Inject repositories instead of Prisma in canellation flow

* simplify

* simplify

* fix formatting issue

* chore: resolve merge conflicts for PR #24159 (#26820)

* matched colour of icons across website (#26394)

* fix(auth): resolve session user by token subject ID (#26399)

* fix(auth): align session user resolution with token subject

* test(auth): add unit tests for getServerSession user resolution

* chore: release v6.0.7

* fix: Custom time input for availability (#26373)

* add custom time input

* add unit test

* add validation logic

* feat(companion): Add DropdownMenu and Alert Dialog for Android (#26385)

* feat(companion): add DropdownMenu for Android event types list

Replace Alert.alert with react-native-reusables DropdownMenu component
for Android event type list items, providing a native-feeling menu
experience that matches iOS functionality.

Changes:
- Install react-native-reusables dropdown-menu component and dependencies
  (lucide-react-native, tailwindcss-animate, class-variance-authority,
  clsx, tailwind-merge)
- Create EventTypeListItem.android.tsx with DropdownMenu implementation
  - Single ellipsis button triggers dropdown menu
  - Menu includes: Preview, Copy link, Edit, Duplicate, Delete
  - Delete action marked as destructive variant
  - Proper safe area insets handling
- Add PortalHost to app/_layout.tsx for portal rendering support
- Create lib/utils.ts with cn() helper for className merging
- Update global.css with theme CSS variables (popover, border, accent,
  destructive, etc.) for dropdown menu styling
- Update tailwind.config.js with theme colors and tailwindcss-animate plugin
- Update metro.config.js with inlineRem: 16 for proper rem unit handling
- Remove Android Alert.alert fallback from event types index.tsx
- Fix lint issues in generated dropdown-menu.tsx (remove unnecessary fragments)

The Android experience now matches iOS with a single menu button that
opens a dropdown containing all event type actions, replacing the
previous Alert.alert dialog and separate action buttons.

Refs: https://reactnativereusables.com/docs/components/dropdown-menu

* adjust with of menu

* feat(companion): add DropdownMenu for Android booking and availability list items

- Add BookingListItem.android.tsx with DropdownMenu for booking actions
- Add BookingDetailScreen.android.tsx with DropdownMenu in header
- Add AvailabilityListItem.android.tsx with DropdownMenu for schedule actions

Actions include: Reschedule, Edit Location, Add Guests, View Recordings,
Meeting Session Details, Mark as No-Show, Report Booking, Cancel Event
for bookings; Set as Default, Duplicate, Delete for availability schedules.

* fix lint issues

* feat(android): replace native alerts with AlertDialog and Toast in event types

- Install AlertDialog and Alert components from react-native-reusables
- Create Android-specific event types screen (index.android.tsx)
- Replace native Alert.alert() with AlertDialog for delete confirmation
- Add inline validation errors (red border + error text) in create modal
- Implement Toast snackbar for success/error notifications (no layout shift)
- Auto-dismiss toast after 2.5 seconds
- Fix React Compiler compatibility by removing animated refs

This provides a more consistent and polished UI experience on Android,
matching the design system used in other parts of the app.

* feat(android): add AlertDialog for availability delete and booking cancel

- Add index.android.tsx for availability with AlertDialog for delete confirmation
- Add index.android.tsx for bookings with AlertDialog for cancel (with reason input)
- Both screens include Toast snackbar for success/error notifications
- Follows the same pattern as event types Android implementation

* feat(companion): add DropdownMenu and AlertDialog for Android

- Replace native Alert.alert context menus with DropdownMenu component
  for event types, bookings, and availability lists
- Replace FullScreenModal with AlertDialog for create/delete/cancel flows
- Add toast notifications for success/error feedback on Android
- Set consistent 380px max-width for all AlertDialogs
- Fix layout headers showing "index" text on event-types and availability
- Create Android-specific More screen with AlertDialog logout confirmation

Uses react-native-reusables components for polished Android UI

* better code

* fix cubics comments

* refactor(android): revert delete confirmations to native Alert.alert()

- Logout: reverted to native Alert.alert() (simple yes/no)
- Event Types Delete: reverted to native Alert.alert() (simple yes/no)
- Availability Delete: reverted to native Alert.alert() (simple yes/no)

Keep AlertDialog only where user input is needed:
- Event Types Create (has TextInput for title)
- Availability Create (has TextInput for name)
- Bookings Cancel (has TextInput for cancellation reason)

* refactor(android): remove redundant index.android.tsx files

The main index.tsx files already handle Android via Platform.OS checks.
Android-specific behavior for actions is in the list item components:
- EventTypeListItem.android.tsx
- BookingListItem.android.tsx
- AvailabilityListItem.android.tsx

This consolidates the code and reduces duplication.

* corrected the implementation both native and alert dialog

* address cubics comments

* fix lint issue and address cubic comments

* chore: add logging in next-auth (#26404)

* Add logging in next-auth
* Add logging at other return

* fix: Make incomplete booking form mobile-responsive (#26413)

* fix: update bundle identifier (#26402)

* fix: patch React 19 vulnerabilities by upgrading to 19.2.3 (#26411)

* security: patch React 19 vulnerabilities by upgrading to 19.2.3

* chore: revert lingo.dev upgrade

* refactor(companion): event type details screen improvements (#26415)

* refactor(companion): move EventTypeDetail component to a new file and update routing

* refactor(companion): format code for better readability in TabLayout and EventTypeDetail components

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code readability and formatting in EventTypeDetail component

* refactor(companion): improve code formatting and readability in EventTypeDetail component

* refactor(companion): enhance code formatting and readability in EventTypeDetail component

* refactor(companion): improve code formatting and readability in TabLayout component

* fix: add vertical spacing when hovered (#26419)

* fix(seed): add missing Host entries for seeded round‑robin team events (#26426)

* feat(companion): new availability detail and actions pages for ios (#26424)

* version 1

* version 1.1

* better code

* covered all edge cases

* address cubics comments

* address cubics comments

* fix(auth): enhance SAML login handling by introducing userId field and updating JWT token structure (#26428)

* fix(ci): delete old prod build caches on cache miss (#26437)

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

* fix(ci): add yarn prisma generate before cache key generation (#26439)

This ensures consistent cache keys between the Build Web App job and E2E
shards by running yarn prisma generate before generating the cache key.

The issue was that packages/prisma/enums/index.ts is:
1. Generated by yarn prisma generate
2. In .gitignore (not committed to git)
3. Included in the SOURCE_HASH (matches packages/**/**.[jt]s)
4. NOT excluded from the hash

E2E jobs already run yarn prisma generate before cache-build, but the
Build Web App job did not, causing different cache keys in the same
workflow run.

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

* fix: show empty screen from event type availability tab (#26396)

* fix

* update

* fix

* Remove copying of App Store static files step

Removed step to copy App Store static files from the workflow.

* feat: queue or cancel payment reminder flow (#24889)

Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* feat: integrate BookingHistory with Bookings V3 design (#26301)

* Integrate BookingHistory with Bookings V3 design

* Enhance booking features by integrating booking audit functionality

- Updated the booking page to retrieve user feature statuses for "bookings-v3" and "booking-audit".
- Modified BookingDetailsSheet and BookingListContainer components to accept and utilize the new bookingAuditEnabled prop.
- Adjusted the BookingHistory display logic to conditionally render based on the bookingAuditEnabled state.
- Refactored SegmentedControl to support generic types for better type safety.

This change improves the user experience by allowing conditional access to booking audit features based on user permissions.

* Refactor BookingDetailsSheet to manage active segment state with Zustand store

- Removed local state management for active segment in BookingDetailsSheet and integrated Zustand store for better state synchronization.
- Introduced useActiveSegmentFromUrl hook to sync active segment with URL query parameters.
- Updated BookingDetailsSheet to handle derived active segment logic based on bookingAuditEnabled state.
- Adjusted SegmentedControl to ensure it defaults to "info" when activeSegment is null.

This refactor enhances the maintainability and responsiveness of the booking details component.

* refactor: rename useBiDirectionalSyncBetweenZustandAndNuqs to useBiDirectionalSyncBetweenStoreAndUrl

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

---------

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

* feat: create BookingHistoryViewerService to combine audit logs with routing form submissions (#26045)

* feat: create BookingHistoryViewerService to combine audit logs with routing form submissions

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

* refactor(booking): rename audit log query and enhance type safety

- Updated the booking logs view to use the new getBookingHistory query instead of getAuditLogs.
- Introduced DisplayBookingAuditLog type for improved clarity in BookingAuditViewerService.
- Refactored BookingHistoryViewerService to utilize the new DisplayBookingAuditLog type and added sorting functionality for history logs.
- Adjusted related types and methods to ensure consistency across services.

* refactor(routing-forms): streamline imports and enhance type definitions

- Consolidated type exports and imports from the features library for better organization.
- Removed redundant type definitions and functions in zod.ts, findFieldValueByIdentifier.ts, getFieldIdentifier.ts, and parseRoutingFormResponse.ts.
- Introduced new utility functions for handling field responses and parsing routing form responses.
- Improved type safety and clarity across routing form response handling.

* fix: remove double prefix from uniqueId in form submission entry

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

* 1c97f9cc5d50416788c01876fe539bcc9750e9b2 (#26453)

---------

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

* chore: Ensure that uuid is available in server session[Booking Audit Prerequisite] (#25963)

## What does this PR do?

Similar to #25721, adds uuid in session so that BookingAudit has it readily available

Adds the user's UUID to the booking metadata by:
1. Extending the NextAuth `User` interface to include an optional `uuid` property from PrismaUser
2. Making `uuid` required on `Session.user` via intersection type (`User & { uuid: PrismaUser["uuid"] }`)
3. Adding `uuid` to the session user object in `getServerSession.ts`
4. Adding `uuid` to the `AdapterUser` transformation in `next-auth-custom-adapter.ts`
5. Passing `userUuid` from the session to the booking creation flow
6. Updating the API key verification flow to include `uuid` in the user data (repository, service, and type definitions)
7. Adding `req.userUuid` as a required field on the request object (like `req.userId`)
8. Adding `uuid` to mock session objects in web app routes and test context
9. Adding `uuid` to the `findByEmailAndIncludeProfilesAndPassword` query in UserRepository

Also removes commented-out code that was placeholder for future work and fixes lint warnings for unused variables.

## 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.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify that the NextAuth session callback is already populating the `uuid` field on the user object
2. Create a booking and confirm `userUuid` is included in the booking metadata
3. Test API v1 endpoints (`/api/invites` POST and `/api/teams/[teamId]/publish`) to verify they receive the uuid from the authenticated user
4. Check that the booking flow works correctly with the new parameter
5. Test SAML login flow to verify session still works correctly (uuid is resolved from database after authentication)

## Human Review Checklist

- [ ] Verify the NextAuth session callback populates `uuid` - if not, this change will pass `undefined` at runtime
- [ ] Confirm `userUuid` is consumed downstream in the booking service
- [ ] Verify that `PrismaApiKeyRepository.findByHashedKey()` correctly fetches the user's uuid from the database
- [ ] Verify the discriminated union type in `ApiKeyService.ts` ensures `result.user` is always defined when `result.valid` is true
- [ ] Confirm all API v1 endpoints using `req.userUuid` go through the `verifyApiKey` middleware
- [ ] Verify `UserRepository.findByEmailAndIncludeProfilesAndPassword()` includes `uuid` in the select clause
- [ ] Verify SAML login still works correctly - uuid is now optional on User interface so SAML providers don't need to supply it at profile stage

## Updates since last revision

- **Made uuid optional on User, required on Session**: Changed the type strategy so `uuid` is optional on the NextAuth `User` interface but required on `Session.user` via intersection type. This allows SAML providers to not supply uuid at the profile stage while ensuring uuid is always present on the session after the user is resolved from the database.
- **Removed uuid from SAML functions**: Since uuid is now optional on User, the SAML profile and authorize functions no longer need to include it.

---

Link to Devin run: https://app.devin.ai/sessions/97e5603b719a420b9b35041252c9db26
Requested by: hariom@cal.com (@hariombalhara)

* fix: add @calcom/trpc#build dependency to @calcom/web#dev task (#26460)

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

* fix(auth): make identityProviderId lookup case-insensitive (#26405)

SAML IdPs may send NameIDs with different casing than stored, causing login failures.
Aligns with the existing case-insensitive email lookup pattern

* fix: cancel running CI workflow before re-triggering and allow trusted GitHub Apps (#26461)

* fix: cancel running CI workflow before re-triggering and allow trusted bots

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

* fix: remove hardcoded bot allowlist, keep only cancel-and-rerun improvement

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

* fix: add app_id verification for trusted GitHub Apps (Graphite)

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

* fix: simplify trusted bot check to use sender type, login, and installation context

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

* chore: remove unnecessary comments

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

---------

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

* feat: update translations via @LingoDotDev (#26445)

Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* fix: remove installation requirement from trusted bot check (#26466)

* fix: remove installation requirement from trusted bot check

The installation object is not present in the webhook payload when
GitHub Apps add labels via pull_request_target events. This caused
graphite-app[bot] to fail the authorization check and fall through
to the human permission check, which doesn't work for bots.

The fix removes the installation requirement and relies on:
- sender.type === 'Bot'
- sender.login matching the trusted bot list

This is secure because the sender fields come from GitHub's webhook
payload and cannot be forged by contributors.

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

* chore: add extra logging about sender type

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

* chore: remove senderId from logging

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

* Update run-ci.yml

---------

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

* refactor: Move trpc-dependent components from features to web [2] (#26420)

* fix

* move event types components to web

* update import paths

* mv apps components

* migrate form builder

* fix

* mv sso

* fix

* mv

* update import paths

* update import paths

* mv

* mv

* mv

* fix

* update Booker

* fix

* fix

* fix

* fix

* mv video

* mv embed components to web

* update import paths

* mv calendar weekly view components

* update import paths

* fix

* fixp

* fix

* fix

* fix

* fix: update FormBuilder imports to use @calcom/features/form-builder

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

* fix: update broken import paths after file migrations

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

* fix: correct import paths for platform atoms and moved components

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

* fix: apply CSS type fixes and add missing atoms exports

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

* fix: resolve type errors in test files after component migrations

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

* fix: resolve remaining type errors in test files

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

* fix

* migrate

* fix: resolve type errors in test and mock files

- Add missing bookingForm, bookerFormErrorRef, instantConnectCooldownMs to Booker.test.tsx bookings prop
- Add all required BookerEvent properties to event.mock.ts
- Add vi import from vitest to all mock files
- Fix date parameter types in packages/dayjs/__mocks__/index.ts
- Add verificationCode and setVerificationCode to test-utils.tsx mock store
- Remove children.type access in Section.tsx mock to fix type error
- Fix lint issues: remove unused React imports, use import type where needed, add return types
- Add biome-ignore comments for pre-existing lint warnings in test files

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

* migrate

* migrate

* migrate

* update import paths

* update import paths

* update import paths

* fix

* migrate data table

* migrate data table

* fix

* fix

* fix

* migrate insights components

* migrate insights components

* fix

* mv

* update import paths

* fix

* fix

* fix

* fix

* fix

* fix: resolve type errors in test mocks

- Booker.test.tsx: Add all required UseFormReturn methods to bookingForm mock
- event.mock.ts: Fix entity, subsetOfHosts, instantMeetingParameters, fieldTranslations, image types
- dayjs/__mocks__/index.ts: Use Object.assign for proper typing of mock properties
- Section.tsx: Change 'class' to 'className' in JSX with biome-ignore comment

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

* fix: add missing hasDataErrors and dataErrors to bookings.errors mock

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

* fix: add missing loadingStates properties to bookings mock

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

* fix: add missing slots properties (setTentativeSelectedTimeslots, tentativeSelectedTimeslots, slotReservationId)

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

* fix: update quickAvailabilityChecks to include utcEndIso and use valid status type

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

* fix: add missing bookerForm properties (formName, beforeVerifyEmail, formErrors)

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

* fix: add missing UseFormReturn properties to bookerForm.bookingForm mock

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

* fix: add hasFormErrors and formErrors to bookerForm.formErrors mock

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

* fix: add hasFormErrors and formErrors to bookerForm.errors mock

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

* fix: add missing isError property to mockEvent

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

* fix: use complete BookerEvent mock in Booker.test.tsx

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

* fix: use branded bookingFields type in event mock

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

* fix: add missing schedule mock properties (isError, isSuccess, isLoading, dataUpdatedAt)

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

* revert

* fix

* fix

* fix

* fix build

* fix

* fix

* fix

* fix: correct AddMembersWithSwitch test wrapper to use initial assignAllTeamMembers value

- Fixed test wrapper to initialize useState with componentProps.assignAllTeamMembers
  instead of hardcoded false, allowing tests to properly test different states
- Updated test expectations for ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE
  state to match actual component behavior (toggle should be present and checked)
- Fixed 'should show Segment when toggled on' test to start with assignAllTeamMembers: false
  to properly test the flow of enabling it
- Added explicit types to satisfy biome lint requirements

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

* fix: use JSX.Element instead of React.JSX.Element for type compatibility

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

---------

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

* chore(deps): update dependencies and add version constraints (#26390)

- Update sanitize-html to 2.17.0
- Remove unused Storybook dependencies from @calcom/ui
- Add resolutions for consistent dependency versions
- Clean up packageExtensions

* feat: add lightweight E2E session warmup page (#26451)

* feat: add lightweight E2E session warmup endpoint

- Add /api/__e2e__/session-warmup endpoint that triggers NextAuth session loading
- Update apiLogin fixture to use the new endpoint instead of navigating to /settings/my-account/profile
- The endpoint is gated by NEXT_PUBLIC_IS_E2E=1 (already set in playwright.config.ts)
- This reduces overhead in E2E tests by avoiding loading a full UI page just to warm up the session

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

* refactor: move session warmup endpoint to App Router

- Move /api/__e2e__/session-warmup from pages/api to app/api
- Use App Router patterns (NextResponse, buildLegacyRequest)
- Maintains same functionality for E2E session warming

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

* rename path

* refactor: switch from API route to minimal SSR page (Option 2)

- Replace /api/e2e/session-warmup API route with /e2e/session-warmup page
- Use App Router page pattern with getServerSession for session warmup
- Update apiLogin fixture to navigate to the page instead of API request

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

* revert users fixture but with a new url

* render nothing on success

* clean up

* trying something

* Revert "trying something"

This reverts commit 2ae2f7dcb42612e54eb072a9f09857272020889a.

---------

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

* Disable noReactSpecificProps as we use react (#26479)

* fix(auth): fix SAML tenant extraction and validation (#26482)

- Extract tenant from userInfo in saml-idp (IdP-initiated)
- Add profile.requested?.tenant fallback for OAuth (SP-initiated)
- Block invalid tenant format in hosted (security)

* fix: atoms build by updating import paths (#26489)

* fix build

* fix build

* fix: "New" button sizing inconsistent between Workflows and Event Types pages (#26066)

* fix: consistent button sizing between fab and button variants on desktop

* fix: consistent button sizing between fab and button variants on desktop

* fix(ui): align New button sizing across pages

* fix: New button sizing inconsistent between Workflows and Event Types pages

* Update Button.tsx

* test: fix unit test flake (#25557)

* fix: revalidate teams cache after accepting invite via token

When a user accepts a team invite via token on the /teams page, the
teams cache was not being invalidated. This caused the page to show
stale data (empty list) while the sidebar correctly showed the teams.

This fix adds a call to revalidateTeamsList() after processing an
invite token, ensuring the cache is invalidated and fresh data is
fetched immediately.

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

* fix: revalidate teams cache after creating team in onboarding flow

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

* Remove comments on teams cache revalidation

Removed comments about revalidating teams cache after invite processing.

* fix unit test flake

* Remove unused import in useCreateTeam hook

Removed unused import for revalidateTeamsList.

* Remove unused import for revalidateTeamsList

---------

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

* chore: Add impersonation context support to booking audit (#26014)

## What does this PR do?

Adds infrastructure to track impersonation context in booking audit records and displays it in the UI. When an admin impersonates another user and performs booking actions, the audit system now:
- Records the **admin** as the actor (who actually performed the action)
- Stores the **impersonated user's UUID** in a separate `context` field
- Displays **"Impersonated By"** in the booking logs UI when viewing audit details

This separation ensures audit trail integrity (the admin is accountable) while preserving full context about whose account was being used.

### Changes
- Added `uuid` to `impersonatedBy` session object for actor identification
- Added `uuid` to top-level `User` type in next-auth types for session enrichment
- Added `context Json?` field to `BookingAudit` Prisma model
- Added `BookingAuditContextSchema` for type-safe context handling with `actingAsUserUuid` field
- Updated producer service interface and implementation to pass context through all queue methods
- Updated consumer service to persist context to database
- Updated repository to store and fetch context in BookingAudit records
- Added `impersonatedBy` field to `EnrichedAuditLog` type in `BookingAuditViewerService`
- Added `enrichImpersonationContext` method to resolve impersonated user details
- Updated booking logs UI to display "Impersonated By" in expanded details
- Added `impersonated_by` translation key

Link to Devin run: https://app.devin.ai/sessions/3f1252527aef4ead9401bdf055c0817b
Requested by: hariom@cal.com (@hariombalhara)

## 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 - internal infrastructure change
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.

## How should this be tested?

1. Verify type checks pass: `yarn type-check:ci --force`
2. Verify existing audit tests still pass: `TZ=UTC yarn test`
3. To fully test impersonation context display:
   - Have an admin impersonate a user
   - Perform a booking action (create, cancel, reschedule)
   - Navigate to the booking's audit logs
   - Expand the details for the action
   - Verify "Impersonated By" row appears showing the impersonated user's name
   - Verify the BookingAudit record has:
     - `actorId` pointing to the admin's AuditActor
     - `context` containing `{ actingAsUserUuid: "<impersonated-user-uuid>" }`

## Human Review Checklist

- [ ] Verify the `context` field schema design is appropriate for future extensibility
- [ ] Confirm the `uuid` addition to User type in next-auth doesn't break existing auth flows
- [ ] Check that the optional `context` parameter doesn't break existing queue method callers
- [ ] Verify no migration file is needed (or if squashing is handled separately)
- [ ] Verify the UI displays "Impersonated By" correctly when impersonation context is present
- [ ] Confirm `enrichImpersonationContext` handles edge cases (null context, invalid context, deleted user)

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have checked if my changes generate no new warnings

* perf: improve cal video webhook (#26495)

* perf: improve cal video webhook

* save format

* refactor: use errorMs

* chore: change API codeowner to Foundation (#26504)

* chore(auth): add error logging for saml-idp silent failures (#26484)

* chore(auth): add error logging for saml-idp silent failures

* chore(auth): add warn-level logging for saml-idp silent failures

* chore(auth): change 'No user found' log to warn level

* chore(auth): add warn-level logging for silent auth failures

- saml-idp authorize: credentials, code, token, userInfo, user lookup
- callbacks:signIn: account type, email, name, catch-all
- callbacks:jwt: unknown account type (info → warn)
- saml:profile: missing email from IdP
- getServerSession: user not found for valid token

* 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>

* chore: remove Mintlify AI chat from CMD+K widget (#26485)

* chore: remove Mintlify AI chat from CMD+K widget

- Remove MintlifyChat component and related state from Kbar.tsx
- Delete packages/features/mintlify-chat directory (MintlifyChat.tsx, util.ts)
- Delete apps/web/app/api/mintlify-chat API routes and tests
- Delete packages/lib/server/mintlifyChatValidation.ts
- Remove Mintlify-related env vars from .env.example and turbo.json
- Refactor Kbar.tsx to fix lint issues (explicit types, exports at end)

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

* fix: use ReactNode import instead of JSX from react

The JSX type is not exported from 'react' module. Use the global
JSX.Element type (available in React projects) and import ReactNode
for the children prop type.

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

* feat: add all event-types and upcoming bookings to KBar

- Increase event types limit from 10 to 100 to show more event types
- Add useUpcomingBookingsAction hook to fetch and display upcoming bookings
- Bookings show title, date, and time in KBar search results
- Navigate to booking details page when selecting a booking

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

* Revert "feat: add all event-types and upcoming bookings to KBar"

This reverts commit 69d03397e3820e45e7207eb55b38117d269eae5e.

---------

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

* feat: update translations via @LingoDotDev (#26497)

Co-authored-by: Lingo.dev <support@lingo.dev>

* 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>

* feat: add organization banner to user profile page (#26514)

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

* feat: Hubspot write to meeting object (#26039)

* feat: Hubspot write to meeting object

* fix: translate hardcoded strings and remove debug console.log

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

* refactor

* fix: improve static value detection for placeholder replacement

- Changed condition from startsWith/endsWith to includes('{') to properly detect embedded placeholders
- Strings like 'Hello {name}!' are now correctly processed for placeholder replacement
- Pure placeholder tokens that can't be resolved return null
- Partially resolved values are returned as-is

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

* refactor: split WriteToObjectSettings into types and utils files

- Extract interfaces, enums, and type definitions to WriteToObjectSettings.types.ts
- Extract constants and utility functions to WriteToObjectSettings.utils.ts
- Update main component to use the new utility functions
- Improves code organization and maintainability

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

* revert: restore original static value detection logic

Per user request - the startsWith/endsWith check was intentional

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

* test: add unit tests for HubSpot CRM service

Tests cover:
- ensureFieldsExistOnMeeting: field validation against HubSpot properties
- getTextValueFromBookingTracking: UTM parameter extraction
- getTextValueFromBookingResponse: placeholder replacement
- getDateFieldValue: date field resolution for different date types
- getFieldValue: main field value resolution for all field types
- generateWriteToMeetingBody: write-to-meeting body generation
- getContacts: contact search functionality

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

* fix: correct type errors in HubSpot CRM service tests

- Import WhenToWrite enum from crm-enums
- Replace string literals with WhenToWrite.EVERY_BOOKING enum values
- Add missing whenToWrite property to field config objects

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

* fix: use type casting for intentional type errors in tests

- Cast numeric fieldValue to string for testing non-string handling
- Cast invalid field type string to CrmFieldType for testing unsupported types

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

* fix: prevent unhandled promise rejections in HubSpot CRM tests

- Re-apply mockGetAppKeysFromSlug implementation in beforeEach to ensure
  mock is always set correctly after clearAllMocks
- Change vi.resetAllMocks() to vi.clearAllMocks() to preserve mock
  implementations between tests
- Add explicit types to satisfy biome lint rules
- This fixes the 'Cannot read properties of undefined (reading client_id)'
  errors that were causing CI to fail with exit code 1

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

* refactor: convert HubSpot tests to black-box testing through public methods

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

* fix: properly type mock CalendarEvent in HubSpot tests

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

* fix: properly type TFunction in mock CalendarEvent

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

* chore: graceful owner fail test

* refactor

* fix: type check

* fix: remove null fields

* Update packages/app-store/hubspot/lib/CrmService.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.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>

* docs: add DTO location and naming conventions to knowledge base (#26478)

* docs: add DTO location and naming conventions to knowledge base

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

* docs: clarify DTO location rules for new features vs refactored code

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

* docs: simplify DTO location - all DTOs go in packages/lib/dto/

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

---------

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

* refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency (#26515)

* refactor: convert PrismaAttributeToUserRepository to accept Prisma as dependency

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

* fix: use Prisma types from generated client instead of custom types

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

---------

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

* fix: handle existing users on invite token flow (#26217)

* fix(auth): validate user before signup with invite token

Validate if user already exists before creating account when
signing up with team or organization invite tokens. Existing users
are redirected to login to accept the invitation.

- Add user existence check in signup handlers
- Return 409 for existing users with redirect to login
- Extract signup fetch logic to dedicated module
- Add e2e test coverage

* fix(auth): address code review feedback

- Fix fetchSignup tests to use vi.spyOn for proper mock restoration
- Add content-type validation before parsing JSON response
- Guard against undefined error in Stripe callback
- Use t() for localized error message
- Fix race condition in handlers by catching P2002 on create

* fix(auth): address additional code review feedback

- Add INVALID_SERVER_RESPONSE constant to follow established pattern
- Check error.meta.target includes email before returning USER_ALREADY_EXISTS
to avoid false positives from other unique constraint violations
- Add select: { id: true } to user.create calls since downstream functions only
need the user id

* test: add unit tests for P2002 handling in signup handlers

- Add shared test suite covering all P2002 edge cases
- Ensure 409 only for email constraint violations
- Fix non-token paths to use atomic create + catch pattern

* fix: update error message copy per review feedback

* fix(auth): address code review feedback and prevent orphan Stripe customers

- Add user existence check before Stripe customer creation (token flow)
- Add select clause to user.create for consistency
- Fix showToast argument order (pre-existing bug)
- Use toHaveURL instead of waitForURL in E2E tests

* fix(auth): resolve 500 errors by fixing Prisma error detection across module boundaries

The instanceof check for PrismaClientKnownRequestError fails when different
Prisma client instances are loaded. Added fallback check by constructor name

* fix(auth): validate invitedTo before upsert on team invite signup

* test(auth): update P2002 tests for new invite flow

P2002 tests now use non-token flow since token flow uses upsert
Added tests for invitedTo validation on invite signup

* fix(auth): add guards and P2002 handling per review feedback

- Guard existingUser check with if (foundToken?.teamId)
- Guard username check with if (username) for premium flow
- Add `select` clause to findFirst/findUnique queries
- Add try-catch on upsert for race condition P2002 errors

* fix(auth): narrow P2002 handling to email/username targets

* chore: release v6.0.8

* fix: Support 10-digit phone numbers for Ivory Coast (+225) (#26465)

* fix: update ivory coast mask to 10 digits

* update formating for Benin numbers

---------

Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>

* fix(ci): use env vars for input interpolation in workflow run steps (#26520)

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

* refactor: use structured logger in video adapters (#26285)

- Remove debug console.log/console.error statements
- Add logger.debug for observability (meeting lifecycle events)
- Add logger.error with safe error pattern (message + name only)
- Fix error messages to avoid exposing response details
- Remove redundant try/catch blocks (errors propagate naturally)

* fix: validate owner email on platform org creation (#26286)

Remove isPlatform bypass from owner verification to ensure users can only create organizations where they are the designated owner. Add test coverage for create and intentToCreateOrg handlers:

- Regression tests for isPlatform bypass fix
- Happy path for admin creating org for another user

* 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>

* Make booking-audit integration test utils reusable (#26526)

* fix: generate compliant passwords using meeting_password_requirement (#26148)

* fix(zoomvideo): generate compliant passwords using meeting_password_requirement

- Add meetingPasswordRequirementSchema to parse Zoom's password policy settings
- Implement validatePasswordAgainstRequirements() to check if a password meets the policy
- Implement generateCompliantPassword() to create passwords that comply with the policy
- Update translateEvent() to use getCompliantPassword() which validates the default password
  or generates a new compliant one based on meeting_password_requirement
- Add meeting_password_requirement to the settings API filter
- Improve error handling for non-JSON responses in OAuthManager (XML validation errors)

This fixes the frequent 'Error in JSON parsing Zoom API response' errors caused by
Zoom returning XML validation errors when the password doesn't comply with the
account's password policy (e.g., numeric-only requirement).

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

* refactor: use cleaner single-pass consecutive character check

- Replace nested-loop O(n*k) implementation with single-pass O(n) helper
- Add proper guard for consecutiveLength < 4 (Zoom allows 0, 4-8)
- Move consecutive check before only_allow_numeric to apply it for all cases
- Fix edge-case bug where consecutiveLength 1-3 could incorrectly reject passwords

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

* Optimize OAuth response handling

Refactor OAuth response validation to read body only once.

* Improve error handling in Zoom API response parsing

Refactor error handling for Zoom API response parsing to improve logging and clarity.

* Improve compliant password generation logic

Enhance password generation to avoid consecutive characters when numeric only is required.

* Remove password requirement handling from VideoApiAdapter

Removed meeting password requirement schema and related functions for password validation and generation.

---------

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

* refactor: Clean up the /tests in the root (#26525)

* refactor: Delete mockTRPCContext and mockData, and relocate mockStripeSubscription to stripe mock.

* chore: Delete unused Stripe, video client, and reminder scheduler mock files.

* feat(companion): UI Enhancements for Android and Extension (#26434)

* feat: companion-android-ui-upgrade version 1

* recurrings and unconfirmed booking filter and page implementation

* add badge and links to event type list page

* address cubics comments

* feat(companion): unify dropdown menu for Android and extension (#26486)

* feat(companion): unify dropdown menu for Android and extension

- Merge Android-specific dropdown implementations into base component files
- EventTypeListItem: Add DropdownMenu with Preview, Copy link, Edit, Duplicate, Delete actions
- BookingListItem: Add DropdownMenu with booking actions (reschedule, edit location, add guests, etc.)
- RecurringBookingListItem: Add DropdownMenu with recurring booking actions
- AvailabilityListItem: Add DropdownMenu with Set as Default, Duplicate, Delete actions
- BookingDetailScreen: Add DropdownMenu in header for Android with AlertDialog for cancel confirmation
- Delete all .android.tsx files as implementations are now unified

* fix(companion): fix typecheck errors after dropdown unification

- Remove unused props from EventTypeListItem.ios.tsx (copiedEventTypeId, handleEventTypeLongPress)
- Remove unused onActionsPress prop from BookingListItem.ios.tsx
- Remove copiedEventTypeId and handleEventTypeLongPress props from index.ios.tsx and index.tsx
- Remove onLongPress and onActionsPress props from BookingListScreen.tsx
- Remove handleScheduleLongPress, setSelectedSchedule, setShowActionsModal props from AvailabilityListScreen.tsx
- Fix BookingDetailScreen.tsx to use correct action property names (reschedule.visible instead of canReschedule, etc.)

* fix(companion): remove unused code after dropdown unification

- Remove unused handleEventTypeLongPress function and ActionSheetIOS import from index.ios.tsx
- Remove unused copiedEventTypeId state, handleEventTypeLongPress function, and ActionSheetIOS import from index.tsx
- Prefix unused setSelectedBooking with underscore in BookingListScreen.tsx
- Remove unused handleScheduleLongPress function and ActionSheetIOS import from AvailabilityListScreen.tsx

* feat(companion): unify booking filter UI for Android and extension

- Remove SegmentedControl from web/extension booking list page
- Use Header dropdown for booking status filter on both Android and web
- Use unified event type filter dropdown for both platforms
- Remove unused showFilterModal state and related code
- Pass filterOptions, activeFilter, and onFilterChange to Header for all platforms

* fix(companion): add header padding for web/extension to prevent button clipping

- Add headerLeftContainerStyle and headerRightContainerStyle with 12px padding for web platform
- Applied to root Stack and all nested tab Stack layouts
- Fixes issue where header buttons were touching edges and getting chopped off on extension/web
- Android remains unaffected as the fix is web-only

* fix(companion): add HeaderButtonWrapper for web-only header padding

- Create HeaderButtonWrapper component that adds 12px margin on web only
- Wrap all header buttons with HeaderButtonWrapper to prevent clipping
- Revert invalid screenOptions changes that caused typecheck errors
- Apply fix to all screens with native header buttons:
  - reschedule.tsx, edit-location.tsx, add-guests.tsx
  - mark-no-show.tsx, view-recordings.tsx, meeting-session-details.tsx
  - event-type-detail.tsx, BookingDetailScreen.tsx, profile-sheet.tsx
  - edit-availability-day.tsx, edit-availability-name.tsx, edit-availability-override.tsx

* update more ui-ux

* address cubics comments

* address cubics comments & open event type list page first for inttial render of app

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

* 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 declaratio…

* fix: remove duplicate onBookingCancelled call

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

---------

Signed-off-by: Bandhan Majumder <bandhanmajumder16@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ram Shukla <codewithrex@gmail.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Manas Kenge <man.kng02@gmail.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Eesh Midha <72607015+eeshm@users.noreply.github.com>
Co-authored-by: Beto <43630417+betomoedano@users.noreply.github.com>
Co-authored-by: shashank-100 <shashank.telkhade@gmail.com>
Co-authored-by: Kartik Labhshetwar <kartik.labhshetwar@gmail.com>
Co-authored-by: Abhay Mishra <grabhaymishra@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Ryukemeister <sahalrajiv6900@gmail.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: cal-com-ci[bot] <247290566+cal-com-ci[bot]@users.noreply.github.com>
Co-authored-by: Lingo.dev <support@lingo.dev>
Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: Anshumancanrock <109489361+Anshumancanrock@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Amit Sharma <74371312+Amit91848@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Kartik <103111467+kartik-212004@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Adarsh Tiwari <adarshtiwari797023@gmail.com>
Co-authored-by: Dylan Tarre <timecreepsby@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Amin Jaoui <101276751+aminjaoui@users.noreply.github.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Mehmet Sungur <mehmetsungurmutlu@gmail.com>
Co-authored-by: xDipzz <155362028+xDipzz@users.noreply.github.com>
Co-authored-by: Pasquale Vitiello <pasqualevitiello@gmail.com>
Co-authored-by: pasquale@cal.com <pasquale@cal.com>
Co-authored-by: cal.com <morgan@cal.com>
Co-authored-by: Anas Najam <129951478+anzz14@users.noreply.github.com>
Co-authored-by: Bandhan Majumder <133476557+bandhan-majumder@users.noreply.github.com>
Co-authored-by: mintlify[bot] <109931778+mintlify[bot]@users.noreply.github.com>
Co-authored-by: Kartik Saini <41051387+kart1ka@users.noreply.github.com>
Co-authored-by: Abhishek <abhiifour@gmail.com>
Co-authored-by: susan@cal.com <susan@cal.com>
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
Co-authored-by: simiondolha <34995943+simiondolha@users.noreply.github.com>
Co-authored-by: simiondolha <simiondolha@users.noreply.github.com>
Co-authored-by: Kirankumar Ambati <kiran.chinna12520@gmail.com>
2026-01-14 08:20:37 -03:00
f32ea8b4c5 fix: Booker reschedule behaviour for org admin (#26530)
* fix: reschedule behaviour for org admin

* fix: use pbac for permissions check

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-13 18:12:32 +00:00