Commit Graph
16348 Commits
Author SHA1 Message Date
RomitandDevin AI 56099f0107 fix: add missing vi.mock() calls to parseFrontmatter test to prevent vitest worker shutdown flakiness (#28626)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-28 14:18:49 +05:30
dhruveshmishraandRomit a42b51051e fix: improve German translation for reschedule button #28607 (#28624)
* fix: improve German translation for reschedule button

* fix: use accurate German translation for reschedule button

Change "Neuen Termin buchen" (Book new appointment) to "Neu terminieren"
(Re-schedule) to align with the English "Reschedule" meaning.

---------

Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-03-28 08:48:11 +00:00
RomitandDevin AI 0936fdafaf fix: upgrade handlebars to 4.7.9 to resolve critical vulnerability (#28625)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-28 17:01:18 +09:00
Sahitya Chandra 2fc630ed92 fix: mock delegationCredential in getRoutedUsers test to prevent flaky worker shutdown errors (#28603)
* fix: mock delegationCredential in getRoutedUsers test to prevent flaky worker shutdown errors

The getRoutedUsers.test.ts file only tests the pure sync function
getRoutedUsersWithContactOwnerAndFixedUsers, but importing getRoutedUsers.ts
triggers a heavy transitive import chain:

  getRoutedUsers.ts
  -> @calcom/app-store/delegationCredential
  -> _utils/getCalendar
  -> calendar.services.generated (all calendar services)
  -> CalendarService.ts -> ics/tsdav

Sometimes the vitest worker finishes tests and shuts down before all async
module resolution completes, causing:
  Error: [vitest-worker]: Closing rpc while "fetch" was pending

Mock @calcom/app-store/delegationCredential to cut off the import chain
since the tested function doesn't use it.

* Clean up comments in getRoutedUsers.test.ts

Removed comments about mocking delegationCredential to improve code clarity.
2026-03-27 08:54:29 -03:00
Sahitya Chandra b436f331c7 fix: guard against document being undefined in embed-iframe informAboutScroll (#28596)
* fix: guard against document being undefined in informAboutScroll to fix flaky test

* fix: update comment to not reference test environment
2026-03-27 11:50:35 +00:00
15005d89bd fix(auth): implement proper debounce ref for forgot password requests (#28490)
* fix(auth): implement proper debounce ref for forgot password requests

* Add cleanup for debounced submit function

Cancel debounced function on component unmount.

---------

Co-authored-by: javidan <javababayev@gmail.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-27 14:44:59 +05:30
RomitandDevin AI 87fb2abf59 fix: scope cleanup query in managedEventReassignment test to prevent cross-file interference (#28587)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-26 15:48:55 +05:30
fb3ab660e1 fix: stabilize flaky Team filter E2E tests in bookings-list (#28576)
* fix: stabilize flaky Team filter E2E tests in bookings-list

Backport fix from calcom/cal: replace fragile expect.poll().toBe(1)
with explicit toBeHidden() wait for filtered-out booking item followed
by toHaveCount(1). This prevents race conditions where the DOM hasn't
updated yet after the team filter API response returns.

Fixes all three Team filter tests:
- Team filter shows bookings for direct team event types
- Team filter shows bookings for managed event types (child events)
- Team filter excludes bookings from other teams

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

* fix: adjust direct team event types test assertion

In cal.com, the team filter includes personal bookings of team members,
so instead of asserting the personal booking is hidden, verify that the
team booking is visible and present. The managed event types and
cross-team tests correctly use toBeHidden since those filters do
exclude the expected items.

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

* fix: strengthen direct team event types assertion with filter-active check

Add assertion that the teamId filter popover trigger is visible in the UI,
proving the filter was applied before checking the team booking is present.
This addresses the concern that toBeVisible alone would pass even without
the filter being active.

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

* chore: remove comments per review feedback

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-25 14:34:42 +05:30
e073cbd5ea fix: resolve flaky team-management E2E test (#28575)
* fix: resolve flaky team-management E2E test

Fix two failure modes in the 'Can create teams via Wizard' test:

1. Strict mode violation: locator('[data-testid=new-team-btn]') resolves to
   2 elements during Next.js streaming/hydration. Fixed by using .first().

2. Race condition in disband assertion: raw .count() check doesn't wait for
   UI to update after team deletion. Replaced with Playwright's auto-retrying
   toBeHidden() assertion with a 10s timeout.

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

* chore: remove explanatory comments per review feedback

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-25 14:19:35 +05:30
ecc5e66fd4 fix(e2e): replace false-passing assertions and hard-coded waits in test suite (#28486)
* fix(e2e): replace always-passing assertions and hard-coded waits

- Replace toBeTruthy() on Locator objects with toBeVisible() (always-passing)
- Replace toBeTruthy() on boolean expressions with toBe(true) for clarity
- Replace hardcoded waitForTimeout() with element-based waits (waitFor/toBeVisible)
- Fix strict mode violation: getByTestId("away-emoji").first()
- Fix error assertion: infinite redirect error shown as toast → getByTestId("toast-error")
- Fix isDisabled() no-op → await expect().toBeDisabled() in workflows fixture
- Fix alby setup: add waitForURL(), remove unverifiable "Connect with Alby" assertion
- Fix stripe/paypal: replace no-op isDisabled() with toBeChecked() on paypal switch

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

* fix(e2e): fix stale comment in stripe price test

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

* fix(e2e): address cubic review feedback on assertion patterns

- workflows.ts: replace non-retrying isDisabled() snapshot with toBeDisabled()
- out-of-office.e2e.ts: add .first() for away-emoji strict mode, use toast-error testid, remove unused const t
- payment-apps.e2e.ts: replace always-passing toBeTruthy() with toHaveURL() assertion

* fix

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-03-25 05:25:49 +00:00
a3baf493eb fix(calendar): add pointer cursor to enabled date buttons (#28534)
Co-authored-by: Pranav Gawande <pranavv00@users.noreply.github.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-03-25 04:41:53 +00:00
Alex van AndelandDevin AI 806fd8edd0 fix: prevent IDOR in PBAC updateRole and deleteRole tRPC endpoints (#28569)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-25 03:38:35 +05:30
ee973c6661 fix: harden seed script org settings upsert and P2002 error handling (#28527)
* fix: harden seed script org settings upsert and P2002 error handling

Co-Authored-By: romitgabani1 <romitgabani1.work@gmail.com>

* fix: remove PII from P2002 log and recover existing user instead of returning null

- Replace username interpolation in log message with generic text (Cubic violation #2, confidence 9/10)
- On P2002, fetch the existing user from DB and return it with membership data instead of returning null, which was dropping users from org setup on retries (Cubic violation #3, confidence 9/10)

Co-Authored-By: bot_apk <apk@cognition.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2026-03-24 21:43:50 +00:00
Alex van AndelandDevin AI e9e96671bd fix: remove shared pbac feature flag deletion from e2e test cleanup (#28573)
The afterAll hooks in PBAC-related e2e specs were deleting the global
'pbac' feature definition via featuresRepositoryFixture.deleteBySlug().
When multiple test suites run in parallel, one suite's cleanup would
delete the feature while other suites still depend on it, causing
intermittent failures.

Each test already creates its own team-level feature flag association
and cleans that up correctly. The global feature definition does not
need per-suite deletion and is better left intact to avoid cross-suite
interference.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-24 21:35:13 +00:00
Sahitya ChandraandDevin AI b46c04da87 fix(form-builder): show default label when field label is only whitespace (#27793)
* fix(form-builder): show default label when field label is only whitespace

* fix: add validation to ensure label is not empty or whitespace

* fix: enhance label validation to prevent empty or whitespace labels in FormBuilder

* fix: refactor label validation in FormBuilder to streamline whitespace checks

* chore: retrigger CI (flaky vitest worker shutdown)

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-22 21:34:23 +05:30
dc43eba23b feat: add Move Team to Organization admin migration page (#25067)
* feat: restore moveTeamToOrg admin endpoint for organization migration

- Add moveTeamToOrg and removeTeamFromOrg functions to orgMigration.ts
- Restore API endpoint at /api/orgMigration/moveTeamToOrg
- Restore admin UI page at /settings/admin/orgMigrations/moveTeamToOrg
- Add helper functions for team redirect management
- Support moving team members along with the team

This endpoint allows admins to migrate teams to organizations after org creation,
which is needed as a temporary solution until proper org admin permissions are implemented.

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

* fix: move moveTeamToOrg to lib/orgMigration and fix redirect URL

- Move moveTeamToOrg and removeTeamFromOrg functions from playwright/lib to lib/orgMigration.ts
- Update API endpoint to import from lib/orgMigration instead of playwright/lib
- Fix redirect URL format: use / instead of /team/
- Fix import path: use ../playwright/lib/orgMigration instead of ./playwright/lib/orgMigration
- Rename unused _dbRemoveTeamFromOrg in playwright file to satisfy linter
- Remove duplicate functions from playwright/lib/orgMigration.ts

This fixes the Vercel deployment failure caused by importing from test-only directories
in production API routes, and corrects the redirect URL format to match the original implementation.

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

* refactor: reuse existing createTeamsHandler for moveTeamToOrg endpoint

- Remove custom orgMigration.ts implementation
- Update API endpoint to call existing createTeamsHandler with org owner impersonation
- Remove moveMembers option from UI (always moves members by design)
- Fix Vercel deployment by removing playwright import from production code
- Use OrganizationRepository.adminFindById to fetch org owner

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

* refactor: migrate moveTeamToOrg admin page and API to App Router

- Move admin page from pages/settings/admin/orgMigrations to app/(use-page-wrapper)/settings/(admin-layout)/admin/orgMigrations
- Convert API route from pages/api/orgMigration/moveTeamToOrg.ts to app/api/orgMigration/moveTeamToOrg/route.ts
- Create client view component in modules/settings/admin/org-migrations/
- Remove old pages directory files and getServerSideProps

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

* fix: correct import paths for App Router compatibility

- Fix @calcom/lib/server to @calcom/lib/server/i18n for getTranslation
- Fix @calcom/ui barrel import to specific component paths

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

* fix: use TFunction type for getFormSchema parameter

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

* fix: use buildLegacyRequest for App Router session compatibility

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

* Remove unused fn

* cleanup

* cleanup

* fix: ui

* fix: handle slug conflict error when moving team to organization

- Intercept Prisma P2002 unique constraint error when moving a team
- Convert to user-friendly CONFLICT error with clear message
- Add test case for slug conflict scenario

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

* fix: use isPending instead of isLoading for tRPC mutation

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

* fixes

* fix: remove PII (emails) from admin log statement

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

* refactor: use instanceof pattern for Prisma error detection

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

* fixes

* fix: use i18n key for slug conflict error message instead of hardcoded English string

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix: narrow P2002 catch scope to only prisma.team.update call

Separates the try-catch for prisma.team.update (slug conflict) from
creditService.moveCreditsFromTeamToOrg to avoid misattributing credit
service P2002 errors as slug conflicts.

Co-Authored-By: bot_apk <apk@cognition.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-03-19 09:55:02 +05:30
Muhammad UsmanandSahitya Chandra 4b247640a8 fix: Filter invalid keys and handle disabled states during booking limit transformation, with added tests (#28035)
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-18 19:31:42 -03:00
Shivang GoliyanandSahitya Chandra 8caa062ae1 fix: replace Image with Avatar for org/team logos in settings sidebar (#28418)
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-18 20:20:20 +01:00
f2a44279fe refactor: evt calendar event builder (#27203)
* refactor: evt creation

* refactor: evt creation

* refactor: evt creation

* fix: type

* test: update unit tests

* chore: add comments

* fix: handle undefined in withConditional to match NonNullable<T> type

Co-Authored-By: unknown <>

* refactor: evt

* fix: type err

* refactor: remove add videoCallData

* refactor: use error with code

* test: update unit test

* refactor: feedback

* refactor: remove conditional

* refactor: more strict types

* fix: type err

* chor: remove un used

* refactor:  improve recurring event handling in RegularBookingService

Removed unnecessary whitespace and clarified comments regarding the attachment of recurring configurations in the booking handler. Adjusted logic to ensure that recurring settings are only applied when relevant.

* refactor: test

* fix: type error

* refactor: improve code

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-19 03:50:48 +09:00
3c57960b7d feat: api v2 DELETE booking attendees endpoint (#27781)
* feat: remove attendee endpoint

* fix: remove attendee email from error logs to avoid logging PII

Co-Authored-By: unknown <>

* fix: add isBookingAuditEnabled to removeAttendee handler

Align removeAttendee.handler.ts with the new onAttendeeRemoved interface
that requires isBookingAuditEnabled, following the same pattern used in
addGuests.handler.ts.

Co-Authored-By: bot_apk <apk@cognition.ai>

* style: apply biome formatting to conflict-resolved files

Co-Authored-By: bot_apk <apk@cognition.ai>

* chore: implement PR feedback

* fixup

* revert: biome formatting changes

* chore: implement feedback part 1

* chore: implement feedback part 2

* fix: await cancellation email flow to prevent uncaught promise rejections

The fire-and-forget .then() chain on prepareAttendeePerson() left
rejections from that promise uncaught. Await both prepareAttendeePerson()
and sendCancelledEmailToAttendee() so errors are properly handled.
sendCancelledEmailToAttendee() already has an internal try/catch, so
awaiting it will not cause the overall removeAttendee flow to fail on
email errors.

Addresses Cubic AI review (confidence 9/10).

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

* chore: implement feedback part 3

* chore: implement devin feedback

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-03-18 13:25:53 +02:00
Sahitya Chandraandcubic-dev-ai[bot] 72acf09ff2 feat(unified-cal): connection-based unified calendar API with CRUD, freebusy, and list connections (#28387)
* feat(unified-cal): connection-based unified calendar API with CRUD, freebusy, and list connections

- New GET /v2/calendars/connections endpoint returning all calendar connections with connectionId
- Connection-scoped CRUD: GET/POST/PATCH/DELETE /v2/calendars/connections/{connectionId}/events/*
- Connection-scoped free/busy: GET /v2/calendars/connections/{connectionId}/freebusy
- Legacy calendar-type endpoints: GET/POST/DELETE /v2/calendars/{calendar}/events, GET /{calendar}/freebusy
- Backward compat: dual @Patch decorators for singular /event/ (deprecated) and plural /events/
- ConnectedCalendarEntry interface to eliminate inline type annotations
- DRY service layer with shared private helpers (listEventsWithClient, createEventWithClient, etc.)
- Input validation: @IsDefined() on start/end, @IsTimeZone() on timezone fields, cross-field to >= from validation
- All-day event support: Google Calendar date-only events converted to midnight UTC
- New findCredentialByIdAndUserId method in CredentialsRepository for connection-scoped lookups

* style: apply biome formatting to unified calendar API files

* fix: use @IsTimeZone() validator for timeZone field in CreateEventDateTimeWithZone

* fix: add delegation auth support, extract freebusy service layer

- Comment 3: getCalendarClientForUser and getCalendarClientByCredentialId now
  use getAuthorizedCalendarInstance with delegated-auth fallback instead of
  requiring credential.key directly. Added findCredentialWithDelegationByTypeAndUserId
  and expanded findCredentialByIdAndUserId to include delegationCredentialId.

- Comment 5: Extracted freebusy and connections logic from controller into
  UnifiedCalendarsFreebusyService, keeping the controller thin (HTTP-only).
  Moved ConnectedCalendarEntry type and INTEGRATION_TYPE_TO_API mapping into
  the service layer.

- Biome auto-formatting applied to touched files.

* test: add unit and integration tests for unified calendar API

- GoogleCalendarService: 30 tests covering delegation auth, client creation, CRUD
- UnifiedCalendarsFreebusyService: 21 tests covering connections, busy times, filtering
- CalUnifiedCalendarsController: 31 tests covering all endpoints (connection-scoped + legacy)
- Pipe specs: 37 existing tests continue to pass

Total: 98 tests across 5 suites

* fix: address Devin Review feedback - fix JSDoc and validator pattern

- Fix incorrect JSDoc on listEventsForUser (all-day events ARE included, not skipped)
- Fix IsAfterFrom validator to return false instead of throwing BadRequestException
  (preserves standard ValidationPipe error format)

* fix: revert IsAfterFrom to throw BadRequestException per team convention

Cubic AI (confidence 9/10, team feedback): validators should throw
BadRequestException to preserve the API's standard bad-request response
structure, per team convention.

* fix: add calendarId query param to createConnectionEvent for API consistency

All other connection-scoped endpoints accept calendarId; this was the
only one hardcoding 'primary'. Added @ApiQuery decorator and @Query
parameter with ?? 'primary' fallback, plus a test for custom calendarId.

* Update apps/api/v2/src/modules/cal-unified-calendars/controllers/cal-unified-calendars.controller.ts

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

* Revert "Update apps/api/v2/src/modules/cal-unified-calendars/controllers/cal-unified-calendars.controller.ts"

This reverts commit e18e4621eff46d8ec49e4d03230783ce50b0c0e4.

* feat: enhance calendar service with connection-specific methods and improve API documentation

* test: complete delegation auth tests, document virtual mocks, fix key leak tests

- Item 3: Add 7 comprehensive delegation auth integration tests covering
  JWT creation params, email cleaning, fallback scenarios, and error handling
- Item 7: Document why virtual mocks are necessary in all test files
  (workspace packages with DB dependencies cannot resolve in Jest)
- Cubic #1: Document getCalendarsForConnection caching and upstream limitation
- Cubic #2+#3: Make credential key leak tests non-vacuous by including
  actual key fields in mocks and verifying they don't leak
- Remove unused BadRequestException import from freebusy service

* fix: add defense-in-depth key stripping in listConnections controller

Controller now destructures only { connectionId, type, email } from each
connection before returning, so credential.key can never leak even if the
service layer has a future regression. Test updated to verify stripping.

* feat: add unified calendar API endpoints for connections and events management

* fix: add try/catch error handling to CRUD helper methods

Wrap Google Calendar API calls in listEventsWithClient, createEventWithClient,
getEventWithClient, updateEventWithClient, and deleteEventWithClient with
try/catch blocks matching the legacy getEventDetails/updateEventDetails pattern.
This ensures proper NestJS exceptions (NotFoundException, BadRequestException)
are returned instead of raw 500 errors when the Google API throws.

* fix: map Google API errors to correct HTTP status codes

Replace blanket NotFoundException/BadRequestException in CRUD catch blocks
with mapGoogleApiError() that inspects the GaxiosError status code and
returns the appropriate NestJS exception (404→NotFoundException,
401/403→UnauthorizedException, 400→BadRequestException, else→500).

* fix: preserve upstream Google API status codes in error mapping

Separate 403 (ForbiddenException) from 401 (UnauthorizedException) and
add 429 rate-limit handling. This ensures permission-denied and throttling
errors are not misreported to API clients.

* fix: distinguish Google quota/rate-limit 403 from permission 403

Check GaxiosError reason field for rateLimitExceeded, userRateLimitExceeded,
and dailyLimitExceeded before mapping 403 to ForbiddenException. Quota
errors are now correctly mapped to 429 (retriable) instead.

* fix: keep dailyLimitExceeded as 403 (non-retriable quota exhaustion)

dailyLimitExceeded is a daily quota cap, not transient throttling.
Only rateLimitExceeded and userRateLimitExceeded are remapped to 429.

* fix: add missing @ApiQuery decorators for calendarId on get/update/delete endpoints

getConnectionEvent, updateConnectionEvent, and deleteConnectionEvent were
missing @ApiQuery({ name: 'calendarId', required: false }) which caused
OpenAPI spec to incorrectly mark calendarId as required.

* ci: retry flaky vitest worker test

* fix: update calendarId query parameter to be optional in OpenAPI specification

* fix: swap dual decorator order so plural /events/ path appears in OpenAPI spec

NestJS Swagger only picks up the first HTTP method decorator. Swapping
the order ensures the preferred plural path (/events/:eventUid) is
generated in the OpenAPI spec, while the deprecated singular path
(/event/:eventUid) still works at runtime.

* fix: split dual decorators into separate methods so both paths appear in OpenAPI spec

NestJS Swagger only picks up the first HTTP method decorator per handler.
Split getCalendarEventDetails and updateCalendarEvent into separate
methods for the singular /event/ (deprecated) and plural /events/ paths,
each delegating to a shared private helper. Both routes now appear in
the generated OpenAPI spec.

* fix: update openapi.json with split dual-decorator paths for GET/PATCH event endpoints

* fix: mapGoogleApiError - coerce string code to number and read errors from response.data

* fix: mapGoogleApiError - guard against NaN from non-numeric error codes

* fix: use read replica for findCredentialWithDelegationByTypeAndUserId query

* refactor: address review comments - UnifiedCalendarService, ParseConnectionIdPipe, thin controller

- Comment 70 (Ryukemeister): Remove 'what' JSDoc from calendars.service.ts
- Comment 71 (Ryukemeister): Use array syntax for dual paths instead of separate methods
- Comments 73-78 (ThyMinimalDev): Create ParseConnectionIdPipe for connectionId validation
- Comments 79-84 (ThyMinimalDev): Create UnifiedCalendarService with strategy pattern
- Comment 85 (ThyMinimalDev): Move getConnections from freebusy to UnifiedCalendarService
- Controller now only handles HTTP concerns, delegates all logic to UnifiedCalendarService
- Updated all test specs to match refactored architecture

* chore: regenerate openapi.json after controller refactor to array syntax paths

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-03-18 15:15:53 +05:30
fa20f19e54 fix: Add descriptive alt text to images for accessibility (#28469)
* fix: add descriptive alt text to images for accessibility

Signed-off-by: Rakshit Yadav <yadavrakshit60@gmail.com>

* Apply suggestions from code review

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

* fix: internationalize alt text strings for accessibility

Signed-off-by: Rakshit Yadav <yadavrakshit60@gmail.com>

* Update apps/web/components/settings/EnableTwoFactorModal.tsx

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

* Apply suggestions from code review

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

* add useLocale to EventTypeGroup component for translations

Signed-off-by: Rakshit Yadav <yadavrakshit60@gmail.com>

---------

Signed-off-by: Rakshit Yadav <yadavrakshit60@gmail.com>
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-17 21:11:01 +05:30
089a39f59f feat: add integration options for API v2 update booking location endpoint (#26363)
* init: improvements for update location endpoint

* chore: init function to update calendar event

* fix: bad imports

* chore: update calendar event when updating location

* chore: update platform libraries

* fix: update calendar event

* chore: update platform libraries

* chore: cleanup

* feat: add logic for video conferecing integrations

* chore: update platform libraries

* feat: add sms and email notifications

* chore: update e2e tests

* chore: update openapi spec

* chore: implement cubic feedback

* chore: update openapi spec

* fix: add Jest mock for Daily.co video adapter in e2e test

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

* fix: mock createMeeting directly to bypass database check in e2e test

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

* chore: implement PR feedback

* chore: implement feedback

* fix: mock throttler guard to prevent rate limiting in e2e tests

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

* fix: merge conflicts

* chore: update platform libraries

* chore: implement feedback part 1

* chore: implement feedback part 2

* chore: remove unnecessary type casting

* chore: implement cubic feedback

* chore: implement devin feedback

* chore: implement PR feedback

* fix: type error

* chore: update openapi spec

* test: add mocks and tests for Google Meet and Microsoft Teams integration location updates

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

* refactor: simplify service code - extract shared helpers, remove duplication

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

* feat: implement fixtures for bookings references

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-17 15:15:17 +05:30
RomitandDevin AI 4291a59b2c fix: add missing vi.mock() calls to prevent vitest worker shutdown flakiness (#28459)
* fix: add missing vi.mock() calls to prevent vitest worker shutdown flakiness

Add vi.mock() calls for modules that trigger background network requests
or database connections during import. These transitive imports can cause
the vitest worker RPC to shut down while pending fetch/network operations
are still in flight, resulting in flaky test failures with:
  Error: [vitest-worker]: Closing rpc while "fetch" was pending

The primary modules mocked are:
- @calcom/app-store/delegationCredential (triggers credential lookups)
- @calcom/prisma (triggers database initialization)
- @calcom/features/calendars/lib/CalendarManager (triggers calendar API calls)
- @calcom/features/auth/lib/verifyEmail (triggers email service)
- @calcom/lib/domainManager/organization (triggers domain lookups)

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

* fix: remove conflicting empty prisma mocks from files with prismock/prismaMock setups

- Remove vi.mock('@calcom/prisma', () => ({ default: {}, prisma: {} })) from 28 files
  that already have prismock/prismaMock test doubles. Vitest hoists all vi.mock() calls
  and the last one wins, so these empty mocks were overriding the functional test doubles.
- Fix CalendarSubscriptionService.test.ts to reuse the shared mock from
  __mocks__/delegationCredential instead of creating a new unconfigured vi.fn()
- Remove DelegationCredentialRepository.test.ts empty prisma mock (different pattern)
- Remove vi.mock from inside beforeEach in intentToCreateOrg.handler.test.ts

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

* fix: add comprehensive delegationCredential mock exports to prevent CI test failures

The vi.mock blocks for @calcom/app-store/delegationCredential were missing
exports that the code under test transitively imports (e.g.
enrichUsersWithDelegationCredentials, enrichUserWithDelegationCredentialsIncludeServiceAccountKey,
buildAllCredentials, getFirstDelegationConferencingCredentialAppLocation).

Added all exports with passthrough implementations so the booking flow
works correctly without triggering real network requests.

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

* fix: correct credential mock return shapes to match real module API

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

* fix: revert unintended yarn.lock changes

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-17 09:55:37 +05:30
353f71bdc6 feat: Sink url shortner for sms workflow reminders (#26608)
* feat: Sink url shortner for sms workflow reminders

* fix: remove hardcoded dub values

* update .env.example

* fix: unit tests

* chore: add tests for scheduleSmsReminder and utils

* review refactor

* fix: type check

* review refactor

* fix: update test to account for smsReminderNumber fallback from main

Co-Authored-By: unknown <>

* feat: add feature flag for sink and more tests to verify

* fix: type check

* use proper feature flags for sink

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-03-16 20:51:28 +00:00
12446d826b feat(i18n): complete Turkish (tr) translations (#28441)
* feat(i18n): complete Turkish (tr) translations

* fix(i18n): fix nested objects and missing placeholders in Turkish translations

- Move booking_audit_action dotted keys into existing nested object
- Move busy_time dotted keys into proper nested object
- Restore missing {{appName}}, {{item}}, {{count}}, {{success}}, {{failed}} placeholders
- Replace ICU plural format with i18next {{variable}} format

* nits

---------

Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-03-15 19:03:59 +00:00
3bbeaad50d feat(i18n): complete Ukrainian (uk) translations (#28440)
* feat(i18n): complete Ukrainian (uk) translations

* fix(i18n): restore missing placeholders in Ukrainian translations

Fix 6 placeholder issues identified by cubic:
- accept_our_license: fix malformed {{agree}} placeholder
- invalid_credential: restore {{appName}} placeholder
- invalid_event_name_variables: restore {{item}} placeholder
- signing_up_terms: restore {{appName}} placeholder
- entries_deleted_successfully: use {{count}} instead of ICU plural
- entries_deleted_with_errors: use {{success}}/{{failed}} instead of ICU plural

* Update packages/i18n/locales/uk/common.json

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

* nits

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-03-15 22:33:10 +05:30
AryaandRomit 9a1add0b65 feat(i18n): complete Swedish (sv) translations (#28439)
Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-03-15 15:15:46 +01:00
Arya cf424505d4 feat(i18n): complete Vietnamese (vi) translations (#28442) 2026-03-15 13:12:47 +05:30
AryaandRomit 81572b9bb1 feat(i18n): add Korean (ko) translations (#28426)
* feat(i18n): add Korean (ko) translations

* chore

---------

Co-authored-by: Romit <romitgabani1.work@gmail.com>
2026-03-15 11:16:59 +05:30
swalihkolakkadan c8f9085988 fix(docs): correct ListSchedules prop name from getRedirectUrl to getScheduleUrl (#28419)
The documentation referenced `getRedirectUrl` but the actual component
prop is `getScheduleUrl`, causing the callback to silently not fire.
2026-03-14 08:31:59 +00:00
Anirban Singha 27a7821c72 chore: remove duplicate translation key (#28409) 2026-03-13 16:02:51 +00:00
592cb4fb7b feat: add platform URL support for reschedule and cancel links in workflow emails (#27132)
* feat: add platform URL support for reschedule and cancel links in workflow emails

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

* feat: pass platform URL data to CalendarEventBuilder in workflow emails

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

* Revert "feat: pass platform URL data to CalendarEventBuilder in workflow emails"

This reverts commit 1d4d3623c93cd4eeeef18ffdad0597fe583b6a55.

* chore: provide platform metadat to workflow email task

* fixup! chore: provide platform metadat to workflow email task

* test: add unit tests for platform URL handling in EmailWorkflowService

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

* test: update WorkflowService tests to include platform params in tasker payload

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-13 15:48:51 +04:00
swalihkolakkadanandRomit a694202c46 fix: add "Use a different email" button to verify-email page (#28398)
* fix: add "Use a different email" button to verify-email page

Closes #28393

* fix: address review feedback on verify-email page

- Use signOut({ callbackUrl }) instead of manual redirect
- Stack buttons vertically with flex-col

---------

Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-03-13 07:35:12 +00:00
Kartik c496801655 fix: correct Norwegian booking and cancellation (#28394) 2026-03-12 20:04:16 +00:00
e5fd455a30 refactor: move AppList to features with slot props (#28100)
* refactor: move AppSetDefaultLinkDialog to features + inline QueryCell + fix broken type import

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

* refactor: move AppList to features with slot props + delete AppListCard switcher

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

* fix: correct ConnectedApps type to avoid double nesting of items

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-03-12 11:00:20 +01:00
972d70379f refactor: move useAppsData to features (#28098)
* refactor: move useAppsData to features + replace useIsPlatform with isPlatform prop in DisconnectIntegrationModal

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

* refactor: remove old useAppsData from web (moved to features)

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-03-12 14:52:15 +05:30
26e225e87b chore: remove temporary plan files that were accidentally merged (#28381)
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-03-12 08:54:00 +00:00
Henry Kwon 7c8f17ccc7 feat: Lyra App (#27370)
* feat: lyra conference app

* fix: lyra -> lyra meeting

* api url in env example

* feat: lyra oauth

* remove setup page

* fix: revision on feb 25 review

* production api url

* fix: final suggestions implementation

* yarn.lock revert
2026-03-12 07:10:22 +00:00
7ff2eaf293 fix: consolidate booking access checks into doesUserIdHaveAccessToBooking (#28071)
* fix: align checkBookingAccessWithPBAC with listing logic for personal event types

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

* fix: align permission strings with doesUserIdHaveAccessToBooking granular permissions

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

* change implementation

* remove unused code

* test: add getBookingDetails tests for personal event type booking access

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

* fix: remove unused MembershipRole import

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

* test: convert BookingDetailsService tests to integration tests

Replace unit tests with mocks by integration tests using real database.
Tests verify org/team admin access to personal event type bookings.

- Org admin viewing team member's personal event booking (fails on main, passes on PR)
- Team admin viewing team member's personal event booking (fails on main, passes on PR)
- Non-admin denied access (passes on both)
- Owner viewing own booking (passes on both)
- Non-existent booking returns Forbidden (passes on both)

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

* test: refactor integration tests to use repositories instead of direct prisma calls

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

* test: replace direct prisma usage with TestXXXRepository pattern in integration tests

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

* test: use production repositories (OrganizationRepository, BookingRepository, UserRepository) instead of test repos for setup

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

* test: inline test repository logic into integration test file

The TestXXXRepository classes were thin wrappers around single prisma
calls with barely any logic, so the indirection wasn't justified.

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

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:46:57 -03:00
Rajiv Sahal d3dad196d6 fixup (#28365) 2026-03-11 17:15:14 +00:00
Romit c589399700 fix(app-store-cli): incorrect type annotation (#28319) 2026-03-11 18:32:44 +05:30
Richard HenkenjohannandSahitya Chandra 2509116b28 Fix Keycloak OIDC flow (#27716)
Some OIDC providers like Keycloak (v18+) include an `iss` (issuer) parameter in the authentication response for security (as per RFC 9207). The oidc route was explicitly extracting only `code` and `state`, thus losing the `iss` parameter and other potential parameters like `session_state`. When Jackson passed the incomplete set of parameters to `openid-client`, the library failed validation with the error `invalid response encountered` because it expected the `iss` parameter to be present if the server supports it.

Fixes #22238.

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-11 16:13:55 +05:30
Russ MitchellandSahitya Chandra a8e27c3832 fix: allow hyphens, dots, and underscores in Dialpad meeting URL validation (#28253)
The Dialpad conferencing integration's URL regex only accepted
alphanumeric characters in the meeting room path ([a-zA-Z0-9]+),
causing valid personal meeting URLs containing hyphens, dots, or
underscores to fail validation.

For example, https://meetings.dialpad.com/mmit-russ is rejected
despite being a valid Dialpad personal meeting link. The sample URL
shown in the error message (alphanumeric only) passes, but
real-world room names commonly use hyphens and other characters.

Updated the urlRegExp character class from [a-zA-Z0-9] to
[a-zA-Z0-9._-] to match all valid Dialpad meeting room slugs.

Fixes issue introduced in #15444.

Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
2026-03-11 08:20:08 +00:00
Anirban SinghaandRomit c026bedb99 refactor: simplify redundant recurring event condition in EventTypeDescription (#28355)
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
2026-03-10 21:17:05 +00:00
f86767c125 fix: correct admin password banner message and auto-sign-out after 2FA enable (#28129)
* fix: correct admin password banner message to require both password length and 2FA

The banner message incorrectly used 'or' implying only one condition was needed,
but the code requires BOTH a password of at least 15 characters AND 2FA enabled.

Updated the message to clearly state both requirements and added a hint that
users need to log out and log back in after updating their security settings.

Fixes #9527

Co-Authored-By: unknown <>

* fix: auto-sign-out INACTIVE_ADMIN users after enabling 2FA

When an INACTIVE_ADMIN user enables 2FA, automatically sign them out so
they can log back in with refreshed session role, dismissing the banner.
This matches the existing behavior for password changes.

Co-Authored-By: unknown <>

* feat: add dynamic admin banner message based on inactiveAdminReason

Co-Authored-By: unknown <>

* Remove and add various localization strings

* Update common.json

* Add cookie consent checkbox message and remove entries

* test: add unit tests for AdminPasswordBanner and inactiveAdminReason logic

Co-Authored-By: unknown <>

* fix: add expires field to session mock to fix type check

Co-Authored-By: unknown <>

* fix: wrap CALENDSO_ENCRYPTION_KEY mutations in try/finally to prevent env state leaks

Addresses Cubic AI review feedback (confidence 9/10): when a test fails
early, the CALENDSO_ENCRYPTION_KEY env var was not being restored, which
could leak state into subsequent tests. Wrapped the env mutation in
try/finally blocks to guarantee cleanup.

Co-Authored-By: bot_apk <apk@cognition.ai>

* fix: add missing 'expires' field to buildSession in AdminPasswordBanner test

The Session type requires 'expires' to be a string, but buildSession was
not providing it, causing a type error caught by CI type-check.

Co-Authored-By: bot_apk <apk@cognition.ai>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: bot_apk <apk@cognition.ai>
2026-03-10 12:46:31 -03:00
Romit f3f5523f31 fix: add missing OpenAPI ApiParam decorators to API v2 controllers (#28305)
* fix: add missing apiparam decorators

* chore: move api param to class level

* revert oasdiff

* chore

* fix: update oasdiff-err-ignore.txt

* chore
2026-03-10 14:34:21 +05:30
Romit e75614164b fix: corrects routing form response type (#28336)
* fix(docs): corrects routing form response type

* fix: update oasdiff-err-ignore
2026-03-10 14:26:17 +05:30
Romit c8e1b4e66d fix: correct @ApiProperty types in verified resources outputs (#28340)
* fix(docs): corrects output response type for verified resources endpoints

* fix: udpate oasdiff-err-ignore.txt
2026-03-09 22:09:09 -03:00
Romit d6741a1e2b fix: rename OOO controller file to match NestJS Swagger plugin convention (#28342)
* fix: rename OOO controller file to match NestJS Swagger plugin convention for type generation

* fix: update organization module import

* feat: generate openapi docs
2026-03-09 22:07:58 -03:00