Compare commits

...

524 Commits

Author SHA1 Message Date
Gustavo Maronato 51ca072d0e Add terms of service
Signed-off-by: Gustavo Maronato <maronato@noreply@maronato.dev>
2024-01-28 02:46:39 -03:00
Gustavo Maronato f730ad9ff5 Add privacy policy
Signed-off-by: Gustavo Maronato <maronato@noreply@maronato.dev>
2024-01-28 02:31:06 -03:00
Benny Joo b76a2a4019
chore: [app-router-migration 21] Migrate "/d/*" pages (#13047)
* Migrate d/* page group

* Fix metadata

* manual: fix type of arg of getData

* fix

* manual: fix type errors

* Fix type errors

* fix type errors

* fix error

* fix

* fix build error
2024-01-12 18:37:25 -03:00
DmytroHryshyn a28b9cacd2
chore: [app-router-migration 17]: migrate payments page (#13039)
* chore: migrate payments page

* migrate page to WithLayout HOC, replace new ssrInit

* fix type error

* fix

* revert version changes

* fix

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-01-12 18:36:48 -03:00
DmytroHryshyn abd90f6af8
chore: [app-router-migration 14] migrate not-found page (#13032)
* chore: migrate not-found page

* migrate page, replace ssgInit

* fix flaky test

* fix

* fix

* fix
2024-01-12 18:21:35 -03:00
Benny Joo 0bdc45a1a5
chore: [app-router-migration 18] Migrate "/settings/organizations/*" pages (#13042)
* manual: app-directory-boilerplate-calcom

* manual: import components directly

* manual: move files to correct route groups and add metadata

* manual: Change structure & Refactor to make code up to date

* manual: refactors

* Fix

* manual: fix type of arg of getData

* manual: fix type error

* fix type bugs

* fix

* fixing the build

* wip

---------

Co-authored-by: Greg Pabian <35925521+grzpab@users.noreply.github.com>
2024-01-12 15:32:39 -03:00
Riddhesh Mahajan 65d9704f2b
fix: add check for already used slug (#13076)
* add check for already used slug

* Update _patch.ts

Removed comment that added no value based on the code. Renamed const

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-12 11:07:39 -03:00
sean-brydon d8ba783369
fix: use brand accent instead of invert on current day selector (#13194)
* fix: use brand accent instead of invert

* fix: use brand accent instead of invert

* chore: remove constants from commit
2024-01-12 13:44:26 +00:00
Alex van Andel 782127a993 v3.6.4 2024-01-12 12:42:31 +00:00
sean-brydon fbc3f7b51f
fix: correctly use eventTriggers parsed and use Array.from (#13193)
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-12 11:19:40 +00:00
Crowdin Bot 619ccf4065 New Crowdin translations by Github Action 2024-01-12 11:12:57 +00:00
Alan Daniel 40d8f34e8d
chore: rename 'reason' to 'cancellationReason' to match the api params schema (#13178)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-01-12 11:10:04 +00:00
DmytroHryshyn 9c1e1d7312
chore: [app-router-migration 24] migrate more page (#13054) 2024-01-11 21:45:45 +00:00
Carina Wollendorfer 710a1a7d38
add teamId when refreshing access token (#13159)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-11 21:43:15 +00:00
Peer Richelsen f25605ef4d
chore: corrected event-types icons (#13173) 2024-01-11 21:42:29 +00:00
DmytroHryshyn 684575d0a4
chore: [app-router-migration 15] migrate bookings/* page group (#13038)
* codemod: remove-get-static-props

* replace ssrInit

* manual: extract getServerSideProps into a file

* manual: Export getServerSideProps from legacy page

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-01-11 18:20:03 -03:00
sean-brydon bc6267e99b
fix: Use constants.ts for brand colours > db DEFAULT (#13167)
* fix: user proper default values if no brand colour is set.

* fix:default value

* fix: more ?? to defined default as color is possibly null
2024-01-11 20:22:35 +00:00
Crowdin Bot 9901c91e9b New Crowdin translations by Github Action 2024-01-11 18:32:20 +00:00
Rahil Ansari dfe03efc37
fix: fix the fluctuations in sidebar when we scroll main content (#13115)
* fix the fluctuations in sidebar when we scroll main content

* fix: reduced vertical padding instead of
TOP_BANNER_HEIGHT

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-01-11 18:29:03 +00:00
Crowdin Bot 0eabb56f07 New Crowdin translations by Github Action 2024-01-11 15:35:52 +00:00
Carina Wollendorfer cdd066c653
add missing translations (#13125)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2024-01-11 15:31:52 +00:00
Ethan Chen 026f22fbaf
feat: add utcOffset in webhook payload (#12709)
* add utcOffset in webhook

* add utcOffset in webhook

* fix type

* fix type

* fix function error

* fix: UTCOffset DST

* getUTCOffsetByTimezone support date param

* add startTime in `getUTCOffsetByTimezone` func

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-11 14:35:02 +00:00
Keith Williams 5950c5a756
fix: Bundle analysis message (#13161) 2024-01-11 13:30:14 +00:00
Greg Pabian cd9d16be3e
chore: [app-router-migration 23] Migrate the "enterprise" page (#13044) 2024-01-11 12:56:30 +00:00
Keith Williams 993f92acba
chore: Ignore admin and devops team labels (#13162) 2024-01-11 09:46:42 -03:00
Benny Joo 6f110d21fd
chore: [app-router-migration 22] Migrate `/insights` page (#13055)
* intuita codemod: remove-get-static-props

* intuita codemod: app-directory-boilerplate-calcom

* manual: refactor and add metadata title/description

* manual: Change structure & Refactor to make code up to date
2024-01-11 12:45:26 +00:00
Benny Joo 0df6777814
chore: [app-router-migration 20] Migrate `/settings/security/*` pages (#13046)
* intuita codemod: app-directory-boilerplate-calcom

* manual: move folders to (settings-layout) route group

* manual: add title/description metadata

* manual: Change structure & Refactor to make code up to date
2024-01-11 12:44:44 +00:00
Benny Joo 5f14cd31d1
chore: [app-router-migration 19] Migrate `/settings/my-account/*` pages (#13045)
* intuita codemod: app-directory-boilerplate-codemod

* manual: move to (settings-layout) route group

* manual: add title/description metadata

* manual: Change structure & Refactor to make code up to date
2024-01-11 09:22:44 -03:00
DmytroHryshyn 070ec326aa
chore: [app-router-migration 13] Migrate reschedule page group (#13030)
* app-boilerplate-codemod

* fin

* fix

* fix & test & move to new struct

* manual: fix type error

* manual: fix lint error

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-01-11 07:50:29 -03:00
DmytroHryshyn 4ca79af13f
chore: [app-router-migration-11] Migrate workflow page group (#12777)
* add a/b test flags for apps, workflows, getting-started, settings/teams

* Finalize

* Discard changes to apps/web/app/layoutHOC.tsx

* fix: types

* manual: address Keith's comments

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
2024-01-11 07:49:46 -03:00
Crowdin Bot a2e70f9aad New Crowdin translations by Github Action 2024-01-11 03:01:54 +00:00
Benny Joo f186d2e41d
Migrate: `/maintenance` page group (#13056) 2024-01-10 23:58:38 -03:00
Riddhesh Mahajan aaeea250bc
fix: only consider unique eventTriggers (#13080)
* only consider unique eventTriggers

* remove intermediary const

---------

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2024-01-10 18:26:19 +00:00
alannnc 96af17d8d7
feat: OOO booking-forwarding (#12653)
* feat-profile-forwarding

* fix for promises of handling

* fix badge success color

* clean up

* fix suggested changes

* Changed design on booking-forward pages and moar test

* taking care of suggested changes, trpc errors and code cleaning

* improve text

* fix conflicting data-testid

* fix unique data-testid

* fix error css-global, email button styles, error conditional

* rename files to match functionality, remove away ui

* Add translations and migration

* remove log

* small fixes + improvements

* fix styles to match new design

* merge fixes

* Fix styles dark mode

* Solving merge conflicts from earlier

* Fix/change test to match new elements

* use trash icon button insted of dots (design issues)

* only send email if toUserId is set

* Fix date picker dark mode

* merge with remote

* removed status field from table and email its now for notify

* small text improvement in email

* check for team plan not paid plan

* fixes and clean up due to removing status

* fix old send request name to new behaviour

* more naming improvements and text

* remove status from handle-type

* code clean up

* fix type error

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2024-01-10 17:04:02 +00:00
Carina Wollendorfer dfaa6d28e4
fix: scheduling/canceling workflow emails in cron api call (#13123)
* set credentials for sendgrid client on all requests

* fix typo

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2024-01-10 16:44:37 +00:00
Peer Richelsen 6a2de993bb
fix: org link for desktop (#13119)
* fixed org link for desktop

* Update globals.css

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-10 15:02:07 +00:00
Keith Williams b69d885ee6
fix: Bundle analysis commenting (#13116)
* fix: Bundle analysis commenting

* Remove if on build step for testing

* Remove GitHub event number check for testing

* Reverted changes for testing
2024-01-10 14:35:27 +00:00
Alex van Andel d001c4e2ae v3.6.3 2024-01-10 13:41:03 +00:00
Hariom Balhara 558f1c9478
fix: Payment Page not showing (#13146) 2024-01-10 13:34:49 +00:00
zomars 74748a6183 Update yarn.lock 2024-01-09 12:42:37 -07:00
Omar López 986f17f54b
chore: mitigates docker rate limiting (#13130) 2024-01-09 12:40:56 -07:00
Alex van Andel ab342016d2 v3.6.2 2024-01-09 12:08:05 +00:00
Alex van Andel c34c27fc0a
fix: Button re-enables on sluggish networks whilst redirecting (#13106)
* fix: Button re-enables on sluggish networks whilst re-direct is happening

* Add explanatory comment

* fix: Booking form validation can take a while

---------

Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-09 11:32:25 +00:00
Riddhesh Mahajan 6dbf372ab0
add check for parentId (#13078) 2024-01-09 11:16:44 +00:00
Keith Williams 7dc7f949cf
chore: Upgrade deprecated parts of bundle analysis (#13104)
* chore: Upgrade deprecated parts of bundle analysis

* Added workflow_dispatch to allow for manual runs

* Removed conditions just for testing
2024-01-09 11:13:41 +00:00
DmytroHryshyn 5690718e7f
chore: [app-router-migration 10.5]: replace new trpc helper with legacy ssrInit/ssgInit (#13108) 2024-01-09 02:59:11 +00:00
zomars 97d5bb9fe6 Update turbo.json 2024-01-08 15:37:32 -07:00
DmytroHryshyn fcc50c1d0f
chore: [app-router-migration-11] Migrate settings/teams page group (#12778)
* intuita codemod: app-directory-boilerplate-calcom

* manual: add title and description metadata for each page

* manual: move between folders

* manual: finalize migration

* manual: fix client components

* manual: Change structure & Refactor to make code up to date

---------

Co-authored-by: Benny Joo <sldisek783@gmail.com>
2024-01-08 10:51:40 -07:00
Morgan b832289f8e
refactor: booker import dynamically specific ui components instead of the whole package (#13101) 2024-01-08 17:49:39 +00:00
Hariom Balhara 4aa0b4cc65
fix: Team URL and booker URLs (#13050)
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-08 15:25:48 +00:00
Hariom Balhara e2ef9dd710
fix: Failing tests (#13091)
* Stripe needs month starting from 1 and not 0

* Fix Routing form failure

* Fix failing test
2024-01-08 14:23:41 +00:00
Keith Williams 15b0e0c5bd
chore: Change PR template to have bullet points instead of checkboxes for type (#13096) 2024-01-08 13:59:03 +00:00
Udit Takkar 020515de8c
fix: invalid cal video bug (#13058)
* fix: invalid cal video bug

* chore: undo

* fix: daily video

* chore: refactor code
2024-01-08 13:10:06 +00:00
Keith Williams 87cb8e918f
chore: Add E2E test suite back to PRs (#13093)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-08 12:36:47 +00:00
Peer Richelsen 69677495ca
Revert "feat(app-store): add feishu calendar (#13089)" (#13094)
This reverts commit a40520b90c.
2024-01-08 12:28:59 +00:00
techknowlogick a40520b90c
feat(app-store): add feishu calendar (#13089)
* feat(app-store): add feishu calendar

* fix type names
2024-01-08 12:28:21 +00:00
Keith Williams c07b456b2d
chore: Stop closing stale PRs (#13092) 2024-01-08 12:19:52 +00:00
Crowdin Bot 7ec2a4b8fa New Crowdin translations by Github Action 2024-01-07 20:49:49 +00:00
Riddhesh Mahajan dccaf5fb67
align username update, cancel and check icon (#13085) 2024-01-07 20:46:45 +00:00
Erik d76060e037
fix: Stripe e2e regression (#13062)
* fix: Stripe e2e regression

* chore: remove
2024-01-07 05:47:01 +00:00
Crowdin Bot 48d4725e10 New Crowdin translations by Github Action 2024-01-07 03:24:54 +00:00
Hariom Balhara 2f1e545976
feat: Allow org creation with conflicting slug and renaming team slug during migration (#13065) 2024-01-07 08:51:59 +05:30
Gabriel Hall 50fb903ba6
chore: minor typo (#13064) 2024-01-06 12:42:06 +00:00
DmytroHryshyn ccda3fd71e
chore: [app-router-migration-10] Migrate getting started page (#12776)
* make no-meeting-found page use ssr

* remove-route-groups

* add LayoutHOC

* fix

* fix

* add a/b test flags for apps, workflows, getting-started, settings/teams

* chore: migrate getting-started-page

* fix: move fonts css variables to layout

* chore/implement-ab-test

* Discard changes to .env.example

---------

Co-authored-by: zomars <zomars@me.com>
2024-01-05 10:21:11 -07:00
Udit Takkar c44fb074ab
fix: Mobile scrolling issue (#13049) 2024-01-05 16:07:17 +00:00
Alex van Andel d56d649bf0
fix: Broken test after recent organization avatar revamp (#13059)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-05 15:44:59 +00:00
Amit Sharma 8856ba7d70
fix: Changed dynamic to group meeting and udpated meta (#13028)
* Changed dynamic to group meeting and udpated meta

* type fix

* Update packages/features/bookings/components/BookerSeo.tsx

* Update packages/features/eventtypes/lib/getPublicEvent.ts

* Update packages/features/bookings/components/BookerSeo.tsx

* Update packages/features/eventtypes/lib/getPublicEvent.ts

* Update getPublicEvent.ts

* Apply suggestions from code review

* Update packages/lib/defaultEvents.ts

* Update packages/lib/defaultEvents.ts

* Update packages/lib/defaultEvents.ts

* Update packages/lib/defaultEvents.ts

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-05 13:20:17 +00:00
Alex van Andel 0897bf20da
feat: Add newline as a bulk import seperator (#13052) 2024-01-05 12:50:11 +00:00
Hariom Balhara 6ce6d570db
Avoid duplicate inline embeds (#13048) 2024-01-05 12:32:53 +00:00
Amit Sharma b99ccb1a5a
fix: Can't resubmit otp while verifying email (#13034)
* Can't resubmit otp while verifying email fix

* submit button added

* chore: remove disabled

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2024-01-05 12:28:20 +00:00
sean-brydon 698d8ae4bd
chore: front-end-avatars (#12716)
* Update UserAvatar and remove org avatar

* Update Imports

* Fix imports to use calcom/ui

* type: fix imports

* fix: use testId on profile

* test: use image src instead of innerHTML

* fix: Allow alt on useravatar

* test: add testId to org profile

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2024-01-05 10:36:44 +00:00
DmytroHryshyn 0dddc2224a
chore: [app-router-migration-9] Migrate apps/index page (#12775)
Co-authored-by: zomars <zomars@me.com>
2024-01-04 14:36:31 -07:00
Peer Richelsen 49f9f5489b
fix: team availability data table scrolling (#13036)
* fixed data table scrolling for team availability

* Update packages/features/shell/Shell.tsx

* nit
2024-01-04 20:33:02 +00:00
DmytroHryshyn ecb693c70e
chore: [app-router-migration 8.6] reorganize future pages file structure (#12988)
* make no-meeting-found page use ssr

* remove-route-groups

* add LayoutHOC

* fix

* fix

* ensure proper types for withLayout function

---------

Co-authored-by: Greg Pabian <35925521+grzpab@users.noreply.github.com>
2024-01-04 11:26:11 -07:00
Peer Richelsen 3c6fdfe724
chore: removed old booker feature flag (#13040)
Co-authored-by: Omar López <zomars@me.com>
2024-01-04 11:23:51 -07:00
Somay Chauhan ef7f0e2259
feat: Organization Add member to a team email communication (#12946) 2024-01-04 16:29:07 +00:00
Riddhesh Mahajan 3791af8644
feat: Make private URLs easier to copy-paste from web app (#13018)
* Make private URLs easier to copy-paste from web app

* Apply suggestions from code review

* Update apps/web/pages/event-types/index.tsx

* lint

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-04 16:28:23 +00:00
Keith Williams c19799e275
chore: Remove invalid DATABASE_URL 'with' value (#13027) 2024-01-04 01:39:45 -03:00
Keith Williams 4c4fc9e38b
chore: Fix NODE_OPTIONS error (#13024) 2024-01-04 01:39:17 -03:00
Keith Williams 2220778e6b
chore: Upgrade buildjet cache action to v3 (#13026) 2024-01-04 14:38:48 +10:00
Keith Williams 0f707a55b0
chore: Upgrade upload-artifact action to v4 (#13025) 2024-01-04 14:38:27 +10:00
Hariom Balhara de1c9d01cd
feat: orgMigration - Support moving users as an option when moving a team (#12917)
* Move orgMigration routes to app to allow them to be tested as they are here to stay for longer tim

* move to Form everywhere and fix session reading

---------

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2024-01-04 08:33:51 +05:30
gitstart-app[bot] 6a1325867e
fix: Fix all TS warnings (fix-tsWarnings) (#12139)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-03 18:18:42 -07:00
Keith Williams 574a4a847d
chore: Allow labeler action to use workflow_dispatch (#12993)
* chore: Update team labeler to workflow_dispatch

* Fixed conflict
2024-01-03 20:35:16 -03:00
Benny Joo f201266d69
chore: [app-router-migration-7] Migrate `/teams` page (#12622)
Co-authored-by: Dmytro Hryshyn <dev.dmytroh@gmail.com>
Co-authored-by: zomars <zomars@me.com>
2024-01-03 21:29:11 +00:00
Keith Williams 71e57bafde
chore: Remove need for force merges (#13021) 2024-01-03 19:51:24 +00:00
Peer Richelsen c4b296d580
chore: replace global.css with todesktop tailwind variant (#12991)
* installed todesktop tailwind variant

* moved todesktop styles into tailwind classes

* fixed back button in settings
2024-01-03 13:54:44 -03:00
Riddhesh Mahajan 7d7e74c869
fix: skeleton width for settings menu in sidebar (#13017) 2024-01-03 16:46:10 +00:00
Udit Takkar 6dec98129c
fix: bad request in webhook route (#13008) 2024-01-03 14:35:29 +00:00
Kartik Saini c7b62950de
fix: cal video link on booking confirmation (#12944)
* fix: Ensure generated Cal Video link matches expected pattern on booking confirmation

* fix: missing Google Meet videoCallUrl in webhooks on booking confirmation

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-01-03 07:35:46 +00:00
Keith Williams 4dba72fecb
fix: Permissions issue with team labeler (#12992)
* fix: Permissions issue with team labeler

* Made the job runnable
2024-01-02 22:39:39 +00:00
gitstart-app[bot] e61be783d1
test: Check the recurring event tab and your funtionalities (teste2e-recurring) (#12331)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-02 21:56:48 +00:00
Amit Sharma 299a866aac
fix: dynamic booking duration (#12951)
* dynamic booking duration fix

* fix: Correct duration handling from boolean -> number

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2024-01-02 16:24:45 +00:00
Keith Williams e39e6ccf79
chore: Merge PR labeler actions (#12987) 2024-01-02 16:07:58 +00:00
Peer Richelsen 218f6a84b9
fix: layout for settings/teams (#12979)
* fixed url

* added settings fix
2024-01-02 20:24:28 +05:30
Keith Williams 1a3e4d10c0
chore: Update permissions used for assigning team labels (#12984)
* chore: Inherit secrets for assigning team labels

* Added workflow_call for testing

* Added this branch for testing

* Moved secrets label

* Trying to set permissions differently

* Removed testing branch
2024-01-02 14:34:59 +00:00
Shubham Palriwala f848a44f1a
feat: integrate formbricks in help feedback box (#12276)
* feat: integrate formbricks in help feedback box

* Update yarn.lock

* Update yarn.lock

* fix: use formbricks/api@v1.1 & set user with userId linked to feedback

* fix: use separate env vars as suggested

* test: Add more orgs tests (#12241)

* feat: integrate formbricks in help feedback box

* Update yarn.lock

* fix: yarn lockfile

* fix: yarn lockfile again

* feat: link cal and formbricks user.id and add attributes of email and username to formbricks person object

* Update yarn.lock

* Update yarn.lock

* fix: type safety in enums

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-02 14:08:11 +00:00
Robbie 2181731d64
docs: Add Tunnelmole as an open source alternative to ngrok (#12925)
* doc: Add Tunnelmole as an open source alternative to ngrok plus minor grammar fixes

* Update README.md

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2024-01-02 14:00:38 +00:00
Udit Takkar 8c8401330a
fix: preview url for booking page (#12973)
* fix: preview url for booking page

* chore: use cal url

* chore: fix tests

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2024-01-02 14:00:00 +00:00
DmytroHryshyn 7015c8909f
fix: fix-animations on event-types/[type] page (#12900) 2024-01-02 08:56:50 -05:00
Peer Richelsen cbee4ff704
added macos styles to global.css (#12981) 2024-01-02 13:45:31 +00:00
Ankit Das ffefb3461e
fix: check your email page flickers (#12969)
* fixes#12966

* fixes#12966

* "fix-modification

* fix-mis-paste

* checks-fixes

* civilized-code-of-same-previous-approach

* civilized-changes-of-same-approach

* fix

* checks-fix

* fix

* fix

* checks-fix

* checksfix

* check fix

* undochanges-_-

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-01-02 09:32:57 +00:00
Udit Takkar 1c2fff5447
fix: ui bugs in settings page (#12975) 2024-01-01 22:50:56 +00:00
Peer Richelsen 6f942cfcac
chore: removed isSignup for 404 page (#12967)
* removed isSignup for 404 page

* removed unused i18n

* minor fix to go back button

* nit
2023-12-30 22:23:14 +00:00
DmytroHryshyn 7579417d7e
chore: allow disabling source map generation with env var (#12899) 2023-12-29 18:21:19 +00:00
Peer Richelsen 16d1adf990
fix: dark mode improvements for signup (#12965)
* dark mode improvements

* small changes

* readded producthunt badges

* only show social proof on cal.com
2023-12-29 18:08:36 +00:00
Saurabh Jaswal bdc36acdf5
fix: updated the bg-emphasis style in dark mode (#12933)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-29 17:33:41 +00:00
Jatin Sandilya 1f036bf35e
feat: pipedrive crm app on cal (#12316)
* add pipedrive crm app w/ revert api

* update lockfile

* fix issues highlighted by codacy

* get pipedrive `client_id` & `client_secret` from db

* update readme with instructions to add credentials

* Fix yarn.lock

* fix `turbo.json`

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-29 09:55:26 +00:00
sean-brydon 5de77e386c
fix:Remove fixed height and overflow (#12959) 2023-12-28 20:32:48 +00:00
Peer Richelsen 412e7ecbce
fixes to org email (#12937) 2023-12-27 16:16:17 +00:00
Hariom Balhara 55c9efec3e
fix: Flakiness in tests (#12929) 2023-12-23 07:48:02 -05:00
Peer Richelsen c4792c55fe
chore: minor changes to instant meetings (#12931) 2023-12-22 19:52:25 +00:00
Peer Richelsen 04cad3a69e
chore: remove scrollbar-gutter (#12936) 2023-12-22 19:02:22 +00:00
Keith Williams f7b257750a
v3.6.1 2023-12-22 08:28:33 -05:00
Hariom Balhara 4fa7bb64eb
test: e2e for not allowing reschedule of a cancelled booking (#12928)
* test: e2e for not allowing reschedule of a cancelled booking

* Fix failing test
2023-12-22 08:07:47 -05:00
Hariom Balhara 69656b7861
fix: Dont allow rescheduling for an already cancelled/rejected and thus resheduled booking (#12926) 2023-12-22 15:15:55 +05:30
Sourav b543c4030c
Fix: #12898 (#12919) 2023-12-22 09:54:43 +05:30
Jas Krrish Singh 4ce62b84ce
fix: Link Provided in the Setup of PostgreSQL DB with Railway.app was wrong or not Updated (#12915)
* Fix #12863

* Fixes #12863

* Revert yarn.lock

* Update README.md fix:#12914

* Update fix: #12914

* Update fix: #12914

* Update [[...step]].tsx

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-21 15:01:13 +00:00
Carina Wollendorfer 076868d243
test: testing workflow triggers (#12823)
* add workflows to bookingScenario

* activate sandbox mode for unit/integreation tests

* add sendgrid specific code to SendgridProvider

* Refactor WIP

* remove duplicate sendgridProvider file

* first implementation for testing workflows

* revert unintended changes

* comment out Workflow trigger tests

* move sendgrid check after test mode

* Update signup.tsx

* fix esLint

* test webhooks on all tests in fresh-booking.test.ts

* fix subjectPattern as title can be different

* add workflow tests to reschedule.test.ts

* code clean up

* code clean up

* fix sendgrid credentials missing message

* code clean up

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-21 18:57:06 +05:30
Hariom Balhara a03a1ba34e
fix: bookerUrl for the user that isn't part of the org but appears in a team inside the org (#12911) 2023-12-21 09:17:41 -03:00
Somay Chauhan dea873fef1
feat: Restrict organization creation to admins and then automatically verify all organizations (#12787)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-12-21 12:10:46 +00:00
sean-brydon 9fbb0808be
fix: leading-none (#12908)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-21 08:22:19 +00:00
Udit Takkar beae1aae8b
fix: siderbar hover state (#12910) 2023-12-21 13:43:15 +05:30
Carina Wollendorfer e56b4b57bf
fix organization invitation e2e tests (#12904)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-20 19:51:57 -05:00
Joe Au-Yeung 4faad64978
test: Seed GCal test credentials (#12596)
* Seed GCal test credentials

* Set yml .env to secrets

* Switch to vars

* Add error messages

* Set error message

* Error messages

* Change .env to secrets

* Run db-seed even with cache

* Add with DATABASE_URL

* Set DB URL

* Set DB URL

* Inputs DB URL

* Move database URL to with block

* Create env under yarn db-studio

* Fix typo

* WIP

* WIP

* WIP

* WIP

* WIP

* Add credential console log

* Hit cache

* Add logs

* Remove echo

* Run on ubuntu latest

* Don't cache db

* Uncache

* WIP

* WIP

* Change back to buildjet

* Seed GCal keys in test

* Test uses GCal keys

* Parse keys

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Clean up

* Type fix

* Clean up

* Clean up
2023-12-20 14:28:24 -05:00
Keith Williams b384e4a9d8
chore: Reduced shard count to 5 for E2E (#12901) 2023-12-20 18:31:27 +00:00
Joe Au-Yeung d07e86e4f3
fix: Update Event Type Pricing For Multiple Installed Payment Apps (#12272)
* Prevent two payment apps from being enabled

* Find the enabled payment app to update the event type

* Add string

* Add tests

* Type fix

* Abstract check for multiple payment app logic

* Type check

* Address feedback

* chore: Enable One Payment App Per Event Type (#12414)

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Morgan Vernay <morgan@cal.com>

* Fix bug

* Fix test

* Clean up

* Fix test

* Fix test

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Morgan Vernay <morgan@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-12-20 13:29:23 -05:00
Somay Chauhan 68d40cabbe
fix: Organization's Team invite emails (#12843)
Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-20 21:21:42 +05:30
Alex van Andel f07d0479d4 fix: openssl rand -base64 32 documentation error 2023-12-20 14:25:58 +00:00
Hariom Balhara 9a2c2aaca4
fix: Links on avatar for org events (#12892)
* fix: Links on avatar for org events

* Remove noop code

* Fix self review feedbavk
2023-12-20 14:21:29 +00:00
Ritik Sharma 2693b30c51
fix: managed event type string (#12891)
* fix: managed event type string

* Update EventTypeSingleLayout.tsx

Updated the translation string with the right value.

* Update EventTypeSingleLayout.tsx

Bring back formMethods variable.

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-12-20 14:09:39 +00:00
Udit Takkar 95cc0eeaae
fix: only use event type's webhooks (#12894)
* fix: only use event type's webhooks

* chore: improve code
2023-12-20 18:48:10 +05:30
Crowdin Bot b49317a83f New Crowdin translations by Github Action 2023-12-20 10:05:19 +00:00
Carina Wollendorfer 24264c32dc
fix: creating workflow reminders for existing bookings when new step is added (#12878)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-20 15:31:56 +05:30
DmytroHryshyn e248dfbda7
chore: [app-router-migration-8.5]: add a/b test flags for apps, workflows, getting-started, settings/teams (#12797)
* add a/b test flags for apps, workflows, getting-started, settings/teams

* fix linter

* fix

* fix

---------

Co-authored-by: zomars <zomars@me.com>
2023-12-19 21:58:33 +00:00
Benny Joo 31c0804386
chore: [app-router-migration-8] Migrate all pages in `/video` directory (#12623)
* chore: migrate trpc, ssgInit, ssrInit

* intuita codemod: remove-get-static-props

* intuita codemod: app-directory-boilerplate-calcom

* manual: refactor and add title/description metadata

* intuita codemod: app-directory-boilerplate-calcom

* manual: refactor and add metadata

* manual: add ab test redirect

* fix: restore emails

* fix linter and ts issues

---------

Co-authored-by: Dmytro Hryshyn <dev.dmytroh@gmail.com>
Co-authored-by: zomars <zomars@me.com>
2023-12-19 14:47:47 -07:00
zomars a3443b4e76 fix: deploy script 2023-12-19 14:00:04 -07:00
zomars 254dfc9e6a fix: deploy script 2023-12-19 13:36:42 -07:00
zomars ef6bf3d451 chore: add staging deploy script for Vercel 2023-12-19 13:19:49 -07:00
DmytroHryshyn 4b3ad579c8
chore: [app-router-migration-6] bookings/[status] page (#12621)
Co-authored-by: zomars <zomars@me.com>
2023-12-19 19:57:18 +00:00
zomars 27ce5e7808 fix: type fix 2023-12-19 12:48:14 -07:00
zomars 4d99a7fbdf chore: Lockfile update 2023-12-19 12:26:52 -07:00
zomars 27541227c8 chore: Settings update 2023-12-19 12:26:52 -07:00
zomars 83a187bf11 Revert "fix: temp renamed app dir to prevent OOM"
This reverts commit 0d3baee593.

Revert "fix: temp renamed app dir to prevent OOM"

This reverts commit 0d3baee593.

Revert "fix: temp renamed app dir to prevent OOM"

This reverts commit 0d3baee593.

Revert "fix: temp renamed app dir to prevent OOM"

This reverts commit 0d3baee593.
2023-12-19 12:26:52 -07:00
Peer Richelsen 200ce6932d
feat: Instant Meeting (#12345)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-12-19 11:01:42 -08:00
Sourav 6d5983fabc
fix: #12863 (#12874)
* Fix: #12830

* Fix: ##12863

---------

Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-19 18:30:15 +00:00
Manavpreet Singh 18b994bb4c
Fix: dropdown menu awkward hover state fixed (#12876)
Co-authored-by: ManavpreetSingh <119919977+manavpreetsingh@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-19 18:05:33 +00:00
Hariom Balhara a8975f541f
fix: Dynamic Group Booking link for organization (#12825)
Co-authored-by: Erik <erik@erosemberg.com>
Co-authored-by: Omar López <zomars@me.com>
2023-12-19 17:42:40 +00:00
Alex van Andel 31b88c5537
chore: User page crash on bad metadata (#12858)
* chore: User page crash on bad metadata

* Sentry.captureException -> logger.error

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-12-19 12:17:39 -05:00
Carina Wollendorfer f0bd628713
fix: ZodError in auth/oauth/authorize (#12877)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-19 16:55:09 +00:00
Somay Chauhan 260bd4829c
fix: Users Cannot Be Upgraded to Owner in Organizations (#12737)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-19 16:38:06 +00:00
Crowdin Bot dc8731d64f New Crowdin translations by Github Action 2023-12-19 16:36:58 +00:00
Amit Sharma 48eba5ef5c
fix: translate boolean values in emails (#12741)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-19 16:33:06 +00:00
Sourav 544d76d503
fix: Troubleshooter - Vertical scrolling not working on left panel or calendar (#12792)
Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-12-19 11:15:06 -05:00
Somay Chauhan 6ce2d9819e
fix: multiple bookings created on verify-email (#12864)
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2023-12-19 10:47:54 -05:00
Somay Chauhan 2e0c9c7068
feat: meeting started webhook (#12764)
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
2023-12-19 09:52:35 -05:00
Thanh Nguyen 038008502c
fix: minor typo (#12842)
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
2023-12-19 11:20:54 -03:00
Hariom Balhara 5886792285
feat: More admin options for organizations (#12424)
* Add more features in org admin

* Pr feedback addressed
2023-12-19 18:31:22 +05:30
Hariom Balhara e3905f631f
fix: Copy invite link on safari (#12873) 2023-12-19 12:38:34 +00:00
Hariom Balhara e5e0fa97eb
fix: Across Org Scenarios - Wrong links for event and team (#12358)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-12-19 19:33:30 +10:00
Somay Chauhan f1caaad536
fix: videoCallUrl missing in webhooks for event types that require confirmation (#12856) 2023-12-19 13:55:06 +05:30
Udit Takkar b6279f4128
fix: country code [Testing] (#12807)
* fix: country code

* chore

* chore: only test cloudflare

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-12-19 08:01:08 +00:00
Hariom Balhara 5fb1857538
fix: Org invitation e2e flakiness (#12861) 2023-12-19 07:34:15 +00:00
Carina Wollendorfer a8d9b0210a
fix: catch error for invalid subcriber url on webhook ping test (#12784)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-19 07:18:08 +00:00
Somay Chauhan 5751f0f634
fix: join subteam as their respective organization role (#12216)
* fix: join subteam as their respective organization role

* refactor code

* fix: join subteam as their respective organization role

* fix: join subteam as their respective organization role for pending members

* fix: Set subteam role to admin when updating organization role to admin

* refactor: suggested changes and fix type error

* fix: type error
2023-12-19 06:10:06 +00:00
Hariom Balhara 4b16860d07
fix: Correctly prefill username in case of non-org email invite in an org (#12854)
* fix: Correctly prefill username in case of non-org email invite in an org

* Update test

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-19 02:44:48 +00:00
SuPrabhu f77e480d02
fix: Fix the Bg color of the sign In button after clicking Fix No #12773 (#12833)
* Updated the Big FIx 12773 sing-in

* FIX #12773 CSS Issue - Type Error

* Lint Error CHanges

* Debug Lint Error

* Lint Error Fix

* Changed

* Added CSS typo Error

* Added CSS typo Error - Removed Style Componet

* VS COde lint error fix

* Removing in the Button

* chore: fix login button

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-18 18:21:46 +00:00
Keith Williams 099f36deeb
fix: Workflow files for E2E naming issue (#12859) 2023-12-18 18:15:14 +00:00
Keith Williams 09f804413b
chore: Moved e2e suite to run on pushes to main (#12819)
* chore: Moved e2e suite to run on pushes to main

* Update yarn.lock

* Small cleanup

* Moved production build without database to pre-release

* Added name to script

* Added changes, lint and build dependencies
2023-12-18 17:48:55 +00:00
Somay Chauhan e1a9576530
fix: only owners can award owner role in an organization. (#12803)
* fix: only owners can award owner role in an organization.

* chore: improve code

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-12-18 12:39:27 +00:00
sean-brydon 2410f8b3aa
Payment success screen re-design (#12831)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-18 12:34:20 +00:00
Hariom Balhara a28e8ff39b
fix: A user joining from invite link of a team doesn't automatically become member of the org (#12774)
* fix: Add org membership when invite link for a team in an org is generated

* Run tests sequentially till we fix emails fixture
2023-12-18 17:48:35 +05:30
Sourav 7d2500a32f
Fix: #12830 (#12837) 2023-12-18 12:12:57 +00:00
Udit Takkar 22d906798e
fix: dark mode switch color (#12850) 2023-12-18 12:11:48 +00:00
Kartik Saini f71759f70b
feat: Shows link location and respective icon in /bookings (#12760)
* Add metadata to bookingMinimalSelect

* add: Show link location in /bookings

* Refactor: Update variable declaration and conditional rendering in booking metadata

- Remove explicit type declaration in locationVideoCallUrl assignment
- Use conditional rendering for provider icon based on iconUrl existence

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>

* Display URL location exclusively, omitting addresses

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-18 01:28:49 +00:00
Peer Richelsen a323e06e88
Revert "Inter 4.0 (#12766)" (#12839) 2023-12-17 08:21:22 +10:00
Omar López b4db3a75a8
v3.6.0 2023-12-15 14:27:12 -07:00
Hariom Balhara a9fcd900cd
fix: Enhance the Robustness of Embed Snippets for Multiple Embeds on a Single Page (#11512)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Omar López <zomars@me.com>
2023-12-15 11:51:51 -07:00
Riddhesh Mahajan fcb443a8eb
fix: Zapier subscriber url shown in webhooks (#12702)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-12-15 16:09:59 +00:00
Joe Au-Yeung 9dfa596e3e
feat: Add consistent iCalUID (#12122)
Co-authored-by: Hariom <hariombalhara@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-12-15 10:28:32 -05:00
Natnael Yilma 0e8ac7e4ed
fix: email validation in user post method API (#12743)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-15 08:03:18 -07:00
Alex van Andel b236bffca2
fix: 404 /event-types on login (#12811)
* fix: 404 /event-types on login

* Set APP_ROUTER env vars to 0 whilst appdir is disabled
2023-12-15 14:39:15 +00:00
Udit Takkar 6e829e23f9
fix: type error (#12808)
* fix: type error

* chore

* Dont run future tests

* Skip more tests

* Fix 404 text

* Fix more tests

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-15 13:21:38 +00:00
sean-brydon b778b2962a
chore: hsl-update-colors (#12199)
* chore:hsl-update-colors

* chore:hsl-update-colors

* update % color

* Fix HSL SL %

* Update SB styles

* lint

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-15 04:52:51 +00:00
zomars 0d3baee593 fix: temp renamed app dir to prevent OOM 2023-12-14 14:40:40 -07:00
Matt Nicolls f9dcbaaa42
fix: create event type for a team that you are an owner or admin of (#12564)
* fix: allow API access to creating a team that you are a member of

* update roles allowed to create event types

* add back comment

* revert yarn.lock

---------

Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-14 07:14:12 -05:00
Amit Sharma 60700e1a7a
fix: padding off event user avatar (#12733) 2023-12-13 20:16:19 -08:00
Peer Richelsen 456adea570
Update semantic-pull-requests.yml 2023-12-13 20:05:52 -08:00
Manavpreet Singh 63abda1693
chore: changed checkbox color (#12783)
Co-authored-by: ManavpreetSingh <119919977+manavpreetsingh@users.noreply.github.com>
2023-12-13 19:29:37 -08:00
sean-brydon 4dd73f4d86
fix: Add scroll to troubleshooter sidebar (#12785) 2023-12-13 19:29:13 -08:00
Peer Richelsen 31caf8288d
feat: roam (ro.am) conferencing (#12579) 2023-12-14 02:19:22 +00:00
Hariom Balhara 99e71365ab
fix: Disallow changing username and email in case of Organization email invite (#12735)
Co-authored-by: Omar López <zomars@me.com>
2023-12-13 20:08:16 +00:00
Somay Chauhan 943c7a4c6c
fix: other team members page invite issue (#12745) 2023-12-13 19:53:20 +00:00
sean-brydon 228e509a3b
Inter 4.0 (#12766) 2023-12-13 16:18:50 +00:00
sean-brydon eb909cc87a
fix: datatable toolbar (#12757)
* Fix toolbar

* Slide animation

* Animate out and fix selection model

* Disable on mobile - fix tablet position

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-13 10:15:18 +00:00
Peer Richelsen 65a36b37c5
removed org_team_names_example_1 (#12759) 2023-12-13 13:08:59 +05:30
Alex van Andel 2799ddf3a4
fix: 500 error on email conflict (#12725) 2023-12-13 02:24:36 +00:00
Carina Wollendorfer 3164cd4ae7
feat: mandatory email reminder for attendees with @gmail.com (#12747)
Co-authored-by: Chiranjeev Vishnoi <somu209e@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-13 02:23:48 +00:00
Udit Takkar 6b26dbc6da
fix: checkbox color (#12742)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-13 02:19:12 +00:00
Hariom Balhara 6b09c6b3b4
fix: Allow lowercase/uppercase/mixedcase access with org team event booking page (#12721)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-12-12 18:02:38 -08:00
Keith Williams 2352bb1075
chore: Wire up Sentry for API (#12756) 2023-12-12 14:57:39 -08:00
DmytroHryshyn a568e1ac66
chore: [app-router-migration-5] apps/installed page (#12618)
Co-authored-by: zomars <zomars@me.com>
2023-12-12 12:48:40 -07:00
DmytroHryshyn add6ffdfc4
chore: [app-router-migration-4]: apps/categories page (#12619) 2023-12-12 11:43:15 -07:00
Alex van Andel 7a67331d96
fix: Disable source maps which looks to be infinitely looping (#12744) 2023-12-12 16:16:04 +00:00
Amitabh Sahu 1aa8b8439a
fix: change booking page filter ui to match Figma (#12134)
* fix: change booking page filter ui to match figma

* fix: style change for filters in mobile

* made all changes requested by reviewers

* fix: add clear filter

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-12-12 11:29:13 +00:00
Alex van Andel 50e405353c v3.5.5 2023-12-11 23:11:43 +00:00
Alex van Andel 565e21bc50
fix: Dynamic duration was always overwritten with the default (30) (#12444)
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-12-11 16:07:21 -07:00
DmytroHryshyn 098d41fc62
chore: [app-router-migration-3] apps/[slug]/index, apps/[slug]/setup (#12620)
Co-authored-by: Omar López <zomars@me.com>
2023-12-11 16:05:07 -07:00
Patrick Arminio a20179727b
Hide expires on message if never expires is selected (#12723) 2023-12-11 17:15:56 +00:00
sean-brydon 795aaca64f
Trim spaces on datatable search key (#12713) 2023-12-11 06:58:26 +00:00
Mehul 2ab7846a4a
fix: location Select auto focus (#12715) 2023-12-09 20:53:49 +00:00
Udit Takkar e9ea0fcc20
feat: add cal video logo whitelabel for organization (#12616) 2023-12-09 09:02:14 +00:00
Hariom Balhara 090b166b1c
Update PULL_REQUEST_TEMPLATE.md (#12711) 2023-12-08 17:24:41 +00:00
Bijoy Sijo ea2d8fc873
docs: Remove duplicate CALENDSO key setup from README. (#12595) 2023-12-08 07:23:21 -08:00
Ethan Chen 46c51df1e0
fix: Up libphonenumber-js to fix #12394 (#12519)
* Up libphonenumber-js

* Re-patch libphonenumber-js and restore the test files.

* fix: yarn and check

* Conflict Resolution

* fix lint error

* Restore files

* Fix yarn.lock

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-08 14:09:45 +00:00
Guilherme Santos 5fe919452b
test: Make sure response is still writable before setting headers (#12478) 2023-12-08 18:56:49 +05:30
nicktrn 83c8f97afd
test: booking and duration limits e2e (#10968)
* test: booking and frequency limits e2e

* test: refactor limit e2e and check multiple

* test: move limits e2e to separate file

* fix: blocked day assertions

* chore: rename to booking-limits

* fix: use todo test util

* chore: un-DRY tests

* feat: create user with limits helper

* chore: move user limit helper to utils

* fix: multiple limits test

* feat: fail faster

* chore: event url helper

* fix: prismock count date comparisons

* chore: improve booking limit types in test utils

* test: add typed weekStart to getOrganizer helper

* test: add custom fromDate to getDate helper

* fix: correctly handle negative date increments

* test: add helper for partial weeks

* test: booking limits edge cases

* chore: remove booking limit e2e todos

* chore: normalize getDate return type and skip test

* Fix imports paths that are changes after main merge

* Fix failing types

* Skip failing test

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-08 10:23:31 +00:00
Carina Wollendorfer f87eac193f
fix: rr-host booked outside of availability (#12704)
* correctly query overlapping bookings

* remove console.log

* fix getting busy bookings for getAvailableSlots

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-12-08 01:31:02 +00:00
Aswath S c53e891c8a
fix: refactor booking details api middleware to use team member booking join (#12695)
* refactor booking details api middleware to use team member booking join

Signed-off-by: titanventura <aswath7862001@gmail.com>

* fix. security issue in previous commit. check for booking against current user. then check for team booking

Signed-off-by: titanventura <aswath7862001@gmail.com>

---------

Signed-off-by: titanventura <aswath7862001@gmail.com>
2023-12-07 22:43:51 +00:00
Udit Takkar 90a6fc3f26
refactor: Top Banner and add google calendar credential banner (#12532)
Fixes: https://github.com/calcom/cal.com/issues/12473

TODO:
- [x] Fix Type error

<img width="1512" alt="Screenshot 2023-12-02 at 12 47 19 AM" src="https://github.com/calcom/cal.com/assets/53316345/8a5c6dd0-6095-482b-b4d0-81653607a270">


<img width="1512" alt="Screenshot 2023-12-02 at 12 47 39 AM" src="https://github.com/calcom/cal.com/assets/53316345/fc64edb9-27b3-438f-b42d-75b200ac96e9">
2023-12-07 15:32:47 -07:00
Ujjwal Garg 969411041b
fix: Edit Location modal fields truncates on mobile view (#12684)
* fix #12640: Edit Location modal fields truncates on mobile

* chore: fix dialog

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-07 21:10:41 +00:00
Udit Takkar 518cfbc037
feat: daily webhooks (#12273)
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2023-12-07 16:08:51 -05:00
Harshith Pabbati 47277ced2d
chore: auto verify OTP whenever user enters 6 digits OTP instead of waiting for them to click on verify button (#12326) 2023-12-07 16:08:11 -05:00
DmytroHryshyn db625157d1
chore: [app-router-migration-2] migrate trpc, ssgInit, ssrInit (#12593)
* chore: migrate trpc, ssgInit, ssrInit

* manual: fix emails

* manual: fix ts issues

* Update packages/emails/README.md

* remove unneeded use client statements

* fix flaky locale tests, fix flaky login test

---------

Co-authored-by: Omar López <zomars@me.com>
2023-12-07 13:43:41 -07:00
Alex van Andel bf2af799d5
perf: Improve performance of working hours processing (#12687) 2023-12-07 09:46:45 +00:00
Somay Chauhan 75eaed1c4d
fix: adding team members from organization tab that alredy exist (#11689)
* fix: adding team members from organization tab that alredy exist

* changed organizations.listOtherTeamMembers from useQuery to useInfiniteQuery

* undo yarn.lock

* fix: invalidate the organizations.getMembers query on removeMember and inviteMember Mutation

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-12-07 09:39:23 +00:00
Carina Wollendorfer e1ac6f5454
fix: ignore original rescheduled booking for booking limits (#12625)
* ignore original rescheduled booking for booking limits

* fix unit test

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-07 13:13:19 +05:30
Henrik Klee 55d44ce789
fix: component styles and sign up / onboarding dark mode (#12581)
* fix divider border for addOnLeading

* fix primary button in dark mode and password input border

* signup dark mode and corner fix

* onboarding dark mode

* fix css var issue and use inline vars for light and dark mode

* Invert google icon on dark mode

* Fix typo

* fix eslint errors with yarn lint:fix

* use css vars on login page as well

* running lint manually

* Fix subtle

* Fix

* Fix

* linting

* linting

* chore: restore main yarn.lock

* fix: lint error

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Sean Brydon <sean@brydon.io>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: sean-brydon <sean@cal.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-12-06 21:10:14 +00:00
zomars 8bed690ed6 Update yarn.lock 2023-12-06 10:49:52 -07:00
Syed Ali Shahbaz adf012643a
fix: '/slots' endpoint API fixes (#12693) 2023-12-06 10:10:25 -07:00
Henrik Klee ca0d23529a
updates storybook config and fixes and updates stories (#12683)
add packages
2023-12-06 10:41:35 +02:00
Hariom Balhara 9f50941904
test: Booking creation failure in case of stray destinationCalendar with no matching calendar credential (#12682) 2023-12-05 18:50:55 +00:00
Hariom Balhara f2a59fe4e8
Fix booking error in case of no calendar credential but stray destinationCalendar (#12680) 2023-12-05 16:16:54 +00:00
Nafees Nazik 325f250d39
feat: add resend email transport (#12645)
Co-authored-by: Erik <erik@erosemberg.com>
2023-12-04 15:31:55 -08:00
Benny Joo bb7057ea04
fix: type error in `settings/admin` in app router (#12638) 2023-12-04 15:31:36 -08:00
sean-brydon d185d7f7d8
feat: invites bypass disabled signup (#12626)
* invites bypass disabled signup

* nit:remove new line

* add tests

* chore: spelling

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-12-04 16:00:36 +00:00
Morgan 80b92b5f11
chore: upgrade storybook 7.6.3 + use @storybook/nextjs (#12673)
* chore: upgrade storybook 7.6.3 + use @storybook/nextjs

* fix: color picker tests
2023-12-04 11:06:44 +00:00
Brendan Woodward 9a6d4e63e8
chore: Sentry Wrapper with Performance and Error Tracing (#12642)
* add wrapper for sentry and update functions in 'getUserAvailability'. Update tracesSampleRate to 1.0

* Make Sentry Wrapper utilize parent transaction, if it exists.

* Update wrapper for functions to inherit parameters from the child function

* add comment of when to use the wrapper

* check for sentry before wrapping, if not call unwrapped function

* refactored wrapper to have async and sync separate functions that utilize helpers for common behaviour

* update type of args to unknown

* fixed types of returns from wrapped functions

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-12-03 21:06:01 -05:00
Harshith Pabbati 4062ae8486
feat: add matomo analytics app (#12646) 2023-12-03 15:49:00 +00:00
Crowdin Bot c6f26f2a2a New Crowdin translations by Github Action 2023-12-03 00:10:11 +00:00
Haran Rajkumar 2f4b1818d0
feat: Allow only first slot to be booked (#12636)
Co-authored-by: Morgan Vernay <morgan@cal.com>
2023-12-02 19:07:06 -05:00
zomars 8e1ce633fb fix: workaround for future app dir routes 2023-12-02 13:25:06 -07:00
Crowdin Bot 44e4f4c644 New Crowdin translations by Github Action 2023-12-02 18:30:14 +00:00
Mike Zhou 0b9cf78e9b
feat: display long durations in hours on booking (#12631)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-12-02 18:27:11 +00:00
Varun Prahlad Balani b2cdb08780
feat: add clear filters option in bookings page (#12629)
* add clear filters option

* fix vscode settings.json

* use removeAllQueryParams()

* fix yarn lock

* remove toggleoption
2023-12-02 23:40:45 +05:30
Peer Richelsen dcf9c6a5e5
chore: added cursor-pointer to img upload (#12624)
* added cursor-pointer to img upload

* nit
2023-12-02 12:06:56 +00:00
Benny Joo ca78be011c
chore: [app-router-migration-1] migrate the pages in `settings/admin` to the app directory (#12561)
Co-authored-by: Dmytro Hryshyn <dev.dmytroh@gmail.com>
Co-authored-by: DmytroHryshyn <125881252+DmytroHryshyn@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
2023-12-01 13:07:26 -07:00
Manpreet Singh d13dedda9a
fix: handle reschedule request for dynamic meetings (#12275) 2023-12-01 16:39:06 +00:00
Samyabrata Maji 9ca2ad2d41
fix: typo in @calcom/emails readme (#12615) 2023-12-01 13:25:22 +00:00
Pratik Kumar 3d89809e67
fix: Signup options are not disabled (#12610)
* fix: Signup options are not disabled

* fixes/signup disabling suggested changes done

* chore: signup and login improvements

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-12-01 11:09:34 +00:00
Crowdin Bot 252ce07861 New Crowdin translations by Github Action 2023-12-01 08:59:52 +00:00
sean-brydon a75ef8870b
fix: signup nit (#12585)
* Disable submit on empty form

* Fix submit

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-12-01 08:56:19 +00:00
Peer Richelsen b840b3b1bb
Succession (#12605)
Readme change to reflect succession state.
2023-11-30 22:58:21 +00:00
Omar López 2e50625165
v3.5.4 2023-11-30 15:47:15 -07:00
sean-brydon c78eb752a7
feat: rate limit removeMember (#12570)
* feat: rate limit removeMember

* Remove optional type as its always there

* fix

---------

Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-11-30 22:16:40 +00:00
Somay Chauhan 1c20bdcecf
fix: rescheduling recurring events (#12567) 2023-11-30 13:27:37 -05:00
Amit Sharma 338756439f
fix: meeting ended incorrect content type (#12484) 2023-11-30 17:52:55 +00:00
Carina Wollendorfer 56050b994d
fix 'attempt booking in the past' error (#12597)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-30 17:31:59 +00:00
sean-brydon c11ecbb323
Fix:use typed query initially fill default paramaters (#12568) 2023-11-29 17:51:47 -05:00
Peer Richelsen 7f23ae156b
fix: improved team upgrade screen to also show unpublished teams (#12492)
* improved team upgrade screen to also show unpublished teams

* Update TeamsListing.tsx

* bunch of stuff

---------

Co-authored-by: Omar López <zomars@me.com>
2023-11-29 14:48:26 -07:00
zomars 33250652b3 Double e2e shards 2023-11-29 14:40:21 -07:00
Morgan a65e18d92d
chore: improve invitation form validation (#12594)
* chore: improve invitation form validation

* fixup! chore: improve invitation form validation

* fixup! fixup! chore: improve invitation form validation
2023-11-29 12:44:48 -07:00
Carina Wollendorfer d0f7085cb8
fix: updating workflow with new step and new active event type (#12592)
* correctly filter event types to avoid null values

* clean up all filters

* re-add reverted fix

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-29 23:51:12 +05:30
Morgan ea8437b4f7
fix: invite member by username (#12591)
* fix: invite member by username

* fixup! fix: invite member by username
2023-11-29 19:57:51 +02:00
Joe Au-Yeung 877cd4cdff
refactor: Team Creation Flow [CAL-2751] (#12501)
* Create new endpoint for creating a team

* Generate a team checkout session

* Create team navigate to checkout

* Clean up

* UI changes

* Add comments

* Fix

* Type fix

* Type fix

* Type fix

* Type fixes

* Set telemetry

* Import fix

* Type fix

* Update tests

* Type fix

* fix: e2e

* fix: e2e

* fix: e2e

* fix: e2e

* Update teams.e2e.ts

* fix: e2e

---------

Co-authored-by: Omar López <zomars@me.com>
2023-11-29 09:39:21 -07:00
Igor Perzic bae3bd76e5
docs: update byte size for openssl command (#12587) 2023-11-29 15:15:04 +00:00
Joe Au-Yeung 8b24995d52
refactor: Abstract `createBooking` in `handleNewBooking` [CAL-2619] (#11959)
## What does this PR do?

<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

In anticipation of refactoring `handleSeats` we need to abstract `createBooking` in order to get the return type. This PR is purposely aiming to do one thing so nothing is missed while refactoring `handleNewBooking`

Fixes # (issue)

<!-- Please provide a loom video for visual changes to speed up reviews
 Loom Video: https://www.loom.com/
-->

## Requirement/Documentation

<!-- Please provide all documents that are important to understand the reason of that PR. -->

- If there is a requirement document, please, share it here.
- If there is ab UI/UX design document, please, share it here.

## Type of change

<!-- Please delete bullets that are not relevant. -->

- [x] Chore (refactoring code, technical debt, workflow improvements)


## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

- Are there environment variables that should be set?
- What are the minimal test data to have?
- What is expected (happy path) to have (input and output)?
- Any other important info that could help to test that PR

## Mandatory Tasks

- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

## Checklist

<!-- Please remove all the irrelevant bullets to your PR -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my PR needs changes to the documentation
- I haven't checked if my changes generate no new warnings
- I haven't added tests that prove my fix is effective or that my feature works
- I haven't checked if new and existing unit tests pass locally with my changes
2023-11-29 08:11:09 -07:00
Udit Takkar 7dc6df2ad6
chore: improve logs (#12467)
* chore: improve logs

* fix: import

* chore: use safe stringify

* chore: add more logs to google calendar

* chore: use this.log

---------

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-11-29 19:39:25 +05:30
Peer Richelsen 6c4b1154b8
chore: removed last web3 references (#12540)
* removed last web3 references

* updated yarn

* Update schema.prisma

* readded icon

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-29 11:57:50 +00:00
Pratik Kumar 1099bad930
fix:selecting behaviour fixed (#12578)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-29 11:53:31 +00:00
Crowdin Bot dbd5d27d9d New Crowdin translations by Github Action 2023-11-29 09:57:23 +00:00
Udit Takkar 45c4f4789b
chore: add check for recording (#12584)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-11-29 09:54:14 +00:00
Morgan 07f42057fc
fix: increase maxWait/Timeout invite members transaction (#12583) 2023-11-29 09:07:03 +00:00
Crowdin Bot 79ee7c41b2 New Crowdin translations by Github Action 2023-11-29 08:03:18 +00:00
Joe Au-Yeung 57e6971942
chore: Refactor `<CalendarListContainer />` (#12388)
* Import calendarlistcontainer in settings

* Change CalendarListComponent to Figma design

* Add border subtle

* Address feedback
2023-11-29 13:29:51 +05:30
Alex van Andel bd6ca21e02
fix: Toggling really fast throws internal errors (#12580) 2023-11-28 23:04:54 +00:00
Carina Wollendorfer f19a1926b4
chore: refactor reschedule EventManager with changed organizer (#12574)
## What does this PR do?

Follow up for https://github.com/calcom/cal.com/pull/12469

Event creation is now already handled in the reschedule function of EventManager. 

## Type of change

- [x] Chore (refactoring code, technical debt, workflow improvements)

## How should this be tested?

- Same as in https://github.com/calcom/cal.com/pull/12469
2023-11-28 11:37:31 -07:00
Erik 477ee1c526
v3.5.3 2023-11-28 15:32:02 -03:00
Udit Takkar 6704e18e32
fix: cal video issues (#12546)
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2023-11-28 18:28:35 +00:00
Crowdin Bot 20f17903b9 New Crowdin translations by Github Action 2023-11-28 14:56:47 +00:00
sean-brydon 8dabbbd09f
feat: signup refactor (#11421)
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-28 14:52:53 +00:00
sean-brydon 32933ed6ef
fix: premium username to premium username (#12569) 2023-11-28 12:55:35 +00:00
Omar López c765ea9b31
fix: team and org invite e2e tests (#12566) 2023-11-28 10:49:06 +00:00
Matt Nicolls d3ddbf418f
fix: fetch event type with a team permissions (#12448)
Co-authored-by: Omar López <zomars@me.com>
2023-11-27 23:14:59 -07:00
Joe Au-Yeung 79d0513428
Change method to `getOrgMembership` (#12563) 2023-11-27 14:46:55 -05:00
Carina Wollendorfer 230b82d3bf
fix: rescheduling round robin events (emails and calendar events) (#12469)
* send the correct booking email for round robin rescheduling

* fixing originalBookingMemberEmails

* fix calendar event (needs some code refactoring)

* refactor rescheduling code

* code clean up

* add comment

* fix event name if host changes

* add tests for rr rescheduling emails

* fix videoCallUrl of google meet

* code clean up

* fix destinationCalendar for new booking

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-27 13:09:33 -05:00
Hariom Balhara c9b50ffb78
fix: Provide calOrigin for organization embeds (#12380) 2023-11-27 10:38:27 -07:00
Somay Chauhan ada0ef242b
fix: crash on other team members and profile page (#12539) 2023-11-27 16:59:03 +00:00
Shashank Kaul b26e688950
fix(api): Added correct include for `GET /teams/{teamId}/event-types` (#12459)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-27 16:44:13 +00:00
Crowdin Bot d9041d03b7 New Crowdin translations by Github Action 2023-11-27 16:10:27 +00:00
Peer Richelsen f60b3c14e1
fix: small UI improvements for troubleshooter (#12535)
Co-authored-by: Sean Brydon <sean@brydon.io>
2023-11-27 16:06:54 +00:00
Crowdin Bot fbcc43931e New Crowdin translations by Github Action 2023-11-27 13:57:45 +00:00
Udit Takkar a48e7cb39a
fix: remove duplicate key in common.json (#12543)
* fix: remove duplicate key in common.json

* chore: add  both keys in same log
2023-11-27 19:23:35 +05:30
sean-brydon db3f718ba6
fix: removing next steps (#12549)
* Removing next steps

* Removing next steps
2023-11-27 16:49:40 +05:30
Morgan ca5dd4626d
fix: event-types post api endpoint not showing hosts in response data (#12550) 2023-11-27 12:35:39 +02:00
Amit Sharma 4524d722f6
fix: phone-number-input (#12266) 2023-11-27 10:27:01 +00:00
Morgan 2094d59856
refactor: invite members handler (#12442)
* refactor: invite members handler

* fixup! refactor: invite members handler

* fixup! fixup! refactor: invite members handler

* refactor: promise all settled send emails

* fixup! refactor: promise all settled send emails

* fixup! fixup! refactor: promise all settled send emails

* fixup! fixup! fixup! refactor: promise all settled send emails

* fix: opening team invite link in email throws error on signup page

* fixup! Merge branch 'main' into cal-2698-refactor-invitemember-handler

* fix: centralize validation if invitee can be invited

* fix: improve select query and fix tests

* fixup! Merge branch 'main' into cal-2698-refactor-invitemember-handler

* rename functions and add some tests
2023-11-27 09:27:27 +00:00
Lauris Skraucis 7b350a5b8f
revert: sync platform branch with main (#12548) 2023-11-27 08:35:58 +00:00
Brijendra Singh 5a869228d3
typo (#12541) 2023-11-26 14:34:40 +05:30
Peer Richelsen dabd5eae73
chore: fixed order of tips (#12529) 2023-11-25 13:55:40 -03:00
Somay Chauhan cb78de231a
feat: if profile only has one public event-type, redirect to it (#12158)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-24 21:54:14 +00:00
DmytroHryshyn b0a1ef8a49
chore: remove dynamic loading of EventTypeDescription on event-types page (#12524) 2023-11-24 19:12:43 +00:00
Joe Au-Yeung 0a43aa3351
OAuth URL account for dev environment (#12530) 2023-11-24 17:38:21 +00:00
Lauris Skraucis ed4cce1c7e
fix: platform branch sync with main (#12528) 2023-11-24 17:46:33 +01:00
Lauris Skraucis d595aa23c0
fix: platform branch sync with main (#12526) 2023-11-24 20:30:01 +05:30
Lauris Skraucis a6df49235f
chore: sync platform branch with main (#12525) 2023-11-24 15:18:08 +01:00
Erik 5df41e37a0
fix: Stripe webhook event mismatch (#12522) 2023-11-24 13:18:06 +00:00
Peer Richelsen fca5778b6d
chore: avatar padding (#12515) 2023-11-23 23:43:14 +00:00
Alex van Andel 0ddefaa141
Remove cache-control and disable cache (#12517) 2023-11-23 23:42:18 +00:00
Peer Richelsen c11f7aeffc
chore: insights UI refresher (#12498)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-11-23 21:25:27 +00:00
Erik 9903fcaa05
chore: Remove free use of Cal.AI (#12489) 2023-11-23 21:07:08 +00:00
Alex van Andel 0910f65b87 v3.5.2 2023-11-23 16:56:52 +00:00
Alex van Andel 343f8ee303
Avatar write and unset, ensure no bad behaviour (#12504)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-11-23 15:39:50 +00:00
Hariom Balhara de479bb2da
fix: getting-started crash and build failure (#12506) 2023-11-22 22:41:20 -07:00
Omar López 5dc3065a47
v3.5.1 2023-11-22 15:42:24 -07:00
Manpreet Singh 36d315343c
fix: adds teamId to team events payload (#12417) 2023-11-22 14:54:18 -05:00
zomars 2171a320f5 fix: Locks Stripe version 2023-11-22 12:19:30 -07:00
JA 7ee035c3a3
feat(webhooks): pass webhook secret to `testTrigger` (#12187) 2023-11-22 14:17:50 -05:00
Greg Pabian 1de05ebf3d
chore: migrate the event-types page to the app directory (#12390)
Co-authored-by: Omar López <zomars@me.com>
2023-11-22 19:17:33 +00:00
zomars 53d7e2ec3f syncpack fix-mismatches 2023-11-22 12:08:30 -07:00
Udit Takkar f65c7e413f
fix: default organizer bug in managed event type (#11921) 2023-11-22 12:43:25 -05:00
Joe Au-Yeung b762f60214
test: Integration Test GCal Primary Calendar (#12011)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-11-22 11:15:47 -03:00
Joe Au-Yeung 2498785c49
chore: Clean Up Delete Credential Selected Calendar Error Message (#12353) 2023-11-22 10:22:03 -03:00
Matt Nicolls 9a6683e01d
fix: include eventTypeId in BOOKING_CANCELLED event (#12445) 2023-11-22 12:04:51 +00:00
sebzz 2853288f49
docs: add google credentials in example env (#11695)
* docs:add google credentials in example env

* docs: add a space after #

* chore: update .env.example

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-11-22 11:49:27 +00:00
Morgan d04226ab9a
fix: alby payment isPaid always false on create (#12463) 2023-11-22 11:39:00 +00:00
Amit Sharma cb7ddc455a
chore: Add team invite tests (#12425)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-22 11:26:43 +00:00
Adugna Tadesse 73aa1e8a22
outlook second account fix (#12013)
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2023-11-22 11:01:29 +00:00
Udit Takkar a3b5263b76
chore: reset form on submission (#12465) 2023-11-22 10:42:19 +00:00
Peer Richelsen af2c6c0844
chore: ignore "platform" in pr-assign-team workflow (#12487) 2023-11-22 10:25:56 +00:00
Peer Richelsen 113195224a
chore: fixed cal.ai thumbnail (#12486) 2023-11-22 10:23:54 +00:00
Peer Richelsen 828092c1d0
chore: fix cal.ai price (#12485) 2023-11-22 10:18:09 +00:00
Somay Chauhan 4b060fc2cd
fix: opening team invite link in email throws error on signup page (#12397)
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-11-22 06:49:37 -03:00
Syed Ali Shahbaz 16c5b070b6
fix: Admin Logic for event-type API endpoint (#12482)
* Fix Admin logic

* chore: fix prettier

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-11-22 06:46:03 -03:00
Hariom Balhara 48dde246e9
test: Add more orgs tests (#12241) 2023-11-21 14:03:01 -03:00
Morgan 556b382f75
fix: better errors for googlecalendar integration (#12403) 2023-11-21 15:14:25 +00:00
Ujjwal Goyal 85237c4985
fix: Date overrides UI bug depending on screen size (#12423)
* Update DateOverrideInputDialog.tsx

fix: Date overrides UI bug depending on screen size (calcom#12406)

* chore: remove comment

---------

Co-authored-by: madhurgoyal19 <35370133+madhurgoyal19@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-11-21 14:56:59 +00:00
Crowdin Bot 404bc0e4d6 New Crowdin translations by Github Action 2023-11-21 12:13:50 +00:00
Morgan 00553e897b
fix: alby payment could not be created (#12460)
* fix: alby payment could not be created

* fixup! fix: alby payment could not be created

* fixup! fixup! fix: alby payment could not be created
2023-11-21 12:09:50 +00:00
Crowdin Bot ed2ce005c9 New Crowdin translations by Github Action 2023-11-20 16:42:20 +00:00
Peer Richelsen 058844b6b8
chore: paid support wip (#12419)
* paid support wip

* nit

* added upgrade box to intercom

* nit
2023-11-20 22:08:39 +05:30
Manpreet Singh 77fa3702db
fix: slug value in webhook payload (#12290)
Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-20 15:39:21 +00:00
Lars Artmann 9eb2ae470c
fix: [embed-react] types fix for compatible with TypeScript's "moduleResolution": "bundler" (#12327)
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-20 13:33:27 +00:00
Somay Chauhan 3de7b73f5f
fix: don't send notes to booker if "Hide notes in calendar" is on (#12333) 2023-11-20 13:28:40 +00:00
Alex van Andel 8e7785ca64
fix: Better error reporting & some fixes to deleteUser API (#12439) 2023-11-20 13:28:25 +00:00
sean-brydon 608b891536
fix: identifer (#12426)
Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-11-20 13:28:10 +00:00
Alex van Andel 4f26ca1a7b
feat: Base implementation of v2 of avatars (#12369)
* feat: Base implementation of v2 of avatars

* Make avatarUrl and logoUrl entirely optional

* Made necessary backwards compat changes

* fix: type errors

* Fix: OG image

* fix types

* Consistency with other behaviour, ux tweak

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-20 12:49:38 +00:00
Hariom Balhara c55b36f235
fix: Members count when `team` slug is same as `org` slug (#12124) 2023-11-20 18:01:50 +05:30
sean-brydon bdd3b132d4
feat: troubleshooter with weekly view (V2) (#12280)
* Inital UI + layout setup

* use booker approach of grid

* event-select - sidebar + store work

* adds get schedule by event-type-slug

* Calendar toggle

* Load schedule from event slug

* Add busy events to calendar

* useschedule

* Store more event info than just slug

* Add date override to calendar

* Changes sizes on smaller screens

* add event title as a tooltip

* Ensure header navigation works

* Stop navigator throwing errors on inital render

* Correct br

* Event duration fixes

* Add getMoreInfo if user is authed with current request.username

* Add calendar color map wip

* Add WIP comments for coloured outlines

* Revert more info changes

* Calculate date override correctly

* Add description option

* Fix inital schedule data not being populated

* Nudge overlap over to make it clearer

* Fix disabled state

* WIP on math logic

* Event list overlapping events logic

* NIT about width

* i18n + manage calendars link

* Delete old troubleshooter

* Update packages/features/calendars/weeklyview/components/event/EventList.tsx

* Remove t-slots

* Fix i18n & install calendar action

* sm:imrovments

* NITS

* Fix types

* fix: back button

* Month prop null as we control from query param

* Add head SEO

* Fix headseo import

* Fix date override tests
2023-11-20 17:49:33 +05:30
Crowdin Bot 9a4c20cca4 New Crowdin translations by Github Action 2023-11-20 11:08:01 +00:00
Hariom Balhara 2144fcb23e
fix: add node-mocks-http to web (#12435) 2023-11-20 16:34:29 +05:30
Crowdin Bot f2c39fc786 New Crowdin translations by Github Action 2023-11-17 16:12:37 +00:00
Crowdin Bot e83e0a770c New Crowdin translations by Github Action 2023-11-17 16:09:31 +00:00
Omar López c818ef3188
feat: implements basic user locking for admins (#12393)
* feat: implements basic user locking for admins

* Update sendPasswordReset.handler.ts

* check fixes

* Update packages/features/ee/users/components/UsersTable.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

---------

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-11-17 16:06:29 +00:00
Mehul 176564f4ed
fix: logo lack of contrast (#12401)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-17 14:10:58 +00:00
Morgan 27d59b6413
fix: add idx scheduleId on eventType (#12400) 2023-11-17 11:01:13 +00:00
Somay Chauhan 57a65401e7
fix: weird date override behaviour (#12292)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-16 21:09:48 +00:00
DmytroHryshyn 28acbe549a
chore: [app dir bootstrapping 9]: replace useSearchParams with useCompatSearchParams hook (#12056)
Co-authored-by: zomars <zomars@me.com>
2023-11-16 13:38:27 -07:00
Keith Williams 3534e3c224
Revert "perf: Increased memory/vCPU for slots perf (#12387)" (#12389)
This reverts commit 0b96ef5476.
2023-11-16 20:40:42 +02:00
Erik e48a6c3dcf
chore: Disable i18n cache in development (#12374) 2023-11-16 16:56:24 +00:00
Carina Wollendorfer 7d09ccb0d7
fix: add sendgrid-specific header only for SendGrid smtp server (#11932)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-16 13:51:30 -03:00
Morgan 9029c5b4c4
fix: change api root statusCode to 200 (#12362) 2023-11-16 16:50:43 +00:00
Udit Takkar a4c1df3658
refactor: team settings redesign (#12230)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-16 16:18:24 +00:00
Keith Williams 0b96ef5476
perf: Increased memory/vCPU for slots perf (#12387) 2023-11-16 11:57:37 -03:00
shaharyarshamshi ca9e0f5b72
refactor: Removed the dirName config for app store cli (#12321)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-16 13:59:01 +00:00
gitstart-app[bot] a9418b06d6
fix: Wrong spelling of the word "pode" (fix-wrongStringPT-BR) (#12344)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-16 13:15:38 +00:00
Crowdin Bot 833a326c5b New Crowdin translations by Github Action 2023-11-16 13:09:03 +00:00
sean-brydon b7e2a62e26
chore: Use apiLogin instead of user.login in e2e tests (#12382) 2023-11-16 13:05:39 +00:00
Crowdin Bot f687056d60 New Crowdin translations by Github Action 2023-11-16 08:51:33 +00:00
Morgan 0a39f53a4b
fix(stripePaymentCallback): better errors (#12223)
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-11-16 08:48:46 +00:00
Joe Au-Yeung ea0a64624c
fix: saving credential id for payment apps (#12251)
## What does this PR do?

<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

This PR adds the `credentialId` to payment app data. This fixes a bug where team installed payment apps were not working with team events.

Fixes # (issue)

<!-- Please provide a loom video for visual changes to speed up reviews
 Loom Video: https://www.loom.com/
-->

## Requirement/Documentation

<!-- Please provide all documents that are important to understand the reason of that PR. -->

- If there is a requirement document, please, share it here.
- If there is ab UI/UX design document, please, share it here.

## Type of change

<!-- Please delete bullets that are not relevant. -->

- [x] Bug fix (non-breaking change which fixes an issue)

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

- Install Stripe for the individual user
- Enable it for the individual's event type
- The `credentialId` should be saved to the metadata
- Install Stripe to the user's team
- Enable it in the team's event type
- The `credentialId` should be saved to the metadata

## Mandatory Tasks

- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't checked if new and existing unit tests pass locally with my changes
2023-11-15 19:59:43 -07:00
Erik 6a8726f5f8
chore: Insights readonly DB client (#12373) 2023-11-15 14:50:20 -07:00
Omar López eb97e1660b
v3.5.0 2023-11-15 14:48:10 -07:00
Udit Takkar 371a0f7245
feat: booking errors logging (#12325)
Fixes: https://github.com/calcom/cal.com/issues/12297
Fixes https://github.com/calcom/cal.com/issues/11234

- Displaying error message and X-Vercel-Id( Unique Request Id ) to user on book event form
- Improve error logging 
- Add Error codes

Few things to discuss

1) How to handle calendar integration failures ?
   Currently if for example google integration is broken and someone is trying to book that person then we log the error but don't inform the user that the google calendar is broken and the meeting goes through.
   
 Should I throw error when integration is broken ?
   
<img width="758" alt="Screenshot 2023-11-12 at 12 52 36 AM" src="https://github.com/calcom/cal.com/assets/53316345/c4d921c4-9c8a-4b9b-82a2-bbe0fdbcb3d4">

   
2)  How to handle conferencing app failures? 
 We just default to Cal Video  as location if we are unable to generated conferencing url and log the error and not inform the user(organizer).
2023-11-15 12:52:19 -07:00
Carina Wollendorfer 270d4f6e82
fix: round-robin booked out of availability (#12376)
## What does this PR do?

Fixes that it can happen that Round Robin host is booked outside of availability. 

I found and fixed the following two scenarios where this can happen: 
- when host has a date override
- when host is available for only a part the event time (for example, booking time 9:00-11:00 and user is only available between 10:00-11:00)

Fixes #10315
Fixes #11690

It also fixes that it can happen that round robin doesn't correctly pick the luck user (least recently booked). This happened when a user was an attendee of a booking before, then we always compared this booking and never the actual last booking of this user. 

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How should this be tested?

#### Booked outside of availability: 
1. 
- Create Round Robin event and assign user1 and user2 as round robin hosts
   - event duration: 120 minutes 
- user 1 availability: 
  - Monday to Friday 9:00-17:00
- user2 availability: 
  - Monday to Friday 10:00-17:00
- Book event at a 9:00 slot -> check if i user1 is booked 
- Book event again at a 9:00 slot -> check if user1 is booked again (user2 is not available at that time)

2.
- Change availability of user2
   - Mark Monday as unavailable 
   -   Add date override on any day this month 
- Book any Monday this month -> see that user 1 is booked 
- Again Book any Monday this month -> see that user 1 is booked again 

#### Wrong lucky user 
- Book event and add user1's email as the attendee email address
- Book several slots where both users should be available, and see that it alternates between user1 and user2 (before it ended up always booking user1)

## Mandatory Tasks

- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.
2023-11-15 12:49:03 -07:00
DmytroHryshyn 48e7b616b8
chore: [app dir bootstrapping 10] adds ab tests middleware (#12045)
## What does this PR do?
 - Adds AB tests middleware that redirects users to the app-dir pages with probability that is defined by env var
 
<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

Fixes # (issue)

<!-- Please provide a loom video for visual changes to speed up reviews
 Loom Video: https://www.loom.com/
-->

## Requirement/Documentation

<!-- Please provide all documents that are important to understand the reason of that PR. -->

This PR requires new env variables:
`APP_ROUTER_EVENT_TYPES_ENABLED`  - boolean that defines if app dir event-types page redirect is enabled
`AB_TEST_BUCKET_PROBABILITY` - number [0, 100] that defines the percentage of users getting redirected to the app dir pages

## Type of change

<!-- Please delete bullets that are not relevant. -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] Chore (refactoring code, technical debt, workflow improvements)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->
Does not requires testing, implements middleware as a dead code

## Mandatory Tasks

- [x] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.
2023-11-15 11:06:18 -07:00
Crowdin Bot 8b80ea99c2 New Crowdin translations by Github Action 2023-11-15 16:18:21 +00:00
Rajiv Sahal 150c6e0f50
refactor: rename `AtomsProvider` to `CalProvider` (#12375)
* rename context provider

* rename atoms provider export
2023-11-15 16:14:37 +00:00
Crowdin Bot 4037e87fbd New Crowdin translations by Github Action 2023-11-15 12:33:14 +00:00
Erik a804a29516
feat: Stripe paid apps flow (#12103)
* chore: Stripe paid apps flow

* chore: Subscription

* chore: Webhooks

* chore: Abstract functions

* chore: Lockfile

* chore: Webhook handler

* chore: Use catch-all

* chore: Webhook changes, etc

* chore: Cleanup

* chore: Use actual price id

* chore: Updates

* chore: Install normally until expiry date

* Disable team install for paid apps and cal.ai\

* Fix the same at another place

* Fix Typescript error

* redactedCause doesnt have message has enumerable prop

* Fix reinstallation of an already installed app

* chore: Remove unused deps

* chore: Ensure index

* chore: Price in usd

* chore: PR suggestion

* Fix missing packages in yarn.lock

---------

Co-authored-by: Hariom <hariombalhara@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-15 09:29:41 -03:00
Crowdin Bot 87b514b91b New Crowdin translations by Github Action 2023-11-15 10:14:51 +00:00
Crowdin Bot 693ca04626 New Crowdin translations by Github Action 2023-11-15 10:11:45 +00:00
Crowdin Bot 67f83c7e7d New Crowdin translations by Github Action 2023-11-15 10:08:40 +00:00
Crowdin Bot ecfecd832d New Crowdin translations by Github Action 2023-11-15 10:05:17 +00:00
Crowdin Bot e55302cbc5 New Crowdin translations by Github Action 2023-11-15 10:02:20 +00:00
Crowdin Bot 9514a68039 New Crowdin translations by Github Action 2023-11-15 09:59:22 +00:00
Crowdin Bot 4e3d159401 New Crowdin translations by Github Action 2023-11-15 09:56:40 +00:00
Mehul a519941b81
fix avatar remove button (#12249) 2023-11-15 15:23:33 +05:30
Crowdin Bot f62c58532d New Crowdin translations by Github Action 2023-11-15 00:52:06 +00:00
Ash Davis 0981c4cb23
feat: POST/PATCH `availabilities` API to accept `date` field (#12238) 2023-11-14 21:49:27 -03:00
Hariom Balhara 9d06f6dd0e
fix: Fix 'Book a new time' link in request-reschedule for Team Event (#12261)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-11-14 13:23:44 -07:00
Morgan 00df493623
revert: "fix: create prisma client singleton with immediately invoked function" (#12366) 2023-11-14 20:22:35 +00:00
Crowdin Bot 2cf2b11a7b New Crowdin translations by Github Action 2023-11-14 19:32:20 +00:00
Joe Au-Yeung 5c3fd0993e
fix: getting shimmer app keys (#12363)
* Fix getting shimmer app keys

* Read from config
2023-11-15 00:59:32 +05:30
Crowdin Bot 811e655720 New Crowdin translations by Github Action 2023-11-14 15:30:43 +00:00
Crowdin Bot defaafc9be New Crowdin translations by Github Action 2023-11-14 15:27:31 +00:00
Crowdin Bot e0c6feff1f New Crowdin translations by Github Action 2023-11-14 15:23:26 +00:00
Morgan d17dcbd319
v3.4.10 2023-11-14 17:19:22 +02:00
Rajiv Sahal 90d52663ac
feat: `AtomsProvider` component (#12354)
* init: atoms provider component

* chore: add atoms provider to index of atoms package

* cleanup comments
2023-11-14 20:47:48 +05:30
sean-brydon ada74467bc
fix: Callback redirect (#12361) 2023-11-14 12:15:50 -03:00
Crowdin Bot 7db758c2d5 New Crowdin translations by Github Action 2023-11-14 14:04:22 +00:00
Amit Sharma 2867d53442
fix resend team member invite (#12360) 2023-11-14 13:59:49 +00:00
Crowdin Bot 31067fcd45 New Crowdin translations by Github Action 2023-11-14 12:59:06 +00:00
Hariom Balhara 8c2ce972cc
fix: team booking page having same slug as the org (#12213) 2023-11-14 18:25:46 +05:30
Crowdin Bot d3ab11e38e New Crowdin translations by Github Action 2023-11-14 11:54:31 +00:00
Crowdin Bot 3d596fcb1a New Crowdin translations by Github Action 2023-11-14 11:51:13 +00:00
Crowdin Bot 820b45a912 New Crowdin translations by Github Action 2023-11-14 11:48:30 +00:00
Udit Takkar b945849736
chore: variables names (#12352) 2023-11-14 11:45:09 +00:00
Crowdin Bot 6b2c59b733 New Crowdin translations by Github Action 2023-11-14 10:27:14 +00:00
Crowdin Bot b7f85d785a New Crowdin translations by Github Action 2023-11-14 10:23:40 +00:00
Crowdin Bot 08e4e816c6 New Crowdin translations by Github Action 2023-11-14 10:20:41 +00:00
Crowdin Bot 20430022e1 New Crowdin translations by Github Action 2023-11-14 10:17:32 +00:00
Crowdin Bot e4c71e5d2c New Crowdin translations by Github Action 2023-11-14 10:14:23 +00:00
Crowdin Bot 28eda407be New Crowdin translations by Github Action 2023-11-14 10:11:07 +00:00
Crowdin Bot 9dab171520 New Crowdin translations by Github Action 2023-11-14 10:07:51 +00:00
Crowdin Bot d5f359291d New Crowdin translations by Github Action 2023-11-14 10:03:34 +00:00
Morgan 3c1d0a9bf1
fix: add translations to api dockerfile (#12349) 2023-11-14 09:59:32 +00:00
Crowdin Bot 3057edbd87 New Crowdin translations by Github Action 2023-11-14 04:59:52 +00:00
Carina Wollendorfer a2f859b55a
fix: unhandled promise rejection in scheduleWorkflowReminder (#12301)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-14 10:27:16 +05:30
Crowdin Bot b2f4eaee63 New Crowdin translations by Github Action 2023-11-13 21:53:32 +00:00
Hariom Balhara b66c3f3452
fix: Org: Any team URL with slug starting with `d` is 404 (#12302) 2023-11-13 14:50:54 -07:00
Keith Williams 5ab0b85e52
chore: Reduce slots API serverless memory configuration (#12270)
* chore: Reduce API serverless memory configuration

* Only limit to slots for now

* Moved the vercel.json file to root

* More fun with vercel.json files

* Trying new pattern

* Using a pattern that matches the Vercel deployment summary function name

* Trying to set the memory directly in the handler file

* Trying it on all functions

* Changed glob

* Moved vercel.json file to root

* Trying a new glob

* Give me all functions

* Trying just * for all functions

* Trying again...

* Putting the config on the defaultResponder

* Seeing if web app takes setings

* Changed .js to .ts

* Changed root path

* Added back vercel.json now that the path is changed

* Reduced API slots memory to 512

* Removed unneeded code changes'

* Update defaultResponder.ts
2023-11-13 15:37:26 +00:00
Alex van Andel 4135c1038e v3.4.9 2023-11-13 15:13:25 +00:00
Crowdin Bot fc5190a33b New Crowdin translations by Github Action 2023-11-13 14:31:15 +00:00
Carina Wollendorfer f29328e6a2
fix: meeting url variable in workflow notifitcations (#12308)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-13 09:28:15 -05:00
Udit Takkar 621f7639ff
fix: display organizer location after booking (#12088)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-11-13 19:29:50 +05:30
Alex van Andel 63f2f6edba
fix: getTeamOrThrow ran on every request (#12337)
* fix: getTeamOrThrow ran on every request

This creates unnecessary strain on the DB when someone is hitting the endpoint a lot.

* Add rate limit

* Update packages/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler.ts

---------

Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-11-13 13:45:46 +00:00
Morgan 199f41fb1a
fix: add teamId index on VerificationToken (#12339)
* fix: add teamId index on InvitationToken

* fix: add migration
2023-11-13 13:42:27 +00:00
Crowdin Bot 3ea9faa414 New Crowdin translations by Github Action 2023-11-13 11:58:42 +00:00
Peer Richelsen 518ec4f605
feat: added /enterprise upgrade tip (#12207) 2023-11-13 13:55:28 +02:00
Hichem Fantar 4db0da5da4
feat: smooth transitions to interactive elements (#11983)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-12 17:45:44 +00:00
Crowdin Bot 115ded8429 New Crowdin translations by Github Action 2023-11-12 17:16:59 +00:00
DmytroHryshyn 71485d1b57
chore: [app dir bootstrapping 7] update middleware (#12044) 2023-11-12 17:14:38 +00:00
Crowdin Bot 87071c4f19 New Crowdin translations by Github Action 2023-11-11 11:19:34 +00:00
Hariom 412f15814e Add removeItem to webstorage 2023-11-11 11:16:35 +00:00
Hariom a57085cf64 fix: Broken embed in incognito of chrome 2023-11-11 11:16:35 +00:00
Crowdin Bot 65d1a34e39 New Crowdin translations by Github Action 2023-11-10 20:09:57 +00:00
Hariom Balhara e4abc85382
fix: Fix recurring booking failure due to rate limiting (#12322)
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-11-10 20:06:52 +00:00
Crowdin Bot eb1eb722f2 New Crowdin translations by Github Action 2023-11-10 18:41:47 +00:00
Amit Sharma 033bc45dd1
appstore-install-loader-fix (#12269) 2023-11-10 18:38:45 +00:00
Jatin Sandilya affe85d02c
fix: link attendee to meeting in ZohoCRM app (#12200)
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-10 13:50:30 +00:00
Morgan d6f9a833bd
fix: add missing config files to api dockerfile (#12318) 2023-11-10 12:50:49 +00:00
Keith Williams e4281a852a
feat: Add Sentry to edge (#12304) 2023-11-10 08:47:55 -03:00
gitstart-app[bot] e4b2464548
fix: Fix "could not book the meeting" issue (fix-confirmBookingIssue) (#12305)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
2023-11-09 18:43:48 -03:00
Abhinav 8c99a2a7af
fix: fix bookings today (#12060)
* fix : fixed today's bookings in bookings upcoming section

* chore: improvements

* chore: fix type error

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-11-10 02:20:51 +05:30
Keith Williams 2236dfe411
v3.4.8 2023-11-09 14:43:25 -03:00
Udit Takkar a67369460a fix: ui fixes 2023-11-09 16:55:37 +00:00
Siddharth Movaliya b2526300a7 fix duplicate labels 2023-11-09 16:55:37 +00:00
Siddharth Movaliya d69395434f fix: Duplicate labels for Destination Calendar 2023-11-09 16:55:37 +00:00
Peer Richelsen 2720c9cc67 added tracking link 2023-11-09 16:36:35 +00:00
Peer Richelsen f1465a15f6 remove dependency 2023-11-09 16:36:35 +00:00
Peer Richelsen 1d24f2654d added deel app 2023-11-09 16:36:35 +00:00
Keith Williams f7eb86577c
fix: Sentry warnings for startTransaction (#12300) 2023-11-09 12:55:53 -03:00
Peer Richelsen cc515f00b7
chore: fix avatar margin (#12274) 2023-11-09 15:34:28 +00:00
Morgan e695f75113
fix: create prisma client singleton with immediately invoked function (#12267) 2023-11-09 12:00:19 -03:00
Ash Davis 0d1b6ea5b2
feat: configure availability time picker interval by env variable (#12174) 2023-11-09 09:50:42 -05:00
Joe Au-Yeung 26637cda08
fix: When Installing Calendar App, Set Primary Calendar As Selected Calendar (#12291)
* GCal set primary calendar on install

* Outlook set default calendar as selected cal

* Zoho create selected calendar on install

* Lark create selected cal on install
2023-11-09 14:47:53 +00:00
Morgan 529054aa76
fix: add missing config files to api dockerfile (#12295) 2023-11-09 12:53:37 +00:00
Hariom Balhara 8deee738c2
fix: Recurring Booking - Check for conflicts on first 2 slots only (#11774)
* Add recurring booking tests and fix the bug

* Fix recurring booking tests supporting the new link verification assertions

* Convert tab to spaces
2023-11-09 17:00:51 +05:30
vikcodes 6848362683
feat: 11642 app shimmer video (#12159)
* added initial app

* created basic functionality for Shimmer Video app with tracking of Daily rooms

* changed the type config value in the shimmer video config.json

* re-fixed update to shimmer-video config type

* updated static images for shimmer video app

* fixed tracking Shimmer video event parameter

* Add zod files

* Allow query for "conferencing" apps

* Move to shimmer video

* Redirect to shimmer app

* Remove console.logs

* Remove legacy use of seed-app-store.

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Vik <vsreed@stanford.edu>
Co-authored-by: pathaksarvesh <sarvesh@incrediblevisibility.com>
Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Hariom <hariombalhara@gmail.com>
2023-11-09 14:03:50 +05:30
Keith Williams 09fc7e1a4c
fix: Remove count from query to update schedule (#12287)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-11-08 14:47:33 -03:00
Carina Wollendorfer 2f73be0ee6
fix: tests for booking limits (#12284)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-08 17:13:56 +00:00
Ryukemeister 3cdf59f2cc fix capitalization typo for show event type message 2023-11-08 14:27:21 +00:00
Morgan 1f9880204e
fix: payment cancel button redirects properly (#12254) 2023-11-08 12:34:50 +02:00
Peer Richelsen d0be48ebde
chore: delete welcome workflow (#12279) 2023-11-08 09:39:56 +00:00
Keith Williams 5c8abbb3e9
v3.4.7 2023-11-07 15:07:42 -03:00
Carina Wollendorfer 7bb42ba577
fix: booking limits (#12172)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-07 14:17:05 -03:00
Keith Williams 2e3b3257db
feat: Add Sentry (#12155)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-07 13:18:25 -03:00
gitstart-app[bot] d28e20e92e
fix: Fix "Could not book the meeting" issue (fix-bookingIssue) (#12252)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
2023-11-07 12:33:49 -03:00
Carina Wollendorfer 8b89d6635a
fix: recurring events with calendar connections (#12250)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-07 12:09:56 -03:00
Benny Joo 13ec810cb9
fix: [app dir bootstrapping 8] `useParamsWithFallback` hook and add tests (#12041)
* fix: first solution using RouterContext

* fix: second solution by importing router from next/compat/router

* fix return type
2023-11-07 13:48:02 +00:00
Morgan 367c8a96d8
feat: Add user's avatar to POST and PATCH requests in users endpoints (#11187) (#12256)
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

## What does this PR do?

<!-- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. -->

Fix wrong import introduced in this pr: #11187

<!-- Please provide a loom video for visual changes to speed up reviews
 Loom Video: https://www.loom.com/
-->

## Requirement/Documentation

<!-- Please provide all documents that are important to understand the reason of that PR. -->

- If there is a requirement document, please, share it here.
- If there is ab UI/UX design document, please, share it here.

## Type of change

<!-- Please delete bullets that are not relevant. -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Chore (refactoring code, technical debt, workflow improvements)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update

## How should this be tested?

<!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. Write details that help to start the tests -->

- Are there environment variables that should be set?
- What are the minimal test data to have?
- What is expected (happy path) to have (input and output)?
- Any other important info that could help to test that PR

## Mandatory Tasks

- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.

## Checklist

<!-- Remove bullet points below that don't apply to you -->

- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project
- I haven't commented my code, particularly in hard-to-understand areas
- I haven't checked if my PR needs changes to the documentation
- I haven't checked if my changes generate no new warnings
- I haven't added tests that prove my fix is effective or that my feature works
- I haven't checked if new and existing unit tests pass locally with my changes
2023-11-07 10:21:20 +00:00
Hamza Fouad e94c030c45
feat: Add user's avatar to POST and PATCH requests in users endpoints (#11187)
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-07 08:06:52 +00:00
Morgan 6d0c7e4214
chore: init infra folder with dockerized api (#12243)
* chore(infra): scripts and dockerfile for api

* chore(infra): basic readme file

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-11-07 09:47:06 +02:00
Carina Wollendorfer e11cb9e3a5
fix: unhandled promise error in scheduleEmailReminders endpoint (#12183)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-11-06 09:14:35 -05:00
Manpreet Singh 809abd2f4f
fix: Removes send an invite email option & always send email (#12229) 2023-11-06 13:30:37 +05:30
gitstart-app[bot] d1d50b0d91
test: Create E2E tests for bookings with custom/required Multiple Emails + other questions (teste2e-multipleEmailQuestion) (#11565)
* Remove unnecessary changes

* add changes

* Requested changes

* Requested changes

* fix: rename file to have .e2e

---------

Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
Co-authored-by: Morgan Vernay <morgan@cal.com>
2023-11-03 15:29:47 +00:00
Lauris Skraucis fc716f5921
fix: booking timeslots (#12195) 2023-11-03 10:58:58 -04:00
gitstart-app[bot] 5348464972
test: Create E2E tests for bookings for all questions together as custom/required (teste2e-allQuestions) (#11592)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
2023-11-03 11:12:17 -03:00
gitstart-app[bot] 3fac6e698e
test: Create E2E tests for bookings with custom/required Radio Group + other questions (teste2e-radioGroupQuestion) (#11567)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
2023-11-03 11:11:18 -03:00
gitstart-app[bot] dcafbf672a
test: Create E2E tests for bookings with custom/required Checkbox Group + other questions (teste2e-checkboxGroupQuestion) (#11568)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
2023-11-03 11:10:17 -03:00
Rahul Roy dff89a4df8
feat: #11922 Removed error for cancelling past time slots (#12126)
Co-authored-by: Rahul Roy <rahulro@maqsoftware.com>
2023-11-03 11:29:41 +00:00
Syed Ali Shahbaz ed04062540
fix: API to return hosts on event types response (#12204) 2023-11-03 11:28:16 +00:00
Siddharth Movaliya 23fda4a9e6
feat: The 'confirm' button triggers after entering the code (#12128)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-11-03 11:27:52 +00:00
Udit Takkar 14c3028c2a fix: use 18n 2023-11-03 11:27:09 +00:00
Udit Takkar dfe49e1732 fix: link input 2023-11-03 11:27:09 +00:00
Udit Takkar 6148c6baea chore: add placeholder 2023-11-03 11:27:09 +00:00
Udit Takkar 5366d891bb fix: improve error message 2023-11-03 11:27:09 +00:00
Sean Brydon 2ee021a87f fix:installed-calendar-info 2023-11-03 10:23:50 +00:00
Alex van Andel dd0c2dbff2
fix: Set the dateFrom to startOf day otherwise bad fromOffset is used (#12210) 2023-11-03 03:13:42 +00:00
Hariom Balhara f044c2d7c7
fix: Embed: data-cal-origin not used by modal(which is used by both element click popup and floating button popup) (#12075) 2023-11-02 19:39:58 +00:00
Somay Chauhan 703bcd861e
fix: should allow org owners and admins to delete members from subteams (#11710)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-11-02 14:37:19 -04:00
Syed Ali Shahbaz d4d96eb5cd
fix admin check (#12175) 2023-11-02 12:29:15 +00:00
Hariom Balhara d8356e9a5b
fix: Make sure if header is set already, it isn't set again (#12194) 2023-11-02 09:22:16 -03:00
Alexander Zeitler 9348279818
docs(README): remove unpaired symbol (#12133) 2023-11-02 09:36:47 +00:00
Peer Richelsen 5d77e4ce1d
chore: changed readme (#12171) 2023-11-02 09:36:00 +00:00
Syed Ali Shahbaz 968e782dbe
Update README.md (#12176) 2023-11-02 09:34:59 +00:00
Udit Takkar 01fb3dd03b
fix: hide Check for recording (#12184) 2023-11-02 09:34:25 +00:00
Lauris Skraucis c3537f3290
docs: needs approval label (#12177)
Our CI workflow doesn't allow merging for only .md changes because the required check doesn't clear based on file filters.
2023-11-01 11:52:11 -03:00
Joe Au-Yeung 3bb42f276e
fix: Attach `credentialId` to location option (#12086)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Udit Takkar <udit222001@gmail.com>
2023-11-01 09:34:05 -04:00
Keith Williams 51fd4102ae
v3.4.6 2023-10-31 17:25:46 -03:00
Ritesh Kumar 9d1ef0a649
chore: [CAL-2654] Broken Icons in org invitation email (#12119)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-10-31 20:00:07 +00:00
gitstart-app[bot] f80dc0738a
test: Create E2E tests for bookings with custom/required Select + other questions (teste2e-selectQuestion) (#11564)
Co-authored-by: gitstart-calcom <gitstart-calcom@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-10-31 19:44:18 +00:00
Peer Richelsen 678ab3f453
chore: remove merge conflicts workflow (#12173) 2023-10-31 19:43:38 +00:00
Syed Ali Shahbaz 199d3e4c3f
fix: Auto-link credentials internally on destination calendar (#12055)
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2023-10-31 13:54:09 -03:00
Siddharth Movaliya 79a6aef0e7
fix: text colour for no-show acknowledgment (#12132) 2023-10-31 16:41:25 +00:00
Udit Takkar 4d49fb0636
fix: cal video recording email (#12079)
* fix: cal video recording email

* fix: add check for recording

* chore: remove logs

* chore: change message

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-10-31 13:35:23 -03:00
Udit Takkar 0be1387d0f
fix: org settings for member improvements (#12161) 2023-10-31 16:24:51 +00:00
Morgan 58ab278813
fix(e2e): failsafe if no availabilities (#12168) 2023-10-31 16:10:08 +00:00
Alex van Andel 4de142cb7c
fix: Check for same day, not with <= (#12167)
* fix: Check for same day, not with <=

* Cover this situation with a test

* Make the test timezone-independent
2023-10-31 14:48:47 +00:00
Hariom Balhara b4d27a9326
Fix Google spam policy alert layout in embed (#12153) 2023-10-31 10:46:35 +00:00
sean-brydon 31f3d9778e
Use correct typing for totalTeamMembers (#12152) 2023-10-30 17:29:09 +02:00
sean-brydon 0a59c95b93
fix: impersonation for orgs (#12113) 2023-10-30 12:20:48 -03:00
Hariom Balhara 9e3465eeb6
fix: Support embedding org profile page (#12116)
* support embedding org profile page

* Add checkly tests

* Fix test titles

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-10-30 17:49:13 +05:30
Hariom Balhara 31fc4724e0
fix: request reschedule link in email for an Org event (#12125) 2023-10-30 16:25:12 +05:30
Hariom Balhara f81f0a26ec
fix: Prevent possible reason behind avatar infinite redirect (#12143) 2023-10-30 09:19:06 +00:00
Hariom Balhara 9a80bb6194
fix: Skip failing tests (#12144) 2023-10-30 09:05:05 +00:00
Udit Takkar 901fc36c97
fix: padding in footer in profile (#12101) 2023-10-28 18:17:41 +01:00
Joe Au-Yeung 2831fb2b57
refactor: Falling Back to `FirstCalendarCredential` (#11986) 2023-10-27 11:52:56 -04:00
Hariom Balhara 426d31712e
test: E2E for Orgs - The beginning (#12095) 2023-10-27 18:14:16 +05:30
Carina Wollendorfer 09ecd445bb
fix adding managed event type to workflow (#12111)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-10-27 17:30:34 +05:30
Carina Wollendorfer 08d65c85de
fix: cron scheduleEmailRemider time out (#12108)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-10-27 08:53:53 -03:00
Peer Richelsen b9cef10ef2
chore: new cal.ai tip (#12096) 2023-10-27 11:25:28 +00:00
Manish Singh Bisht 0dc41592f2
fix: use app.slug not hard coded zoom (#11963)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-10-27 12:05:30 +01:00
1135 changed files with 48641 additions and 20029 deletions

View File

@ -37,6 +37,7 @@ BASECAMP3_USER_AGENT=
DAILY_API_KEY=
DAILY_SCALE_PLAN=''
DAILY_WEBHOOK_SECRET=''
# - GOOGLE CALENDAR/MEET/LOGIN
# Needed to enable Google Calendar integration and Login with Google
@ -126,4 +127,12 @@ ZOHOCRM_CLIENT_ID=""
ZOHOCRM_CLIENT_SECRET=""
# - REVERT
# Used for the Pipedrive integration (via/ Revert (https://revert.dev))
# @see https://github.com/calcom/cal.com/#obtaining-revert-api-keys
REVERT_API_KEY=
REVERT_PUBLIC_TOKEN=
# NOTE: If you're self hosting Revert, update this URL to point to your own instance.
REVERT_API_URL=https://api.revert.dev/
# *********************************************************************************************************

View File

@ -25,6 +25,7 @@ CALCOM_LICENSE_KEY=
DATABASE_URL="postgresql://postgres:@localhost:5450/calendso"
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
INSIGHTS_DATABASE_URL=
# Uncomment to enable a dedicated connection pool for Prisma using Prisma Data Proxy
# Cold boots will be faster and you'll be able to scale your DB independently of your app.
@ -106,6 +107,19 @@ NEXT_PUBLIC_HELPSCOUT_KEY=
NEXT_PUBLIC_FRESHCHAT_TOKEN=
NEXT_PUBLIC_FRESHCHAT_HOST=
# Google OAuth credentials
# To enable Login with Google you need to:
# 1. Set `GOOGLE_API_CREDENTIALS` above
# 2. Set `GOOGLE_LOGIN_ENABLED` to `true`
# When self-hosting please ensure you configure the Google integration as an Internal app so no one else can login to your instance
# @see https://support.google.com/cloud/answer/6158849#public-and-internal&zippy=%2Cpublic-and-internal-applications
GOOGLE_LOGIN_ENABLED=false
# - GOOGLE CALENDAR/MEET/LOGIN
# Needed to enable Google Calendar integration and Login with Google
# @see https://github.com/calcom/cal.com#obtaining-the-google-api-credentials
GOOGLE_API_CREDENTIALS=
# Inbox to send user feedback
SEND_FEEDBACK_EMAIL=
@ -115,6 +129,15 @@ SENDGRID_API_KEY=
SENDGRID_EMAIL=
NEXT_PUBLIC_SENDGRID_SENDER_NAME=
# Sentry
# Used for capturing exceptions and logging messages
NEXT_PUBLIC_SENTRY_DSN=
# Formbricks Experience Management Integration
FORMBRICKS_HOST_URL=https://app.formbricks.com
FORMBRICKS_ENVIRONMENT_ID=
FORMBRICKS_FEEDBACK_SURVEY_ID=
# Twilio
# Used to send SMS reminders in workflows
TWILIO_SID=
@ -126,7 +149,7 @@ TWILIO_WHATSAPP_PHONE_NUMBER=
NEXT_PUBLIC_SENDER_ID=
TWILIO_VERIFY_SID=
# Set it to "1" if you need to run E2E tests locally.
# Set it to "1" if you need to run E2E tests locally.
NEXT_PUBLIC_IS_E2E=
# Used for internal billing system
@ -137,6 +160,7 @@ NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE=
STRIPE_TEAM_MONTHLY_PRICE_ID=
STRIPE_ORG_MONTHLY_PRICE_ID=
STRIPE_WEBHOOK_SECRET=
STRIPE_WEBHOOK_SECRET_APPS=
STRIPE_PRIVATE_KEY=
STRIPE_CLIENT_ID=
PAYMENT_FEE_FIXED=
@ -177,6 +201,10 @@ EMAIL_SERVER_PORT=1025
# Make sure to run mailhog container manually or with `yarn dx`
E2E_TEST_MAILHOG_ENABLED=
# Resend
# Send transactional email using resend
# RESEND_API_KEY=
# **********************************************************************************************************
# Set the following value to true if you wish to enable Team Impersonation
@ -203,6 +231,8 @@ CSP_POLICY=
EDGE_CONFIG=
NEXT_PUBLIC_MINUTES_TO_BOOK=5 # Minutes
# Control time intervals on a user's Schedule availability
NEXT_PUBLIC_AVAILABILITY_SCHEDULE_INTERVAL=
# - ORGANIZATIONS *******************************************************************************************
# Enable Organizations non-prod domain setup, works in combination with organizations feature flag
@ -224,12 +254,32 @@ PROJECT_ID_VERCEL=
TEAM_ID_VERCEL=
# Get it from: https://vercel.com/account/tokens
AUTH_BEARER_TOKEN_VERCEL=
# Add the main domain that you want to use for testing vercel domain management for organizations. This is necessary because WEBAPP_URL of local isn't a valid public domain
# Would create org1.example.com for an org with slug org1
# LOCAL_TESTING_DOMAIN_VERCEL="example.com"
## Set it to 1 if you use cloudflare to manage your DNS and would like us to manage the DNS for you for organizations
# CLOUDFLARE_DNS=1
## Get it from: https://dash.cloudflare.com/profile/api-tokens. Select Edit Zone template and choose a zone(your domain)
# AUTH_BEARER_TOKEN_CLOUDFLARE=
## Zone ID can be found in the Overview tab of your domain in Cloudflare
# CLOUDFLARE_ZONE_ID=
## It should usually work with the default value. This is the DNS CNAME record content to point to Vercel domain
# CLOUDFLARE_VERCEL_CNAME=cname.vercel-dns.com
# - APPLE CALENDAR
# Used for E2E tests on Apple Calendar
E2E_TEST_APPLE_CALENDAR_EMAIL=""
E2E_TEST_APPLE_CALENDAR_PASSWORD=""
# - CALCOM QA ACCOUNT
# Used for E2E tests on Cal.com that require 3rd party integrations
E2E_TEST_CALCOM_QA_EMAIL="qa@example.com"
# Replace with your own password
E2E_TEST_CALCOM_QA_PASSWORD="password"
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS=
E2E_TEST_CALCOM_GCAL_KEYS=
# - APP CREDENTIAL SYNC ***********************************************************************************
# Used for self-hosters that are implementing Cal.com into their applications that already have certain integrations
# Under settings/admin/apps ensure that all app secrets are set the same as the parent application
@ -239,7 +289,7 @@ CALCOM_WEBHOOK_SECRET=""
CALCOM_WEBHOOK_HEADER_NAME="calcom-webhook-secret"
CALCOM_CREDENTIAL_SYNC_ENDPOINT=""
# Key should match on Cal.com and your application
# must be 32 bytes for AES256 encryption algorithm
# must be 24 bytes for AES256 encryption algorithm
# You can use: `openssl rand -base64 24` to generate one
CALCOM_APP_CREDENTIAL_ENCRYPTION_KEY=""
@ -257,3 +307,27 @@ E2E_TEST_OIDC_USER_EMAIL=
E2E_TEST_OIDC_USER_PASSWORD=
# ***********************************************************************************************************
# provide a value between 0 and 100 to ensure the percentage of traffic
# redirected from the legacy to the future pages
AB_TEST_BUCKET_PROBABILITY=50
# whether we redirect to the future/event-types from event-types or not
APP_ROUTER_EVENT_TYPES_ENABLED=0
APP_ROUTER_SETTINGS_ADMIN_ENABLED=0
APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED=0
APP_ROUTER_APPS_SLUG_ENABLED=0
APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0
# whether we redirect to the future/apps/categories from /apps/categories or not
APP_ROUTER_APPS_CATEGORIES_ENABLED=0
# whether we redirect to the future/apps/categories/[category] from /apps/categories/[category] or not
APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED=0
APP_ROUTER_BOOKINGS_STATUS_ENABLED=0
APP_ROUTER_WORKFLOWS_ENABLED=0
APP_ROUTER_SETTINGS_TEAMS_ENABLED=0
APP_ROUTER_GETTING_STARTED_STEP_ENABLED=0
APP_ROUTER_APPS_ENABLED=0
APP_ROUTER_VIDEO_ENABLED=0
APP_ROUTER_TEAMS_ENABLED=0
# disable setry server source maps
SENTRY_DISABLE_SERVER_WEBPACK_PLUGIN=1

View File

@ -47,3 +47,9 @@ assignees: ""
-->
(Share it here.)
---
##### House rules
- If this issue has a `🚨 needs approval` label, don't start coding yet. Wait until a core member approves feature request by removing this label, then you can start coding.
- For clarity: Non-core member issues automatically get the `🚨 needs approval` label.
- Your feature ideas are invaluable to us! However, they undergo review to ensure alignment with the product's direction.

View File

@ -19,11 +19,12 @@ Fixes # (issue)
<!-- Please delete bullets that are not relevant. -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Chore (refactoring code, technical debt, workflow improvements)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
- Bug fix (non-breaking change which fixes an issue)
- Chore (refactoring code, technical debt, workflow improvements)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing functionality to not work as expected)
- Tests (Unit/Integration/E2E or any other test)
- This change requires a documentation update
## How should this be tested?
@ -40,7 +41,7 @@ Fixes # (issue)
## Checklist
<!-- Please remove all the irrelevant bullets to your PR -->
<!-- Remove bullet points below that don't apply to you -->
- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code doesn't follow the style guidelines of this project

View File

@ -24,6 +24,8 @@ runs:
**/.turbo/**
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ env.key-3 }}-${{ env.key-4 }}
- run: yarn build
- run: |
export NODE_OPTIONS="--max_old_space_size=8192"
yarn build
if: steps.cache-build.outputs.cache-hit != 'true'
shell: bash

View File

@ -17,10 +17,14 @@ runs:
cache-name: cache-db
key-1: ${{ hashFiles('packages/prisma/schema.prisma', 'packages/prisma/migrations/**/**.sql', 'packages/prisma/*.ts') }}
key-2: ${{ github.event.pull_request.number || github.ref }}
DATABASE_URL: ${{ inputs.DATABASE_URL }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ inputs.E2E_TEST_CALCOM_QA_EMAIL }}
E2E_TEST_CALCOM_QA_PASSWORD: ${{ inputs.E2E_TEST_CALCOM_QA_PASSWORD }}
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ inputs.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
with:
path: ${{ inputs.path }}
key: ${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ env.key-1 }}-${{ env.key-2 }}
- run: yarn db-seed
- run: echo ${{ env.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }} && yarn db-seed
if: steps.cache-db.outputs.cache-hit != 'true'
shell: bash
- name: Postgres Dump Backup

View File

@ -5,7 +5,7 @@ runs:
steps:
- name: Cache playwright binaries
id: playwright-cache
uses: buildjet/cache@v2
uses: buildjet/cache@v3
with:
path: |
~/Library/Caches/ms-playwright

View File

@ -1,74 +0,0 @@
name: "Apply issue labels to PR"
on:
pull_request_target:
types:
- opened
jobs:
label_on_pr:
runs-on: ubuntu-latest
permissions:
contents: none
issues: read
pull-requests: write
steps:
- name: Apply labels from linked issue to PR
uses: actions/github-script@v5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
async function getLinkedIssues(owner, repo, prNumber) {
const query = `query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $prNumber) {
closingIssuesReferences(first: 10) {
nodes {
number
labels(first: 10) {
nodes {
name
}
}
}
}
}
}
}`;
const variables = {
owner: owner,
repo: repo,
prNumber: prNumber,
};
const result = await github.graphql(query, variables);
return result.repository.pullRequest.closingIssuesReferences.nodes;
}
const pr = context.payload.pull_request;
const linkedIssues = await getLinkedIssues(
context.repo.owner,
context.repo.repo,
pr.number
);
const labelsToAdd = new Set();
for (const issue of linkedIssues) {
if (issue.labels && issue.labels.nodes) {
for (const label of issue.labels.nodes) {
labelsToAdd.add(label.name);
}
}
}
if (labelsToAdd.size) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: Array.from(labelsToAdd),
});
}

View File

@ -2,7 +2,7 @@ name: Check types
on:
workflow_call:
env:
NODE_OPTIONS: "--max-old-space-size=8192"
NODE_OPTIONS: --max-old-space-size=4096
jobs:
check-types:
runs-on: buildjet-4vcpu-ubuntu-2204

View File

@ -17,10 +17,11 @@ jobs:
steps:
- uses: actions/stale@v7
with:
days-before-close: -1
days-before-issue-stale: 60
days-before-issue-close: -1
days-before-pr-stale: 14
days-before-pr-close: 7
days-before-pr-close: -1
stale-pr-message: "This PR is being marked as stale due to inactivity."
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued."
operations-per-run: 100

View File

@ -1,7 +1,8 @@
name: E2E App-Store Apps
name: E2E App-Store Apps Tests
on:
workflow_call:
env:
NODE_OPTIONS: --max-old-space-size=4096
jobs:
e2e-app-store:
timeout-minutes: 20
@ -29,10 +30,15 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
env:
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn e2e:app-store --shard=${{ matrix.shard }}/${{ strategy.job-total }}
@ -43,6 +49,10 @@ jobs:
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
E2E_TEST_MAILHOG_ENABLED: ${{ vars.E2E_TEST_MAILHOG_ENABLED }}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: ${{ vars.CI_GOOGLE_LOGIN_ENABLED }}
@ -65,7 +75,7 @@ jobs:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: app-store-results-${{ matrix.shard }}_${{ strategy.job-total }}
path: test-results

View File

@ -1,7 +1,8 @@
name: E2E Embed React tests and booking flow(for non-embed as well)
name: E2E Embed React tests and booking flow (for non-embed as well)
on:
workflow_call:
env:
NODE_OPTIONS: --max-old-space-size=4096
jobs:
e2e-embed:
timeout-minutes: 20
@ -24,7 +25,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
@ -61,7 +61,7 @@ jobs:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: embed-react-results-${{ matrix.shard }}_${{ strategy.job-total }}
path: test-results

View File

@ -1,7 +1,8 @@
name: E2E Embed Core tests and booking flow(for non-embed as well)
name: E2E Embed Core tests and booking flow (for non-embed as well)
on:
workflow_call:
env:
NODE_OPTIONS: --max-old-space-size=4096
jobs:
e2e-embed:
timeout-minutes: 20
@ -29,7 +30,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
@ -65,7 +65,7 @@ jobs:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: embed-core-results-${{ matrix.shard }}_${{ strategy.job-total }}
path: test-results

View File

@ -1,8 +1,8 @@
name: E2E test
name: E2E tests
on:
workflow_call:
env:
NODE_OPTIONS: --max-old-space-size=4096
jobs:
e2e:
timeout-minutes: 20
@ -28,7 +28,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
@ -68,7 +67,7 @@ jobs:
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.shard }}_${{ strategy.job-total }}
path: test-results

View File

@ -1,6 +1,7 @@
name: "Pull Request Labeler"
on:
- pull_request_target
pull_request_target:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
@ -16,3 +17,81 @@ jobs:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
# https://github.com/actions/labeler/issues/442#issuecomment-1297359481
sync-labels: ""
team-labels:
permissions:
contents: read
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: equitybee/team-label-action@main
with:
repo-token: ${{ secrets.EQUITY_BEE_TEAM_LABELER_ACTION_TOKEN }}
organization-name: calcom
ignore-labels: "admin, app-store, ai, authentication, automated-testing, devops, platform, billing, bookings, caldav, calendar-apps, ci, console, crm-apps, docs, documentation, emails, embeds, event-types, i18n, impersonation, manual-testing, ui, performance, ops-stack, organizations, public-api, routing-forms, seats, teams, webhooks, workflows, zapier"
apply-labels-from-issue:
runs-on: ubuntu-latest
permissions:
contents: none
issues: read
pull-requests: write
steps:
- name: Apply labels from linked issue to PR
uses: actions/github-script@v5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
async function getLinkedIssues(owner, repo, prNumber) {
const query = `query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $prNumber) {
closingIssuesReferences(first: 10) {
nodes {
number
labels(first: 10) {
nodes {
name
}
}
}
}
}
}
}`;
const variables = {
owner: owner,
repo: repo,
prNumber: prNumber,
};
const result = await github.graphql(query, variables);
return result.repository.pullRequest.closingIssuesReferences.nodes;
}
const pr = context.payload.pull_request;
const linkedIssues = await getLinkedIssues(
context.repo.owner,
context.repo.repo,
pr.number
);
const labelsToAdd = new Set();
for (const issue of linkedIssues) {
if (issue.labels && issue.labels.nodes) {
for (const label of issue.labels.nodes) {
labelsToAdd.add(label.name);
}
}
}
if (labelsToAdd.size) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
labels: Array.from(labelsToAdd),
});
}

View File

@ -25,7 +25,7 @@ jobs:
- name: Upload ESLint report
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: lint-results
path: lint-results

View File

@ -1,18 +0,0 @@
name: Auto Comment Merge Conflicts
on: push
permissions:
pull-requests: write
jobs:
auto-comment-merge-conflicts:
runs-on: ubuntu-latest
steps:
- uses: codytseng/auto-comment-merge-conflicts@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
comment-body: "Hey there, there is a merge conflict, can you take a look?"
wait-ms: 3000
max-retries: 5
label-name: "🚨 merge conflict"
ignore-authors: dependabot,otherAuthor

View File

@ -2,6 +2,7 @@ name: "Next.js Bundle Analysis"
on:
workflow_call:
workflow_dispatch:
push:
branches:
- main
@ -27,14 +28,14 @@ jobs:
npx -p nextjs-bundle-analysis@0.5.0 report
- name: Upload bundle
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: bundle
path: apps/web/.next/analyze/__bundle_analysis.json
- name: Download base branch bundle stats
uses: dawidd6/action-download-artifact@v2
if: success() && github.event.number
if: success()
with:
workflow: nextjs-bundle-analysis.yml
branch: ${{ github.event.pull_request.base.ref }}
@ -54,7 +55,7 @@ jobs:
# Either of these arguments can be changed or removed by editing the `nextBundleAnalysis`
# entry in your package.json file.
- name: Compare with base branch bundle
if: success() && github.event.number
if: success()
run: |
cd apps/web
ls -laR .next/analyze/base && npx -p nextjs-bundle-analysis compare
@ -68,10 +69,10 @@ jobs:
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
echo ::set-output name=body::$body
echo "{body}=${body}" >> $GITHUB_OUTPUT
- name: Find Comment
uses: peter-evans/find-comment@v1
uses: peter-evans/find-comment@v2
if: success() && github.event.number
id: fc
with:
@ -79,14 +80,14 @@ jobs:
body-includes: "<!-- __NEXTJS_BUNDLE_@calcom/web -->"
- name: Create Comment
uses: peter-evans/create-or-update-comment@v1.4.4
uses: peter-evans/create-or-update-comment@v3
if: success() && github.event.number && steps.fc.outputs.comment-id == 0
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.get-comment-body.outputs.body }}
- name: Update Comment
uses: peter-evans/create-or-update-comment@v1.4.4
uses: peter-evans/create-or-update-comment@v3
if: success() && github.event.number && steps.fc.outputs.comment-id != 0
with:
issue-number: ${{ github.event.number }}

View File

@ -1,16 +0,0 @@
name: Assign PR team labels
on:
pull_request:
branches:
- main
jobs:
team-labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: equitybee/team-label-action@main
with:
repo-token: ${{ secrets.GH_ACCESS_TOKEN }}
organization-name: calcom
ignore-labels: "app-store, ai, authentication, automated-testing, billing, bookings, caldav, calendar-apps, ci, console, crm-apps, docs, documentation, emails, embeds, event-types, i18n, impersonation, manual-testing, ui, performance, ops-stack, organizations, public-api, routing-forms, seats, teams, webhooks, workflows, zapier"

View File

@ -4,9 +4,6 @@ on:
pull_request_target:
branches:
- main
paths-ignore:
- "**.md"
- ".github/CODEOWNERS"
merge_group:
workflow_dispatch:
@ -15,15 +12,21 @@ concurrency:
cancel-in-progress: true
jobs:
login:
runs-on: ubuntu-latest
steps:
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
changes:
name: Detect changes
runs-on: buildjet-4vcpu-ubuntu-2204
permissions:
pull-requests: read
outputs:
app-store: ${{ steps.filter.outputs.app-store }}
embed: ${{ steps.filter.outputs.embed }}
embed-react: ${{ steps.filter.outputs.embed-react }}
has-files-requiring-all-checks: ${{ steps.filter.outputs.has-files-requiring-all-checks }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
@ -31,78 +34,83 @@ jobs:
id: filter
with:
filters: |
app-store:
- 'apps/web/**'
- 'packages/app-store/**'
- 'playwright.config.ts'
embed:
- 'apps/web/**'
- 'packages/embeds/**'
- 'playwright.config.ts'
embed-react:
- 'apps/web/**'
- 'packages/embeds/**'
- 'playwright.config.ts'
has-files-requiring-all-checks:
- "!(**.md|.github/CODEOWNERS)"
type-check:
name: Type check
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/check-types.yml
secrets: inherit
test:
name: Unit tests
uses: ./.github/workflows/test.yml
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/unit-tests.yml
secrets: inherit
lint:
name: Linters
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/lint.yml
secrets: inherit
build:
name: Production build
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/production-build.yml
secrets: inherit
build-without-database:
name: Production build (without database)
needs: [changes]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/production-build-without-database.yml
secrets: inherit
e2e:
name: E2E tests
needs: [changes, lint, build]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e.yml
secrets: inherit
e2e-app-store:
name: E2E App Store tests
needs: [changes, lint, build]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-app-store.yml
secrets: inherit
e2e-embed:
name: E2E embeds tests
needs: [changes, lint, build]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-embed.yml
secrets: inherit
e2e-embed-react:
name: E2E React embeds tests
needs: [changes, lint, build]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/e2e-embed-react.yml
secrets: inherit
analyze:
needs: build
name: Analyze Build
needs: [changes, build]
if: ${{ needs.changes.outputs.has-files-requiring-all-checks == 'true' }}
uses: ./.github/workflows/nextjs-bundle-analysis.yml
secrets: inherit
required:
needs: [lint, type-check, test, build, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
needs: [changes, lint, type-check, test, build, e2e, e2e-embed, e2e-embed-react, e2e-app-store]
if: always()
runs-on: buildjet-4vcpu-ubuntu-2204
steps:
- name: fail if conditional jobs failed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')
if: needs.changes.outputs.has-files-requiring-all-checks == 'true' && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled'))
run: exit 1

82
.github/workflows/pre-release.yml vendored Normal file
View File

@ -0,0 +1,82 @@
name: Pre-release checks
on:
workflow_dispatch:
jobs:
changes:
name: Detect changes
runs-on: buildjet-4vcpu-ubuntu-2204
permissions:
pull-requests: read
outputs:
app-store: ${{ steps.filter.outputs.app-store }}
embed: ${{ steps.filter.outputs.embed }}
embed-react: ${{ steps.filter.outputs.embed-react }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
app-store:
- 'apps/web/**'
- 'packages/app-store/**'
- 'playwright.config.ts'
embed:
- 'apps/web/**'
- 'packages/embeds/**'
- 'playwright.config.ts'
embed-react:
- 'apps/web/**'
- 'packages/embeds/**'
- 'playwright.config.ts'
lint:
name: Linters
uses: ./.github/workflows/lint.yml
secrets: inherit
build:
name: Production build
uses: ./.github/workflows/production-build.yml
secrets: inherit
e2e:
name: E2E tests
needs: [changes, lint, build]
uses: ./.github/workflows/e2e.yml
secrets: inherit
e2e-app-store:
name: E2E App Store tests
needs: [changes, lint, build]
uses: ./.github/workflows/e2e-app-store.yml
secrets: inherit
e2e-embed:
name: E2E embeds tests
needs: [changes, lint, build]
uses: ./.github/workflows/e2e-embed.yml
secrets: inherit
e2e-embed-react:
name: E2E React embeds tests
needs: [changes, lint, build]
uses: ./.github/workflows/e2e-embed-react.yml
secrets: inherit
build-without-database:
name: Production build (without database)
uses: ./.github/workflows/production-build-without-database.yml
secrets: inherit
required:
needs: [e2e, e2e-app-store, e2e-embed, e2e-embed-react, build-without-database]
if: always()
runs-on: buildjet-4vcpu-ubuntu-2204
steps:
- name: fail if conditional jobs failed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')
run: exit 1

View File

@ -9,6 +9,10 @@ env:
DATABASE_URL: ${{ secrets.CI_DATABASE_URL }}
E2E_TEST_APPLE_CALENDAR_EMAIL: ${{ secrets.E2E_TEST_APPLE_CALENDAR_EMAIL }}
E2E_TEST_APPLE_CALENDAR_PASSWORD: ${{ secrets.E2E_TEST_APPLE_CALENDAR_PASSWORD }}
E2E_TEST_CALCOM_QA_EMAIL: ${{ secrets.E2E_TEST_CALCOM_QA_EMAIL }}
E2E_TEST_CALCOM_QA_PASSWORD: ${{ secrets.E2E_TEST_CALCOM_QA_PASSWORD }}
E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS: ${{ secrets.E2E_TEST_CALCOM_QA_GCAL_CREDENTIALS }}
E2E_TEST_CALCOM_GCAL_KEYS: ${{ secrets.E2E_TEST_CALCOM_GCAL_KEYS }}
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: ${{ vars.CI_GOOGLE_LOGIN_ENABLED }}
NEXTAUTH_SECRET: ${{ secrets.CI_NEXTAUTH_SECRET }}

View File

@ -44,5 +44,5 @@ jobs:
with:
header: pr-title-lint-error
message: |
Thank you for following the naming conventions! 🙏 Feel free to join our [discord](https://go.cal.com/discord) and post your PR link to [collect XP and win prizes!](https://cal.com/blog/community-incentives)
Thank you for following the naming conventions! 🙏 Feel free to join our [discord](https://go.cal.com/discord) and post your PR link.

View File

@ -11,7 +11,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=6144"' >> $GITHUB_ENV
- uses: ./.github/actions/yarn-install
# Should be an 8GB machine as per https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
- run: yarn test

View File

@ -1,27 +0,0 @@
name: "Welcome new contributors"
on:
issues:
types: opened
pull_request:
types: opened
permissions:
pull-requests: write
issues: write
jobs:
welcome-message:
name: Welcoming New Users
runs-on: ubuntu-latest
timeout-minutes: 10
if: github.event.action == 'opened'
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: |-
Thank you for making your first Pull Request and taking the time to improve Cal.com ! ❤️🎉
Feel free to join our [discord](https://go.cal.com/discord) and post your PR link to [collect XP and win prizes!](https://cal.com/blog/community-incentives)
issue-message: |
Thank you for opening your first issue, one of our team members will review it as soon as it possible. ❤️🎉

View File

@ -2,7 +2,7 @@
"typescript.tsdk": "node_modules/typescript/lib",
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"typescript.preferences.importModuleSpecifier": "non-relative",
"spellright.language": ["en"],

View File

@ -1,15 +1,15 @@
diff --git a/index.cjs b/index.cjs
index b645707a3549fc298508726e404243499bbed499..f34b0891e99b275a9218e253f303f43d31ef3f73 100644
index c83f700ae9998cd87b4c2d66ecbb2ad3d7b4603c..76a2200b57f0b9243e2c61464d578b67746ad5a4 100644
--- a/index.cjs
+++ b/index.cjs
@@ -13,8 +13,8 @@ function withMetadataArgument(func, _arguments) {
// https://github.com/babel/babel/issues/2212#issuecomment-131827986
// An alternative approach:
// https://www.npmjs.com/package/babel-plugin-add-module-exports
-exports = module.exports = min.parsePhoneNumberFromString
-exports['default'] = min.parsePhoneNumberFromString
+// exports = module.exports = min.parsePhoneNumberFromString
+// exports['default'] = min.parsePhoneNumberFromString
// `parsePhoneNumberFromString()` named export is now considered legacy:
// it has been promoted to a default export due to being too verbose.
// https://github.com/babel/babel/issues/2212#issuecomment-131827986
// An alternative approach:
// https://www.npmjs.com/package/babel-plugin-add-module-exports
-exports = module.exports = min.parsePhoneNumberFromString
-exports['default'] = min.parsePhoneNumberFromString
+// exports = module.exports = min.parsePhoneNumberFromString
+// exports['default'] = min.parsePhoneNumberFromString
// `parsePhoneNumberFromString()` named export is now considered legacy:
// it has been promoted to a default export due to being too verbose.

View File

@ -2,7 +2,18 @@
Contributions are what makes the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
- Before jumping into a PR be sure to search [existing PRs](https://github.com/calcom/cal.com/pulls) or [issues](https://github.com/calcom/cal.com/issues) for an open or closed item that relates to your submission.
## House rules
- Before submitting a new issue or PR, check if it already exists in [issues](https://github.com/calcom/cal.com/issues) or [PRs](https://github.com/calcom/cal.com/pulls).
- GitHub issues: take note of the `🚨 needs approval` label.
- **For Contributors**:
- Feature Requests: Wait for a core member to approve and remove the `🚨 needs approval` label before you start coding or submit a PR.
- Bugs, Security, Performance, Documentation, etc.: You can start coding immediately, even if the `🚨 needs approval` label is present. This label mainly concerns feature requests.
- **Our Process**:
- Issues from non-core members automatically receive the `🚨 needs approval` label.
- We greatly value new feature ideas. To ensure consistency in the product's direction, they undergo review and approval.
## Priorities

37
PRIVACY.md Normal file
View File

@ -0,0 +1,37 @@
## PRIVACY POLICY
Last updated January 28, 2024
### Introduction
This is the privacy notice of MaroCalendar, a personal calendar booking service that is only used by me, Gustavo Maronato, to manage my personal and work calendars, and allow you to book events with me. Here, you'll find a description of how and why I might collect, store, and use your information when you book an event with me using this service.
The service is located at [https://cal.maronato.dev](https://cal.maronato.dev).
### Questions or concerns?
Reading this privacy notice will help you understand your privacy rights and choices. If you do not agree with my policies and practices, please do not access or book an event with me using this service.
## SUMMARY OF KEY POINTS
### What personal information do I process?
When you choose to book an event with me, you provide me with your name and email address.
### Do I process any sensitive personal information?
I do not process sensitive personal information.
### Do I receive any information from third parties?
I do not receive any information from third parties.
### How do I process your information?
When you book an event with me, I use your name and email address to send you an email with a calendar invite to the event you booked.
### In what situations and with which parties do I share personal information?
The information you submit is used to create a booking between myself and you. I do not share your information with any third parties.
### How do I keep your information safe?
I use reasonable and appropriate security measures to protect your personal information from loss, misuse, and unauthorized access, disclosure, alteration, and destruction.
### What are your rights?
You can cancel your booking at any time by clicking the link in the confirmation email you received when you booked the event.
### Google Calendar
I use a Google Calendar oAuth integration to automatically display to you what are my free time slots and manage the events you book on my calendar. You do not interact with this integration and you are not allowed to use your Google account to add this integration to your Google Calendar. This integration is only used by me to manage my calendar and is not shared with anyone else.

View File

@ -7,7 +7,7 @@
<h3 align="center">Cal.com (formerly Calendso)</h3>
<p align="center">
The open-source Calendly alternative.
The open-source Calendly successor.
<br />
<a href="https://cal.com"><strong>Learn more »</strong></a>
<br />
@ -50,7 +50,7 @@
# Scheduling infrastructure for absolutely everyone
The open source Calendly alternative. You are in charge
The open source Calendly successor. You are in charge
of your own data, workflow, and appearance.
Calendly and other scheduling tools are awesome. It made our lives massively easier. We're using it for business meetings, seminars, yoga classes, and even calls with our families. However, most tools are very limited in terms of control and customization.
@ -122,7 +122,7 @@ Here is what you need to be able to run Cal.com.
### Setup
1. Clone the repo into a public GitHub repository (or fork https://github.com/calcom/cal.com/fork). If you plan to distribute the code, keep the source code public to comply with [AGPLv3](https://github.com/calcom/cal.com/blob/main/LICENSE). To clone in a private repository, [acquire a commercial license](https://cal.com/sales))
1. Clone the repo into a public GitHub repository (or fork https://github.com/calcom/cal.com/fork). If you plan to distribute the code, keep the source code public to comply with [AGPLv3](https://github.com/calcom/cal.com/blob/main/LICENSE). To clone in a private repository, [acquire a commercial license](https://cal.com/sales)
```sh
git clone https://github.com/calcom/cal.com.git
@ -147,7 +147,7 @@ Here is what you need to be able to run Cal.com.
- Duplicate `.env.example` to `.env`
- Use `openssl rand -base64 32` to generate a key and add it under `NEXTAUTH_SECRET` in the `.env` file.
- Use `openssl rand -base64 24` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file.
- Use `openssl rand -base64 32` to generate a key and add it under `CALENDSO_ENCRYPTION_KEY` in the `.env` file.
5. Setup Node
If your Node version does not meet the project's requirements as instructed by the docs, "nvm" (Node Version Manager) allows using Node at the version required by the project:
@ -216,12 +216,11 @@ echo 'NEXT_PUBLIC_DEBUG=1' >> .env
If you don't want to create a local DB. Then you can also consider using services like railway.app or render.
- [Setup postgres DB with railway.app](https://arctype.com/postgres/setup/railway-postgres)
- [Setup postgres DB with railway.app](https://docs.railway.app/guides/postgresql)
- [Setup postgres DB with render](https://render.com/docs/databases)
1. Copy and paste your `DATABASE_URL` from `.env` to `.env.appStore`.
1. Set a 32 character random string in your `.env` file for the `CALENDSO_ENCRYPTION_KEY` (You can use a command like `openssl rand -base64 24` to generate one).
1. Set up the database using the Prisma schema (found in `packages/prisma/schema.prisma`)
In a development environment, run:
@ -555,6 +554,10 @@ following
[Follow these steps](./packages/app-store/zoho-bigin/)
### Obtaining Pipedrive Client ID and Secret
[Follow these steps](./packages/app-store/pipedrive-crm/)
## Workflows
### Setting up SendGrid for Email reminders
@ -597,8 +600,6 @@ Distributed under the [AGPLv3 License](https://github.com/calcom/cal.com/blob/ma
Special thanks to these amazing projects which help power Cal.com:
[<img src="https://cal.com/powered-by-vercel.svg">](https://vercel.com/?utm_source=calend-so&utm_campaign=oss)
- [Vercel](https://vercel.com/?utm_source=calend-so&utm_campaign=oss)
- [Next.js](https://nextjs.org/)
- [Day.js](https://day.js.org/)

117
TERMS-OF-SERVICE.md Normal file
View File

@ -0,0 +1,117 @@
Terms of Service
----------------
Effective date: 01/28/2024
Introduction
------------
These are the terms of service for my personal calendar booking service, MaroCalendar. You may use this service to book events with me by providing your name, email address, and date/time preferences.
These Terms of Service (“Terms”, “Terms of Service”) govern your use of this service located at https://cal.maronato.dev operated by Gustavo Maronato.
You can also find it's privacy policy here https://git.maronato.dev/maronato/cal/src/branch/main/PRIVACY.md
And the source code here https://git.maronato.dev/maronato/cal
If you do not agree with (or cannot comply with) these terms, then you may not use the Service.
Thank you for being responsible.
Communications
--------------
By using this service to book an event with me, you agree to receive an email with the calendar invite. You may also receive a reminder email before the event, or a confirmation email if you reschedule or cancel the event.
Purchases
---------
There are no purchases on this service. You may use it to book events with me, but you will not be charged for it.
Contests, Sweepstakes and Promotions
------------------------------------
There are no contests, sweepstakes, or promotions on this service.
Subscriptions
-------------
There is no subscription on this service.
Fee Changes
-----------
There are no fees on this service.
Refunds
-------
This is a free service, so there are no refunds.
Content
-------
Our Service allows you to create an event with me by providing your name and email address. You are responsible for that information that you submit on or through Service, including its legality, reliability, and appropriateness.
By posting Content on or through Service, You represent and warrant that: (i) Content is yours (you own it) and/or you have the right to use it, and (ii) that the posting of your Content on or through Service does not violate the privacy rights, publicity rights, copyrights, contract rights or any other rights of any person or entity. I reserve the right to not meet with you.
Prohibited Uses
---------------
You may use Service only for lawful purposes and in accordance with Terms. You agree not to use Service:
* In any way that violates any applicable national or international law or regulation.
* For the purpose of exploiting, harming, or attempting to exploit or harm minors in any way by exposing them to inappropriate content or otherwise.
* To transmit, or procure the sending of, any advertising or promotional material, including any “junk mail”, “chain letter,” “spam,” or any other similar solicitation.
* To impersonate or attempt to impersonate Company, a Company employee, another user, or any other person or entity.
* In any way that infringes upon the rights of others, or in any way is illegal, threatening, fraudulent, or harmful, or in connection with any unlawful, illegal, fraudulent, or harmful purpose or activity.
* To engage in any other conduct that restricts or inhibits anyones use or enjoyment of Service, or which, as determined by us, may harm or offend Company or users of Service or expose them to liability.
Additionally, you agree not to:
* Use Service in any manner that could disable, overburden, damage, or impair Service or interfere with any other partys use of Service, including their ability to engage in real time activities through Service.
* Use any robot, spider, or other automatic device, process, or means to access Service for any purpose, including monitoring or copying any of the material on Service.
* Use any manual process to monitor or copy any of the material on Service or for any other unauthorized purpose without our prior written consent.
* Use any device, software, or routine that interferes with the proper working of Service.
* Introduce any viruses, trojan horses, worms, logic bombs, or other material which is malicious or technologically harmful.
* Attempt to gain unauthorized access to, interfere with, damage, or disrupt any parts of Service, the server on which Service is stored, or any server, computer, or database connected to Service.
* Attack Service via a denial-of-service attack or a distributed denial-of-service attack.
* Take any action that may damage or falsify Company rating.
* Otherwise attempt to interfere with the proper working of Service.
Analytics
---------
There is no analytics on this service.
No Use By Minors
----------------
Service is intended only for access and use by individuals at least eighteen (18) years old. By accessing or using any of Company, you warrant and represent that you are at least eighteen (18) years of age and with the full authority, right, and capacity to enter into this agreement and abide by all of the terms and conditions of Terms. If you are not at least eighteen (18) years old, you are prohibited from both the access and usage of Service.
Accounts
--------
You cannot create an account on this service. The only account that exists is mine.
Changes To Service
------------------
I reserve the right to withdraw or amend this Service, and any service or material I provide via Service, in my sole discretion without notice. I will not be liable if for any reason all or any part of Service is unavailable at any time or for any period. From time to time, I may restrict access to some parts of Service, or the entire Service, to visitors.
Amendments To Terms
-------------------
I may amend Terms at any time by posting the amended terms on this site. It is your responsibility to review these Terms periodically.
Acknowledgement
---------------
BY USING SERVICE OR OTHER SERVICES PROVIDED BY ME, YOU ACKNOWLEDGE THAT YOU HAVE READ THESE TERMS OF SERVICE AND AGREE TO BE BOUND BY THEM.
Contact Me
----------
If you have any questions about these terms of service, please contact me:
By email: support@maronato.dev

4
__checks__/README.md Normal file
View File

@ -0,0 +1,4 @@
# Checkly Tests
Run as `yarn checkly test`
Deploy the tests as `yarn checkly deploy`

View File

@ -0,0 +1,75 @@
import type { Page } from "@playwright/test";
import { test, expect } from "@playwright/test";
test.describe("Org", () => {
// Because these pages involve next.config.js rewrites, it's better to test them on production
test.describe("Embeds - i.cal.com", () => {
test("Org Profile Page should be embeddable", async ({ page }) => {
const response = await page.goto("https://i.cal.com/embed");
expect(response?.status()).toBe(200);
await page.screenshot({ path: "screenshot.jpg" });
await expectPageToBeServerSideRendered(page);
});
test("Org User(Peer) Page should be embeddable", async ({ page }) => {
const response = await page.goto("https://i.cal.com/peer/embed");
expect(response?.status()).toBe(200);
await expect(page.locator("text=Peer Richelsen")).toBeVisible();
await expectPageToBeServerSideRendered(page);
});
test("Org User Event(peer/meet) Page should be embeddable", async ({ page }) => {
const response = await page.goto("https://i.cal.com/peer/meet/embed");
expect(response?.status()).toBe(200);
await expect(page.locator('[data-testid="decrementMonth"]')).toBeVisible();
await expect(page.locator('[data-testid="incrementMonth"]')).toBeVisible();
await expectPageToBeServerSideRendered(page);
});
test("Org Team Profile(/sales) page should be embeddable", async ({ page }) => {
const response = await page.goto("https://i.cal.com/sales/embed");
expect(response?.status()).toBe(200);
await expect(page.locator("text=Cal.com Sales")).toBeVisible();
await expectPageToBeServerSideRendered(page);
});
test("Org Team Event page(/sales/hippa) should be embeddable", async ({ page }) => {
const response = await page.goto("https://i.cal.com/sales/hipaa/embed");
expect(response?.status()).toBe(200);
await expect(page.locator('[data-testid="decrementMonth"]')).toBeVisible();
await expect(page.locator('[data-testid="incrementMonth"]')).toBeVisible();
await expectPageToBeServerSideRendered(page);
});
});
test.describe("Dynamic Group Booking", () => {
test("Dynamic Group booking link should load", async ({ page }) => {
const users = [
{
username: "peer",
name: "Peer Richelsen",
},
{
username: "bailey",
name: "Bailey Pumfleet",
},
];
const response = await page.goto(`http://i.cal.com/${users[0].username}+${users[1].username}`);
expect(response?.status()).toBe(200);
expect(await page.locator('[data-testid="event-title"]').textContent()).toBe("Dynamic");
expect(await page.locator('[data-testid="event-meta"]').textContent()).toContain(users[0].name);
expect(await page.locator('[data-testid="event-meta"]').textContent()).toContain(users[1].name);
// 2 users and 1 for the organization(2+1)
expect((await page.locator('[data-testid="event-meta"] [data-testid="avatar"]').all()).length).toBe(3);
});
});
});
// This ensures that the route is actually mapped to a page that is using withEmbedSsr
async function expectPageToBeServerSideRendered(page: Page) {
expect(
await page.evaluate(() => {
return window.__NEXT_DATA__.props.pageProps.isEmbed;
})
).toBe(true);
}

View File

@ -83,6 +83,10 @@
"NEXT_PUBLIC_TEAM_IMPERSONATION": {
"description": "Set the following value to true if you wish to enable Team Impersonation",
"value": "false"
},
"NEXT_PUBLIC_AVAILABILITY_SCHEDULE_INTERVAL": {
"description": "Control time intervals on a user's Schedule availability",
"value": "15"
}
},
"scripts": {

View File

@ -48,17 +48,21 @@ Here is the full architecture:
### Email Router
To expose the AI app, run `ngrok http 3005` (or the AI app's port number) in a new terminal. You may need to install [nGrok](https://ngrok.com/).
To expose the AI app, you can use either [Tunnelmole](https://github.com/robbie-cahill/tunnelmole-client), an open source tunnelling tool; or [nGrok](https://ngrok.com/), a popular closed source tunnelling tool.
For Tunnelmole, run `tmole 3005` (or the AI app's port number) in a new terminal. Please replace `3005` with the port number if it is different. In the output, you'll see two URLs, one http and a https (we recommend using the https url for privacy and security). To install Tunnelmole, use `curl -O https://install.tunnelmole.com/8dPBw/install && sudo bash install`. (On Windows, download [tmole.exe](https://tunnelmole.com/downloads/tmole.exe))
For nGrok, run `ngrok http 3005` (or the AI app's port number) in a new terminal. You may need to install nGrok first.
To forward incoming emails to the serverless function at `/agent`, we use [SendGrid's Inbound Parse](https://docs.sendgrid.com/for-developers/parsing-email/setting-up-the-inbound-parse-webhook).
1. Ensure you have a [SendGrid account](https://signup.sendgrid.com/)
2. Ensure you have an authenticated domain. Go to Settings > Sender Authentication > Authenticate. For DNS host, select `I'm not sure`. Click Next and add your domain, eg. `example.com`. Choose Manual Setup. You'll be given three CNAME records to add to your DNS settings, eg. in [Vercel Domains](https://vercel.com/dashboard/domains). After adding those records, click Verify. To troubleshoot, see the [full instructions](https://docs.sendgrid.com/ui/account-and-settings/how-to-set-up-domain-authentication).
3. Authorize your domain for email with MX records: one with name `[your domain].com` and value `mx.sendgrid.net.`, and another with name `bounces.[your domain].com` and value `feedback-smtp.us-east-1.amazonses.com`, both with priority `10` if prompted.
3. Authorize your domain for email with MX records: one with name `[your domain].com` and value `mx.sendgrid.net.`, and another with name `bounces.[your domain].com` and value `feedback-smtp.us-east-1.amazonses.com`. Set the priority to `10` if prompted.
4. Go to Settings > [Inbound Parse](https://app.sendgrid.com/settings/parse) > Add Host & URL. Choose your authenticated domain.
5. In the Destination URL field, use the nGrok URL from above along with the path, `/api/receive`, and one param, `parseKey`, which lives in [this app's .env](/apps/ai/.env.example) under `PARSE_KEY`. The full URL should look like `https://abc.ngrok.io/api/receive?parseKey=ABC-123`.
5. In the Destination URL field, use the Tunnelmole or ngrok URL from above along with the path, `/api/receive`, and one param, `parseKey`, which lives in [this app's .env](/apps/ai/.env.example) under `PARSE_KEY`. The full URL should look like `https://abc.tunnelmole.net/api/receive?parseKey=ABC-123` or `https://abc.ngrok.io/api/receive?parseKey=ABC-123`.
6. Activate "POST the raw, full MIME message".
7. Send an email to `[anyUsername]@example.com`. You should see a ping on the nGrok listener and server.
7. Send an email to `[anyUsername]@example.com`. You should see a ping on the Tunnelmole or ngrok listener and server.
8. Adjust the logic in [receive/route.ts](/apps/ai/src/app/api/receive/route.ts), save to hot-reload, and send another email to test the behaviour.
Please feel free to improve any part of this architecture!

View File

@ -0,0 +1,4 @@
export function isValidBase64Image(input: string): boolean {
const regex = /^data:image\/[^;]+;base64,(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
return regex.test(input);
}

View File

@ -26,6 +26,7 @@ const schemaAvailabilityCreateParams = z
startTime: z.date().or(z.string()),
endTime: z.date().or(z.string()),
days: z.array(z.number()).optional(),
date: z.date().or(z.string()).optional(),
})
.strict();
@ -34,6 +35,7 @@ const schemaAvailabilityEditParams = z
startTime: z.date().or(z.string()).optional(),
endTime: z.date().or(z.string()).optional(),
days: z.array(z.number()).optional(),
date: z.date().or(z.string()).optional(),
})
.strict();

View File

@ -3,7 +3,6 @@ import { z } from "zod";
import { _DestinationCalendarModel as DestinationCalendar } from "@calcom/prisma/zod";
export const schemaDestinationCalendarBaseBodyParams = DestinationCalendar.pick({
credentialId: true,
integration: true,
externalId: true,
eventTypeId: true,
@ -15,7 +14,6 @@ const schemaDestinationCalendarCreateParams = z
.object({
integration: z.string(),
externalId: z.string(),
credentialId: z.number(),
eventTypeId: z.number().optional(),
bookingId: z.number().optional(),
userId: z.number().optional(),
@ -47,5 +45,4 @@ export const schemaDestinationCalendarReadPublic = DestinationCalendar.pick({
eventTypeId: true,
bookingId: true,
userId: true,
credentialId: true,
});

View File

@ -60,6 +60,7 @@ export const schemaEventTypeBaseBodyParams = EventType.pick({
successRedirectUrl: true,
locations: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
})
.merge(
@ -147,6 +148,7 @@ export const schemaEventTypeReadPublic = EventType.pick({
seatsShowAvailabilityCount: true,
bookingFields: true,
bookingLimits: true,
onlyShowFirstAvailableSlot: true,
durationLimits: true,
}).merge(
z.object({

View File

@ -21,7 +21,16 @@ export const schemaSchedulePublic = z
.merge(
z.object({
availability: z
.array(Availability.pick({ id: true, eventTypeId: true, days: true, startTime: true, endTime: true }))
.array(
Availability.pick({
id: true,
eventTypeId: true,
date: true,
days: true,
startTime: true,
endTime: true,
})
)
.transform((v) =>
v.map((item) => ({
...item,

View File

@ -4,6 +4,7 @@ import { checkUsername } from "@calcom/lib/server/checkUsername";
import { _UserModel as User } from "@calcom/prisma/zod";
import { iso8601 } from "@calcom/prisma/zod-utils";
import { isValidBase64Image } from "~/lib/utils/isValidBase64Image";
import { timeZone } from "~/lib/validations/shared/timeZone";
// @note: These are the ONLY values allowed as weekStart. So user don't introduce bad data.
@ -91,7 +92,7 @@ export const schemaUserBaseBodyParams = User.pick({
// Here we can both require or not (adding optional or nullish) and also rewrite validations for any value
// for example making weekStart only accept weekdays as input
const schemaUserEditParams = z.object({
email: z.string().email(),
email: z.string().email().toLowerCase(),
username: usernameSchema,
weekStart: z.nativeEnum(weekdays).optional(),
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
@ -106,13 +107,14 @@ const schemaUserEditParams = z.object({
.optional()
.nullable(),
locale: z.nativeEnum(locales).optional().nullable(),
avatar: z.string().refine(isValidBase64Image).optional(),
});
// @note: These are the values that are editable via PATCH method on the user Model,
// merging both BaseBodyParams with RequiredParams, and omiting whatever we want at the end.
const schemaUserCreateParams = z.object({
email: z.string().email(),
email: z.string().email().toLowerCase(),
username: usernameSchema,
weekStart: z.nativeEnum(weekdays).optional(),
brandColor: z.string().min(4).max(9).regex(/^#/).optional(),
@ -128,6 +130,7 @@ const schemaUserCreateParams = z.object({
.nullable(),
locale: z.nativeEnum(locales).optional(),
createdDate: iso8601.optional(),
avatar: z.string().refine(isValidBase64Image).optional(),
});
// @note: These are the values that are editable via PATCH method on the user Model,

View File

@ -1,6 +1,8 @@
const { withAxiom } = require("next-axiom");
const { withSentryConfig } = require("@sentry/nextjs");
module.exports = withAxiom({
const plugins = [withAxiom];
const nextConfig = {
transpilePackages: [
"@calcom/app-store",
"@calcom/core",
@ -66,4 +68,15 @@ module.exports = withAxiom({
],
};
},
});
};
if (!!process.env.NEXT_PUBLIC_SENTRY_DSN) {
nextConfig["sentry"] = {
autoInstrumentServerFunctions: true,
hideSourceMaps: true,
};
plugins.push(withSentryConfig);
}
module.exports = () => plugins.reduce((acc, next) => next(acc), nextConfig);

View File

@ -13,6 +13,7 @@
"lint": "eslint . --ignore-path .gitignore",
"lint:fix": "eslint . --ext .ts,.js,.tsx,.jsx --fix",
"start": "PORT=3002 next start",
"docker-start-api": "PORT=80 next start",
"type-check": "tsc --pretty --noEmit"
},
"devDependencies": {
@ -29,7 +30,7 @@
"@calcom/lib": "*",
"@calcom/prisma": "*",
"@calcom/trpc": "*",
"@sentry/nextjs": "^7.20.0",
"@sentry/nextjs": "^7.73.0",
"bcryptjs": "^2.4.3",
"memory-cache": "^0.2.0",
"next": "^13.4.6",

View File

@ -6,18 +6,44 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
async function authMiddleware(req: NextApiRequest) {
const { userId, prisma, isAdmin, query } = req;
if (isAdmin) {
return;
}
const { id } = schemaQueryIdParseInt.parse(query);
const userWithBookings = await prisma.user.findUnique({
const userWithBookingsAndTeamIds = await prisma.user.findUnique({
where: { id: userId },
include: { bookings: true },
include: {
bookings: true,
teams: {
select: {
teamId: true,
},
},
},
});
if (!userWithBookings) throw new HttpError({ statusCode: 404, message: "User not found" });
if (!userWithBookingsAndTeamIds) throw new HttpError({ statusCode: 404, message: "User not found" });
const userBookingIds = userWithBookings.bookings.map((booking) => booking.id);
const userBookingIds = userWithBookingsAndTeamIds.bookings.map((booking) => booking.id);
if (!isAdmin && !userBookingIds.includes(id)) {
throw new HttpError({ statusCode: 401, message: "You are not authorized" });
if (!userBookingIds.includes(id)) {
const teamBookings = await prisma.booking.findUnique({
where: {
id: id,
eventType: {
team: {
id: {
in: userWithBookingsAndTeamIds.teams.map((team) => team.teamId),
},
},
},
},
});
if (!teamBookings) {
throw new HttpError({ statusCode: 401, message: "You are not authorized" });
}
}
}

View File

@ -33,7 +33,7 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
* type: boolean
* description: Delete all remaining bookings
* - in: query
* name: reason
* name: cancellationReason
* required: false
* schema:
* type: string
@ -56,10 +56,6 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
* <td>The provided id didn't correspond to any existing booking.</td>
* </tr>
* <tr>
* <td>Cannot cancel past events</td>
* <td>The provided id matched an existing booking with a past startDate.</td>
* </tr>
* <tr>
* <td>User not found</td>
* <td>The userId did not matched an existing user.</td>
* </tr>

View File

@ -205,8 +205,8 @@ import { defaultResponder } from "@calcom/lib/server";
async function handler(req: NextApiRequest) {
const { userId, isAdmin } = req;
if (isAdmin) req.userId = req.body.userId || userId;
const booking = await handleNewBooking(req);
return booking;
return await handleNewBooking(req);
}
export default defaultResponder(handler);

View File

@ -1,6 +1,12 @@
import type { Prisma } from "@prisma/client";
import type { NextApiRequest } from "next";
import type { z } from "zod";
import { getCalendarCredentials, getConnectedCalendars } from "@calcom/core/CalendarManager";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import type { PrismaClient } from "@calcom/prisma";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import {
schemaDestinationCalendarEditBodyParams,
@ -56,16 +62,251 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
* 404:
* description: Destination calendar not found
*/
type DestinationCalendarType = {
userId?: number | null;
eventTypeId?: number | null;
credentialId: number | null;
};
type UserCredentialType = {
id: number;
appId: string | null;
type: string;
userId: number | null;
user: {
email: string;
} | null;
teamId: number | null;
key: Prisma.JsonValue;
invalid: boolean | null;
};
export async function patchHandler(req: NextApiRequest) {
const { prisma, query, body } = req;
const { userId, isAdmin, prisma, query, body } = req;
const { id } = schemaQueryIdParseInt.parse(query);
const parsedBody = schemaDestinationCalendarEditBodyParams.parse(body);
const assignedUserId = isAdmin ? parsedBody.userId || userId : userId;
validateIntegrationInput(parsedBody);
const destinationCalendarObject: DestinationCalendarType = await getDestinationCalendar(id, prisma);
await validateRequestAndOwnership({ destinationCalendarObject, parsedBody, assignedUserId, prisma });
const userCredentials = await getUserCredentials({
credentialId: destinationCalendarObject.credentialId,
userId: assignedUserId,
prisma,
});
const credentialId = await verifyCredentialsAndGetId({
parsedBody,
userCredentials,
currentCredentialId: destinationCalendarObject.credentialId,
});
// If the user has passed eventTypeId, we need to remove userId from the update data to make sure we don't link it to user as well
if (parsedBody.eventTypeId) parsedBody.userId = undefined;
const destinationCalendar = await prisma.destinationCalendar.update({
where: { id },
data: parsedBody,
data: { ...parsedBody, credentialId },
});
return { destinationCalendar: schemaDestinationCalendarReadPublic.parse(destinationCalendar) };
}
/**
* Retrieves user credentials associated with a given credential ID and user ID and validates if the credentials belong to this user
*
* @param credentialId - The ID of the credential to fetch. If not provided, an error is thrown.
* @param userId - The user ID against which the credentials need to be verified.
* @param prisma - An instance of PrismaClient for database operations.
*
* @returns - An array containing the matching user credentials.
*
* @throws HttpError - If `credentialId` is not provided or no associated credentials are found in the database.
*/
async function getUserCredentials({
credentialId,
userId,
prisma,
}: {
credentialId: number | null;
userId: number;
prisma: PrismaClient;
}) {
if (!credentialId) {
throw new HttpError({
statusCode: 404,
message: `Destination calendar missing credential id`,
});
}
const userCredentials = await prisma.credential.findMany({
where: { id: credentialId, userId },
select: credentialForCalendarServiceSelect,
});
if (!userCredentials || userCredentials.length === 0) {
throw new HttpError({
statusCode: 400,
message: `Bad request, no associated credentials found`,
});
}
return userCredentials;
}
/**
* Verifies the provided credentials and retrieves the associated credential ID.
*
* This function checks if the `integration` and `externalId` properties from the parsed body are present.
* If both properties exist, it fetches the connected calendar credentials using the provided user credentials
* and checks for a matching external ID and integration from the list of connected calendars.
*
* If a match is found, it updates the `credentialId` with the one from the connected calendar.
* Otherwise, it throws an HTTP error with a 400 status indicating an invalid credential ID.
*
* If the parsed body does not contain the necessary properties, the function
* returns the `credentialId` from the destination calendar object.
*
* @param parsedBody - The parsed body from the incoming request, validated against a predefined schema.
* Checked if it contain properties like `integration` and `externalId`.
* @param userCredentials - An array of user credentials used to fetch the connected calendar credentials.
* @param destinationCalendarObject - An object representing the destination calendar. Primarily used
* to fetch the default `credentialId`.
*
* @returns - The verified `credentialId` either from the matched connected calendar in case of updating the destination calendar,
* or the provided destination calendar object in other cases.
*
* @throws HttpError - If no matching connected calendar is found for the given `integration` and `externalId`.
*/
async function verifyCredentialsAndGetId({
parsedBody,
userCredentials,
currentCredentialId,
}: {
parsedBody: z.infer<typeof schemaDestinationCalendarEditBodyParams>;
userCredentials: UserCredentialType[];
currentCredentialId: number | null;
}) {
if (parsedBody.integration && parsedBody.externalId) {
const calendarCredentials = getCalendarCredentials(userCredentials);
const { connectedCalendars } = await getConnectedCalendars(
calendarCredentials,
[],
parsedBody.externalId
);
const eligibleCalendars = connectedCalendars[0]?.calendars?.filter((calendar) => !calendar.readOnly);
const calendar = eligibleCalendars?.find(
(c) => c.externalId === parsedBody.externalId && c.integration === parsedBody.integration
);
if (!calendar?.credentialId)
throw new HttpError({
statusCode: 400,
message: "Bad request, credential id invalid",
});
return calendar?.credentialId;
}
return currentCredentialId;
}
/**
* Validates the request for updating a destination calendar.
*
* This function checks the validity of the provided eventTypeId against the existing destination calendar object
* in the sense that if the destination calendar is not linked to an event type, the eventTypeId can not be provided.
*
* It also ensures that the eventTypeId, if provided, belongs to the assigned user.
*
* @param destinationCalendarObject - An object representing the destination calendar.
* @param parsedBody - The parsed body from the incoming request, validated against a predefined schema.
* @param assignedUserId - The user ID assigned for the operation, which might be an admin or a regular user.
* @param prisma - An instance of PrismaClient for database operations.
*
* @throws HttpError - If the validation fails or inconsistencies are detected in the request data.
*/
async function validateRequestAndOwnership({
destinationCalendarObject,
parsedBody,
assignedUserId,
prisma,
}: {
destinationCalendarObject: DestinationCalendarType;
parsedBody: z.infer<typeof schemaDestinationCalendarEditBodyParams>;
assignedUserId: number;
prisma: PrismaClient;
}) {
if (parsedBody.eventTypeId) {
if (!destinationCalendarObject.eventTypeId) {
throw new HttpError({
statusCode: 400,
message: `The provided destination calendar can not be linked to an event type`,
});
}
const userEventType = await prisma.eventType.findFirst({
where: { id: parsedBody.eventTypeId },
select: { userId: true },
});
if (!userEventType || userEventType.userId !== assignedUserId) {
throw new HttpError({
statusCode: 404,
message: `Event type with ID ${parsedBody.eventTypeId} not found`,
});
}
}
if (!parsedBody.eventTypeId) {
if (destinationCalendarObject.eventTypeId) {
throw new HttpError({
statusCode: 400,
message: `The provided destination calendar can only be linked to an event type`,
});
}
if (destinationCalendarObject.userId !== assignedUserId) {
throw new HttpError({
statusCode: 403,
message: `Forbidden`,
});
}
}
}
/**
* Fetches the destination calendar based on the provided ID as the path parameter, specifically `credentialId` and `eventTypeId`.
*
* If no matching destination calendar is found for the provided ID, an HTTP error with a 404 status
* indicating that the desired destination calendar was not found is thrown.
*
* @param id - The ID of the destination calendar to be retrieved.
* @param prisma - An instance of PrismaClient for database operations.
*
* @returns - An object containing details of the matching destination calendar, specifically `credentialId` and `eventTypeId`.
*
* @throws HttpError - If no destination calendar matches the provided ID.
*/
async function getDestinationCalendar(id: number, prisma: PrismaClient) {
const destinationCalendarObject = await prisma.destinationCalendar.findFirst({
where: {
id,
},
select: { userId: true, eventTypeId: true, credentialId: true },
});
if (!destinationCalendarObject) {
throw new HttpError({
statusCode: 404,
message: `Destination calendar with ID ${id} not found`,
});
}
return destinationCalendarObject;
}
function validateIntegrationInput(parsedBody: z.infer<typeof schemaDestinationCalendarEditBodyParams>) {
if (parsedBody.integration && !parsedBody.externalId) {
throw new HttpError({ statusCode: 400, message: "External Id is required with integration value" });
}
if (!parsedBody.integration && parsedBody.externalId) {
throw new HttpError({ statusCode: 400, message: "Integration value is required with external ID" });
}
}
export default defaultResponder(patchHandler);

View File

@ -1,7 +1,9 @@
import type { NextApiRequest } from "next";
import { getCalendarCredentials, getConnectedCalendars } from "@calcom/core/CalendarManager";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import { credentialForCalendarServiceSelect } from "@calcom/prisma/selects/credential";
import {
schemaDestinationCalendarReadPublic,
@ -38,9 +40,6 @@ import {
* externalId:
* type: string
* description: 'The external ID of the integration'
* credentialId:
* type: integer
* description: 'The credential ID it is associated with'
* eventTypeId:
* type: integer
* description: 'The ID of the eventType it is associated with'
@ -65,20 +64,38 @@ async function postHandler(req: NextApiRequest) {
const parsedBody = schemaDestinationCalendarCreateBodyParams.parse(body);
await checkPermissions(req, userId);
const assignedUserId = isAdmin ? parsedBody.userId || userId : userId;
const assignedUserId = isAdmin && parsedBody.userId ? parsedBody.userId : userId;
/* Check if credentialId data matches the ownership and integration passed in */
const credential = await prisma.credential.findFirst({
where: { type: parsedBody.integration, userId: assignedUserId },
select: { id: true, type: true, userId: true },
const userCredentials = await prisma.credential.findMany({
where: {
type: parsedBody.integration,
userId: assignedUserId,
},
select: credentialForCalendarServiceSelect,
});
if (!credential)
if (userCredentials.length === 0)
throw new HttpError({
statusCode: 400,
message: "Bad request, credential id invalid",
});
const calendarCredentials = getCalendarCredentials(userCredentials);
const { connectedCalendars } = await getConnectedCalendars(calendarCredentials, [], parsedBody.externalId);
const eligibleCalendars = connectedCalendars[0]?.calendars?.filter((calendar) => !calendar.readOnly);
const calendar = eligibleCalendars?.find(
(c) => c.externalId === parsedBody.externalId && c.integration === parsedBody.integration
);
if (!calendar?.credentialId)
throw new HttpError({
statusCode: 400,
message: "Bad request, credential id invalid",
});
const credentialId = calendar.credentialId;
if (parsedBody.eventTypeId) {
const eventType = await prisma.eventType.findFirst({
where: { id: parsedBody.eventTypeId, userId: parsedBody.userId },
@ -91,7 +108,9 @@ async function postHandler(req: NextApiRequest) {
parsedBody.userId = undefined;
}
const destination_calendar = await prisma.destinationCalendar.create({ data: { ...parsedBody } });
const destination_calendar = await prisma.destinationCalendar.create({
data: { ...parsedBody, credentialId },
});
return {
destinationCalendar: schemaDestinationCalendarReadPublic.parse(destination_calendar),

View File

@ -2,6 +2,7 @@ import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import { MembershipRole } from "@calcom/prisma/enums";
import { schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransformParseInt";
@ -51,6 +52,7 @@ export async function getHandler(req: NextApiRequest) {
customInputs: true,
team: { select: { slug: true } },
users: true,
hosts: { select: { userId: true, isFixed: true } },
owner: { select: { username: true, id: true } },
children: { select: { id: true, userId: true } },
},
@ -88,7 +90,9 @@ async function checkPermissions<T extends BaseEventTypeCheckPermissions>(
if (req.isAdmin) return true;
if (eventType?.teamId) {
req.query.teamId = String(eventType.teamId);
await canAccessTeamEventOrThrow(req, "MEMBER");
await canAccessTeamEventOrThrow(req, {
in: [MembershipRole.OWNER, MembershipRole.ADMIN, MembershipRole.MEMBER],
});
}
if (eventType?.userId === req.userId) return true; // is owner.
throw new HttpError({ statusCode: 403, message: "Forbidden" });

View File

@ -45,6 +45,7 @@ async function getHandler(req: NextApiRequest) {
customInputs: true,
team: { select: { slug: true } },
users: true,
hosts: { select: { userId: true, isFixed: true } },
owner: { select: { username: true, id: true } },
children: { select: { id: true, userId: true } },
},

View File

@ -3,8 +3,10 @@ import type { NextApiRequest } from "next";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import { MembershipRole } from "@calcom/prisma/client";
import { schemaEventTypeCreateBodyParams, schemaEventTypeReadPublic } from "~/lib/validations/event-type";
import { canUserAccessTeamWithRole } from "~/pages/api/teams/[teamId]/_auth-middleware";
import checkParentEventOwnership from "./_utils/checkParentEventOwnership";
import checkTeamEventEditPermission from "./_utils/checkTeamEventEditPermission";
@ -299,7 +301,7 @@ async function postHandler(req: NextApiRequest) {
data.hosts = { createMany: { data: hosts } };
}
const eventType = await prisma.eventType.create({ data });
const eventType = await prisma.eventType.create({ data, include: { hosts: true } });
return {
event_type: schemaEventTypeReadPublic.parse(eventType),
@ -316,8 +318,20 @@ async function checkPermissions(req: NextApiRequest) {
statusCode: 401,
message: "ADMIN required for `userId`",
});
/* Admin users are required to pass in a userId */
if (isAdmin && !body.userId) throw new HttpError({ statusCode: 400, message: "`userId` required" });
if (
body.teamId &&
!isAdmin &&
!(await canUserAccessTeamWithRole(req.prisma, req.userId, isAdmin, body.teamId, {
in: [MembershipRole.OWNER, MembershipRole.ADMIN],
}))
)
throw new HttpError({
statusCode: 401,
message: "ADMIN required for `teamId`",
});
/* Admin users are required to pass in a userId or teamId */
if (isAdmin && !body.userId && !body.teamId)
throw new HttpError({ statusCode: 400, message: "`userId` or `teamId` required" });
}
export default defaultResponder(postHandler);

View File

@ -1,5 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next";
export default async function CalcomApi(_: NextApiRequest, res: NextApiResponse) {
res.status(201).json({ message: "Welcome to Cal.com API - docs are at https://developer.cal.com/api" });
res.status(200).json({ message: "Welcome to Cal.com API - docs are at https://developer.cal.com/api" });
}

View File

@ -1,5 +1,9 @@
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import type { NextApiRequest, NextApiResponse } from "next";
import dayjs from "@calcom/dayjs";
import { isSupportedTimeZone } from "@calcom/lib/date-fns";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import { createContext } from "@calcom/trpc/server/createContext";
@ -9,10 +13,34 @@ import { getAvailableSlots } from "@calcom/trpc/server/routers/viewer/slots/util
import { TRPCError } from "@trpc/server";
import { getHTTPStatusCodeFromError } from "@trpc/server/http";
// Apply plugins
dayjs.extend(utc);
dayjs.extend(timezone);
async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const input = getScheduleSchema.parse(req.query);
return await getAvailableSlots({ ctx: await createContext({ req, res }), input });
const { usernameList, ...rest } = req.query;
let slugs = usernameList;
if (!Array.isArray(usernameList)) {
slugs = usernameList ? [usernameList] : [];
}
const input = getScheduleSchema.parse({ usernameList: slugs, ...rest });
const timeZoneSupported = input.timeZone ? isSupportedTimeZone(input.timeZone) : false;
const availableSlots = await getAvailableSlots({ ctx: await createContext({ req, res }), input });
const slotsInProvidedTimeZone = timeZoneSupported
? Object.keys(availableSlots.slots).reduce(
(acc: Record<string, { time: string; attendees?: number; bookingUid?: string }[]>, date) => {
acc[date] = availableSlots.slots[date].map((slot) => ({
...slot,
time: dayjs(slot.time).tz(input.timeZone).format(),
}));
return acc;
},
{}
)
: availableSlots;
return slotsInProvidedTimeZone;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (cause) {
if (cause instanceof TRPCError) {

View File

@ -22,7 +22,21 @@ export async function checkPermissions(
role: Prisma.MembershipWhereInput["role"] = MembershipRole.OWNER
) {
const { userId, prisma, isAdmin } = req;
const { teamId } = schemaQueryTeamId.parse(req.query);
const { teamId } = schemaQueryTeamId.parse({
teamId: req.query.teamId,
version: req.query.version,
apiKey: req.query.apiKey,
});
return canUserAccessTeamWithRole(prisma, userId, isAdmin, teamId, role);
}
export async function canUserAccessTeamWithRole(
prisma: NextApiRequest["prisma"],
userId: number,
isAdmin: boolean,
teamId: number,
role: Prisma.MembershipWhereInput["role"] = MembershipRole.OWNER
) {
const args: Prisma.TeamFindFirstArgs = { where: { id: teamId } };
/** If not ADMIN then we check if the actual user belongs to team and matches the required role */
if (!isAdmin) args.where = { ...args.where, members: { some: { userId, role } } };

View File

@ -58,12 +58,44 @@ export async function patchHandler(req: NextApiRequest) {
const { prisma, body, userId } = req;
const data = schemaTeamUpdateBodyParams.parse(body);
const { teamId } = schemaQueryTeamId.parse(req.query);
/** Only OWNERS and ADMINS can edit teams */
const _team = await prisma.team.findFirst({
include: { members: true },
where: { id: teamId, members: { some: { userId, role: { in: ["OWNER", "ADMIN"] } } } },
});
if (!_team) throw new HttpError({ statusCode: 401, message: "Unauthorized: OWNER or ADMIN required" });
const slugAlreadyExists = await prisma.team.findFirst({
where: {
slug: {
mode: "insensitive",
equals: data.slug,
},
},
});
if (slugAlreadyExists && data.slug !== _team.slug)
throw new HttpError({ statusCode: 409, message: "Team slug already exists" });
// Check if parentId is related to this user
if (data.parentId && data.parentId === teamId) {
throw new HttpError({
statusCode: 400,
message: "Bad request: Parent id cannot be the same as the team id.",
});
}
if (data.parentId) {
const parentTeam = await prisma.team.findFirst({
where: { id: data.parentId, members: { some: { userId, role: { in: ["OWNER", "ADMIN"] } } } },
});
if (!parentTeam)
throw new HttpError({
statusCode: 401,
message: "Unauthorized: Invalid parent id. You can only use parent id of your own teams.",
});
}
let paymentUrl;
if (_team.slug === null && data.slug) {
data.metadata = {

View File

@ -56,6 +56,14 @@ async function getHandler(req: NextApiRequest) {
members: { some: { userId } },
},
},
include: {
customInputs: true,
team: { select: { slug: true } },
users: true,
hosts: { select: { userId: true, isFixed: true } },
owner: { select: { username: true, id: true } },
children: { select: { id: true, userId: true } },
},
};
const data = await prisma.eventType.findMany(args);

View File

@ -68,6 +68,18 @@ async function postHandler(req: NextApiRequest) {
}
}
// Check if parentId is related to this user
if (data.parentId) {
const parentTeam = await prisma.team.findFirst({
where: { id: data.parentId, members: { some: { userId, role: { in: ["OWNER", "ADMIN"] } } } },
});
if (!parentTeam)
throw new HttpError({
statusCode: 401,
message: "Unauthorized: Invalid parent id. You can only use parent id of your own teams.",
});
}
// TODO: Perhaps there is a better fix for this?
const cloneData: typeof data & {
metadata: NonNullable<typeof data.metadata> | undefined;

View File

@ -1,5 +1,6 @@
import type { NextApiRequest } from "next";
import { deleteUser } from "@calcom/features/users/lib/userDeletionService";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
@ -41,10 +42,18 @@ export async function deleteHandler(req: NextApiRequest) {
// Here we only check for ownership of the user if the user is not admin, otherwise we let ADMIN's edit any user
if (!isAdmin && query.userId !== req.userId) throw new HttpError({ statusCode: 403, message: "Forbidden" });
const user = await prisma.user.findUnique({ where: { id: query.userId } });
const user = await prisma.user.findUnique({
where: { id: query.userId },
select: {
id: true,
email: true,
metadata: true,
},
});
if (!user) throw new HttpError({ statusCode: 404, message: "User not found" });
await prisma.user.delete({ where: { id: user.id } });
await deleteUser(user);
return { message: `User with id: ${user.id} deleted successfully` };
}

View File

@ -65,6 +65,9 @@ import { schemaUserEditBodyParams, schemaUserReadPublic } from "~/lib/validation
* locale:
* description: The user's locale. Acceptable values are one of [EN, FR, IT, RU, ES, DE, PT, RO, NL, PT_BR, ES_419, KO, JA, PL, AR, IW, ZH_CH, ZH_TW, CS, SR, SV, VI]
* type: string
* avatar:
* description: The user's avatar, in base64 format
* type: string
* examples:
* user:
* summary: An example of USER

View File

@ -60,6 +60,9 @@ import { schemaUserCreateBodyParams } from "~/lib/validations/user";
* locale:
* description: The new user's locale. Acceptable values are one of [EN, FR, IT, RU, ES, DE, PT, RO, NL, PT_BR, ES_419, KO, JA, PL, AR, IW, ZH_CH, ZH_TW, CS, SR, SV, VI]
* type: string
* avatar:
* description: The user's avatar, in base64 format
* type: string
* examples:
* user:
* summary: An example of USER

View File

@ -69,7 +69,12 @@ import { schemaWebhookEditBodyParams, schemaWebhookReadPublic } from "~/lib/vali
export async function patchHandler(req: NextApiRequest) {
const { prisma, query, userId, isAdmin } = req;
const { id } = schemaQueryIdAsString.parse(query);
const { eventTypeId, userId: bodyUserId, ...data } = schemaWebhookEditBodyParams.parse(req.body);
const {
eventTypeId,
userId: bodyUserId,
eventTriggers,
...data
} = schemaWebhookEditBodyParams.parse(req.body);
const args: Prisma.WebhookUpdateArgs = { where: { id }, data };
if (eventTypeId) {
@ -87,6 +92,11 @@ export async function patchHandler(req: NextApiRequest) {
args.data.userId = bodyUserId;
}
if (args.data.eventTriggers) {
const eventTriggersSet = new Set(eventTriggers);
args.data.eventTriggers = Array.from(eventTriggersSet);
}
const result = await prisma.webhook.update(args);
return { webhook: schemaWebhookReadPublic.parse(result) };
}

View File

@ -66,7 +66,12 @@ import { schemaWebhookCreateBodyParams, schemaWebhookReadPublic } from "~/lib/va
*/
async function postHandler(req: NextApiRequest) {
const { userId, isAdmin, prisma } = req;
const { eventTypeId, userId: bodyUserId, ...body } = schemaWebhookCreateBodyParams.parse(req.body);
const {
eventTypeId,
userId: bodyUserId,
eventTriggers,
...body
} = schemaWebhookCreateBodyParams.parse(req.body);
const args: Prisma.WebhookCreateArgs = { data: { id: uuidv4(), ...body } };
// If no event type, we assume is for the current user. If admin we run more checks below...
@ -87,6 +92,11 @@ async function postHandler(req: NextApiRequest) {
args.data.userId = bodyUserId;
}
if (args.data.eventTriggers) {
const eventTriggersSet = new Set(eventTriggers);
args.data.eventTriggers = Array.from(eventTriggersSet);
}
const data = await prisma.webhook.create(args);
return {

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,5 @@
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
});

View File

@ -0,0 +1,6 @@
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
});

View File

@ -8,6 +8,7 @@ import { describe, expect, test, vi } from "vitest";
import dayjs from "@calcom/dayjs";
import sendPayload from "@calcom/features/webhooks/lib/sendPayload";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { buildBooking, buildEventType, buildWebhook } from "@calcom/lib/test/builder";
import prisma from "@calcom/prisma";
@ -148,7 +149,7 @@ describe.skipIf(true)("POST /api/bookings", () => {
expect(res._getStatusCode()).toBe(500);
expect(JSON.parse(res._getData())).toEqual(
expect.objectContaining({
message: "No available users found.",
message: ErrorCode.NoAvailableUsersFound,
})
);
});

7
apps/api/vercel.json Normal file
View File

@ -0,0 +1,7 @@
{
"functions": {
"pages/api/slots/*.ts": {
"memory": 512
}
}
}

View File

@ -8,7 +8,9 @@ pnpm-debug.log*
lerna-debug.log*
node_modules
storybook-static
storybook-static/*
!storybook-static/favicon.ico
!storybook-static/sb-cover.jpg
dist
dist-ssr
*.local

View File

@ -1,76 +0,0 @@
const path = require("path");
module.exports = {
stories: [
"../intro.stories.mdx",
"../../../packages/ui/components/**/*.stories.mdx",
"../../../packages/atoms/**/*.stories.mdx",
"../../../packages/features/**/*.stories.mdx",
"../../../packages/ui/components/**/*.stories.@(js|jsx|ts|tsx)",
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"storybook-addon-rtl-direction",
"storybook-react-i18next",
"storybook-addon-next",
"storybook-addon-next-router",
/*{
name: "storybook-addon-next",
options: {
nextConfigPath: path.resolve(__dirname, "../../web/next.config.js"),
},
},*/
],
framework: "@storybook/react",
core: {
builder: "webpack5",
},
staticDirs: ["../public"],
webpackFinal: async (config, { configType }) => {
config.resolve.fallback = {
fs: false,
assert: false,
buffer: false,
console: false,
constants: false,
crypto: false,
domain: false,
events: false,
http: false,
https: false,
os: false,
path: false,
punycode: false,
process: false,
querystring: false,
stream: false,
string_decoder: false,
sys: false,
timers: false,
tty: false,
url: false,
util: false,
vm: false,
zlib: false,
};
config.module.rules.push({
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true, // Enable modules to help you using className
},
},
],
include: path.resolve(__dirname, "../src"),
});
return config;
},
typescript: { reactDocgen: "react-docgen" },
};

View File

@ -0,0 +1,96 @@
import type { StorybookConfig } from "@storybook/nextjs";
import path, { dirname, join } from "path";
const config: StorybookConfig = {
stories: [
"../intro.stories.mdx",
"../../../packages/ui/components/**/*.stories.mdx", // legacy SB6 stories
"../../../packages/ui/components/**/*.stories.@(js|jsx|ts|tsx)",
"../../../packages/ui/components/**/*.docs.mdx",
"../../../packages/features/**/*.stories.@(js|jsx|ts|tsx)",
"../../../packages/features/**/*.docs.mdx",
"../../../packages/atoms/**/*.stories.@(js|jsx|ts|tsx)",
"../../../packages/atoms/**/*.docs.mdx",
],
addons: [
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@storybook/addon-interactions"),
getAbsolutePath("storybook-addon-rtl-direction"),
getAbsolutePath("storybook-react-i18next"),
],
framework: {
name: getAbsolutePath("@storybook/nextjs") as "@storybook/nextjs",
options: {
// builder: {
// fsCache: true,
// lazyCompilation: true,
// },
},
},
staticDirs: ["../public"],
webpackFinal: async (config, { configType }) => {
config.resolve = config.resolve || {};
config.resolve.fallback = {
fs: false,
assert: false,
buffer: false,
console: false,
constants: false,
crypto: false,
domain: false,
events: false,
http: false,
https: false,
os: false,
path: false,
punycode: false,
process: false,
querystring: false,
stream: false,
string_decoder: false,
sys: false,
timers: false,
tty: false,
url: false,
util: false,
vm: false,
zlib: false,
};
config.module = config.module || {};
config.module.rules = config.module.rules || [];
config.module.rules.push({
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true, // Enable modules to help you using className
},
},
],
include: path.resolve(__dirname, "../src"),
});
return config;
},
typescript: { reactDocgen: "react-docgen" },
docs: {
autodocs: true,
},
};
export default config;
function getAbsolutePath(value) {
return dirname(require.resolve(join(value, "package.json")));
}

View File

@ -1,48 +0,0 @@
import { addDecorator } from "@storybook/react";
import { AppRouterContext } from "next/dist/shared/lib/app-router-context";
import { I18nextProvider } from "react-i18next";
import "../styles/globals.css";
import "../styles/storybook-styles.css";
import i18n from "./i18next";
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
nextRouter: {
pathname: "/",
asPath: "/",
query: {},
push() {},
Provider: AppRouterContext.Provider,
},
globals: {
locale: "en",
locales: {
en: "English",
fr: "Français",
},
},
i18n,
};
addDecorator((storyFn) => (
<I18nextProvider i18n={i18n}>
<div style={{ margin: "2rem" }}>{storyFn()}</div>
</I18nextProvider>
));
window.getEmbedNamespace = () => {
const url = new URL(document.URL);
const namespace = url.searchParams.get("embed");
return namespace;
};
window.getEmbedTheme = () => {
return "auto";
};

View File

@ -0,0 +1,73 @@
// adds tooltip context to all stories
import { TooltipProvider } from "@radix-ui/react-tooltip";
import type { Preview } from "@storybook/react";
import React from "react";
import { I18nextProvider } from "react-i18next";
import type { EmbedThemeConfig } from "@calcom/embed-core/src/types";
// adds trpc context to all stories (esp. booker)
import { StorybookTrpcProvider } from "@calcom/ui";
import "../styles/globals.css";
import "../styles/storybook-styles.css";
import i18n from "./i18next";
const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
globals: {
locale: "en",
locales: {
en: "English",
fr: "Français",
},
},
i18n,
nextjs: {
appDirectory: true,
},
},
decorators: [
(Story) => (
<StorybookTrpcProvider>
<TooltipProvider>
<I18nextProvider i18n={i18n}>
<div style={{ margin: "2rem" }}>
<Story />
</div>
</I18nextProvider>
</TooltipProvider>
</StorybookTrpcProvider>
),
],
};
export default preview;
declare global {
interface Window {
getEmbedNamespace: () => string | null;
getEmbedTheme: () => EmbedThemeConfig | null;
}
}
window.getEmbedNamespace = () => {
const url = new URL(document.URL);
const namespace = url.searchParams.get("embed");
return namespace;
};
window.getEmbedTheme = () => {
return "auto";
};

View File

@ -1,6 +1,6 @@
import { ArgsTable } from "@storybook/addon-docs";
import { SortType } from "@storybook/components";
import { PropDescriptor } from "@storybook/store";
import type { SortType } from "@storybook/blocks";
import type { PropDescriptor } from "@storybook/preview-api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ignore storybook addon types component as any so we have to do
type Component = any;

View File

@ -9,10 +9,7 @@ import { Meta } from "@storybook/addon-docs";
library, we will be adding more components as we go along.
</p>
<p>
Our{" "}
<a href="https://www.figma.com/file/9MOufQNLtdkpnDucmNX10R/%E2%9D%96-Cal-DS" target="_blank">
Figma
</a>{" "}
Our <a href="https://www.figma.com/file/9MOufQNLtdkpnDucmNX10R/%E2%9D%96-Cal-DS" target="_blank">Figma</a>
library is available for anyone to view and use. If you have any questions or concerns, please reach out to
the design team.
</p>

View File

@ -3,14 +3,14 @@
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "start-storybook -p 6006",
"build": "build-storybook"
"dev": "storybook dev -p 6006",
"build": "storybook build"
},
"dependencies": {
"@calcom/config": "*",
"@calcom/dayjs": "*",
"@calcom/ui": "*",
"@radix-ui/react-avatar": "^1.0.0",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.0",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.5",
@ -20,23 +20,25 @@
"@radix-ui/react-slider": "^1.0.0",
"@radix-ui/react-switch": "^1.0.0",
"@radix-ui/react-tooltip": "^1.0.0",
"@storybook/addon-docs": "^7.6.3",
"@storybook/blocks": "^7.6.3",
"@storybook/nextjs": "^7.6.3",
"@storybook/preview-api": "^7.6.3",
"next": "^13.4.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook-addon-next-router": "^4.0.2",
"storybook-addon-rtl-direction": "^0.0.19"
},
"devDependencies": {
"@babel/core": "^7.19.6",
"@storybook/addon-actions": "^6.5.13",
"@storybook/addon-essentials": "^6.5.13",
"@storybook/addon-interactions": "^6.5.13",
"@storybook/addon-links": "^6.5.13",
"@storybook/builder-vite": "^0.2.4",
"@storybook/builder-webpack5": "^6.5.13",
"@storybook/manager-webpack5": "^6.5.13",
"@storybook/react": "^6.5.13",
"@storybook/testing-library": "^0.0.13",
"@storybook/addon-actions": "^7.6.3",
"@storybook/addon-designs": "^7.0.7",
"@storybook/addon-essentials": "^7.6.3",
"@storybook/addon-interactions": "^7.6.3",
"@storybook/addon-links": "^7.6.3",
"@storybook/nextjs": "^7.6.3",
"@storybook/react": "^7.6.3",
"@storybook/testing-library": "^0.2.2",
"@types/react": "18.0.26",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^2.2.0",
@ -46,10 +48,9 @@
"postcss": "^8.4.18",
"postcss-pseudo-companion-classes": "^0.1.1",
"rollup-plugin-polyfill-node": "^0.10.2",
"storybook-addon-designs": "^6.3.1",
"storybook-addon-next": "^1.6.9",
"storybook-react-i18next": "^1.1.2",
"tailwindcss": "^3.3.1",
"storybook": "^7.6.3",
"storybook-react-i18next": "^2.0.9",
"tailwindcss": "^3.3.3",
"typescript": "^4.9.4",
"vite": "^4.1.2"
}

View File

@ -197,88 +197,91 @@
@layer {
:root {
/* background */
--cal-bg-emphasis: #e5e7eb;
--cal-bg: white;
--cal-bg-subtle: #f3f4f6;
--cal-bg-muted: #f9fafb;
--cal-bg-inverted: #111827;
--cal-bg-emphasis: hsla(220,13%,91%,1);
--cal-bg: hsla(0,0%,100%,1);
--cal-bg-subtle: hsla(220, 14%, 96%,1);
--cal-bg-muted: hsla(210,20%,98%,1);
--cal-bg-inverted: hsla(0,0%,6%,1);
/* background -> components*/
--cal-bg-info: #dee9fc;
--cal-bg-success: #e2fbe8;
--cal-bg-attention: #fceed8;
--cal-bg-error: #f9e3e2;
--cal-bg-dark-error: #752522;
--cal-bg-info: hsla(218,83%,98%,1);
--cal-bg-success: hsla(134,76%,94%,1);
--cal-bg-attention: hsla(37, 86%, 92%, 1);
--cal-bg-error: hsla(3,66,93,1);
--cal-bg-dark-error: hsla(2, 55%, 30%, 1);
/* Borders */
--cal-border-emphasis: #9ca3af;
--cal-border: #d1d5db;
--cal-border-subtle: #e5e7eb;
--cal-border-muted: #f3f4f6;
--cal-border-error: #aa2e26;
--cal-border-emphasis: hsla(218, 11%, 65%, 1);
--cal-border: hsla(216, 12%, 84%, 1);
--cal-border-subtle: hsla(220, 13%, 91%, 1);
--cal-border-booker: #e5e7eb;
--cal-border-muted: hsla(220, 14%, 96%, 1);
--cal-border-error: hsla(4, 63%, 41%, 1);
/* Content/Text */
--cal-text-emphasis: #111827;
--cal-text: #374151;
--cal-text-subtle: #6b7280;
--cal-text-muted: #9ca3af;
--cal-text-inverted: white;
--cal-text-emphasis: hsla(217, 19%, 27%, 1);
--cal-text: hsla(217, 19%, 27%, 1);
--cal-text-subtle: hsla(220, 9%, 46%, 1);
--cal-text-muted: hsla(218, 11%, 65%, 1);
--cal-text-inverted: hsla(0, 0%, 100%, 1);
/* Content/Text -> components */
--cal-text-info: #253985;
--cal-text-success: #285231;
--cal-text-attention: #73321b;
--cal-text-error: #752522;
--cal-text-info: hsla(228, 56%, 33%, 1);
--cal-text-success: hsla(133, 34%, 24%, 1);
--cal-text-attention: hsla(16, 62%, 28%, 1);
--cal-text-error: hsla(2, 55%, 30%, 1);
/* Brand shinanigans
-> These will be computed for the users theme at runtime.
*/
--cal-brand: #111827;
--cal-brand-emphasis: #101010;
--cal-brand-text: white;
-> These will be computed for the users theme at runtime.
*/
--cal-brand: hsla(221, 39%, 11%, 1);
--cal-brand-emphasis: hsla(0, 0%, 6%, 1);
--cal-brand-text: hsla(0, 0%, 100%, 1);
}
.dark {
/* background */
--cal-bg-emphasis: #2b2b2b;
--cal-bg: #101010;
--cal-bg-subtle: #2b2b2b;
--cal-bg-muted: #1c1c1c;
--cal-bg-inverted: #f3f4f6;
--cal-bg-emphasis: hsla(0, 0%, 32%, 1);
--cal-bg: hsla(0, 0%, 10%, 1);
--cal-bg-subtle: hsla(0, 0%, 18%, 1);
--cal-bg-muted: hsla(0, 0%, 12%, 1);
--cal-bg-inverted: hsla(220, 14%, 96%, 1);
/* background -> components*/
--cal-bg-info: #263fa9;
--cal-bg-success: #306339;
--cal-bg-attention: #8e3b1f;
--cal-bg-error: #8c2822;
--cal-bg-dark-error: #752522;
--cal-bg-info: hsla(228, 56%, 33%, 1);
--cal-bg-success: hsla(133, 34%, 24%, 1);
--cal-bg-attention: hsla(16, 62%, 28%, 1);
--cal-bg-error: hsla(2, 55%, 30%, 1);
--cal-bg-dark-error: hsla(2, 55%, 30%, 1);
/* Borders */
--cal-border-emphasis: #575757;
--cal-border: #444444;
--cal-border-subtle: #2b2b2b;
--cal-border-muted: #1c1c1c;
--cal-border-error: #aa2e26;
--cal-border-emphasis: hsla(0, 0%, 46%, 1);
--cal-border: hsla(0, 0%, 34%, 1);
--cal-border-subtle: hsla(0, 0%, 22%, 1);
--cal-border-booker: hsla(0, 0%, 22%, 1);
--cal-border-muted: hsla(0, 0%, 18%, 1);
--cal-border-error: hsla(4, 63%, 41%, 1);
/* Content/Text */
--cal-text-emphasis: #f3f4f6;
--cal-text: #d6d6d6;
--cal-text-subtle: #757575;
--cal-text-muted: #575757;
--cal-text-inverted: #101010;
--cal-text-emphasis: hsla(240, 20%, 99%, 1);
--cal-text: hsla(0, 0%, 84%, 1);
--cal-text-subtle: hsla(0, 0%, 65%, 1);
--cal-text-muted: hsla(0, 0%, 34%, 1);
--cal-text-inverted: hsla(0, 0%, 10%, 1);
/* Content/Text -> components */
--cal-text-info: #dee9fc;
--cal-text-success: #e2fbe8;
--cal-text-attention: #fceed8;
--cal-text-error: #f9e3e2;
--cal-text-info: hsla(218, 83%, 93%, 1);
--cal-text-success: hsla(134, 76%, 94%, 1);
--cal-text-attention: hsla(37, 86%, 92%, 1);
--cal-text-error: hsla(3, 66%, 93%, 1);
/* Brand shenanigans
-> These will be computed for the users theme at runtime.
*/
--cal-brand: white;
--cal-brand-emphasis: #e1e1e1;
--cal-brand-text: black;
-> These will be computed for the users theme at runtime.
*/
--cal-brand: hsla(0, 0%, 100%, 1);
--cal-brand-emphasis: hsla(218, 11%, 65%, 1);
--cal-brand-text: hsla(0, 0%, 0%,1);
}
}

View File

@ -0,0 +1,80 @@
import { getBucket } from "abTest/utils";
import type { NextMiddleware, NextRequest } from "next/server";
import { NextResponse, URLPattern } from "next/server";
import z from "zod";
const ROUTES: [URLPattern, boolean][] = [
["/event-types", process.env.APP_ROUTER_EVENT_TYPES_ENABLED === "1"] as const,
["/settings/admin/:path*", process.env.APP_ROUTER_SETTINGS_ADMIN_ENABLED === "1"] as const,
["/apps/installed/:category", process.env.APP_ROUTER_APPS_INSTALLED_CATEGORY_ENABLED === "1"] as const,
["/apps/:slug", process.env.APP_ROUTER_APPS_SLUG_ENABLED === "1"] as const,
["/apps/:slug/setup", process.env.APP_ROUTER_APPS_SLUG_SETUP_ENABLED === "1"] as const,
["/apps/categories", process.env.APP_ROUTER_APPS_CATEGORIES_ENABLED === "1"] as const,
["/apps/categories/:category", process.env.APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED === "1"] as const,
["/workflows/:path*", process.env.APP_ROUTER_WORKFLOWS_ENABLED === "1"] as const,
["/settings/teams/:path*", process.env.APP_ROUTER_SETTINGS_TEAMS_ENABLED === "1"] as const,
["/getting-started/:step", process.env.APP_ROUTER_GETTING_STARTED_STEP_ENABLED === "1"] as const,
["/apps", process.env.APP_ROUTER_APPS_ENABLED === "1"] as const,
["/bookings/:status", process.env.APP_ROUTER_BOOKINGS_STATUS_ENABLED === "1"] as const,
["/video/:path*", process.env.APP_ROUTER_VIDEO_ENABLED === "1"] as const,
["/teams", process.env.APP_ROUTER_TEAMS_ENABLED === "1"] as const,
].map(([pathname, enabled]) => [
new URLPattern({
pathname,
}),
enabled,
]);
const FUTURE_ROUTES_OVERRIDE_COOKIE_NAME = "x-calcom-future-routes-override";
const FUTURE_ROUTES_ENABLED_COOKIE_NAME = "x-calcom-future-routes-enabled";
const bucketSchema = z.union([z.literal("legacy"), z.literal("future")]);
export const abTestMiddlewareFactory =
(next: (req: NextRequest) => Promise<NextResponse<unknown>>): NextMiddleware =>
async (req: NextRequest) => {
const response = await next(req);
const { pathname } = req.nextUrl;
const override = req.cookies.has(FUTURE_ROUTES_OVERRIDE_COOKIE_NAME);
const route = ROUTES.find(([regExp]) => regExp.test(req.url)) ?? null;
const enabled = route !== null ? route[1] || override : false;
if (pathname.includes("future") || !enabled) {
return response;
}
const safeParsedBucket = override
? { success: true as const, data: "future" as const }
: bucketSchema.safeParse(req.cookies.get(FUTURE_ROUTES_ENABLED_COOKIE_NAME)?.value);
if (!safeParsedBucket.success) {
// cookie does not exist or it has incorrect value
const bucket = getBucket();
response.cookies.set(FUTURE_ROUTES_ENABLED_COOKIE_NAME, bucket, {
expires: Date.now() + 1000 * 60 * 30,
httpOnly: true,
}); // 30 min in ms
if (bucket === "legacy") {
return response;
}
const url = req.nextUrl.clone();
url.pathname = `future${pathname}/`;
return NextResponse.rewrite(url, response);
}
if (safeParsedBucket.data === "legacy") {
return response;
}
const url = req.nextUrl.clone();
url.pathname = `future${pathname}/`;
return NextResponse.rewrite(url, response);
};

9
apps/web/abTest/utils.ts Normal file
View File

@ -0,0 +1,9 @@
import { AB_TEST_BUCKET_PROBABILITY } from "@calcom/lib/constants";
const cryptoRandom = () => {
return crypto.getRandomValues(new Uint8Array(1))[0] / 0xff;
};
export const getBucket = () => {
return cryptoRandom() * 100 < AB_TEST_BUCKET_PROBABILITY ? "future" : "legacy";
};

View File

@ -0,0 +1,21 @@
import type { GetServerSideProps, GetServerSidePropsContext } from "next";
import { notFound, redirect } from "next/navigation";
export const withAppDir =
<T extends Record<string, any>>(getServerSideProps: GetServerSideProps<T>) =>
async (context: GetServerSidePropsContext): Promise<T> => {
const ssrResponse = await getServerSideProps(context);
if ("redirect" in ssrResponse) {
redirect(ssrResponse.redirect.destination);
}
if ("notFound" in ssrResponse) {
notFound();
}
return {
...ssrResponse.props,
// includes dehydratedState required for future page trpcPropvider
...("trpcState" in ssrResponse.props && { dehydratedState: ssrResponse.props.trpcState }),
};
};

View File

@ -0,0 +1,57 @@
import type { GetServerSidePropsContext } from "next";
import { isNotFoundError } from "next/dist/client/components/not-found";
import { getURLFromRedirectError, isRedirectError } from "next/dist/client/components/redirect";
import { notFound, redirect } from "next/navigation";
import { WEBAPP_URL } from "@calcom/lib/constants";
export type EmbedProps = {
isEmbed?: boolean;
};
export default function withEmbedSsrAppDir<T extends Record<string, any>>(
getData: (context: GetServerSidePropsContext) => Promise<T>
) {
return async (context: GetServerSidePropsContext): Promise<T> => {
const { embed, layout } = context.query;
try {
const props = await getData(context);
return {
...props,
isEmbed: true,
};
} catch (e) {
if (isRedirectError(e)) {
const destinationUrl = getURLFromRedirectError(e);
let urlPrefix = "";
// Get the URL parsed from URL so that we can reliably read pathname and searchParams from it.
const destinationUrlObj = new URL(destinationUrl, WEBAPP_URL);
// If it's a complete URL, use the origin as the prefix to ensure we redirect to the same domain.
if (destinationUrl.search(/^(http:|https:).*/) !== -1) {
urlPrefix = destinationUrlObj.origin;
} else {
// Don't use any prefix for relative URLs to ensure we stay on the same domain
urlPrefix = "";
}
const destinationQueryStr = destinationUrlObj.searchParams.toString();
// Make sure that redirect happens to /embed page and pass on embed query param as is for preserving Cal JS API namespace
const newDestinationUrl = `${urlPrefix}${destinationUrlObj.pathname}/embed?${
destinationQueryStr ? `${destinationQueryStr}&` : ""
}layout=${layout}&embed=${embed}`;
redirect(newDestinationUrl);
}
if (isNotFoundError(e)) {
notFound();
}
throw e;
}
};
}

View File

@ -0,0 +1,8 @@
"use client";
import { createHydrateClient } from "app/_trpc/createHydrateClient";
import superjson from "superjson";
export const HydrateClient = createHydrateClient({
transformer: superjson,
});

View File

@ -0,0 +1,5 @@
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import { createTRPCReact } from "@trpc/react-query";
export const trpc = createTRPCReact<AppRouter>({});

View File

@ -0,0 +1,21 @@
"use client";
import { type DehydratedState, Hydrate } from "@tanstack/react-query";
import { useMemo } from "react";
import type { DataTransformer } from "@trpc/server";
export function createHydrateClient(opts: { transformer?: DataTransformer }) {
return function HydrateClient(props: { children: React.ReactNode; state: DehydratedState }) {
const { state, children } = props;
const transformedState: DehydratedState = useMemo(() => {
if (opts.transformer) {
return opts.transformer.deserialize(state);
}
return state;
}, [state]);
return <Hydrate state={transformedState}>{children}</Hydrate>;
};
}

View File

@ -0,0 +1,4 @@
import type { TRPCContext } from "@calcom/trpc/server/createContext";
import { appRouter } from "@calcom/trpc/server/routers/_app";
export const getServerCaller = (ctx: TRPCContext) => appRouter.createCaller(ctx);

View File

@ -0,0 +1,103 @@
import { type DehydratedState, QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { HydrateClient } from "app/_trpc/HydrateClient";
import { trpc } from "app/_trpc/client";
import { useState } from "react";
import superjson from "superjson";
import { httpBatchLink } from "@calcom/trpc/client/links/httpBatchLink";
import { httpLink } from "@calcom/trpc/client/links/httpLink";
import { loggerLink } from "@calcom/trpc/client/links/loggerLink";
import { splitLink } from "@calcom/trpc/client/links/splitLink";
import { ENDPOINTS } from "@calcom/trpc/react/shared";
export type Endpoint = (typeof ENDPOINTS)[number];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const resolveEndpoint = (links: any) => {
// TODO: Update our trpc routes so they are more clear.
// This function parses paths like the following and maps them
// to the correct API endpoints.
// - viewer.me - 2 segment paths like this are for logged in requests
// - viewer.public.i18n - 3 segments paths can be public or authed
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (ctx: any) => {
const parts = ctx.op.path.split(".");
let endpoint;
let path = "";
if (parts.length == 2) {
endpoint = parts[0] as keyof typeof links;
path = parts[1];
} else {
endpoint = parts[1] as keyof typeof links;
path = parts.splice(2, parts.length - 2).join(".");
}
return links[endpoint]({ ...ctx, op: { ...ctx.op, path } });
};
};
export const TrpcProvider: React.FC<{ children: React.ReactNode; dehydratedState?: DehydratedState }> = ({
children,
dehydratedState,
}) => {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: { queries: { staleTime: 5000 } },
})
);
const url =
typeof window !== "undefined"
? "/api/trpc"
: process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}/api/trpc`
: `${process.env.NEXT_PUBLIC_WEBAPP_URL}/api/trpc`;
const [trpcClient] = useState(() =>
trpc.createClient({
links: [
// adds pretty logs to your console in development and logs errors in production
loggerLink({
enabled: (opts) =>
!!process.env.NEXT_PUBLIC_DEBUG || (opts.direction === "down" && opts.result instanceof Error),
}),
splitLink({
// check for context property `skipBatch`
condition: (op) => !!op.context.skipBatch,
// when condition is true, use normal request
true: (runtime) => {
const links = Object.fromEntries(
ENDPOINTS.map((endpoint) => [
endpoint,
httpLink({
url: `${url}/${endpoint}`,
})(runtime),
])
);
return resolveEndpoint(links);
},
// when condition is false, use batch request
false: (runtime) => {
const links = Object.fromEntries(
ENDPOINTS.map((endpoint) => [
endpoint,
httpBatchLink({
url: `${url}/${endpoint}`,
})(runtime),
])
);
return resolveEndpoint(links);
},
}),
],
transformer: superjson,
})
);
return (
<trpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{dehydratedState ? <HydrateClient state={dehydratedState}>{children}</HydrateClient> : children}
</QueryClientProvider>
</trpc.Provider>
);
};

14
apps/web/app/_types.ts Normal file
View File

@ -0,0 +1,14 @@
export type Params = {
[param: string]: string | string[] | undefined;
};
export type SearchParams = {
[param: string]: string | string[] | undefined;
};
export type PageProps = {
params: Params;
searchParams: SearchParams;
};
export type LayoutProps = { params: Params; children: React.ReactElement };

40
apps/web/app/_utils.tsx Normal file
View File

@ -0,0 +1,40 @@
import { type TFunction } from "i18next";
import { headers } from "next/headers";
import { constructGenericImage } from "@calcom/lib/OgImages";
import { IS_CALCOM, WEBAPP_URL, APP_NAME, SEO_IMG_OGIMG } from "@calcom/lib/constants";
import { getFixedT } from "@calcom/lib/server/getFixedT";
import { preparePageMetadata } from "@lib/metadata";
export const _generateMetadata = async (
getTitle: (t: TFunction<string, undefined>) => string,
getDescription: (t: TFunction<string, undefined>) => string
) => {
const h = headers();
const canonical = h.get("x-pathname") ?? "";
const locale = h.get("x-locale") ?? "en";
const t = await getFixedT(locale, "common");
const title = getTitle(t);
const description = getDescription(t);
const metadataBase = new URL(IS_CALCOM ? "https://cal.com" : WEBAPP_URL);
const image =
SEO_IMG_OGIMG +
constructGenericImage({
title,
description,
});
return preparePageMetadata({
title,
canonical,
image,
description,
siteName: APP_NAME,
metadataBase,
});
};

64
apps/web/app/error.tsx Normal file
View File

@ -0,0 +1,64 @@
"use client";
/**
* Typescript class based component for custom-error
* @link https://nextjs.org/docs/advanced-features/custom-error-page
*/
import type { NextPage } from "next";
import type { ErrorProps } from "next/error";
import React from "react";
import { HttpError } from "@calcom/lib/http-error";
import logger from "@calcom/lib/logger";
import { redactError } from "@calcom/lib/redactError";
import { ErrorPage } from "@components/error/error-page";
type NextError = Error & { digest?: string };
// Ref: https://nextjs.org/docs/app/api-reference/file-conventions/error#props
export type DefaultErrorProps = {
error: NextError;
reset: () => void; // A function to reset the error boundary
};
type AugmentedError = NextError | HttpError | null;
type CustomErrorProps = {
err?: AugmentedError;
statusCode?: number;
message?: string;
} & Omit<ErrorProps, "err" | "statusCode">;
const log = logger.getSubLogger({ prefix: ["[error]"] });
const CustomError: NextPage<DefaultErrorProps> = (props) => {
const { error } = props;
let errorObject: CustomErrorProps = {
message: error.message,
err: error,
};
if (error instanceof HttpError) {
const redactedError = redactError(error);
errorObject = {
statusCode: error.statusCode,
title: redactedError.name,
message: redactedError.message,
err: {
...redactedError,
...error,
},
};
}
// `error.digest` property contains an automatically generated hash of the error that can be used to match the corresponding error in server-side logs
log.debug(`${error?.toString() ?? JSON.stringify(error)}`);
log.info("errorObject: ", errorObject);
return (
<ErrorPage statusCode={errorObject.statusCode} error={errorObject.err} message={errorObject.message} />
);
};
export default CustomError;

View File

@ -0,0 +1,3 @@
import { WithLayout } from "app/layoutHOC";
export default WithLayout({ getLayout: null })<"L">;

View File

@ -0,0 +1,126 @@
import AppPage from "@pages/apps/[slug]/index";
import { Prisma } from "@prisma/client";
import { _generateMetadata } from "app/_utils";
import fs from "fs";
import matter from "gray-matter";
import { notFound } from "next/navigation";
import path from "path";
import { z } from "zod";
import { getAppWithMetadata } from "@calcom/app-store/_appRegistry";
import { getAppAssetFullPath } from "@calcom/app-store/getAppAssetFullPath";
import { APP_NAME, IS_PRODUCTION } from "@calcom/lib/constants";
import prisma from "@calcom/prisma";
const sourceSchema = z.object({
content: z.string(),
data: z.object({
description: z.string().optional(),
items: z
.array(
z.union([
z.string(),
z.object({
iframe: z.object({ src: z.string() }),
}),
])
)
.optional(),
}),
});
export const generateMetadata = async ({ params }: { params: Record<string, string | string[]> }) => {
const { data } = await getPageProps({ params });
return await _generateMetadata(
() => `${data.name} | ${APP_NAME}`,
() => data.description
);
};
export const generateStaticParams = async () => {
try {
const appStore = await prisma.app.findMany({ select: { slug: true } });
return appStore.map(({ slug }) => ({ slug }));
} catch (e: unknown) {
if (e instanceof Prisma.PrismaClientInitializationError) {
// Database is not available at build time, but that's ok we fall back to resolving paths on demand
} else {
throw e;
}
}
return [];
};
const getPageProps = async ({ params }: { params: Record<string, string | string[]> }) => {
if (typeof params?.slug !== "string") {
notFound();
}
const appMeta = await getAppWithMetadata({
slug: params?.slug,
});
const appFromDb = await prisma.app.findUnique({
where: { slug: params.slug.toLowerCase() },
});
const isAppAvailableInFileSystem = appMeta;
const isAppDisabled = isAppAvailableInFileSystem && (!appFromDb || !appFromDb.enabled);
if (!IS_PRODUCTION && isAppDisabled) {
return {
isAppDisabled: true as const,
data: {
...appMeta,
},
};
}
if (!appFromDb || !appMeta || isAppDisabled) {
notFound();
}
const isTemplate = appMeta.isTemplate;
const appDirname = path.join(isTemplate ? "templates" : "", appFromDb.dirName);
const README_PATH = path.join(process.cwd(), "..", "..", `packages/app-store/${appDirname}/DESCRIPTION.md`);
const postFilePath = path.join(README_PATH);
let source = "";
try {
source = fs.readFileSync(postFilePath).toString();
source = source.replace(/{DESCRIPTION}/g, appMeta.description);
} catch (error) {
/* If the app doesn't have a README we fallback to the package description */
console.log(`No DESCRIPTION.md provided for: ${appDirname}`);
source = appMeta.description;
}
const result = matter(source);
const { content, data } = sourceSchema.parse({ content: result.content, data: result.data });
if (data.items) {
data.items = data.items.map((item) => {
if (typeof item === "string") {
return getAppAssetFullPath(item, {
dirName: appMeta.dirName,
isTemplate: appMeta.isTemplate,
});
}
return item;
});
}
return {
isAppDisabled: false as const,
source: { content, data },
data: appMeta,
};
};
export default async function Page({ params }: { params: Record<string, string | string[]> }) {
const pageProps = await getPageProps({ params });
return <AppPage {...pageProps} />;
}
export const dynamic = "force-static";

View File

@ -0,0 +1,36 @@
import SetupPage from "@pages/apps/[slug]/setup";
import { _generateMetadata } from "app/_utils";
import type { GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";
import { notFound, redirect } from "next/navigation";
import { getServerSideProps } from "@calcom/app-store/_pages/setup/_getServerSideProps";
import { APP_NAME } from "@calcom/lib/constants";
export const generateMetadata = async ({ params }: { params: Record<string, string | string[]> }) => {
return await _generateMetadata(
() => `${params.slug} | ${APP_NAME}`,
() => ""
);
};
const getPageProps = async ({ params }: { params: Record<string, string | string[]> }) => {
const req = { headers: headers(), cookies: cookies() };
const result = await getServerSideProps({ params, req } as unknown as GetServerSidePropsContext);
if (!result || "notFound" in result) {
notFound();
}
if ("redirect" in result) {
redirect(result.redirect.destination);
}
return result.props;
};
export default async function Page({ params }: { params: Record<string, string | string[]> }) {
const pageProps = await getPageProps({ params });
return <SetupPage {...pageProps} />;
}

View File

@ -0,0 +1,71 @@
import CategoryPage from "@pages/apps/categories/[category]";
import { Prisma } from "@prisma/client";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { notFound } from "next/navigation";
import z from "zod";
import { getAppRegistry } from "@calcom/app-store/_appRegistry";
import { APP_NAME } from "@calcom/lib/constants";
import prisma from "@calcom/prisma";
import { AppCategories } from "@calcom/prisma/enums";
export const generateMetadata = async () => {
return await _generateMetadata(
() => `${APP_NAME} | ${APP_NAME}`,
() => ""
);
};
export const generateStaticParams = async () => {
const paths = Object.keys(AppCategories);
try {
await prisma.$queryRaw`SELECT 1`;
} catch (e: unknown) {
if (e instanceof Prisma.PrismaClientInitializationError) {
// Database is not available at build time. Make sure we fall back to building these pages on demand
return [];
} else {
throw e;
}
}
return paths.map((category) => ({ category }));
};
const querySchema = z.object({
category: z.nativeEnum(AppCategories),
});
const getPageProps = async ({ params }: { params: Record<string, string | string[]> }) => {
const p = querySchema.safeParse(params);
if (!p.success) {
return notFound();
}
const appQuery = await prisma.app.findMany({
where: {
categories: {
has: p.data.category,
},
},
select: {
slug: true,
},
});
const dbAppsSlugs = appQuery.map((category) => category.slug);
const appStore = await getAppRegistry();
const apps = appStore.filter((app) => dbAppsSlugs.includes(app.slug));
return {
apps,
};
};
// @ts-expect-error getData arg
export default WithLayout({ getData: getPageProps, Page: CategoryPage })<"P">;
export const dynamic = "force-static";

View File

@ -0,0 +1,44 @@
import LegacyPage from "@pages/apps/categories/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { APP_NAME } from "@calcom/lib/constants";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () => {
return await _generateMetadata(
() => `Categories | ${APP_NAME}`,
() => ""
);
};
const getData = async (ctx: GetServerSidePropsContext) => {
const ssr = await ssrInit(ctx);
const session = await getServerSession({ req: ctx.req });
let appStore;
if (session?.user?.id) {
appStore = await getAppRegistryWithCredentials(session.user.id);
} else {
appStore = await getAppRegistry();
}
const categories = appStore.reduce((c, app) => {
for (const category of app.categories) {
c[category] = c[category] ? c[category] + 1 : 1;
}
return c;
}, {} as Record<string, number>);
return {
categories: Object.entries(categories).map(([name, count]) => ({ name, count })),
dehydratedState: ssr.dehydrate(),
};
};
export default WithLayout({ getData, Page: LegacyPage, getLayout: null })<"P">;

View File

@ -0,0 +1,3 @@
import { WithLayout } from "app/layoutHOC";
export default WithLayout({ getLayout: null })<"L">;

View File

@ -0,0 +1,36 @@
import LegacyPage from "@pages/apps/installed/[category]";
import { _generateMetadata } from "app/_utils";
import { notFound } from "next/navigation";
import { z } from "zod";
import { APP_NAME } from "@calcom/lib/constants";
import { AppCategories } from "@calcom/prisma/enums";
const querySchema = z.object({
category: z.nativeEnum(AppCategories),
});
export const generateMetadata = async () => {
return await _generateMetadata(
(t) => `${t("installed_apps")} | ${APP_NAME}`,
(t) => t("manage_your_connected_apps")
);
};
const getPageProps = async ({ params }: { params: Record<string, string | string[]> }) => {
const p = querySchema.safeParse(params);
if (!p.success) {
return notFound();
}
return {
category: p.data.category,
};
};
export default async function Page({ params }: { params: Record<string, string | string[]> }) {
await getPageProps({ params });
return <LegacyPage />;
}

View File

@ -0,0 +1,63 @@
import AppsPage from "@pages/apps";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import type { UserAdminTeams } from "@calcom/features/ee/teams/lib/getUserAdminTeams";
import getUserAdminTeams from "@calcom/features/ee/teams/lib/getUserAdminTeams";
import { APP_NAME } from "@calcom/lib/constants";
import type { AppCategories } from "@calcom/prisma/enums";
import { ssrInit } from "@server/lib/ssr";
export const generateMetadata = async () => {
return await _generateMetadata(
() => `Apps | ${APP_NAME}`,
() => ""
);
};
const getData = async (ctx: GetServerSidePropsContext) => {
const ssr = await ssrInit(ctx);
const session = await getServerSession({ req: ctx.req });
let appStore, userAdminTeams: UserAdminTeams;
if (session?.user?.id) {
userAdminTeams = await getUserAdminTeams({ userId: session.user.id, getUserInfo: true });
appStore = await getAppRegistryWithCredentials(session.user.id, userAdminTeams);
} else {
appStore = await getAppRegistry();
userAdminTeams = [];
}
const categoryQuery = appStore.map(({ categories }) => ({
categories: categories || [],
}));
const categories = categoryQuery.reduce((c, app) => {
for (const category of app.categories) {
c[category] = c[category] ? c[category] + 1 : 1;
}
return c;
}, {} as Record<string, number>);
return {
categories: Object.entries(categories)
.map(([name, count]): { name: AppCategories; count: number } => ({
name: name as AppCategories,
count,
}))
.sort(function (a, b) {
return b.count - a.count;
}),
appStore,
userAdminTeams,
dehydratedState: ssr.dehydrate(),
};
};
export default WithLayout({ getLayout, getData, Page: AppsPage });

View File

@ -0,0 +1,10 @@
import OldPage from "@pages/booking/[uid]";
import withEmbedSsrAppDir from "app/WithEmbedSSR";
import { WithLayout } from "app/layoutHOC";
import { getData } from "../page";
const getEmbedData = withEmbedSsrAppDir(getData);
// @ts-expect-error Type '(context: GetServerSidePropsContext) => Promise<any>' is not assignable to type '(arg: {
export default WithLayout({ getLayout: null, getData: getEmbedData, Page: OldPage });

View File

@ -0,0 +1,204 @@
import OldPage from "@pages/booking/[uid]";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import { z } from "zod";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { getBookingWithResponses } from "@calcom/features/bookings/lib/get-booking";
import { parseRecurringEvent } from "@calcom/lib";
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
import prisma from "@calcom/prisma";
import { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { getRecurringBookings, handleSeatsEventTypeOnBooking, getEventTypesFromDB } from "@lib/booking";
import { ssrInit } from "@server/lib/ssr";
const stringToBoolean = z
.string()
.optional()
.transform((val) => val === "true");
const querySchema = z.object({
uid: z.string(),
email: z.string().optional(),
eventTypeSlug: z.string().optional(),
cancel: stringToBoolean,
allRemainingBookings: stringToBoolean,
changes: stringToBoolean,
reschedule: stringToBoolean,
isSuccessBookingPage: stringToBoolean,
formerTime: z.string().optional(),
seatReferenceUid: z.string().optional(),
});
export const generateMetadata = async () =>
await _generateMetadata(
() => "",
() => ""
);
export const getData = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
const session = await getServerSession(context);
let tz: string | null = null;
let userTimeFormat: number | null = null;
let requiresLoginToUpdate = false;
if (session) {
const user = await ssr.viewer.me.fetch();
tz = user.timeZone;
userTimeFormat = user.timeFormat;
}
const parsedQuery = querySchema.safeParse(context.query);
if (!parsedQuery.success) {
notFound();
}
const { uid, eventTypeSlug, seatReferenceUid } = parsedQuery.data;
const { uid: maybeUid } = await maybeGetBookingUidFromSeat(prisma, uid);
const bookingInfoRaw = await prisma.booking.findFirst({
where: {
uid: maybeUid,
},
select: {
title: true,
id: true,
uid: true,
description: true,
customInputs: true,
smsReminderNumber: true,
recurringEventId: true,
startTime: true,
endTime: true,
location: true,
status: true,
metadata: true,
cancellationReason: true,
responses: true,
rejectionReason: true,
user: {
select: {
id: true,
name: true,
email: true,
username: true,
timeZone: true,
},
},
attendees: {
select: {
name: true,
email: true,
timeZone: true,
},
},
eventTypeId: true,
eventType: {
select: {
eventName: true,
slug: true,
timeZone: true,
},
},
seatsReferences: {
select: {
referenceUid: true,
},
},
},
});
if (!bookingInfoRaw) {
notFound();
}
const eventTypeRaw = !bookingInfoRaw.eventTypeId
? getDefaultEvent(eventTypeSlug || "")
: await getEventTypesFromDB(bookingInfoRaw.eventTypeId);
if (!eventTypeRaw) {
notFound();
}
if (eventTypeRaw.seatsPerTimeSlot && !seatReferenceUid && !session) {
requiresLoginToUpdate = true;
}
const bookingInfo = getBookingWithResponses(bookingInfoRaw);
// @NOTE: had to do this because Server side cant return [Object objects]
// probably fixable with json.stringify -> json.parse
bookingInfo["startTime"] = (bookingInfo?.startTime as Date)?.toISOString() as unknown as Date;
bookingInfo["endTime"] = (bookingInfo?.endTime as Date)?.toISOString() as unknown as Date;
eventTypeRaw.users = !!eventTypeRaw.hosts?.length
? eventTypeRaw.hosts.map((host) => host.user)
: eventTypeRaw.users;
if (!eventTypeRaw.users.length) {
if (!eventTypeRaw.owner) {
notFound();
}
eventTypeRaw.users.push({
...eventTypeRaw.owner,
});
}
const eventType = {
...eventTypeRaw,
periodStartDate: eventTypeRaw.periodStartDate?.toString() ?? null,
periodEndDate: eventTypeRaw.periodEndDate?.toString() ?? null,
metadata: EventTypeMetaDataSchema.parse(eventTypeRaw.metadata),
recurringEvent: parseRecurringEvent(eventTypeRaw.recurringEvent),
customInputs: customInputSchema.array().parse(eventTypeRaw.customInputs),
};
const profile = {
name: eventType.team?.name || eventType.users[0]?.name || null,
email: eventType.team ? null : eventType.users[0].email || null,
theme: (!eventType.team?.name && eventType.users[0]?.theme) || null,
brandColor: eventType.team ? null : eventType.users[0].brandColor || null,
darkBrandColor: eventType.team ? null : eventType.users[0].darkBrandColor || null,
slug: eventType.team?.slug || eventType.users[0]?.username || null,
};
if (bookingInfo !== null && eventType.seatsPerTimeSlot) {
await handleSeatsEventTypeOnBooking(eventType, bookingInfo, seatReferenceUid, session?.user.id);
}
const payment = await prisma.payment.findFirst({
where: {
bookingId: bookingInfo.id,
},
select: {
success: true,
refunded: true,
currency: true,
amount: true,
paymentOption: true,
},
});
return {
themeBasis: eventType.team ? eventType.team.slug : eventType.users[0]?.username,
hideBranding: eventType.team ? eventType.team.hideBranding : eventType.users[0].hideBranding,
profile,
eventType,
recurringBookings: await getRecurringBookings(bookingInfo.recurringEventId),
dehydratedState: ssr.dehydrate(),
dynamicEventName: bookingInfo?.eventType?.eventName || "",
bookingInfo,
paymentStatus: payment,
...(tz && { tz }),
userTimeFormat,
requiresLoginToUpdate,
};
};
// @ts-expect-error Argument of type '{ req: { headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }; }' is not assignable to parameter of type 'GetServerSidePropsContext'.
export default WithLayout({ getLayout: null, getData, Page: OldPage });

View File

@ -0,0 +1,45 @@
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import { z } from "zod";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
import { APP_NAME } from "@calcom/lib/constants";
import { ssgInit } from "@server/lib/ssg";
const validStatuses = ["upcoming", "recurring", "past", "cancelled", "unconfirmed"] as const;
const querySchema = z.object({
status: z.enum(validStatuses),
});
export const generateMetadata = async () =>
await _generateMetadata(
(t) => `${APP_NAME} | ${t("bookings")}`,
() => ""
);
export const generateStaticParams = async () => {
return validStatuses.map((status) => ({ status }));
};
const getData = async (ctx: GetServerSidePropsContext) => {
const parsedParams = querySchema.safeParse(ctx.params);
if (!parsedParams.success) {
notFound();
}
const ssg = await ssgInit(ctx);
return {
status: parsedParams.data.status,
dehydratedState: ssg.dehydrate(),
};
};
export default WithLayout({ getLayout, getData })<"L">;
export const dynamic = "force-static";

View File

@ -0,0 +1 @@
export { default } from "@pages/bookings/[status]";

Some files were not shown because too many files have changed in this diff Show More