Commit Graph
15807 Commits
Author SHA1 Message Date
Alex van Andel 509ceeaa86 chore: release v6.1.3 2026-01-22 08:56:41 -03:00
sean-brydonGitHubClaude Sonnet 4.5Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3af533e2c8 feat: add monthly proration processing (#27002)
* feat: add seat tracking infrastructure for monthly proration

Add seat change logging infrastructure with operationId for idempotency.
This PR adds the foundation for monthly proration billing by tracking
seat additions and removals, gated behind the monthly-proration feature flag.

- Add operationId field to SeatChangeLog for idempotency
- Update SeatChangeLogRepository to support upsert with operationId
- Add feature flag guard in SeatChangeTrackingService
- Integrate seat tracking in team member invites
- Integrate seat tracking in bulk user deletions
- Integrate seat tracking in team service operations
- Integrate seat tracking in DSYNC user creation

When monthly-proration feature flag is disabled, seat logging is skipped
and behavior remains unchanged.

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

* feat: add monthly proration processing

Add monthly proration billing processing that works on top of the seat
tracking infrastructure. This PR implements the core proration logic,
webhook handlers, and integration with Stripe billing.

- Enhance MonthlyProrationService to process seat change logs
- Add payment webhook handlers (invoice.payment_succeeded, invoice.payment_failed)
- Update subscription webhook to sync billing period on renewals
- Update TeamBillingService to skip real-time updates when proration enabled
- Enhance StripeBillingService with proration capabilities
- Add Tasker enhancements for processing queues
- Update team creation/upgrade routes

Depends on: feat/monthly-proration-seat-tracking

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

* fix: remove unused logger from SeatChangeTrackingService

* fix: description for calculation

* fix null check on trial

* chore: no more prisma calls

* add feature flag check

* fix stub

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 11:23:38 +00:00
Amit SharmaGitHubunknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f9d40e083f feat: store utm tags in stripe on signup (#26838)
* feat: store utm params in stripe on signup

* fix: fallback to cookie when query params don't contain valid UTM data

Changed from else-if to separate if statement so that when query
params exist but don't contain valid UTM data, the cookie fallback
is still tried. Previously, any request with non-UTM query params
would skip the stored cookie data entirely.

Co-Authored-By: unknown <>

* fix: e2e

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 08:13:47 -03:00
Eunjae LeeandGitHub 087fa03513 test: add e2e test for Feature Opt-In banner (#27100)
## What does this PR do?

Adds an end-to-end test for the Feature Opt-In banner flow. This test verifies the complete user journey from seeing the banner to enabling a feature.

Currently `OPT_IN_FEATURES` in `packages/features/feature-opt-in/config.ts` is empty, so this e2e test skips. Once we uncomment the `bookings-v3` item from the config, this e2e test will run and pass. This is a preparation for when we enable the feature.

**Changes:**
- Creates a new e2e test file (`feature-opt-in-banner.e2e.ts`) that tests the complete opt-in flow
- Adds `data-testid` attributes to banner and dialog components for reliable test selectors

## 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 - test only.
- [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. Add the `ready-for-e2e` label to run e2e tests in CI
2. The test should pass when run with `PLAYWRIGHT_HEADLESS=1 yarn e2e feature-opt-in-banner.e2e.ts`

**Test requirements:**
- The `bookings-v3` feature flag must exist in the Features table (the test uses `prisma.feature.upsert` to ensure this)
- The test will skip if `bookings-v3` is not in `OPT_IN_FEATURES`

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [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

## Updates since last revision

- Replaced text-based locators (`getByText`, `getByRole`) with `data-testid` selectors for more reliable element targeting
- Added `data-testid` attributes to `FeatureOptInBanner`, `FeatureOptInConfirmDialog`, and `FeatureOptInSuccessDialog` components

## Human Review Checklist

- [ ] Verify the `data-testid` attributes don't conflict with existing test IDs in the codebase
- [ ] Confirm the test correctly skips when `bookings-v3` is not in `OPT_IN_FEATURES`
- [ ] Check that the added `data-testid` attributes follow the project's naming conventions

---
Link to Devin run: https://app.devin.ai/sessions/97158ab1b7414e3988ba803b30d95b3e
Requested by: @eunjae-lee
2026-01-22 12:09:13 +01:00
f00568e798 fix(umami): add default SCRIPT_URL in zod.ts (#27114)
* fix(umami): add default SCRIPT_URL in zod.ts

* fix(umami): update default URLs to cloud.umami.is

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-22 10:53:25 +00:00
45ea59ceb8 fix: prevent CalDAV duplicate invitations with RFC-compliant SCHEDULE-AGENT (#22434)
* fix: prevent CalDAV duplicate invitations with RFC-compliant SCHEDULE-AGENT

Fixes #9485

Adds SCHEDULE-AGENT=CLIENT to ATTENDEE lines in CalDAV createEvent and
updateEvent operations per RFC 6638 Section 7.1. This tells CalDAV servers
(Fastmail, NextCloud, etc.) that the client handles scheduling, preventing
duplicate invitation emails.

Implementation includes:
- RFC 5545 compliant line folding (max 75 octets per line)
- UTF-8 aware byte counting for international names
- Proper handling of :mailto: format in ATTENDEE lines
- Skips lines that already have SCHEDULE-AGENT parameter

* fix: address Cubic review - unfold lines and case-insensitive matching

- Add unfoldLines() to handle RFC 5545 folded lines before processing
- Use case-insensitive regex (gim flag) per RFC 5545 spec
- Simplify regex to properly capture params and value separately

* fix: only unfold/refold ATTENDEE lines, preserve other lines

- Match ATTENDEE lines including folded continuations
- Unfold only the matched ATTENDEE line
- Re-fold after adding SCHEDULE-AGENT=CLIENT
- Other iCal lines remain untouched (no RFC 5545 violation)

* fix: check SCHEDULE-AGENT only in params, not value

Only check for existing SCHEDULE-AGENT in the params portion,
not the value (which contains email/CN). This prevents false
positives when email contains "schedule-agent" substring.

* fix: handle quoted colons and exact SCHEDULE-AGENT matching

1. Colon parsing: Match :mailto:/:http:/:urn: patterns, or fallback
   to finding colon not inside quotes
2. SCHEDULE-AGENT check: Use regex to match exact parameter name
   (preceded by ; or at start), not substring match

* add tests

* Update .env.example

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-22 16:23:06 +05:30
Ram ShuklaandGitHub be13bdf18e fix: Matched styling of Webhooks just like api keys page. (#27116)
* fixed text issue

* fixed text issue

* matched style of api keys page
2026-01-22 10:27:20 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ee076d7102 perf: add composite index on EventType(parentId, teamId) (#27099)
* perf: add composite index on EventType(parentId, teamId)

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

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 06:43:05 -03:00
devin-ai-integration[bot]GitHubali@cal.com <ali@cal.com>ali@cal.com <ali@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>ali@cal.com <ali@cal.com>
2a98693dcd feat: add assigned badge to team event types (#27036)
* feat: add assigned badge to team event types

Add an 'Assigned' badge to Round Robin and Collective event types
when the current user is a host/participant of the event type.
This provides visibility to users without edit permissions that
they are included in the rotation.

Changes:
- Add isCurrentUserHost flag in getEventTypesFromGroup handler
- Display blue 'Assigned' badge in event types listing view
- Add i18n translation for 'assigned' text

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

* refactor: remove redundant isTeamEvent check for assigned badge

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-22 10:16:22 +01:00
Lauris SkraucisandGitHub 3b8b2299af docs: OAuth self serve (#27090) 2026-01-22 12:36:57 +04:00
AnshumancanrockandGitHub 856deaaead fix: workflows action delete icon hover color (#27106) 2026-01-22 08:21:33 +00:00
Anik Dhabal BabuandGitHub a934bc5dc2 fix: clic app icon is not showing (#27101) 2026-01-22 13:22:55 +05:30
Eesh MidhaandGitHub 38cdf3b23f fix: disable booking actions for cancelled/rejected/past bookings (#26926)
* fix: disable booking actions for cancelled/rejected/past bookings

* test: add tests for bookign actions disabled states
2026-01-21 20:22:47 +00:00
Volnei MunhozandGitHub f7f4df6922 Fix nav tab-stick position (#27097) 2026-01-21 16:37:25 -03:00
+2
Rajiv SahalGitHubrajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>rajiv@cal.com <sahalrajiv6900@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Peer RichelsenHariom Balhara
8c39210a12 fix: scroll issues in Embed (#26583)
* chore: add new view for two step slot selection for embed

* fix: make sure two step slot selection is false by default

* chore: update embed playground to showcase two step slot selection

* chore: add tests

* chore: update embed snippet generator code to include two step slot selection

* chore: update docs

* fix: back button styling

* chore: implement feedback from cubic

* fix: add missing isEnableTwoStepSlotSelectionVisible properties to test mock store

Co-Authored-By: unknown <>

* chore: implement PR feedback

* chore: update slot selection modal

* chore: add prop to hide available times header

* fix: scope two-step slot selection visibility to mobile only

Restores the isMobile check in the timeslot visibility guard to ensure
desktop embeds continue to show the booking UI when two-step slot
selection is enabled. The feature should only hide the timeslot list
on mobile devices.

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

Co-Authored-By: unknown <>

* fixup: use translations for loading instead of actual word

* fix: type check

* fix: add window.matchMedia mock for jsdom test environment

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

* fix: add window.matchMedia mock to packages/testing/src/setupVitest.ts

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

* fix: unit tests failing

* add a width style to the two-step slot selection embed container.

* refactor: rename enableTwoStepSlotSelection to useSlotsViewOnSmallScreen

- Rename external-facing embed config option from enableTwoStepSlotSelection to useSlotsViewOnSmallScreen
- Update URL parameter parsing in embed-iframe.ts
- Update type definitions in types.ts and index.d.ts
- Update internal variable names to slotsViewOnSmallScreen for consistency
- Update documentation, playground examples, and tests

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

* Add config to prefill all booking fields so that slot has confirm button along with it

* chore: implement PR feedback

* fix: move twoStepSlotSelection embed outside misc-embeds div to fix e2e test

The e2e test was failing because the misc-embeds div content was
intercepting pointer events on mobile viewport. This follows the same
pattern used for skeletonDemo - the embed is now outside misc-embeds
and the div is hidden when testing this namespace.

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

* fix: prevent pointer event interception in twoStepSlotSelection embed

Hide heading and note elements and set pointer-events: none on container
elements while keeping pointer-events: auto on the iframe container.
This prevents the container from intercepting clicks on the iframe
during mobile viewport e2e tests.

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

* fix: hide all non-essential content for twoStepSlotSelection e2e test

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

* fix: disable pointer-events on body for twoStepSlotSelection e2e test

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

* fix: remove pointer-events: auto on container to let clicks pass through to iframe

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

* fix: explicitly set pointer-events: none on container and inline-embed-container

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

* fix: also set pointer-events: none on html element to prevent interception

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

* fix: make .place div fill viewport for twoStepSlotSelection e2e test

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

* fix: failing embed tests

* fixup

* fixup fixup

* fix: failing tests

* fix: update checks for verifying prefilled date

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-01-21 15:44:33 -03:00
6c620e37a6 refactor: remove redundant filtering in service (#25874)
* refactor: remove redundant filtering and return filtered users from service

* Simplify user retrieval by returning users directly

* Fix formatting issue in users.service.ts

* Filter out null users in getDynamicEventType

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-21 15:12:54 -03:00
Ram ShuklaandGitHub 5bfbec6915 made changes to the nav dropdown style to maintain the centre lining and the differentiator in the option avaialable with dropdown (#27038) 2026-01-21 18:04:12 +00:00
Volnei MunhozGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ddcac4b3b1 fix: make linting required for CI (#27091)
* fix: make linting required for CI

- Remove continue-on-error from lint workflow so CI fails on lint errors
- Fix 2 lint errors: avoid importing from @trpc/server in lib package
- Add trpcErrorUtils.ts to handle TRPC errors without circular dependencies
- Update lint-staged to show warnings but not block commits

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

* fix: add message field validation to isTRPCErrorLike type guard

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 15:01:37 -03:00
f17933bc43 fix: prevent HTML encoding in names (#26959)
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-21 17:37:08 +00:00
Peer RichelsenGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
769035b1ee feat: add Help Desk search link when KBar has no results (#27062)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 17:32:58 +00:00
Anik Dhabal BabuandGitHub 186a3e648f fix: handle incomplete href attributes in workflow email links (#27094)
* handle incomplete href

* addrss cubic comment
2026-01-21 17:20:16 +00:00
Hariom BalharaandGitHub 9fa245a03b getSchedule request similar to booking page needs org username instead of user.username (#27086) 2026-01-21 22:19:13 +05:30
Peer RichelsenGitHubpeer@cal.com <peer@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Volnei Munhozcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
cfb1db45b2 feat: add Cloudflare URL Scanner for malicious URL detection (#26387)
* feat: add Cloudflare URL Scanner integration for malicious URL detection

- Add MALICIOUS_URL_IN_WORKFLOW to LockReason enum
- Add URL_SCANNING_ENABLED constant for feature flag
- Create urlScanner.ts utility for Cloudflare Radar URL Scanner API
- Create scanWorkflowUrls task for async URL scanning with polling
- Integrate URL scanning into scanWorkflowBody task
- Add URL scanning for event type redirect URLs
- Lock user accounts when malicious URLs are detected
- Fix pre-existing lint issues (parseInt radix, optional chaining)

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

* fix: address biome lint warnings and TypeScript iterator errors

- Wrap iterators with Array.from() to fix TS2802 errors
- Add biome-ignore comments for process.env usage
- Extract helper functions to reduce function length
- Move exports to end of file per useExportsLast rule
- Remove problematic imports that cause TypeScript errors

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

* fix: address cubic-dev-ai review comments for URL scanning

- Fix P0: Re-fetch workflow steps before scheduling notifications to use actual verifiedAt values from database instead of overriding with new Date()
- Fix P1: Mark workflow step as verified in submitWorkflowStepForUrlScanning when URL scanning is disabled or no URLs found
- Fix P1: Add whitelistWorkflows parameter to submitUrlForUrlScanning for consistency
- Fix P2: Preserve URL context in error results in urlScanner.ts scanUrls function

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

* fix: add select clause to Prisma query for workflow steps

Address cubic-dev-ai P2 comment: Use select to fetch only the required
fields (id, action, sendTo, emailSubject, reminderBody, template, sender,
verifiedAt) instead of fetching all columns from workflowStep table.

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

* fix: add select clause to Prisma query in scanWorkflowBody.ts

Address cubic-dev-ai P2 review comment: Use select to fetch only the
required fields (id, action, sendTo, emailSubject, reminderBody,
template, sender, verifiedAt) instead of fetching all columns.

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

* test: add unit tests for URL scanning functionality

- Add tests for urlScanner.ts (extractUrlsFromHtml, isUrlScanningEnabled)
- Add tests for scanWorkflowUrls.ts (happy/unhappy paths for URL scanning task)
- Add tests for scanWorkflowBody.ts (happy/unhappy paths for workflow body scanning)

Tests cover:
- URL extraction from HTML content
- URL normalization and deduplication
- Handling of malicious URLs and user locking
- Fail-open behavior for API errors
- Whitelisted user handling
- Iffy spam detection integration

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

* test: remove incomplete test that provides no value

Removed the 'should mark all steps as verified when neither Iffy nor URL scanning is enabled' test as it used vi.doMock() which doesn't work after module import, had no assertions, and gave false confidence in test coverage.

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

* refactor: use Cloudflare bulk scanning endpoint to reduce API quota usage

- Added submitUrlsForBulkScanning function that uses /urlscanner/v2/bulk endpoint
- Updated scanUrls to use bulk submission instead of individual URL submissions
- Bulk endpoint accepts up to 100 URLs per request, batching is handled automatically
- Reduces API quota usage as suggested by keithwillcode

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

* Update packages/features/tasker/tasks/scanWorkflowUrls.ts

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

* fix: address cubic-dev-ai review comments

- P1: Sanitize URLs before logging to prevent exposing sensitive query parameters
- P2: Extract handleUrlScanningForStep helper function to reduce code duplication
- P2: Use vi.stubGlobal for fetch mock in tests for proper cleanup

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

* fix: address volnei review comments on PR #26387

- Move vi.unstubAllGlobals() to afterEach hook in iffyScanBody tests
- Restore updateMany optimization when URL scanning is disabled

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-01-21 12:28:57 -03:00
+1
Peer RichelsenGitHublauris@cal.com <lauris@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>eunjae@cal.com <hey@eunjae.dev>Lauris Skraucissupalarrycubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>CarinaWollilauris@cal.com <lauris@cal.com>Morgan
a03722fd7f feat: add OAuth client developer settings page with approval workflow (#25556)
* feat: add OAuth client developer settings page with approval workflow

- Add new developer OAuth page at /settings/developer/oAuth for users to submit OAuth client requests
- Transform admin OAuth page into management dashboard for reviewing/approving submissions
- Add OAuthClientApprovalStatus enum (PENDING, APPROVED, REJECTED) to track submission status
- Add userId and createdAt fields to OAuthClient model for tracking submissions
- Create email notifications for admin (new submission) and user (approval)
- Add sidebar navigation link in developer section below API keys
- Add comprehensive translations for new UI strings
- Create OAuthClientRepository for data access following repository pattern

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

* fix: re-export generateSecret for backward compatibility

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

* feat: make logo mandatory and list items clickable for OAuth clients

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

* fix: add missing translation keys and remove client secret from details dialog

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

* fix: address cubic AI reviewer comments

- Remove duplicate 'there' JSON key in common.json
- Add select clause to findByUserId to avoid exposing clientSecret
- Add @@index([userId]) to OAuthClient model for query performance
- Update migration to include the index

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

* fix: address PR review comments - fix indentation and use useCopy hook

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

* fix: change react-dom/server import to fix Turbopack compatibility

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

* Revert "fix: change react-dom/server import to fix Turbopack compatibility"

This reverts commit c3e0b709c2d88fd221143cb4ce9cd25bb8c94277.

* fix: use email service pattern for OAuth client notifications

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

* fix: add try-catch around email sending to handle Turbopack react-dom/server issue

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

* Revert "fix: add try-catch around email sending to handle Turbopack react-dom/server issue"

This reverts commit fc9d47cd773505ebc5ee2696718aad4a8a98be77.

* fix: improve OAuth client UI with skeleton loaders and smaller dialog styling

- Replace 'Loading...' text with proper skeleton loaders in both developer and admin OAuth client views
- Make client_id and copy button smaller in dialogs using size='sm' and text-sm styling
- Add 'client_id' translation key to common.json for proper i18n

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

* fix: improve skeleton loader to match actual OAuth client list structure

- Remove divide-y from container and use conditional border-b on rows
- Match the exact structure from oauth-clients-view.tsx L126-160
- Use proper spacing for text elements (mt-1 instead of space-y-2)

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

* fix skeleton

* rename the selected oauth client dialog

* fix: address PR feedback - admin auth, dropdown styling, sidebar label

- Add defense-in-depth admin authorization check in updateClientStatus handler
- Fix broken dropdown menu by using DropdownItem with StartIcon prop
- Fix sidebar menu label from 'oAuth' to 'oauth_clients' to match developer view

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

* update common.json

* feat: show client secret in approval email for confidential OAuth clients

- Add regenerateSecret method to OAuthClientRepository
- Regenerate secret when admin approves a PENDING confidential client
- Include client secret in approval notification email
- Add one-time warning message about storing the secret securely
- Only regenerate on first approval (not re-approvals)

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

* feat: add Website URL field, fix logo styling, show client secret after approval

- Add Website URL field to OAuth client forms (admin and developer views)
- Fix Upload Logo section styling by wrapping in Label div with proper gap
- Display client secret in dialog after admin approves a confidential OAuth client
- Add websiteUrl field to Prisma schema with migration
- Update tRPC handlers and repository to support websiteUrl
- Add translation keys for new UI elements

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

* fix: move clientSecret variable declaration outside if block for proper scoping

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

* refactor: dont expose client secret in emails

* refactor: dont regenerate secret upon status change

* refactor: reuse existing hash function

* refactor: rename admin/oAuth to admin/oauth page

* refactor: deduplicate oauth repositories

* refactor: remove withGlobalPrisma from oauth repository

* refactor: developer oauth page

* refactor: oauth status by default accepted

* refactor: request oauth status when creating

* refactor ux

* fix: address Cubic AI code review feedback

- Add purpose field to plain text email body for accessibility
- Convert NewOAuthClientButton to inline JSX to avoid React anti-pattern
- Trigger re-approval when redirectUri changes for security
- Add e.preventDefault() for Space key to prevent page scroll
- Change default approvalStatus to PENDING for defense-in-depth
- Use oauth_clients translation key for consistency
- Add meaningful alt text to Avatar for accessibility
- Remove onClick from DialogClose to prevent double-run close effects
- Return NOT_FOUND for non-owner delete to prevent resource enumeration

Co-Authored-By: unknown <>

* common.json file

* refactor: delete all prisma migrations

* refactor: have just 1 prisma migration

* revert: some devin changes

* fix: typecheck

* test: owner OAuth crud

* test: admin OAuth approval / rejection

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

- schema.prisma: Remove @default("") from purpose field to make it required
- schema.prisma: Use UTC-aware timezone expression for createdAt default
- OAuthClientFormFields.tsx: Localize redirect URI placeholder using t()
- common.json: Add redirect_uri_placeholder translation key

Co-Authored-By: unknown <>

* cubic changes

* refactor: dont log sensitive info and rethrow error

* cubic feedback

* refactor: make oauth client purpose optional

* refactor: admin/oauth not allowed if not logged in

* refactor: admin view skeleton

* refactor: rename state

* refactor: get rid of redundant mapping

* refactor: remove redundant handler

* refactor: remove redundant handler

* refactor: re-usable new oauth client button

* refactor: dialogs

* refactor: modals

* refactor: handler names, dialog, skeleton

* fix: purpose being null

* refactor: rename handler and delete old oauth admin page

* fix: purpose in submission

* refactor: handler names

* refactor: rename

* refactor: update handler

* refactor: rename approvalStatus -> status

* refactor: simplify modal

* refactor: name

* dont require repproval if redirectUri changes

* fix: remove integration sync index creation

* refactor: require re-approval if redirectUri updated

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: remove duplicate common.json keys

* refactor: replace team@cal.com with SUPPORT_MAIL_ADDRESS

* refactor: generate client secret on handler level

* fix: authorization code only available to approved clients

* refactor: cubic review dont display exclamation

* refactor: cubic review website_url in common json

* fix: dont default in ui to approved status

* refactor: optiona logo in schema create handler

* fix: tests

* fix: tests

* fix: /authorize redirect if client not approved or show error

* test: authorize page with invalid client id

* refactor: dont allow refreshing tokens unless approved client

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* fix: flaky e2e test

* chore: warn that pending client is not usable

* fix: approve and reject buttons

* fix: /authorize show error if client not approved

* refactor: info message about editing oauth client and status

* change info alert to warning

* try to fix ci test

* debug: failing e2e test

* fix: improve session propagation in oauth-client-admin E2E test

- Add navigateToAdminOAuthPage helper that waits for listClients API call
- If the API call doesn't arrive (session issue), reload page to force session refresh
- This fixes the CI flakiness where admin page wasn't loading due to session not having ADMIN role

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

* fix: register waitForResponse before navigating in E2E test

- Register the listClients waitForResponse promise BEFORE page.goto()
- This ensures the response isn't missed during page load
- Also register the promise before reload in the catch block

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

* fix: rename oAuth folder to oauth for case-sensitive filesystems

The admin OAuth page route was at /settings/admin/oAuth (capital A) but the
code references /settings/admin/oauth (lowercase). This caused 404 errors
on case-sensitive filesystems (Linux).

Also improved the E2E test navigation helper to retry with delays if the
admin page doesn't load immediately, handling session propagation timing.

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

* test style

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: eunjae@cal.com <hey@eunjae.dev>
Co-authored-by: Lauris Skraucis <lauris.skraucis@gmail.com>
Co-authored-by: supalarry <laurisskraucis@gmail.com>
Co-authored-by: cubic-dev-ai[bot] <1082092+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: lauris@cal.com <lauris@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2026-01-21 12:23:51 -03:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
5449b8d913 refactor: store timestamp instead of boolean for feature opt-in (#27080)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 15:17:32 +00:00
Alex van AndelGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1e1379546b refactor: remove usage of deprecated user.startTime and user.endTime columns (#27085)
These columns are marked as deprecated in the Prisma schema and will be
removed in a follow-up migration. This PR removes all code references to
prepare for the column removal.

Changes:
- Remove startTime/endTime from ProfileRepository userSelect and methods
- Remove startTime/endTime from UserRepository userSelect and methods
- Remove startTime/endTime from me/get.handler.ts API response
- Remove endTime from API v1 user validation schema

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 11:45:37 -03:00
Alex van AndelGitHubalex@cal.com <me@alexvanandel.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ccf99fbb6b refactor: remove Object.freeze hack in getConnectedCalendars (#27070)
* refactor: remove Object.freeze hack in getConnectedCalendars

The previous implementation used Object.freeze to prevent the destinationCalendar
object from being mutated when looping through multiple calendar credentials.
This was a workaround for a bug where the wrong calendar's primaryEmail and
integrationTitle would be set when multiple credentials existed.

This refactor properly fixes the issue by:
1. Only setting destinationCalendar once (when first found)
2. Using a flag to track when the destination calendar is found in the current credential
3. Only setting primaryEmail and integrationTitle for the credential that contains
   the destination calendar

Fixes the hack mentioned in: https://github.com/calcom/cal.com/pull/7644

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

* refactor: move destinationCalendar enrichment outside the loop

Per feedback, moved the destinationCalendar finding and enrichment
completely outside the Promise.all loop. After all connected calendars
are fetched, we search through the results to find and enrich the
destination calendar with primaryEmail and integrationTitle.

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 11:30:20 -03: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
Volnei MunhozGitHubVolnei MunhozDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f44ee33c6c fix: filter out Google system calendars from calendar list (#27074)
* fix: filter out Google system calendars from calendar list

Google system calendars (holidays, birthdays) don't return proper
free/busy information, making them useless for availability checking.
This change filters them out from the listCalendars() method so users
won't see these calendars as selectable options.

Filtered calendar types:
- Holiday calendars (#holiday@group.v.calendar.google.com)
- Birthdays/contacts calendar (#contacts@group.v.calendar.google.com)

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

* test: add tests for Google system calendar filtering

Tests verify that listCalendars() correctly filters out:
- Holiday calendars (#holiday@group.v.calendar.google.com)
- Birthdays/contacts calendar (#contacts@group.v.calendar.google.com)

Test cases cover:
- Filtering holiday calendars
- Filtering birthdays calendar
- Mixed calendars (keeping regular, filtering system)
- All system calendars (returns empty array)
- Null/undefined calendar IDs
- Various international holiday calendar formats

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 10:00:08 -03:00
Dhairyashil ShindeandGitHub 1c3c6292df refactor: handle unavailable features on iOS and consolidate settings UI (#27081)
- Refactor duplicate UI components (SettingsGroup, SettingRow, NavigationRow) into [SettingsUI.tsx]
- Centralize showNotAvailableAlert in utils/alerts.ts
- Replace in-app browser links with Feature not available alerts for iOS on:
  - More tab items (Apps, Routing, Workflows, Insights, Support)
  - Event Type Other tab (Apps, Workflows, Webhooks)
  - Event Type Advanced tab (Private Links)
- Remove View public page from Profile Sheet on iOS
- Remove Preview actions from Event Type (List menu and Detail quick actions) on iOS
- Add Learn More links to Advanced Tab settings
2026-01-21 09:42:06 -03:00
devin-ai-integration[bot]GitHubali@cal.com <ali@cal.com>ali@cal.com <ali@cal.com>unknown <>ali@cal.com <ali@cal.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>ali@cal.com <ali@cal.com>Syed Ali Shahbaz
cb567a91c5 feat: add option to hide duration selector in booking page for multiple durations (#27033)
* feat: add option to hide duration selector in booking page for multiple durations

- Add 'hideDurationSelectorInBookingPage' field to event type metadata schema
- Add checkbox under Default Duration select in event type settings
- Modify Duration component to hide selector when setting is enabled
- URL params can still set duration when selector is hidden
- Add i18n translation for the new checkbox label
- Add e2e tests for the new functionality

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

* fix: rename checkbox label to 'Hide duration selector'

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

* fix: replace text locator with data-testid in E2E test

Replace `text=Multiple duration` locator with `page.getByTestId("event-types").locator('a[title="Multiple duration"]')` to follow E2E test best practices.

Co-Authored-By: unknown <>

* fix: add data-testid to hide duration selector checkbox for E2E tests

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2026-01-21 10:39:36 +02:00
Anik Dhabal BabuGitHubanik@cal.com <adhabal2002@gmail.com>unknown <>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
4162b5be55 feat: remove Revert.dev dependency from Pipedrive integration (#22492)
* feat: remove Revert.dev dependency from Pipedrive integration

- Replace Revert API calls with direct Pipedrive OAuth2 and REST API
- Update OAuth flow to use Pipedrive's authorization endpoint
- Implement token exchange in callback handler
- Map Revert's unified API format to Pipedrive's native API structure
- Remove REVERT_* environment variables from configuration
- Update app config to reflect direct Pipedrive integration
- Follow patterns from other CRM integrations like HubSpot

Breaking change: Requires PIPEDRIVE_CLIENT_ID and PIPEDRIVE_CLIENT_SECRET
environment variables instead of REVERT_* variables

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

* feat: implement proper token refresh logic for Pipedrive OAuth

- Add token refresh implementation following Pipedrive OAuth2 specification
- Use proper Basic Auth for token refresh requests
- Handle token refresh errors with appropriate logging
- Update access token and expiry date after successful refresh
- Add note about database credential update requirement

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

* feat: add database credential updates for Pipedrive token refresh

- Import updateTokenObjectInDb utility for proper credential management
- Store credentialId in constructor for database updates
- Update token refresh logic to persist refreshed tokens to database
- Follow Cal.com patterns for OAuth credential management
- Ensure tokens are properly updated after successful refresh

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

* refactor: use OAuthManager for Pipedrive token management

- Refactor CrmService.ts to use OAuthManager instead of manual token refresh
- Create getPipedriveAppKeys helper function for client credentials
- Update callback.ts to use the new helper function
- Add requestPipedrive helper method for all API calls
- Implement proper token refresh callbacks (isTokenObjectUnusable, isAccessTokenUnusable)

This addresses the review comments from hariom and cubic on PR #22492.

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

* fix: validate token endpoint response before storing Pipedrive credentials

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 13:42:15 +05:30
Benny JooGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c28a0d7db0 fix: handle invalid timezones gracefully in calendar events (#27042)
* fix: handle invalid timezones gracefully in getLuckyUser

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

* refactor: move timezone validation to getCalendarsEvents with offset conversion

- Move invalid timezone handling from getLuckyUser.ts to getCalendarsEvents.ts
- Add convertOffsetToEtcGmt() to convert offset formats (GMT-05:00, UTC+08:00) to valid IANA Etc/GMT timezones
- Preserves timezone precision for fairness calculations instead of falling back to UTC
- Add unit tests for timezone conversion scenarios

* refactor: extract timezone conversion to dedicated file

- Create timezone-conversion.ts with concise convertOffsetToIanaTimezone and normalizeTimezone functions
- Update getCalendarsEvents.ts to import from the new file
- Follow kebab-case naming convention for utility files

* test: add unit tests for timezone conversion proving Intl.DateTimeFormat behavior

- Add tests proving Intl.DateTimeFormat throws RangeError for offset formats (GMT-05:00, UTC+08:00)
- Add tests for convertOffsetToIanaTimezone function
- Add tests for normalizeTimezone function

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 02:51:52 -03:00
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Volnei Munhoz
ec951cacad perf: getUserAvailability if dateRange is empty, early return (#26000)
* Early return if date range is empty

* test: add tests for empty workingHours early return optimization

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
2026-01-21 02:51:01 -03:00
Alex van Andel 546a1510b2 chore: release v6.1.2 2026-01-21 02:19:24 -03:00
Alex van AndelGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
455a91935d fix: enable alby app in E2E tests to fix payment-apps test failures (#27071)
PR #27012 introduced logic to disable apps without valid keys during seeding.
This caused the alby payment app tests to fail because the alby app was
disabled in the App table when its environment keys weren't configured.

This fix adds an ensureAppEnabled helper function that enables the app
in the App table before running the tests, treating it as a mock/test
setup step.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-21 08:40:31 +05:30
Volnei MunhozandGitHub 5ddb4dce3f Add calendar subscription error better management (#27019) 2026-01-20 18:47:03 +02:00
Udit TakkarandGitHub 6c3b10672c fix: managed event type bug (#27047) 2026-01-20 17:29:12 +01:00
cb6b52b334 right fix (#26963)
Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
2026-01-20 15:31:43 +00:00
e8e50b70df fix: resolve search bar overlap with title on tablet viewports (#27050) (#27055)
* fix: resolve search bar overlap with title on tablet viewports (#27050)

* Update ShellMainAppDir.tsx

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-20 14:36:58 +00:00
Udit TakkarandGitHub fd130a3fbd chore: don't use object in dependency (#26972) 2026-01-20 18:45:41 +05:30
Hariom BalharaandGitHub 7ec8601bd6 chore: Integrate edit location booking audit (#26569)
## What does this PR do?

Integrates booking audit logging for the edit location functionality, following the pattern established in PR #26046 (booking creation/rescheduling audit).

This PR adds audit logging when a booking's location is changed through:
1. **Web app** (tRPC handler): `packages/trpc/server/routers/viewer/bookings/editLocation.handler.ts`
2. **API v2**: `apps/api/v2/src/ee/bookings/2024-08-13/services/booking-location.service.ts`

### Changes:
- Added `actionSource` as a **required** parameter to `editLocationHandler` (no fallback)
- Added optional `userUuid` parameter (defaults to logged-in user's uuid)
- Added `ValidActionSource` type that excludes "UNKNOWN" for client-facing APIs
- Captures old location before update for audit data
- Calls `BookingEventHandlerService.onLocationChanged()` after successful location update
- Web app uses `actionSource: "WEBAPP"`, API v2 uses `actionSource: "API_V2"`
- Updated router to explicitly pass `actionSource: "WEBAPP"`
- Updated test to pass `actionSource: "WEBAPP"`
- **API v2**: Uses NestJS dependency injection pattern with `BookingEventHandlerService` injected via constructor

### Updates since last revision:
- **Created `BookingEventHandlerModule`** (`apps/api/v2/src/lib/modules/booking-event-handler.module.ts`) to encapsulate `BookingEventHandlerService` and its dependencies (Logger, TaskerService, HashedLinkService, BookingAuditProducerService)
- Updated both bookings modules (2024-04-15 and 2024-08-13) to import `BookingEventHandlerModule` instead of listing individual providers
- This reduces code duplication and makes dependency management cleaner

## 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. N/A - using existing audit infrastructure that is already tested.

## How should this be tested?

1. Update a booking's location through the web app
2. Update a booking's location through API v2
3. Verify audit logs are created with:
   - Correct `bookingUid`
   - Correct `actor` (user who made the change)
   - Correct `source` ("WEBAPP" or "API_V2")
   - Correct `auditData.location.old` and `auditData.location.new` values

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

## Human Review Checklist

- [ ] Verify all callers of `editLocationHandler` pass `actionSource` (router updated, test updated)
- [ ] Verify `organizationId` derivation is correct in both handlers (tRPC uses `booking.user?.profiles?.[0]?.organizationId`, API v2 uses `existingBookingHost.organizationId`)
- [ ] Confirm audit call placement after location update is intentional (audit failures would fail the operation even though location was already updated)
- [ ] Note: API v2 has its own implementation and does NOT reuse `editLocationHandler` - this is correct
- [ ] Verify `BookingEventHandlerModule` properly exports `BookingEventHandlerService` and is imported in both bookings modules
- [ ] Verify the `updateBookingLocationInDb` return value (`{ updatedLocation }`) is destructured and used correctly for audit data
- [ ] Verify API v2 uses `bookingLocation` for audit `new` value, while tRPC uses `updatedLocation` from DB update

---


Link to Devin run: https://app.devin.ai/sessions/fd1d439779674050a26ea3fa7d799943
Requested by: @hariombalhara
2026-01-20 18:40:48 +05:30
Hariom BalharaandGitHub 39ae54d682 feat: add auto-accept logic for team memberships based on org email domain (#26860)
## What does this PR do?

Adds auto-accept logic to the `/v2/teams/{teamId}/memberships` endpoint, similar to what exists in the `/v2/organizations/{orgId}/teams/{teamId}/memberships` endpoint.

When a user is added to a sub-team of an organization, the system now checks if the user's email domain matches the organization's `orgAutoAcceptEmail` setting. If it matches and the organization is verified, the membership is automatically accepted (overriding any `accepted: false` in the request).

### Changes:
- Modified `TeamsMembershipsService.createTeamMembership()` to check if the team has a parent organization and apply auto-accept logic using the existing `OrganizationMembershipService.shouldAutoAccept()` method
- Exported `OrganizationMembershipService` from `OrganizationsModule` for dependency injection
- Added `TeamsModule` and `UsersModule` imports to `TeamsMembershipsModule`
- Added required dependencies (`OrganizationMembershipService`, `OAuthClientRepository`, etc.) to `TeamsModule` and `TeamsSchedulesModule` since they provide `TeamsMembershipsService` directly
- Added comprehensive E2E tests for auto-accept scenarios
- Added `createOrgSettings` and `deleteOrgSettings` helper methods to test fixtures

## 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?

The E2E tests cover the following scenarios:
1. **Auto-accept when email matches** - User with `@acme.com` email is auto-accepted when org has `orgAutoAcceptEmail: "acme.com"`
2. **Case-insensitive matching** - User with `@ACME.COM` email matches `orgAutoAcceptEmail: "acme.com"`
3. **Override accepted:false** - Even if `accepted: false` is passed, it's overridden to `true` when email matches
4. **No auto-accept for non-matching emails** - User with `@external.com` email is NOT auto-accepted
5. **EventTypes assignment** - Verifies user is added to event types with `assignAllTeamMembers: true`

To run the tests:
```bash
TZ=UTC yarn test:e2e --testPathPattern="teams-memberships.controller.e2e-spec"
```

## Human Review Checklist

- [ ] Verify the auto-accept logic matches the existing implementation in `organizations-teams-memberships.controller.ts`
- [ ] Confirm all modules that provide `TeamsMembershipsService` directly (`TeamsModule`, `TeamsSchedulesModule`, `OrganizationsModule`) have the required dependencies
- [ ] Verify `updateNewTeamMemberEventTypes` is called when auto-accept triggers (controller checks `membership.accepted` after service returns)
- [ ] Consider if organization membership creation is needed when a user is auto-accepted into a sub-team but doesn't have org membership yet (not implemented in this PR)

## Checklist

- [x] I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- [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

---

Link to Devin run: https://app.devin.ai/sessions/578b8904a5a94385b59031f9616379cc
Requested by: @hariombalhara
2026-01-20 18:40:44 +05:30
Dhairyashil ShindeandGitHub bea542b310 fix: correct bookingUrl for EU instance in API responses (#27046)
* fix: use WEBAPP_URL for booking URLs when domains differ

For EU deployments where WEBAPP_URL (app.cal.eu) differs from
WEBSITE_URL (cal.com), use WEBAPP_URL for non-org booking URLs.
This fixes incorrect bookingUrl in API responses for EU instance.

* Created new shared utility getTldPlus1 and updated code to use shared function instead of inline copy

* use same comment
2026-01-20 12:48:30 +00:00
Dhairyashil ShindeandGitHub e7a69d68df fixed the issue with the copy link button not working in the extension (#27048) 2026-01-20 09:47:00 -03:00
d67bf45527 feat: integrate DateTimePickerAndroid for date/time selection (#26979)
* feat: integrate DateTimePickerAndroid for date/time selection

- Added @react-native-community/datetimepicker dependency for native date/time picker functionality.
- Replaced modal-based date/time picker implementation with DateTimePickerAndroid for improved user experience.
- Updated RescheduleScreen to utilize the new date/time picker methods, enhancing the selection process and ensuring better styling consistency.

* feat: add LimitsTabDatePicker component for date selection

- Introduced a new LimitsTabDatePicker component utilizing DateTimePickerAndroid for improved date selection on Android.
- Implemented date parsing and formatting for user-friendly display.
- Enhanced user interaction with a pressable element to open the date picker.

* feat: add EditAvailabilityOverrideScreen for managing schedule overrides

- Introduced EditAvailabilityOverrideScreen component to allow users to create and edit availability overrides.
- Implemented date and time selection using DateTimePickerAndroid for improved user experience.
- Added functionality to handle existing overrides, including editing and deleting options.
- Enhanced user interaction with clear alerts for success and error states during save operations.

* fixed lint warnings, info

* address cubics comments

---------

Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
2026-01-20 09:46:42 -03:00
Rajiv SahalandGitHub 72dc999108 chore: disable dashboard for creating new platform accounts (#27052)
* chore: disable dashboard for creating new platform accounts

* chore: remove page altogether
2026-01-20 12:45:47 +00:00
Rajiv SahalGitHubunknown <>Keith WilliamsDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
14e2fa6893 feat: api v2 getSchedules that are applied to team event type (#25912)
* chore: update teams schedules module

* chore: update schedules and team events repository

* chore: input for teams schedules

* feat: add logic to filter schedules based on event type id

* fix: bad import

* chore: add input for get user schedules

* feat: add logic in user schedule to filter schedules based on event type id

* chore: update e2e tests

* fix: add EventTypesModule_2024_06_14 import to SchedulesModule_2024_06_11

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

* fix: import path

* chore: implement cubic feedback

* fix: replace .finally() with try/finally in E2E tests

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

* chore: implement PR feedback

* fix: correct schedule precedence order for team hosts

Fix the effective schedule resolution to follow the intended precedence:
host schedule > user default schedule > event type schedule

This addresses Cubic AI review feedback with confidence 9/10:
- schedules.service.ts: Fix precedence in getUserSchedulesForEventType
- teams-schedules.service.ts: Fix precedence in getTeamSchedulesForEventType

Co-Authored-By: unknown <>

* fixup

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-20 17:55:38 +05:30
Hariom BalharaandGitHub 2c105aceb8 chore: convert console.log to debug log in raqbUtils (#27008)
## What does this PR do?

Converts a `console.log` statement to use the proper `@calcom/lib/logger` with debug level in the raqbUtils.server.ts file. This ensures the log message only appears when debug logging is enabled, reducing noise in production logs.

## 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. N/A - logging change only.

## How should this be tested?

This is a simple logging change. No specific testing required beyond CI passing.

The log message "A group option found. Using all its sub-options instead" will now only appear when the logger level is set to debug (level 2 or lower via `NEXT_PUBLIC_LOGGER_LEVEL`).

## Checklist

- [x] My code follows the style guidelines of this project
- [x] I have checked if my changes generate no new warnings

<!-- Link to Devin run: https://app.devin.ai/sessions/45d95cd7127541ffac96764f251ae1c9 -->
<!-- Requested by: @hariombalhara -->
2026-01-20 13:54:25 +05:30
devin-ai-integration[bot]GitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>ali@cal.com <ali@cal.com>
1e0b0d949f feat: add 40-minute duration option for multiple duration event types (#27032)
- Add 40 minutes to the multipleDurationOptions array in EventSetupTab
- Add comprehensive tests for 40-minute slot generation including:
  - Full day slot generation
  - Correct time intervals
  - Default duration handling
  - Same day booking with time constraints
  - Multiple date ranges

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: ali@cal.com <ali@cal.com>
2026-01-20 10:43:55 +04:00