v6.1.4
1583
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3355fab4fb | feat: display assignment reason in organizer emails and booking single view (#27192) | ||
|
|
a40c3eebd6 |
feat: group same booking reports together (#26529)
Co-authored-by: unknown <> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
09194c58e1 | fix: onboarding - team invites (#27113) | ||
|
|
0ad4367005 |
feat: Custom host location (#25916)
* chore: save progress * chore: * feat: add input dialog * fix: type error * feat: mass apply dialog * test: per host location * test: fix test * fix: address Cubic AI review feedback (confidence >= 9/10) - Remove PII (address, phone number) from tracing logs in RegularBookingService.ts - Constrain HostLocation.type to EventLocationType["type"] for compile-time validation Co-Authored-By: unknown <> * fix: translation * refactor: improvements * fix: correct grammar in custom host locations tooltip Change 'custom host locations is enabled' to 'custom host locations are enabled' (plural subject requires plural verb). Addresses Cubic AI review feedback (confidence 9/10). Co-Authored-By: unknown <> * refactor: improvements * fix: auth * fix: check * refactor: improvements * fix: address Cubic AI review feedback (confidence >= 9/10) - Add scheduleId to newly created hosts in update.handler.ts to persist host-specific schedules during create operations - Change host location deletion filter from !host.location to host.location === null to only delete when explicitly set to null - Fix static-link per-host locations to use actual link instead of type in locationBodyString for bookingLocationService.ts Co-Authored-By: unknown <> * fix: preserve existing host scheduleId when not explicitly provided Change scheduleId handling for existing hosts from 'host.scheduleId ?? null' to 'host.scheduleId === undefined ? undefined : host.scheduleId' so that when the client doesn't provide a scheduleId, the existing value is preserved instead of being cleared to null. Co-Authored-By: unknown <> * fix; type erro * fix; type erro * fix; type erro * refactor: move repository * refactor: move repository * fix: add singular/plural translations for location_applied_to_hosts Addresses Cubic AI review feedback (confidence 9/10) to fix '1 hosts' rendering as '1 host' by using i18next plural format with _one and _other suffixes. Co-Authored-By: unknown <> * refactor: feedback * fix: type err * fix: use uuid in schema and remove attendee locaiton * fix: type err * fix: type err * fix: validate eventTypeId as integer in massApplyHostLocation schema Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
4115eaacbd |
chore: Add initial webhook wiring (TRPC handlers) to the new architecture (#27170)
* --init * clean up * unnecessary comment * remove comment * fix factory resolver * Add active filter to webhook query |
||
|
|
95f7f03f0e |
chore: Integrate round-robin reassignment booking audit (#26586)
## What does this PR do? Implements booking audit logging for round-robin reassignment events (both manual and automatic). This is part of the booking audit integration plan (PR 7). Changes: - Added audit logging to `roundRobinManualReassignment.ts` for manual host reassignments - Added audit logging to `roundRobinReassignment.ts` for automatic round-robin reassignments - Updated tRPC handlers to pass `actionSource: "WEBAPP"` and `reassignedByUuid` - Updated API v2 bookings service to pass `actionSource: "API_V2"` and `reassignedByUuid` - Updated `ReassignmentAuditActionService.ts` with proper field schemas and translation keys The audit logging uses `BookingEventHandlerService.onReassignment()` with proper actor identification and action source tracking. ## Updates since last revision Addressed review feedback: - Renamed `title` field to `hostName` for semantic clarity (tracks host name changes, not booking titles) - Fixed `assignedById` schema: changed from `NumberChangeSchema` to `z.number()` (no old/new pattern needed - it's always the user who performed the reassignment) - Fixed `reassignmentReason` schema: changed from `StringChangeSchema` to `z.string().nullable()` (no old/new pattern needed) - Added `ValidActionSource` type that excludes `UNKNOWN` - clients must pass explicit action sources - Made `actionSource` required in both reassignment functions (no longer optional) - Added integration tests for `ReassignmentAuditActionService` (15 tests covering all methods) - Updated `roundRobinManualReassign.handler.ts` to pass required `actionSource` and `reassignedByUuid` params **Latest fixes:** - Fixed `hasAttendeeUpdated` check in `ReassignmentAuditActionService.ts`: changed from `!== null` to `!= null` to properly handle undefined values - Updated test expectations in `ReassignmentAuditActionService.test.ts` to match the new display JSON field names (`hostAttendeeUserUuidNew`/`hostAttendeeUserUuidOld` instead of `newAssignedRRHostUuid`/`previousAssignedRRHostUuid`) - Fixed async `getDisplayFields` tests to properly await the Promise and include the `previous_assignee` field - Fixed `hasAttendeeUpdated` to check for `hostAttendeeUpdated` object presence instead of optional `id` field - host changes with only `withUserUuid` populated were being ignored (identified by Cubic AI, confidence 9/10) - Fixed test expectation in `getDisplayJson` test: removed incorrect null expectations for `hostAttendeeIdUpdated`, `hostAttendeeUserUuidNew`, `hostAttendeeUserUuidOld` - the implementation uses conditional spreading to omit these fields when `hostAttendeeUpdated` is not present, rather than setting them to null ## Mandatory Tasks (DO NOT REMOVE) - [x] I have self-reviewed the code (A decent size PR without self-review might be rejected). - [x] I have updated the developer docs in /docs if this PR makes changes that would require a [documentation change](https://cal.com/docs). N/A - no documentation changes needed. - [x] I confirm automated tests are in place that prove my fix is effective or that my feature works. ## How should this be tested? 1. Trigger a manual round-robin reassignment via the webapp and verify audit logs are created with `actionSource: "WEBAPP"` 2. Trigger an automatic round-robin reassignment and verify audit logs are created 3. Use API v2 to reassign a booking and verify audit logs are created with `actionSource: "API_V2"` 4. Verify the audit data contains correct values for `organizerUuid`, `hostAttendeeUpdated`, `reassignmentReason`, and `reassignmentType` ## Checklist - [x] My code follows the style guidelines of this project - [x] I have checked if my changes generate no new warnings ## Human Review Checklist - [x] Verify the `hasAttendeeUpdated` fix is correct: now checks `fields.hostAttendeeUpdated != null` to detect any host attendee update regardless of whether `id` is populated - [x] Verify `getDisplayJson` test fix: fields are correctly omitted (not set to null) when `hostAttendeeUpdated` is not present, matching the conditional spreading implementation - [ ] Verify all callers of reassignment functions pass required `actionSource` and `reassignedByUuid` - [ ] Confirm `getDisplayFields` is properly awaited in all call sites (it's now async) - [ ] Check that `ValidActionSource` type properly excludes `UNKNOWN` for client-side validation ## Important Notes for Reviewer 1. **Dependency on base PR**: The translation key changes use the format from base PR (#26046). This PR should be merged after the base PR. 2. **Schema changes**: The `organizerUuid` and `hostAttendeeUpdated` fields track both organizer changes and round-robin host attendee changes separately for complete audit trail. --- Link to Devin run: https://app.devin.ai/sessions/e4353e2ec6ea4a51ab33313bdc630aba Requested by: @hariombalhara |
||
|
|
6f7c8bdd73 |
feat: add wrong assignment report dialog and webhook for routing form bookings (#25839)
Co-authored-by: peer@cal.com <peer@cal.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
aaabcf4430 |
perf: optimize getEventTypeIdsFromTeamIdsFilter with raw SQL query (#27145)
* perf: optimize getEventTypeIdsFromTeamIdsFilter with raw SQL query Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: use prisma singleton for raw queries to fix runtime error Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: use context prisma for raw queries and update test mocks - Changed getEventTypeIdsFromTeamIdsFilter to use the context-passed prisma parameter instead of importing the singleton - Added $queryRaw mock to test file to support raw SQL queries - Updated test assertion to check for $queryRaw call instead of eventType.findMany The context prisma IS the same singleton at runtime (passed via tRPC context in createContext.ts). The test was failing because the mock didn't include $queryRaw. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Removed extra subquery where not needed * fix: restore subquery optimization for better query performance Restores the subquery structure that allows PostgreSQL to use the composite index on EventType(parentId, teamId) efficiently via Nested Loop joins, resulting in ~66x faster execution (2.46ms vs 164ms in production benchmarks). Identified by Cubic AI (confidence 9/10). Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Fighting with AI --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
aa8804e498 |
feat(flags): add @Memoize and @Unmemoize decorators for declarative caching (#27063)
* feat(flags): add @Memoize and @Unmemoize decorators for declarative caching - Add @Memoize decorator for caching method results with Zod validation - Add @Unmemoize decorator for cache invalidation on mutations - Create UserFeatureRepository using decorators as example implementation - Add comprehensive tests with 80%+ coverage (19 tests) - Add DI module and tokens for UserFeatureRepository - Enable experimentalDecorators in packages/features/tsconfig.json Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(cache): use lazy Redis lookup in decorators - Decorators now access Redis via getRedisService() instead of this.redis - UserFeatureRepository no longer has redis property or direct redis calls - findByUserIdAndFeatureIds now uses decorated findByUserIdAndFeatureId - DI module simplified to only pass prisma dependency - Tests updated to call setRedisService() in beforeEach This ensures the repository only knows about Prisma, with all caching handled transparently by the decorators. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat(flags): add FeatureRepository and TeamFeatureRepository with decorator-based caching - Add FeatureRepository with @Memoize decorators for findAll, findBySlug, getFeatureFlagMap - Add TeamFeatureRepository with @Memoize/@Unmemoize decorators for all CRUD operations - Add comprehensive Zod schemas for Feature, TeamFeatures, and AppFlags validation - Add DI modules and tokens for both repositories - Add comprehensive test coverage (33 tests) for both repositories - Maintain backward compatibility with existing FEATURES_REPOSITORY tokens Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(cache): use DI container pattern for Redis service - Create packages/features/di/containers/Redis.ts with getRedisService() - Update Memoize and Unmemoize decorators to import from DI container - Remove setRedisService() and IRedisService from types.ts exports - Update all tests to mock the container's getRedisService - Fix import ordering issues from biome Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(cache): remove barrel import and add root-level cache export - Remove packages/features/cache/decorators/index.ts barrel file - Add packages/features/cache/index.ts as root-level export for cache feature - Update repository imports to use direct imports from source files - Follows the pattern: avoid barrel imports at nested levels, keep at feature root Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(flags): minimize repository methods and address PR feedback - Remove unnecessary methods from FeatureRepository, TeamFeatureRepository, and UserFeatureRepository - Keep only methods needed by FeatureOptInService - Update imports to use @calcom/features/cache public API instead of relative paths - Handle redis.del() errors gracefully in Unmemoize decorator - Update tests to match simplified repositories Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(cache): use Promise.allSettled for cache invalidation Cleaner approach than Promise.all with individual .catch() handlers Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat(flags): add setAutoOptIn methods and replace featuresRepository usage in _router.ts - Add setAutoOptIn method to TeamFeatureRepository with @Unmemoize decorator - Add setAutoOptIn method to UserFeatureRepository with @Unmemoize decorator - Replace featuresRepository usage in featureOptIn/_router.ts with new repositories - TeamFeatureRepository.setAutoOptIn unmemoizes KEY.autoOptInByTeamId(teamId) - UserFeatureRepository.setAutoOptIn unmemoizes KEY.autoOptInByUserId(userId) Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(flags): use DI containers for TeamFeatureRepository and UserFeatureRepository - Create TeamFeatureRepository.ts container with getTeamFeatureRepository() - Create UserFeatureRepository.ts container with getUserFeatureRepository() - Update _router.ts to use DI containers instead of direct instantiation Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(feature-opt-in): use DI containers for FeatureOptInService dependencies - Update FeatureOptInService to use IFeatureOptInServiceDeps with 3 repositories - Add helper functions teamFeatureToState() and userFeatureToState() - Update DI module to use depsMap pattern with featureRepo, teamFeatureRepo, userFeatureRepo - Create FeatureRepository container file - Replace all FeaturesRepository method calls with new repository methods Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * test(feature-opt-in): update FeatureOptInService tests for new IFeatureOptInServiceDeps interface - Update mock structure to use featureRepo, teamFeatureRepo, userFeatureRepo - Add helper functions createMockTeamFeature and createMockUserFeature - Update all test cases to use new repository method names - Add explicit types to satisfy biome lint rules Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor(flags): use DTOs at repository boundaries to prevent Prisma type leakage - Create FeatureDto, TeamFeaturesDto, UserFeaturesDto in packages/lib/dto/ - Update repository interfaces to return DTOs instead of Prisma types - Add toDto() transformation methods in repository implementations - Update FeatureOptInService to use DTOs instead of Prisma types - Follow data-dto-boundaries.md guidelines for architectural boundaries Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix(flags): update TeamFeatureRepository tests to match DTO structure Remove assignedAt from test mock data since TeamFeaturesDto only includes: teamId, featureId, enabled, assignedBy, and updatedAt Co-Authored-By: unknown <> * fix(cache): make Redis failures non-blocking in @Memoize decorator Wrap Redis get and set operations in try-catch blocks to ensure Redis failures don't break the application flow. If cache read fails, proceed to fetch from source. If cache write fails, silently ignore and return the result. Co-Authored-By: unknown <> * fix(cache): add logging for Redis failures and remove barrel import - Add warning logs for Redis failures in @Memoize and @Unmemoize decorators - Remove packages/lib/dto/index.ts barrel import file - Update all imports to use direct file paths instead of barrel imports Co-Authored-By: unknown <> * fix(cache): sanitize log messages to avoid exposing sensitive data - Remove cacheKey from log messages (may contain PII like user/team IDs) - Log only error.message instead of raw error objects - Addresses Cubic AI feedback (confidence 9/10) Co-Authored-By: unknown <> * sanitize log --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Volnei Munhoz <volnei@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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
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> |
||
|
|
6c3b10672c | fix: managed event type bug (#27047) | ||
|
|
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 |
||
|
|
e620264848 |
fix: resolve noNonNullAssertion and noImplicitAnyLet lint issues (#27021)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
adc198b37b |
feat: add feature opt-in banner system (#26625)
* docs: add feature opt-in banner system plan Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * docs: iterate on feature opt-in banner plan based on feedback - Use config.ts for feature metadata instead of TRPC response - Consolidate localStorage dismissal into single key to avoid bloat - Replace separate success dialog with in-dialog success state for smoother UX Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: implement feature opt-in banner system - Add checkFeatureOptInEligibility TRPC procedure to check if user can opt-in - Create useFeatureOptInBanner hook with localStorage dismissal state - Create FeatureOptInBanner floating component for bottom-right display - Create FeatureOptInConfirmDialog with role-based options and success state - Integrate banner into bookings-view.tsx as example usage Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add i18n translation keys for feature opt-in banner * refactor: create FeatureOptInBannerWrapper for simpler consumer integration Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: use @calcom/lib/webstorage and add Zod schema for localStorage Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: address PR review comments - use PBAC, move logic to service, improve typing Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> # Conflicts: # packages/features/feature-opt-in/services/FeatureOptInService.ts * test: add comprehensive tests for checkFeatureOptInEligibility method Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: correct import and Checkbox type errors Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update message * invalidate after dialog dismiss * feat: simulate user opt-in to determine banner eligibility When a feature has a strict policy and org/team hasn't explicitly enabled it, user opt-in alone won't enable the feature. This change simulates what would happen if the user opts in and only shows the banner if opting in would actually enable the feature. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add early return for missing featureConfig and clarify simulation comment Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix repository usage * refactor: simplify FeatureOptInConfirmDialog UI and remove unused translation Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: replace radio buttons with multi-select dropdown in FeatureOptInConfirmDialog Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * resize banner * refactor: use AnimatedPopover pattern for team selection and rename titleI18nKey to nameI18nKey Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: change 'Just for me' to 'For me', fix width clipping, remove divider Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update style * feat: make 'Just for me' mutually exclusive with teams/org and store opt-ins in localStorage Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: remove barrel imports and update to direct imports Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add modal prop to AnimatedPopover to fix scroll lock conflict in dialogs Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: wrap Popover.Content with Portal to prevent layout interference in dialogs Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: use flexbox gap instead of space-y to prevent popover wrapper from affecting layout Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * Revert "fix: use flexbox gap instead of space-y to prevent popover wrapper from affecting layout" This reverts commit 8385adafa890c2f2674aa3ae3b10ca6e0c55ba5c. * Revert "fix: wrap Popover.Content with Portal to prevent layout interference in dialogs" This reverts commit e84301a35a99b3559d47c2d37316af290834ca2d. * Revert "fix: add modal prop to AnimatedPopover to fix scroll lock conflict in dialogs" This reverts commit b015af2f1cf31ef7087c02cb8535d96cc4a34125. * feat: replace Radix Dialog and AnimatedPopover with coss-ui components This migration uses @coss/ui Dialog and Popover components which are built on Base UI instead of Radix. Base UI handles scroll locking and positioning differently, which should fix the gap issue when opening the popover inside the dialog. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: replace remaining @calcom/ui components with coss-ui - Replace Divider with Separator from @coss/ui - Replace Label with Label from @coss/ui - Replace CheckboxField with Checkbox + Label from @coss/ui - Replace Icon with direct lucide-react icons (UserIcon, BuildingIcon, UsersIcon, CheckIcon) - Replace showToast with toastManager.add() from @coss/ui Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: replace Popover with Menu component from coss-ui - Replace Popover + FilterCheckboxField with Menu + MenuCheckboxItem - MenuCheckboxItem provides built-in checkbox indicator and styling - MenuSeparator provides proper menu separators - Cleaner API with onCheckedChange callback - Better keyboard navigation support Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: align icon and text on same line in MenuCheckboxItem, widen dialog - Wrap icon and text in flex container with items-center gap-2 - Change dialog width from sm:max-w-md to sm:max-w-lg to prevent text wrapping Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * use dimmed bg for coss dialog title * refactor: change nameI18nKey/descriptionI18nKey to nested i18n object - Change OptInFeatureConfig interface to use i18n: { name, description } - Update all component usages to use featureConfig.i18n.name and featureConfig.i18n.description - Update test mocks to use new structure Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add i18n.title to OptInFeatureConfig type definition Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update texts * use title instead of name * update banner style * refactor: split FeatureOptInConfirmDialog into separate success and confirmation dialogs Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: don't record dismissed info in local storage after successful opt-in Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add checkFeatureOptInEligibility to IFeatureOptInService interface Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * update common.json * refactor: move tRPC usage from features package to apps/web/modules Addresses Cubic AI review feedback (confidence 9/10): - Remove @calcom/trpc import from FeatureOptInConfirmDialog.tsx - Add FeatureOptInMutations type for passing mutation functions via props - Move tRPC hooks to useFeatureOptInBanner hook in apps/web/modules - Pass mutations through FeatureOptInBannerWrapper to dialog component This maintains the architectural constraint that packages/features should not import from @calcom/trpc to prevent circular dependencies. Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
2608e136cb |
fix: use appropriate error codes in chargeCard handler (#27013)
- Change 'Booking not found' to throw NOT_FOUND (404) instead of plain Error - Preserve ErrorWithCode for ChargeCardFailure to properly map to BAD_REQUEST (400) - Add specific error handling for 'User is not a member of the team' -> FORBIDDEN (403) - Add specific error handling for 'User ID is required' and 'No payment credential found' -> BAD_REQUEST (400) - Keep INTERNAL_SERVER_ERROR (500) only for actual server errors like 'Payment app not implemented' - Update test to expect ErrorWithCode to be re-thrown instead of wrapped in translated Error Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
ea66a9093c |
fix(teams): add organization scope to membership operations (#26964)
* refactor(teams): improve membership validation for org admins - Add organization scope validation to removeMember handler - Ensure team operations are scoped to users organization context - Update related tests * test(teams): align removeMember tests with updated interface - Add organizationId to test contexts - Add team.findMany mock for org validation - Add test cases for org scope validation * refactor(teams): use TeamRepository for org validation in LegacyRemoveMemberService - Add findByIdsAndOrgId method to TeamRepository - Inject TeamRepository into LegacyRemoveMemberService via constructor - Update RemoveMemberServiceFactory to instantiate and inject TeamRepository - Update tests to mock TeamRepository instead of direct prisma calls Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: keith@cal.com <keithwillcode@gmail.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
e0c637b8ec |
feat: add seat tracking infrastructure for monthly proration (#27001)
Part 1 of monthly proration feature. Adds seat change tracking infrastructure with operationId for idempotency. **Dependency chain:** - This PR (seat tracking) - PR #27002 depends on this |
||
|
|
c0302bfc51 |
fix: get bookings handler for pbac and fallback roles (#25434)
* fix: getTeamIdsWithPermission * fix get bookings handler for pbac and fallback roles * add tests * fix fallback roll query * push integration test fixes * Check for pbac features * fix * restore role behaviour * fix fallabck roles no pbac enabled * debug: add logging to investigate PBAC query failures Co-Authored-By: sean@cal.com <Sean@brydon.io> * re-write integration tests * fix: use >= comparison with bigint cast for PBAC permission count Co-Authored-By: sean@cal.com <Sean@brydon.io> * Restore permission repo * re-write from scratch * fix tests + file * imrpove perf by makign CTE and moving to left join * fix org scoped taems * clean up * fix: update PermissionCheckService mock to use function instead of arrow function Co-Authored-By: sean@cal.com <Sean@brydon.io> * refactor: rename scopedOrgId to orgId Co-Authored-By: sean@cal.com <Sean@brydon.io> * refactor: use MembershipRole enum instead of hardcoded strings Co-Authored-By: sean@cal.com <Sean@brydon.io> --------- Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Eunjae Lee <hey@eunjae.dev> Co-authored-by: Benny Joo <sldisek783@gmail.com> |
||
|
|
9f231d98a4 |
fix: sort workflow dropdown to show org before teams (#26796)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
9ea71d2ba5 |
refactor: migrate MembershipRole usages to PBAC permission checks (#26871)
* refactor: migrate MembershipRole usages to PBAC permission checks - Refactor get.handler.ts to use PermissionCheckService for canUpdateTeams - Refactor checkForInvalidAppCredentials.ts to use getTeamIdsWithPermission - Refactor outOfOffice.utils.ts to use checkPermission for ooo.update - Refactor checkIfOrgNeedsUpgrade.handler.ts to use organization.manageBilling - Refactor getActiveOnOptions.handler.ts to use eventType.update permission - Refactor WorkflowRepository.ts to use workflow.update permission - Refactor organization.tsx to use team.update permission - Refactor getEventTypesByViewer.ts to use eventType.update permission - Refactor getPublicEvent.ts to use team.read permission for private teams - Update CreateNewOutOfOfficeEntryButton.tsx to use canUpdateOOO prop Co-Authored-By: sean@cal.com <Sean@brydon.io> * fix: use organization.update permission instead of team.update for org management Co-Authored-By: sean@cal.com <Sean@brydon.io> * fix: rename teamsWithEventTypeManagePermission to teamsWithEventTypeUpdatePermission Renamed variable to match the permission string being used (eventType.update) Co-Authored-By: sean@cal.com <Sean@brydon.io> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
3a8fe8c7af |
perf: convert services to factory functions and add TypeScript project references (#26117)
* perf(app-store): convert services to factory functions to narrow SDK type exports This change converts CRM, Calendar, Payment, and Analytics services from exporting classes to exporting factory functions that return interface types. This prevents SDK types (HubSpot, Stripe, etc.) from leaking into the type system when TypeScript emits .d.ts files. Services modified: - CRM: hubspot, salesforce, closecom, pipedrive-crm, zoho-bigin, zohocrm - Calendar: all 13 calendar services - Payment: stripe, paypal, alby, btcpayserver, hitpay, mock-payment-app - Analytics: dub Video adapters were audited and already use factory pattern. WIP: Salesforce CRM service has a type error that needs fixing. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(salesforce): add type assertion for appOptions in factory function Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: update remaining consumers to use factory functions - getAnalytics.ts: call factory function instead of new - getConnectedApps.ts: call factory function instead of new - salesforce/CrmService.ts: fix type assertion with default value - salesforce/routingForm/incompleteBookingAction.ts: use factory function - salesforce/routingFormBookingFormHandler.ts: use factory function Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(salesforce): add SalesforceCRM interface for Salesforce-specific methods - Create SalesforceCRM interface extending CRM with findUserEmailFromLookupField and incompleteBookingWriteToRecord methods - Add createSalesforceCrmServiceWithSalesforceType factory function for internal Salesforce modules - Update routing form files to use the new factory function with proper typing Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(salesforce): correct return type in SalesforceCRM interface The findUserEmailFromLookupField method returns { email: string; recordType: RoutingReasons } | undefined, not string | undefined. Updated the interface to match the actual implementation. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: update all call sites to use factory functions - Update calendar API add files to use factory functions (7 files) - Update Google Calendar test files to use factory functions (3 files) - Update Salesforce test files to use SalesforceCRM interface - Add testMode parameter to createSalesforceCrmServiceWithSalesforceType - Remove unused @ts-expect-error directive in bookingScenario.ts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add GoogleCalendar interface and update factory functions for service-specific methods Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: add type annotation to attendee parameter in google-calendar.e2e.ts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: update selected-calendars/route.ts to use GoogleCalendar factory function Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: update remaining GoogleCalendarService call sites to use factory function Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: remove explicit type annotation in google-calendar.e2e.ts to fix type error Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: update test mocks to use factory function pattern for calendar and payment services Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix: convert MockPaymentService to factory function in setupVitest.ts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(api-v2): call calendar service factory functions instead of using new Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * perf(trpc): add TypeScript project references to reduce build file count - Add tsconfig.build.json to app-store with composite settings for declaration emit - Add tsconfig.server.build.json to trpc with project references - Add types and typesVersions to app-store package.json to redirect type resolution to dist-types - Add build:types script to app-store for generating declarations - Add dist-types to .gitignore This reduces the tRPC build file count from 7,733 to 5,618 files (27% reduction) by having TypeScript resolve to prebuilt .d.ts files instead of source files. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(app-store): add fallback to typesVersions for CI compatibility The typesVersions now prefers dist-types but falls back to source files when dist-types don't exist. This fixes CI type-check failures while still allowing the optimization when dist-types are built. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * Added build dependency for tRPC on app-store * fix(app-store): exclude test directories from tsconfig.build.json Exclude __tests__, __mocks__, and tests directories from the build config to prevent test utility files (which import from outside rootDir) from being included in the declaration emit. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(turbo): add build:types task definition for app-store Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(turbo): remove circular build dependency between trpc and app-store The build:types task for app-store transitively imports from @calcom/features, which imports from @calcom/trpc. This creates a circular build dependency when @calcom/trpc#build depends on @calcom/app-store#build:types. Solution: Remove the turbo dependency. The typesVersions fallback pattern ['./dist-types/*', './*'] will use source files when dist-types/ doesn't exist, and use prebuilt declarations when they do exist (for faster builds). Also exclude dist-types from regular tsconfig.json to prevent 'Cannot write file' errors when dist-types/ exists. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * refactor(app-store): rename dist-types to types for consistency Rename the prebuilt TypeScript declarations folder from dist-types to types to match the convention used by @calcom/trpc and other packages in the monorepo. Updated files: - tsconfig.build.json: declarationDir and exclude - tsconfig.json: exclude - package.json: typesVersions paths - turbo.json: build:types outputs - .gitignore: ignore path Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(api-v2): update ICS calendar test to mock factory function instead of class prototype The IcsFeedCalendarService is now a factory function, not a class, so jest.spyOn(IcsFeedCalendarService.prototype, 'listCalendars') no longer works. Updated to use jest.spyOn(appStore, 'IcsFeedCalendarService').mockImplementation() to mock the factory function return value instead. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * refactor(app-store): rename factory functions to Build* naming convention - Rename Calendar factory functions from create*CalendarService to BuildCalendarService - Rename CRM factory functions from create*CrmService to BuildCrmService - Rename Payment factory functions from PaymentService to BuildPaymentService - Rename Analytics factory function from createDubAnalyticsService to BuildAnalyticsService - Update all index.ts re-exports to use new names - Update all call sites throughout the codebase - Update test mocks to use new factory function names This makes it clear that these are factory functions, not class constructors. Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(app-store): update remaining CalendarService and PaymentService imports to Build* names - Update api/add.ts files for applecalendar, caldavcalendar, exchange2013calendar, exchange2016calendar, exchangecalendar, ics-feedcalendar - Update mock-payment-app index.ts to export BuildPaymentService - Fix googlecalendar test import alias for createInMemoryDelegationCredentialForBuildCalendarService Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(tests): update payment service mocks to use BuildPaymentService - Update setupVitest.ts to use BuildPaymentService instead of PaymentService - Update handlePayment.test.ts mock to use BuildPaymentService Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * refactor: address PR review comments - rename to Build* and remove unused code Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * refactor: remove explanatory comments and fix indentation Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * chore: update .gitignore to use *.tsbuildinfo pattern Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * fix(api-v2): update IcsFeedCalendarService to BuildIcsFeedCalendarService in e2e test Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * style: format CalendarService.test.ts Co-Authored-By: keith@cal.com <keithwillcode@gmail.com> * Delete apps/ui-playground/next-env.d.ts --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
511cc87d34 |
fix: properly await async operations in addMembersToTeams (#26866)
* fix: properly await async operations in addMembersToTeams Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * test: add unit tests for addMembersToTeams function Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
6501743e5e |
feat: Add attribute sync logic from Salesforce (#26517)
* Add db schema * Add `CredentialRepository.findByTeamIdAndSlugs` * Add enabled app slugs for attribute syncing * Create repository for `IntegrationAttributeSync` * Create zod schemas * Create `AttributeSyncUserRuleOutputMapper` * Create `IntegrationAttributeSyncService` * Create DI contianer * Create trpc endpoints * Create page * Include team name in `CredentialRepository.findByTeamIdAndSlugs` * Update schema and relations * Update types and schemas * Add more methods to IntegrationAttributeSyncRepository * Add more services to `IntegrationAttributeSyncService` - getById - Init updateIncludeRulesAndMappings * Refactor `getTeams.handler` to use repository * Create `createAttributeSync` trpc endpoint * Create `updateAttributeSync` trpc endpoint * Add router to trpc * Create attribute sync child components * Pass custom actions to `FormCard` * Create `IntegrationAttributeSyncCard` * Pass inital props via server side * Fix prop * Only refetch on mutation * Fixes * Add form error when duplicate field and attribute combo * Add `updateTransactionWithRUleAndMappings` logic * Adjust zod schemas * Service add `updateIncludeRulesAndMappings` * Pass orgId from server to component * Rename types * Add deleteById method to repository * Add name to integrationAttributeSync * Add deleteById method to service * Rename method * Add deleteAttributeSync trpc endpoint * Make the IntegrationAttributeSyncCard a dummy component * test: add tests for IntegrationAttributeSync feature Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Move creating a attribute sync record to the service * Add i18n strings * Safe select credential in find by id and team * Fix default credentialId value in form * Update repository return types * Add i18n string * Make credentialId optional for form schema * Fix label * Add cascade deletes * Add verification that syncs belong to org * Create mapper for repository output * Type fixes * Remove old test file * Pass `attributeOptions` from parent to children * Infer types from zod schema * Type fixes * Type fix * Clean up * Add i18n strings * Remove unused file * Address feedback * Add migration file * Address feedback * Add validation for new integration values * Remove unused router * Move away from z.infer to z.ZodType * Clean up comments * Type fix * Type fixes * Type fix * fix: add passthrough to syncFormDataSchema to preserve extra fields Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Add endpoint for SF to call * Create scratch org config * Create sf cli scripts * Create package logic * Update README * Remove unused file * Add indexes * Add aria label * Address feedback - consistent validation * Fix import paths for attribute types * Add `CredentialRepository.findByAppIdAndKeyValue` * Get credential by instance URL * Verify incoming sfdc orgId matches credential sfdc orgId * Rename method * Get user name integration syncs * refactor: change attributeSyncRules array to singular attributeSyncRule The database schema enforces a one-to-one relationship between IntegrationAttributeSync and AttributeSyncRule (via @unique constraint), and the UI only supports a single rule. This change makes the TypeScript type match the database schema and UI behavior. Changes: - Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null - Update mapper to return singular rule instead of wrapping in array - Update UI component to access sync.attributeSyncRule directly - Update IIntegrationAttributeSyncUpdateParams Omit type - Update tests to use attributeSyncRule: null instead of attributeSyncRules: [] Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Convert `membershipRepository.findAllByUserId` to a normal method * Add temp files to git ignore * Init and process team conditions * Biome formatting * Add `AttributeService` to get user attributes * Add DI container for AttributeService * AttributeSyncService evaluate attribute conditions * Create DI container for attributeSyncService * Return result for full condition * Evaluate if attribute sync should apply to user * Add method * Change PrismaAttributeOptionRepository to instance methods * Init AttributeSyncFieldMappingsService and process attribute syncs * Add AttributeSyncFieldMappingService DI container * Refactor orgId to organizationId * Add membership validation to sync field service * AttributeSYncFieldMappingService use repository methods * AttributeSyncFieldMappingService.processMappings add mapping logic * Add DI tokens * user-sync endpoint to implement attribute syncing * Validate team belongs to org for rule * test: add tests for AttributeSyncRuleService, AttributeSyncFieldMappingService, and AttributeService Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Remove duplicate migration file * Fix merge conflict * fix: resolve type errors in attribute sync feature (#26814) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Rename variable * Fix log typo * Fix file name * Add error logging * Use credential teamId * fix: add missing mockTeamRepository and team validation to tests Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Fix naming * Fix file import * Type fix * Pass MembershipRepository as a dep in AttributeSyncFieldMappingService * Type fix * fix: add mockMembershipRepository to AttributeSyncFieldMappingService tests Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Update packages/app-store/salesforce/api/user-sync.ts Add error handling when getting orgId from stored salesforce id Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> * fix: address Cubic code review comments - PrismaAttributeRepository: use nested select instead of include: true for options - CredentialRepository: use this.primaClient instead of global prisma, use select instead of include for relations - AttributeSyncFieldMappingService: optimize O(n*m) complexity with Map lookup for O(1) access Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Fix typo in CredentialRepository * Update README * Update sfdx-project * Add SFDC package tests * fix: improve Salesforce Apex test assertions to verify actual behavior - Enhanced CalComHttpMock to track HTTP callout invocations and capture requests - Updated UserUpdateHandlerTest to verify HTTP callouts are made with correct data - Updated CalComCalloutQueueableTest to verify HTTP callouts are made correctly - Replaced System.assert(true, ...) with meaningful assertions that verify: - Correct number of HTTP callouts - Request body contains expected fields - Request method is POST Addresses Cubic AI review feedback (confidence 9/10 issues only) Co-Authored-By: unknown <> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> |
||
|
|
1dd2652080 |
fix: Duplicate calls syncing Calendar integrations (#26858)
* fix: Duplicate calls syncing Calendar integrations * fix: TS error in handler * Minor fixup * Set cacheUpdatedAt at correct depth of array * Import RouterOutputs |
||
|
|
53395695b4 |
fix: resolve useLiteralKeys biome lint issues (#26851)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
92d2b59946 |
fix: replace @ts-ignore with @ts-expect-error to fix biome lint errors (#26849)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
2881961859 |
feat: add custom calendar reminder for Google Calendar events (#26078)
* feat: add custom calendar reminder for Google Calendar events Allows users to set default reminder notifications (10, 30, or 60 minutes) for events created via Cal.com bookings in Google Calendar. This addresses the issue where Google Calendar's default reminders don't apply to API-created events. - Add customCalendarReminder field to DestinationCalendar model - Create reminder selector UI in destination calendar settings - Update GoogleCalendarService to apply custom reminders (popup + email) - Add TRPC endpoint for updating reminder settings * fix: address code review feedback - Use z.union with literal values (10, 30, 60) for stricter schema validation - Add localization for toast messages using t() - Fix test data to use null for customCalendarReminder to match test intent * fix: add customCalendarReminder to DestinationCalendar types Update manually-defined DestinationCalendar types to include the new customCalendarReminder field added in the previous commit. This fixes type mismatches when passing Prisma-persisted destination calendars to functions using these local type definitions. * fix: update customCalendarReminder type in test to match Prisma schema The customCalendarReminder field is defined as a non-nullable Int with default value of 10 in the Prisma schema. Changed test value from null to 10 to fix TS2345 type error. * feat: add 'just in time' reminder option for Google Calendar events - Add 0 (just in time) as a valid reminder option alongside 10, 30, 60 minutes - Update TRPC schema to accept 0 as valid reminder value - Add 'Just in time' option to reminder dropdown selector UI - Add translation for 'just_in_time' key in English locale - Include comprehensive test case for 0-minute (just in time) reminders - Remove unused import from test file This addresses reviewer feedback to provide flexible 'just in time' option that allows reminders to fire at exact event start time. 🤖 Generated with Claude Code * fix: add customCalendarReminder to calendars service mock - Add missing customCalendarReminder field to destination calendar mock - Matches the Prisma schema requirement - Fixes type error in calendars controller e2e test * fix: add customCalendarReminder to destination calendars controller test - Add missing customCalendarReminder field to mock destination calendar - Matches Prisma schema requirement - Fixes type error in destination-calendars controller e2e test * fix: cast customCalendarReminder to ReminderMinutes type - Add type cast for reminderValue to ensure type safety - Use nullish coalescing (??) to preserve 0 as valid reminder value - Ensures database number type is properly cast to ReminderMinutes union * refactor: simplify translation logic in DestinationReminderSelector - Remove conditional check for 'just_in_time' label - Pass count parameter to all translations uniformly - Translation function handles unused parameters gracefully Addresses review feedback from @Khaan25 * refactor: make custom calendar reminder opt-in and use repository pattern - Change default from 10 to null (opt-in feature) - Add DestinationCalendarRepository to avoid direct Prisma usage - Add 'Use default reminders' option to UI * refactor: remove redundant migration file The original migration already creates customCalendarReminder as nullable, so this second migration to make it nullable is not needed. * fix: type error for customCalendarReminder in destination calendar settings * refactor: validate customCalendarReminder with Zod schema instead of type casting * refactor: use instance methods in DestinationCalendarRepository Changed from static to instance methods with getInstance() pattern as requested in review. * refactor: replace singleton with DI for DestinationCalendarRepository - Remove getInstance() singleton pattern - Add DI tokens, module, and container - Update GoogleCalendarService and tRPC handler to use DI --------- Co-authored-by: Volnei Munhoz <volnei@cal.com> Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Eunjae Lee <hey@eunjae.dev> |
||
|
|
0b37520f0d |
fix: translate location dropdown group labels and options in event-type settings (#26784)
* fix: translate location dropdown group labels in event-type settings Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: use requesting user's locale for team event type translations For team event types, the current user might not be in eventType.users, causing translations to default to English. This fix queries the user's locale directly from the database when not found in the event type users. Co-Authored-By: morgan@cal.com <morgan@cal.com> * refactor: pass userLocale as parameter instead of database call Per PR feedback, pass the authenticated user's locale as an optional parameter to getEventTypeById instead of making an extra database call. The locale is passed from ctx.user.locale in the tRPC handler. Co-Authored-By: morgan@cal.com <morgan@cal.com> * fix: provide userLocale in apiv2 getEventTypeById * fix: remove unused ts comments --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
4b99072bcc |
feat: add scope configuration for feature opt-in (#26801)
* feat: add scope configuration for feature opt-in Add scope field to OptInFeatureConfig that allows features to be scoped to specific levels (org, team, user). This enables features to be shown only at certain settings pages rather than all three. Changes: - Add OptInFeatureScope type with values 'org', 'team', 'user' - Add optional scope field to OptInFeatureConfig interface - Add getOptInFeaturesForScope helper function to filter features by scope - Update FeatureOptInService to filter features based on scope - Update tRPC router to pass scope parameter for org/team endpoints Features without a scope field default to all scopes for backward compatibility. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add scope validation to setUserFeatureState and setTeamFeatureState - Add isFeatureAllowedForScope helper function to check if a feature is allowed for a scope - Update setUserFeatureState to reject if feature is not scoped to 'user' - Update setTeamFeatureState to accept scope parameter and reject if feature is not allowed - Update tRPC router to pass scope parameter for team and org endpoints - Fix unit test mock to include new config exports Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: use ErrorWithCode for scope validation and add tests - Replace raw Error with ErrorWithCode using ErrorCode.BadRequest - Add comprehensive tests for setUserFeatureState scope validation - Add comprehensive tests for setTeamFeatureState scope validation - Test both enabled/disabled and inherit state scenarios - Test error messages include feature ID and scope name Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: improve Features menu visibility to use scope configuration Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: remove unused hasOptInFeaturesForScope function Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: allow features not in config at all scopes (permissive default) Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: revert permissive default and mock scope validation in integration tests Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
f4303d8d60 | icalsequence fix (#26815) | ||
|
|
c13fce4483 |
fix: changes to error on schedule name empty save (#24044)
* fix #21709: change to error on schedule name empty save * fix comments * minor enahncemnts --------- Co-authored-by: Volnei Munhoz <volnei.munhoz@gmail.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> |
||
|
|
5c686d90f9 |
feat: add tri-state UI settings pages and auto opt-in preference (#25892)
* feat: add tri-state UI settings pages and auto opt-in preference TASK 5: Tri-state UI with ToggleGroup - Create shared TeamOrgFeaturesSettings component - Create user features settings page (features-view.tsx) - Create team features settings page - Create org features settings page TASK 6: Add auto opt-in preference - Add autoOptInExperimentalFeatures field to User and Team models - Add migration for new fields - Add TRPC endpoints for auto opt-in preference (using repository pattern) - Add auto opt-in checkboxes to settings pages Also adds i18n keys for feature opt-in UI. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> refactor: rename autoOptInExperimentalFeatures to autoOptInFeatures Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> refactor: apply PBAC procedure pattern to featureOptIn router - Create createTeamPbacProcedure for team-scoped endpoints - Create createOrgPbacProcedure for organization-scoped endpoints - Refactor all team/org endpoints to use the new PBAC procedures - Significantly reduces boilerplate code for permission checks Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> add features pages implement hooks update style update style rename slug to featureId show Features page on the side bar only if OPT_IN_FEATURES.length > 0 revert unncessary renaming revert some changes remove some changes * fix repository usage * test: add unit tests for PBAC utility procedures Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add 'disabled by organization' badge for Team Level Features page Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * a little clean up * feat: add effectiveReason to computeEffectiveStateAcrossTeams for better UI feedback - Update computeEffectiveStateAcrossTeams to return both enabled state and reason - Add EffectiveStateReason type with 6 possible values - Update FeatureOptInService to include effectiveReason in resolved state - Simplify useUserFeatureOptIn.getBlockedWarning to use effectiveReason directly - Add feature_no_explicit_enablement_warning translation - Invalidate feature list when auto-opt-in setting changes in all hooks * test: add tests for FeatureOptInService.listFeaturesForTeam and refactor router to use TeamRepository Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * make it clearer about auto opt in * move hooks to apps/web/module * fix * fix: move types to packages/features/feature-opt-in, fix imports and test mocks - Move types.ts from apps/web/modules/feature-opt-in/hooks to packages/features/feature-opt-in - Update FeaturesSettings.tsx to import types from new location - Update hooks to import types from @calcom/features/feature-opt-in/types - Fix organization features-view import path (~/settings/organizations -> ~/ee/organizations) - Fix PermissionCheckService mock in util.test.ts to use class syntax Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add validation for team ID and remove isPublic from featureOptIn handler Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: resolve biome lint errors in feature-opt-in files - Add explicit return types to functions and methods - Replace ternary operators with if-else statements - Replace forEach with for...of loops to avoid useIterableCallbackReturn - Extract helper functions to reduce function complexity - Add explicit type annotations to variables - Move exports to end of file to satisfy useExportsLast rule Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: resolve type errors in featureOptIn router - Replace ctx.organizationId with ctx.user.organization.id - Add null checks for organizationId in org procedures - Remove incorrect type annotation from featureOptInRouter Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: address PR feedback on feature opt-in implementation - Refactor createMutationCallbacks to useMutationCallbacks hook with useLocale internally - Restore comment on featureOptIn prop in FeaturesSettings.tsx - Revert getAllTeamIds helper, use ternary operator instead - Use ctx.user.organizationId with proper guard clauses Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix type error * feat: disable toggle when feature is blocked by higher level - Add isBlockedByHigherLevel function to UseFeatureOptInResult interface - Implement blocking detection for user level (org/team disabled) - Implement blocking detection for team level (org disabled) - Organization level never blocked (top level) - Update FeaturesSettings to disable ToggleGroup when blocked Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * change order of toggle buttons * feat: add policy field (permissive/strict) to feature opt-in config - Add OptInFeaturePolicy type with 'permissive' and 'strict' modes - Update computeEffectiveStateAcrossTeams to handle both policies: - Permissive: user opt-in can activate; disables only win if ALL teams disable - Strict: user opt-in alone not enough; ANY explicit disable blocks - Add new EffectiveStateReason values for strict policy - Update FeatureOptInService to read policy from config - Add unit tests for all 9 policy scenarios from spec Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: rewrite test file with scenario tables and make policy required Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix type * fix types * make policy required * disable toggle group if blocked by higher level * refactor: move PBAC procedures to packages/trpc/server/procedures - Move util.ts to pbacProcedures.ts in procedures folder for better reusability - Move util.test.ts to pbacProcedures.test.ts alongside the main file - Update imports in _router.ts to use new location Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: remove redundant null checks in featureOptIn router The createOrgPbacProcedure middleware already validates organizationId and throws if null. Use non-null assertion (!) instead of redundant runtime checks since the middleware guarantees the value exists. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: improve middleware typing to avoid non-null assertions Remove explicit return type from createOrgPbacProcedure to let TypeScript infer the extended context type. This allows handlers to use ctx.organizationId directly (typed as number) instead of ctx.user.organizationId! assertions. The middleware validates organizationId and adds it to the context, so downstream handlers can safely access ctx.organizationId as a number. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat(pbac): use featureOptIn permissions instead of generic team/org permissions Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat(pbac): add PBAC to team features page and pass canEdit to views Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add effectiveReason to IFeatureOptInService and update listFeaturesForTeam interface Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add feature_any_team_disabled to isUserBlockedByHigherLevel check Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: add strict-policy reasons to warning helper function Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> |
||
|
|
d381c2c2cb | init (#26782) | ||
|
|
aaf5958b7d |
feat: adds admin billing section (#26747)
* feat: adds admin billing section * use loading prop * add log on resend error * add error log in billing portal |
||
|
|
fd6e2a9ca5 |
fix: enable DI for FeatureOptInService (#26061)
* fix integration test * fix: enable DI for FeatureOptInService * create containers/FeaturesRepository.ts * refactor: convert FeatureOptInService and FeaturesRepository to moduleLoader pattern - Create feature-specific tokens in feature-opt-in/di/tokens.ts and flags/di/tokens.ts - Update modules to use bindModuleToClassOnToken for type-safe dependency injection - Simplify containers to use moduleLoader.loadModule() for automatic dependency loading - Import feature-specific tokens in central tokens.ts using spread operator Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: rename FeatureOptInServiceInterface to IFeatureOptInService Follow the codebase convention of using 'I' prefix for interface files and names. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * fix: export featuresRepositoryModule for backward compatibility The FeaturesRepository module was refactored to use moduleLoader pattern but AvailableSlots.ts still imports featuresRepositoryModule. This adds the export to maintain backward compatibility. Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
383314d3e2 |
feat: add skip trial feature for teams/orgs billing page (#26584)
* feat: add skip trial feature for teams/orgs billing page Co-Authored-By: sean@cal.com <Sean@brydon.io> * feat: add translation strings for skip trial feature and fix lint-staged config Co-Authored-By: sean@cal.com <Sean@brydon.io> * fix: use IS_TEAM_BILLING_ENABLED instead of IS_SELF_HOSTED Co-Authored-By: sean@cal.com <Sean@brydon.io> * fix: use correct DialogHeader props in billing-view.tsx Co-Authored-By: sean@cal.com <Sean@brydon.io> * restore lint staged config file * invalidate trpc cache * fix: update role filter and error message in skipTrialForTeam handler - Changed role filter to include both OWNER and ADMIN roles to match authorization logic - Updated error message to reflect that both owners and admins can skip the trial Addresses Cubic AI review feedback on PR #26584 Co-Authored-By: unknown <> * fix: optimize skipTrialForTeam to query only specific team by ID Address Cubic AI review feedback: Replace findAllAcceptedTeamMemberships (which fetches all teams) with TeamRepository.findById (which fetches only the specific team needed). Authorization is already validated earlier in the handler, so this redundant query was inefficient. Co-Authored-By: unknown <> * fix static methods * feat: use pbac * fix: remove redundant team query in getSubscriptionStatus handler Co-Authored-By: sean@cal.com <Sean@brydon.io> * add pbac to skip team handler --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
cee3195708 |
fix: optimize routing form mutation to avoid costly name update triggers (#26781)
* fix: optimize routing form mutation to avoid costly name update triggers Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * Add load test script for form responses --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
7c66f33de2 |
chore: UX Fixes (#26643)
* Copy changes
* Move search bar inline with new button
* Get rid of no more results message
* Change hidden badge to (hidden)
* Remove Cal.ai badge from sidebar
* Add dropdown to create button when there is multiple options
* Fix delete dialog
* Saved filters updates
* More string fixes
* Switch members table to use names
* Fix member spacing
* Fix routing form identifier field
* Fix routing forms stuff
* Only show SMS hint on SMS options
* Make workflow delete button minimal
* Fix padding on workflow steps
* Remove min width on workflow title
* Fix delete workflow PR
* Fix org profile buttons
* Fix org profile screen partially scrolled down
* Improve logos & banner uploads
* Personal profile fixes
* Fix settings general view stuff
* Sentence case consistency
* Fix stuff I broke
* Fix fab
* Fix hidden translation string
* Fix text fields
* Make button small for solo users too
* fix: update E2E tests to match sentence case labels in routing forms
* fix: update tests to match sentence case label changes
- insights.e2e.ts: chart titles (14 strings)
- event-types.e2e.ts: Organizer phone number location
- EditLocationDialog.test.tsx: phone number labels
* fix: address Cubic AI review feedback (confidence 9+)
- Replace hardcoded text-gray-500 with text-muted in TextField.tsx hint section
- Replace text locator with data-testid in E2E test for location select
Co-Authored-By: unknown <>
* fix: update E2E tests for sentence case label changes
- Use data-testid selectors for location options (more reliable than text)
- Update field identifiers in routing-forms tests to match new labels
- Fix Long text selector in manage-booking-questions test
* fix: replace text locator with data-testid in manage-booking-questions E2E test
Replace fragile text="Long text" locator with resilient
page.getByTestId("select-option-textarea") selector per E2E best practices.
Addresses Cubic AI review feedback (confidence 9/10).
Co-Authored-By: unknown <>
* fix: use .last() for multiple location select items
---------
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
||
|
|
8dbe3848e7 |
feat: Create Integration Attribute Sync records (#26007)
* Add db schema * Add `CredentialRepository.findByTeamIdAndSlugs` * Add enabled app slugs for attribute syncing * Create repository for `IntegrationAttributeSync` * Create zod schemas * Create `AttributeSyncUserRuleOutputMapper` * Create `IntegrationAttributeSyncService` * Create DI contianer * Create trpc endpoints * Create page * Include team name in `CredentialRepository.findByTeamIdAndSlugs` * Update schema and relations * Update types and schemas * Add more methods to IntegrationAttributeSyncRepository * Add more services to `IntegrationAttributeSyncService` - getById - Init updateIncludeRulesAndMappings * Refactor `getTeams.handler` to use repository * Create `createAttributeSync` trpc endpoint * Create `updateAttributeSync` trpc endpoint * Add router to trpc * Create attribute sync child components * Pass custom actions to `FormCard` * Create `IntegrationAttributeSyncCard` * Pass inital props via server side * Fix prop * Only refetch on mutation * Fixes * Add form error when duplicate field and attribute combo * Add `updateTransactionWithRUleAndMappings` logic * Adjust zod schemas * Service add `updateIncludeRulesAndMappings` * Pass orgId from server to component * Rename types * Add deleteById method to repository * Add name to integrationAttributeSync * Add deleteById method to service * Rename method * Add deleteAttributeSync trpc endpoint * Make the IntegrationAttributeSyncCard a dummy component * test: add tests for IntegrationAttributeSync feature Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Move creating a attribute sync record to the service * Add i18n strings * Safe select credential in find by id and team * Fix default credentialId value in form * Update repository return types * Add i18n string * Make credentialId optional for form schema * Fix label * Add cascade deletes * Add verification that syncs belong to org * Create mapper for repository output * Type fixes * Remove old test file * Pass `attributeOptions` from parent to children * Infer types from zod schema * Type fixes * Type fix * Clean up * Add i18n strings * Remove unused file * Address feedback * Add migration file * Address feedback * Add validation for new integration values * Remove unused router * Move away from z.infer to z.ZodType * Clean up comments * Type fix * Type fixes * Type fix * fix: add passthrough to syncFormDataSchema to preserve extra fields Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Add indexes * Add aria label * Address feedback - consistent validation * Fix import paths for attribute types * refactor: change attributeSyncRules array to singular attributeSyncRule The database schema enforces a one-to-one relationship between IntegrationAttributeSync and AttributeSyncRule (via @unique constraint), and the UI only supports a single rule. This change makes the TypeScript type match the database schema and UI behavior. Changes: - Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null - Update mapper to return singular rule instead of wrapping in array - Update UI component to access sync.attributeSyncRule directly - Update IIntegrationAttributeSyncUpdateParams Omit type - Update tests to use attributeSyncRule: null instead of attributeSyncRules: [] Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * feat: implement FeatureOptInService (#25805) * feat: implement FeatureOptInService WIP * clean up * feat: consolidate feature repositories and add updateFeatureForUser - Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam) - Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository - Update FeatureOptInService to use only FeaturesRepository - Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService - Update _router.ts to remove PrismaFeatureOptInRepository usage - Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts - Update features.repository.interface.ts and features.repository.mock.ts - Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState - Update service.integration-test.ts to use FeaturesRepository Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: rename updateFeatureForUser to setUserFeatureState Rename to match the convention used for setTeamFeatureState Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState * fix integration tests * clean up logics * update services and router * refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array - Renamed getUserFeatureState to getUserFeatureStates - Renamed getTeamFeatureState to getTeamFeatureStates - Changed parameter from featureId: string to featureIds: string[] - Changed return type from FeatureState to Record<string, FeatureState> - Updated FeatureOptInService to use the new batch methods - Added tests for querying multiple features in a single call - Optimized listFeaturesForTeam to fetch all feature states in one query Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add getFeatureStateForTeams for batch querying multiple teams - Added getFeatureStateForTeams method to query a single feature across multiple teams in one call - Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method - Replaces N+1 queries with a single database query for team states - Added comprehensive integration tests for the new method Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: combine org and team state queries into single call - Include orgId in the teamIds array passed to getFeatureStateForTeams - Extract org state and team states from the combined result - Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: use team.isOrganization and clarify computeEffectiveState comment Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * refactor: use MembershipRepository.findAllByUserId with isOrganization Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * feat: add featureId validation using isOptInFeature type guard Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * less queries * add fallback value * fix type error * move files * add autoOptInFeatures column * use autoOptInFeatures flag within FeatureOptInService * add setUserAutoOptIn and setTeamAutoOptIn * fix computeEffectiveState logic * rewrite computeEffectiveState * clean up integration tests * clean up in afterEach * fix type error * refactor: use FeaturesRepository methods instead of direct Prisma calls Replace all manual userFeatures and teamFeatures Prisma operations with the new setUserFeatureState and setTeamFeatureState repository methods. Changes include: - Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam) - Test fixtures and integration tests - Playwright fixtures - Development scripts This ensures consistent feature flag management through the repository pattern and supports the new tri-state semantics (enabled/disabled/inherit). Co-Authored-By: eunjae@cal.com <hey@eunjae.dev> * clean up * fix the logic * extract some logic into applyAutoOptIn() * remove wrong code * refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union - Convert multiple positional parameters to single object parameter - Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit - Update all callers across repository, service, handlers, fixtures, and tests * fix type error * use Promise.all * fix --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * Prevent duplicate field and attribute mappings * Add validation that attribute belongs to the org * fix: address Cubic AI review feedback - Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10) - Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10) Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * fix: address remaining cubic review feedback - RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions - updateAttributeSync.handler.ts: Add early organization check before service calls for consistency - createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching - IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> * Pull test file from main --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Eunjae Lee <hey@eunjae.dev> |
||
|
|
77f59b1e4d |
chore: Integrate confirmation booking audit (#26523)
* chore: Integrate booking confirmation booking audit Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: Use BookingStatus type instead of string for booking.status Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * Make booking-audit integration test utils reusable * refactor: enhance handlePaymentSuccess to accept appSlug and actor identification - Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext. - Introduced getActor function to determine the actor based on appSlug and credentialId. - Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters. - Improved logging for missing credentialId in payment processing. - Adjusted related schemas to ensure proper type handling for booking status and actor identification. * fix: Correct import paths and getActor function call Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: Use ActorIdentification type instead of AuditActor in getActor Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: Add guard clause for undefined actor in fireBookingAcceptedEvent Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: Add actionSource to all confirm calls Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * refactor: Integrate actor identification and action source updates across booking services - Added `makeUserActor` to various booking service files to enhance actor identification. - Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK". - Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling. - Improved error handling and logging for booking actions to enhance traceability. * Remvoe formatting changes * Add test * refactor: Enhance booking confirmation tests and event handling - Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings. - Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings. - Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability. - Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections. * fix tests * refactor: Use confirmHandler directly in link and verify-booking-token routes Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation. Changes: - apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input - apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input - Updated tests to mock confirmHandler instead of tRPC caller Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix ts errors due to merge frommain * feat: introduce getAppActor utility for actor creation This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic. Changes: - New file: packages/app-store/_utils/getAppActor.ts - Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor - Removed redundant actor creation code from these functions * refactor: Update appSlug in payment success handlers to use appConfig.slug This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code. Changes: - Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks. - Adjusted a test case to reflect the new appSlug value for consistency. * test: Enhance booking token verification and audit action tests This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity. Changes: - Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error. - Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`. - Clarified comment in `actionSource.ts` regarding the schema for action sources. - Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events. --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
c9bb03b602 |
chore: Integrate add guests booking audit (#26568)
* chore: Integrate add guests booking audit Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * chore: Add actionSource parameter to support API_V2 audit logging Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * refactor: update attendee audit action service to use new email schema - Modified the `AttendeeAddedAuditActionService` to replace the old attendees schema with a new `emailSchema` for better validation. - Adjusted the `addGuestsHandler` to pass the action source explicitly and updated the audit logging to reflect the new structure. - Cleaned up the code for better readability and consistency. * test: add happy path integration test for attendee added action Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
fc0a2b5a37 |
refactor: Remove trpc/server dependency from @calcom/atoms (#26717)
* mv useTeamMembersWithSegment * remove * fix ts error * remove * remove * remove * biome rule * wip * refactor: remove remaining @calcom/trpc/server imports from atoms - Create local types for schedule handlers (CreateScheduleHandlerReturn, DuplicateScheduleHandlerReturn, GetAvailabilityListHandlerReturn, CreateScheduleInput) - Create local GetAvailableSlotsResponse type for slots hook - Update imports in useAtomCreateSchedule, useAtomDuplicateSchedule, useAtomGetAllSchedules, and useAvailableSlots Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * fix * fix: add userId to Schedule type and create ScheduleForList type - Schedule type now includes userId for create/duplicate handlers - Created ScheduleForList type for list handler (uses select without userId) Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * fix * fix * fix * fix * fix: correct fromUser/toUser types in GetAvailableSlotsResponse - fromUser: { id, displayName } (matches IFromUser) - toUser: { id, username, displayName } (matches IToUser) Co-Authored-By: benny@cal.com <sldisek783@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
3e7e376100 |
chore: Some minor fixes and follow up to #26446 (#26587)
* init * DI and other improvements * type fix --------- Co-authored-by: Volnei Munhoz <volnei@cal.com> |
||
|
|
f6d3b11582 |
refactor: Membership.findByUserIdAndTeamId to instance method (#26628)
* Make and instance method * Refactor files * fix: update MembershipRepository mocks to use vi.hoisted() for proper hoisting Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
0330d14210 |
feat: system admin blocklist table (#25039)
* feat: system admin blocklist table * chore: text * fix: type error * fix: type error * fix: type error * fix: frontend bug * chore: improvments * refactor: use shared components * refactor: improvements * fix: delete * refactor: support multiple watchlist * chore: update translation * fix: type err * fix: bulk bug * tests: add unit test * refactor: file * refactor: file * fix: type error * fix: type error * chore: translation * refactor: use shared comments * fix: imports * fix: type error |
||
|
|
f3a37886e3 |
chore: Integrate reschedule request booking audit (#26527)
## What does this PR do? Adds audit logging for the reschedule request flow. When an organizer requests an attendee to reschedule a booking, this action is now logged to the booking audit system. This is part of the booking audit integration effort, following the pattern established in PR #26046 (booking creation/rescheduling audit) and PR #26458 (cancellation audit). ## Changes - Added audit logging call to `requestReschedule.handler.ts` using `BookingEventHandlerService.onRescheduleRequested()` - Captures audit data: - `rescheduleReason`: The reason provided for requesting the reschedule (nullable string) - `rescheduledRequestedBy`: Email of the user who requested the reschedule - Uses `makeUserActor(user.uuid)` to identify the actor performing the action - Added required `source` parameter for action source tracking (passed as `"WEBAPP"` from tRPC router) - Updated `RescheduleRequestedAuditActionService` schema to use simpler field structure - Updated test helper `getTrpcHandlerData` to pass `source: "WEBAPP"` parameter ## Updates since last revision - Changed `source` parameter from optional with default to required - tests now explicitly pass `source: "WEBAPP"` instead of relying on a default value ## 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 - follows established audit pattern with existing infrastructure tests. ## How should this be tested? 1. Log in as a user with a booking 2. Navigate to the booking and click "Request Reschedule" 3. Provide a reschedule reason and submit 4. Verify the audit log is created with the correct data (requires access to audit log storage/database) The audit logging follows the same pattern as other booking audit integrations, so if those are working, this should work as well. ## 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/ae84d093c4594a5d89b88c45639a6a06 **Requested by**: @hariombalhara ## Human Review Checklist - [ ] Verify the audit data schema matches `RescheduleRequestedAuditActionService` expectations (fields: `rescheduleReason`, `rescheduledRequestedBy`) - [ ] Confirm the schema change from change-based fields (`{ old, new }`) to simple nullable strings is intentional - [ ] Confirm `user.uuid` is available in the tRPC session context - [ ] Note: API v2 does not have a reschedule request endpoint, so no API v2 changes are needed |
||
|
|
d9aef5b6a6 |
fix: add URL validation for logo fields (#26522)
* fix(auth): add URL validation for organization logo fields - Add URL validation utility for server-side fetched URLs - Validate logo URLs in tRPC organization schema - Validate logo URLs in API v2 team DTOs - Add graceful fallback in logo route for invalid URLs - Only allow HTTPS and image data URLs - Add unit tests for URL validation * fix: add missing IP range and type validation - Add RFC 6598 CGNAT range (100.64.0.0/10) to blocked IPs - Add @IsString() decorator before custom URL validators - Add boundary tests for new IP range * fix: address review feedback - Export validateUrlForSSRFSync via @calcom/platform-libraries - Fix nullable/optional order in Zod schema * fix: block localhost hostname and explicit null check - Add localhost to BLOCKED_HOSTNAMES for sync validation - Use explicit null check (url == null) instead of falsy check * fix: allow empty string in URL validation * refactor: extract shared validation logic - Extract validateUrlCore() to eliminate duplication between sync/async versions - Add JSDoc to all exported functions for better discoverability - Remove redundant comments that repeated function names - Simplify existing comments to be more concise * fix: reject empty strings in URL validator Previously if (!url) allowed empty strings to bypass validation. Now explicitly checks for null/undefined only |