Compare commits

...
680 Commits
Author SHA1 Message Date
yu-i-i 9f39fd05e1 Update README.md 2025-01-30 13:23:32 +01:00
yu-i-i 2d1c61650a Refactor authentication code; add OIDC support 2025-01-27 05:16:26 +01:00
yu-i-i 91bebe3cbf Allow adding extra flags to LaTeX compiler through environment variable 2025-01-26 15:53:38 +01:00
yu-i-i 1e407e34e5 Update README.md 2025-01-26 15:53:38 +01:00
yu-i-i 5d2febba7d Enable LDAP and SAML authentication support 2025-01-26 15:53:38 +01:00
yu-i-i 83719f84c2 Enable Symbol Palette 2025-01-26 15:53:38 +01:00
yu-i-i 1fbbfe176f Allow selecting a TeX Live image for a project 2025-01-26 15:53:38 +01:00
Sam Van den Vonder e992cfca64 Enable Sandboxed Compiles feature 2025-01-26 15:53:38 +01:00
yu-i-i b748a664a8 Enable autocomplete of reference keys feature 2025-01-26 15:53:38 +01:00
yu-i-i a7ddd99339 Enable track changes and comments feature 2025-01-26 15:53:37 +01:00
yu-i-i 24fb73810d Redirect non-existing links to Overleaf page 2025-01-26 15:53:37 +01:00
Miguel Serrano 84413c991d Merge pull request #21677 from overleaf/msm-register-hide-sso-login
[web] Hide 'Login with SSO' when accepting SSO group invite

GitOrigin-RevId: fd4c327bbb838209773b4e7b1c41f6e3a355ad8b
2025-01-10 09:06:00 +00:00
Miguel Serrano fe623d2297 Merge pull request #22264 from overleaf/msm-login_support_text-env
[web] Add `OVERLEAF_LOGIN_SUPPORT_TEXT` for CE/SP login pages

GitOrigin-RevId: 7f473b6a3448b4cb73c0c954d0ea1db34b980d6c
2025-01-10 09:05:56 +00:00
Miguel Serrano 0e6318ea0c Merge pull request #22265 from overleaf/msm-blob-url-git-bridge-env
[web] Domain override for git blob URLs from `v1_history`

GitOrigin-RevId: 278f91503a54bff43c0a9f0924939ed43d362281
2025-01-10 09:05:52 +00:00
Miguel Serrano 5f913738a8 Merge pull request #22321 from overleaf/msm-force-flag-delete-user
[web] Fix user deletion in CE/SP when email does not exist

GitOrigin-RevId: 051f822318d63c8a9f50d5e9aeca095f3b37efb4
2025-01-10 09:05:48 +00:00
Jimmy Domagala-Tang 6d5354d7fe Merge pull request #22795 from overleaf/jdt-offline-survey
feat: enable temporary survey hardcoded to only non ds-nav users
GitOrigin-RevId: b96ebb64d5a92d1c2421fc828a1769f31b7d363f
2025-01-10 09:05:40 +00:00
Brian Gough 2ce82fabab Merge pull request #22533 from overleaf/ar-only-use-history-for-blobs-when-enabled
[web] only use history for blobs when enabled

GitOrigin-RevId: 010983e9b29657d4c594e03945dca5700577bf0a
2025-01-10 09:05:32 +00:00
Eric Mc Sween eb1b939f5a Merge pull request #22567 from overleaf/em-collection-method
Add collection method field to Mongo subscriptions

GitOrigin-RevId: 7fffabaecfde8f7da8e05fcedcbbf0b2fdcc70f5
2025-01-10 09:05:25 +00:00
Domagoj Kriskovic a8650b3f0b [web] Fix split test check (#22781)
GitOrigin-RevId: f3ce805fcf1dd79e17264bd134b55fc3dbe59171
2025-01-10 09:05:07 +00:00
Kristina 0db9d88e6f [web] Hide 50 seat option for COP (#22757)
GitOrigin-RevId: cfa418f94f2ba79f5d1af17c6752c828dce87fbe
2025-01-10 09:04:59 +00:00
Domagoj Kriskovic 3e11fffaf0 Add delay on showing "Add comment" tooltip (#22600)
GitOrigin-RevId: eb2f2abc368fdba0e85a5611a4c73e3500b6bbb2
2025-01-10 09:04:55 +00:00
Domagoj Kriskovic 2d57e347aa Ensure track changes is enabled for reviewers when switching roles (#22645)
* Ensure track changes is enabled for reviewers when switching roles

* update track_changes.${userId} if track_changes is an object

GitOrigin-RevId: 3e803f4d475dbb67ff85b30095307ea58a07b2bc
2025-01-10 09:04:51 +00:00
Domagoj Kriskovic 61d300de6a Use owner's reviewer role assigment (#22735)
GitOrigin-RevId: f632ea8c23b5a1f9ac6985922c53f1b6d49e9494
2025-01-10 09:04:46 +00:00
Domagoj Kriskovic 6140201326 [web] Update @codemirror/search dependency (#22764)
* [web] Update @codemirror/search dependency

* Revert "[web] Update @codemirror/search dependency"

This reverts commit 4f7d0f48f625056abae2c3d38c85e8d4bb2f071a.

* update dependency without adding it to web node modules

GitOrigin-RevId: 5977128164ae2e7288862363686a1556b1ba2d4f
2025-01-10 09:04:42 +00:00
Andrew Rumble 813946a693 Merge pull request #22580 from overleaf/ar-migrate-server-ce-scripts
Convert server-ce-scripts module to ES modules

GitOrigin-RevId: 516247b25b5bdbfd89fee4b99a88431097c827de
2025-01-09 09:05:54 +00:00
David d6e763bc57 Merge pull request #22738 from overleaf/dp-new-editor-pdf
Drop in PdfPreview into new editor skeleton

GitOrigin-RevId: c88806904bd2534690a1540d7e39c5f81ab65709
2025-01-09 09:05:47 +00:00
David e9e59bbcc9 Merge pull request #22720 from overleaf/dp-editor-redesign
Editor redesign skeleton page

GitOrigin-RevId: 966c88ac3714e4cc7de3e21951e4e1641bfd6852
2025-01-09 09:05:43 +00:00
Rebeka Dekany 70185ad8a1 Merge pull request #22594 from overleaf/as-kh-group-pricing-2025
[Group Pricing] Update pricing for group plans

GitOrigin-RevId: 0a622bcd5fcd25070dc910823dc547b2342121ec
2025-01-09 09:05:30 +00:00
Rebeka Dekany 65c2adbed0 Merge pull request #22629 from overleaf/rd-recompile-dropdown-close-fix-bs5
[web] Close the Recompile dropdown automatically after item selection

GitOrigin-RevId: 047fdd30990972be07ee2f0572cdf7d7dd3f5584
2025-01-09 09:05:26 +00:00
Miguel Serrano d6f8645e8c Merge pull request #21031 from overleaf/msm-clean-collabratec-tokens
[web] cleanup collabratec tokens

GitOrigin-RevId: 0ad73ca5d4c4c82d79e2ec7119c5b77a83b7086f
2025-01-09 09:05:15 +00:00
Alf Eaton e1f880a62b Wrap dispatchSelectionAndScroll in setTimeout (#22596)
GitOrigin-RevId: 8c2c27acdbbf0e8879978e307ccf952c1be5381e
2025-01-09 09:05:08 +00:00
Alf Eaton 45facc0f78 Call MathJax.typesetClear after typesetting a table cell (#22604)
GitOrigin-RevId: d36236a47815841ee3662f1b9121b4a224d3dada
2025-01-09 09:05:04 +00:00
Alf Eaton aaeac2cd72 Ensure that all callbacks for useEventListener are wrapped in useCallback (#22618)
GitOrigin-RevId: 4a7c409a9720eab04fc17e5111b6a3aeeac6871d
2025-01-09 09:05:00 +00:00
Alf Eaton 49cc7890e4 Upgrade Storybook to 8.4 (#22632)
GitOrigin-RevId: babfbebfceb4ce1614340203610437e5d5d38391
2025-01-09 09:04:56 +00:00
Alf Eaton 47275850fe Ignore another common Non-Error promise rejection error (#22633)
GitOrigin-RevId: a7c8571a6211eeca025f7f6c5dd8970645b911a6
2025-01-09 09:04:52 +00:00
Alf Eaton 823069d13e Remove feedback link from spelling suggestions (#22634)
GitOrigin-RevId: f75dffe5395ad15441aee603c494afdf8488642e
2025-01-09 09:04:47 +00:00
Eric Mc Sween e3485f01da Merge pull request #21472 from overleaf/em-hackathon-mongo-mocks-docker
Do not mock Mongo in unit tests

GitOrigin-RevId: 7a200a4ddc8f91b14e96cf02cb4873c51fc3489a
2025-01-08 09:05:34 +00:00
Jessica Lawshe d511a55466 Merge pull request #22703 from overleaf/jel-cms-sales-contact-form-remove-unused
[web] Remove unused fields from `Element | Sales Contact Form`

GitOrigin-RevId: 7e20ed04ca09b14eeb807eebe569c777f23a17bd
2025-01-08 09:05:30 +00:00
Jessica Lawshe 9f5387384e Merge pull request #22590 from overleaf/jel-card-last-child-spacing
[web] CMS - Remove margin when `last-child` has children

GitOrigin-RevId: a744018027ffce2bee570059757c365ac1b36931
2025-01-08 09:05:25 +00:00
Jessica Lawshe 6292e79253 Merge pull request #22383 from overleaf/jel-cms-btns
[web] CMS - Add ability to adjust `<p>` top margin

GitOrigin-RevId: f85b95e407d8c186141a3e60c7d07a9efa44c4c3
2025-01-08 09:05:17 +00:00
Alf Eaton 3ac1b48d10 Allow context providers to be overridden in ReactContextRoot (#22631)
* Allow providers to be overridden in ReactContextRoot
* Use ReactContextRoot in EditorProviders
* Use ReactContextRoot in ScopeDecorator

GitOrigin-RevId: bb6dab91f3fca843d7563ed812c4ea6f56fb28bb
2025-01-08 09:05:10 +00:00
Jakob Ackermann 70fd6cacbc Merge pull request #22711 from overleaf/jpa-gzip
[history-v1] compress blobs before sending them to AWS

GitOrigin-RevId: 1ca1dda6f36738fbabbf00fdab62b86230b9e4f9
2025-01-08 09:04:57 +00:00
Jakob Ackermann 8171ffafc5 Merge pull request #22710 from overleaf/jpa-fix-tests
[history-v1] fix tests

GitOrigin-RevId: dd16d078a4bfea108e9035c0a83f4fd5c3dd715b
2025-01-08 09:04:52 +00:00
Mathias Jakobsen f89d70f9a8 Merge pull request #22668 from overleaf/ae-deprecated-safari-14
Restore the deprecated browser message

GitOrigin-RevId: 93b49db87893aba7e85da6d831ed446cd66fc10f
2025-01-08 09:04:45 +00:00
Mathias Jakobsen 8b0aae34ed Merge pull request #22592 from overleaf/em-swallowed-error-recurly-wrapper
Do not swallow errors when communicating with Recurly

GitOrigin-RevId: 152f75dce10bd13f0a1655118de2de4f3a03ba08
2025-01-08 09:04:41 +00:00
Mathias Jakobsen 18b8760bbb Merge pull request #22591 from overleaf/em-delete-account
Add blurb about Writefull in the Delete Account modal

GitOrigin-RevId: 3b64a2c66e8c212bcdd6271c78cec43dc2c91192
2025-01-08 09:04:36 +00:00
Kristina 46cc91fac8 [web] plans page spacing updates (#22624)
* make the global seat picker wider to avoid the English label wrapping
* make the plans table take up most of the page
* fixes borders on plans table

GitOrigin-RevId: facd30a860cf270ffbe80052e6fe449201fb9aaa
2025-01-07 09:04:48 +00:00
Kristina 75d3974e11 [web] implement strikethrough for educational discount (#22598)
GitOrigin-RevId: 9cacc3f279c7f441a2e8f1cbdb08f7d49390d447
2025-01-07 09:04:44 +00:00
MoxAmber 301adbc858 Add confirmation disclaimer for educational discounts (#22552)
GitOrigin-RevId: 7a84f047be482c820b71e2d2bf4c5b076e24cfa6
2025-01-07 09:04:40 +00:00
MoxAmberandKristina Hjertberg 18aa1b4e3b [Group Pricing] Add price change warning to cancellation flow (#22640)
* Add price change warning to cancellation flow
* Fixes lint error from translated string
* update pricing effective date

---------

Co-authored-by: Kristina Hjertberg <kristina.hjertberg@overleaf.com>
GitOrigin-RevId: d1b6982ff437d931144feffddcbddd96f5a3405b
2025-01-07 09:04:36 +00:00
Andrew Rumble 2262d03a21 Merge pull request #22648 from overleaf/ar-store-backup-blobs-by-history-id
Use historyId when constructing path for backup

GitOrigin-RevId: 954576b509d5e78511b5008fb7d74e0bc5fa45fd
2024-12-24 09:04:52 +00:00
Andrew Rumble e64e69f539 Merge pull request #22652 from overleaf/ar-handle-filestore-404-when-copying-in-saas
[web] Do not do filestore copy in SAAS

GitOrigin-RevId: 83456ca57f706246a86b997a038968aecfbae4c5
2024-12-24 09:04:48 +00:00
CloudBuild 20c6989074 auto update translation
GitOrigin-RevId: 17b5a70d02f359026ca9371060b0ded2adcb9d2b
2024-12-23 09:04:34 +00:00
CloudBuild 397d7c18b7 auto update translation
GitOrigin-RevId: 514b5b3977f1609074ced18b92c76625056c5bb2
2024-12-20 09:05:29 +00:00
Lucie Germain ee4c8b5fe2 Merge pull request #22630 from overleaf/td-ds-nav-system-messages
Add system messages to DS nav version of project dashboard

GitOrigin-RevId: 85830d58242300a40148190f8a18204666a3065c
2024-12-20 09:05:25 +00:00
CloudBuild 6a8844b673 auto update translation
GitOrigin-RevId: f36b3e4319aa3e290cca9aa78250bf5242be28d4
2024-12-19 09:05:26 +00:00
Rebeka Dekany efc1df2c52 Merge pull request #22535 from overleaf/rd-mongoose-bump-to-7-templates
Upgrade templates service to Mongoose v8.8.3

GitOrigin-RevId: 944aee8a1fd68206d2a4dcae4800d962357f64a4
2024-12-19 09:05:18 +00:00
Rebeka Dekany 0ce29d6efb Merge pull request #22542 from overleaf/ar-promisify-tags-handler
[templates] promisify tags handler

GitOrigin-RevId: 02651db858d9fa50319de0617e2aff1c3c57c752
2024-12-19 09:05:10 +00:00
Tim Down 859527b890 Merge pull request #22599 from overleaf/td-ds-nav-chevron
Hide nav dropdown chevron icon in welcome page

GitOrigin-RevId: df631c2ea13da79be8496b8cfa425e9340894af3
2024-12-19 09:05:05 +00:00
ilkin-overleaf 48c0aaf940 Merge pull request #22578 from overleaf/ii-fl-add-seats-upgrade-plan-link
[web] Add seats "Upgrade my plan" link

GitOrigin-RevId: 7c72101be6b22feee9e3fb2ec119336e0e092ca9
2024-12-19 09:05:01 +00:00
Liangjun Song 7a48061d31 Merge pull request #22584 from overleaf/ls-test-for-group-subscription-upgrade
Add tests for group subscription upgrade

GitOrigin-RevId: 0718dd420930d56602831f127494102045cb6cfc
2024-12-19 09:04:56 +00:00
Tim Down d95df5b486 Merge pull request #22579 from overleaf/td-bs5-dropdown-header-display
Remove flex from dropdown header in BS5

GitOrigin-RevId: 799b99273ed2c69af28a407a23d33628195916e9
2024-12-19 09:04:52 +00:00
Antoine ClausseandTim Down bce3d4df78 Update SurveyNotification style for DS Nav (#22585)
* Hide the "DS nav" survey for users on the default variant

* Create and use `SurveyWidgetDsNav`

* Add link to SurveyWidgetDsNav button

* Revert SurveyNotification changes in the DS Nav mobile view

* Hide DS nav survey via JS rather than CSS

* Remove survey card in DS nav project dashboard mobile view in the short term

* Change sr-only to visually-hidden

* Fix typo

---------

Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com>
GitOrigin-RevId: 6ff91637bcc8ad29c383627c7218f644a7b19d75
2024-12-19 09:04:47 +00:00
Alf Eaton abbac67954 Remove Writefull promo banner from projects dashboard (#22568)
GitOrigin-RevId: 49f95f1317462248f4841882ec0ef0ac23c45fe3
2024-12-19 09:04:42 +00:00
Alf Eaton 9c9ffd8a08 Improve spell check edit tracking (#22577)
GitOrigin-RevId: 237e454b56fc18199bf64087dd3cfb93749b8468
2024-12-19 09:04:37 +00:00
Kristina 7bc9a6673a [web] group tab on plans updates for group pricing (#22485)
* hide discounts
* show updated large groups upsell
* show group member picker
* expand educational discounts to all group plans
* add spacing above group plan prices
* change contact modal trigger to contact sales link
* add dropdown treatment to group tab improvement default treatment

GitOrigin-RevId: 690763361672e248c21198741d8870569411c8c1
2024-12-18 09:06:42 +00:00
Kristina d488791474 [web] Update change plan flow for group-pricing-2025 (#22532)
GitOrigin-RevId: 23f6f5972b1d13b457c7c5e88f508b7cf022469a
2024-12-18 09:06:38 +00:00
Antoine Clausse fce3adc810 [web] Update Navbar icons (Carets and Close) (#22570)
* Use Phosphor icon for navigation close

* Add carets from Phosphor

* Remove CaretUp when expanded (not in design)

* Revert "Remove CaretUp when expanded (not in design)"

This reverts commit 242f295ea18a73aae0e2cf5d2cf0dc1e610dbef9.

* Fixup: Hide the default caret in the desktop view too

* Fixup format after merge

GitOrigin-RevId: 6781028dd50922a017ef2b76fe91c4ff611dd77c
2024-12-18 09:06:34 +00:00
Antoine Clausse 0193d00735 [web] Make the new project dropdown menu scrollable (#22559)
* Make the new project dropdown menu scrollable

* Use CSS variables

GitOrigin-RevId: 9a918f2349cfc74038bde36e48b1060a4de09822
2024-12-18 09:06:30 +00:00
Antoine Clausse 14ba6013ac Replace tags-list dropdown icon to Phosphor ThreeDotsVertical (#22562)
GitOrigin-RevId: 50c70aca162e787eb6ab051ac56c6b226a6c6aa6
2024-12-18 09:06:26 +00:00
Antoine Clausse 19e962876d [web] Replace "scroll-shadow" by "scroll-borders" in the sidebar (#22563)
* Replace "scroll-shadow" by "scroll-borders" in the sidebar

* Set invisible borders to prevent "jumps"

GitOrigin-RevId: b73ec532f28627d1c55dd64cbfabec8a2efb08b2
2024-12-18 09:06:22 +00:00
Antoine Clausse a1e42ff003 [web] Reapply "Update navigation events (navbar menu, new project)" and bugfix (#22576)
* Reapply "[web] Update navigation events (navbar menu, new project) (#22473)"

This reverts commit 134809f73c57d3f019e8158243e1fc74f9f6540a.

* Set the analytics event on the links, not the small contained span (pug)

* Fixup `menu-click` events in pug files: use `trackingKey`, correct event name, ...

* Add `location` prop in NavDropdownMenuItems and ContactUsItem, because they're used in the sidebar too

GitOrigin-RevId: 0bb95f69182268c34929f51121f2d5a2b19c4692
2024-12-18 09:06:18 +00:00
Jessica Lawshe c9f35a2d68 Merge pull request #22586 from overleaf/jel-gallery-header
[web] Fix spacing above gallery

GitOrigin-RevId: f4460b5dc4780566cf8d0d4cda4213840530a275
2024-12-18 09:06:11 +00:00
Jessica Lawshe 2890661d5c Merge pull request #22538 from overleaf/jel-cms-tabs-as-list
[web] CMS - Add support for rendering `Layout | Tab Group` as a linkable list instead of tabs

GitOrigin-RevId: f86e78abd10029085ee8cdf4ffc7dd6e0ffd5300
2024-12-18 09:06:07 +00:00
Jessica Lawshe 2d620952b5 Merge pull request #22469 from overleaf/jel-remove-deprecated-spacing
[web] Remove deprecated row padding options

GitOrigin-RevId: c253be98d14e93123cc4362fa750e27cf5d9d0c3
2024-12-18 09:06:03 +00:00
Jessica Lawshe ae4581d02a Merge pull request #22494 from overleaf/jel-cms-icons
[web] Support all material symbols in CMS icon element

GitOrigin-RevId: 1d65302a8e36a16761e00862acd8cba3cc9adeb5
2024-12-18 09:05:59 +00:00
M Fahru 6daf2bef45 Merge pull request #22082 from overleaf/mf-remove-is-split-test-active
[web] Remove `isSplitTestActive` function since it is no longer used

GitOrigin-RevId: 81f3f61f14bb10d403fa72a61dc4a304c191512f
2024-12-18 09:05:55 +00:00
Eric Mc Sween 659f15d010 Merge pull request #22571 from overleaf/dk-add-comment-mouseup2
Show add comment tooltip on mouse up

GitOrigin-RevId: d12b10c0c3d481a509c19eaacaf8055c2c65ff30
2024-12-18 09:05:47 +00:00
Eric Mc Sween c1360fde7c Merge pull request #22505 from overleaf/em-add-on-checkout
Add an "Add-on:" label to the checkout page for Error Assist

GitOrigin-RevId: c25554b73aa030f880b8d10051247a7cfe5ca3e0
2024-12-18 09:05:43 +00:00
Eric Mc Sween 7cb146765c Merge pull request #22503 from overleaf/em-overleaf-assist
Rename last mentions of Overleaf Assist to Error Assist

GitOrigin-RevId: 83170de1bcf494955138f8ff6484f3fba9c1ea9b
2024-12-18 09:05:39 +00:00
Antoine Clausse 27ea8211f3 Merge pull request #22575 from overleaf/revert-22473-ac-ds-nav-analytics-events
Revert "[web] Update navigation events (navbar menu, new project)"

GitOrigin-RevId: 9608be862e272c29ed92524ae6b8484094e8e0ff
2024-12-18 09:05:35 +00:00
Tim Down 053b84d828 Merge pull request #22557 from overleaf/td-bs5-pdf-detach-height
Copy some <html> and <body> rules from BS3 to fix the detached PDF page

GitOrigin-RevId: 9c14bd4988811b857c8c3516e50589514b400ac1
2024-12-18 09:05:31 +00:00
Andrew Rumble 8417267075 Merge pull request #22188 from overleaf/ar-convert-modules-group-settings-to-es-modules
Convert modules/group-settings to es modules

GitOrigin-RevId: 3f1768fb91148722c0f0c181ab9b5a5a9174deca
2024-12-18 09:05:27 +00:00
Antoine ClausseandIlkin Ismailov c6506d9a2e [web] Update navigation events (navbar menu, new project) (#22473)
* Add project-list-events.ts

* Add event `menu-expand`

* Add event `menu-click`

* Add event `new-project-expand`

* Add event `new-project-click`

* Change `menu-clicked-*` events to "`menu-clicked`+trackingKey"

* Add `SplitTestProvider` to header-footer-react

* Convert to `menu-click` events in pug files

* Add sidebar `menu-expand` events

* Fixup formatting after rebase

* Fixup format after merge

* Get location type from `ExtraSegmentations`

* Replace `any` by `ExtraSegmentations['menu-click']['item']`

Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com>

* Use `string & {}` trick to type `new-project-click.item`

Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com>

* Add `location: 'top-menu'` to Pug events

* Add `menu-expand` tracking event

---------

Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com>
GitOrigin-RevId: c290835c9b92a25a758cec94b49103edcdcdffed
2024-12-18 09:05:23 +00:00
ilkin-overleaf b253d860ff Merge pull request #22554 from overleaf/ii-fl-upgrade-subscription-redirect
[web] FL subscription upgrade error handling

GitOrigin-RevId: 1c9e841ba94cec4aa4de6e91f565cdf75e251b3d
2024-12-18 09:05:16 +00:00
ilkin-overleaf 8e7f1d5e89 Merge pull request #22448 from overleaf/ii-flexible-group-licensing-add-seats-tests
[web] Add seats tests

GitOrigin-RevId: 76fb5edc6eba5579fac2d3e05cd1f64fba16046c
2024-12-18 09:05:12 +00:00
Antoine Clausse df727d64c3 Merge pull request #22548 from overleaf/ac-ds-phosphor-icons-and-splittests-bugfix
[web] Reapply  Use icons from @phosphor-icons/react for the project-list (DS nav)

GitOrigin-RevId: b87767b7c875ff4c081590e7bc0111892c0a1435
2024-12-17 09:05:32 +00:00
Tim Down e68d2e88e0 Merge pull request #22506 from overleaf/td-bs5-ieee-overall-theme-take-2
Always apply overall dark theme with IEEE-branded editor and tear down ieee-stylesheet feature flag, second attempt

GitOrigin-RevId: 311d125a77a46ee3f34769064005b6edea7ce013
2024-12-17 09:05:28 +00:00
Tim Down 79e4b76551 Merge pull request #22222 from overleaf/td-thin-footer-react
Implement thin footer in Bootstrap 5

GitOrigin-RevId: c45f63b3d2536e6266eb55cc95df11b53a6b77ec
2024-12-17 09:05:23 +00:00
Antoine Clausse 0c40841d9f Merge pull request #22547 from overleaf/revert-22517-ac-ds-nav-phosphor-icons
Revert "[web] Use icons from `@phosphor-icons/react` for the project-list (DS-Nav)"

GitOrigin-RevId: 350f5d69a8f575d8ee4e3bd6af46e4e5f7137c7d
2024-12-17 09:05:19 +00:00
Alf Eaton c0cbe51828 Avoid dispatching unnecessary transaction for review panel tooltip (#22524)
* Avoid dispatching unneeded review panel effects
* Remove event listeners

GitOrigin-RevId: 17fec45f660fdd7934aa6ef3202159377902f6a5
2024-12-17 09:05:11 +00:00
Alf Eaton d434a2ba86 Remove toolbar visibility button (#22519)
GitOrigin-RevId: 51084bf6f21a6ecaf9d38dab33a8e1541bf62bc8
2024-12-17 09:05:06 +00:00
Alf Eaton 9b82969e44 Upgrade CodeMirror dependencies (#22489)
GitOrigin-RevId: 77d2773a382ddb8dfa8f3a66bd6f8041720490b3
2024-12-17 09:05:02 +00:00
Antoine ClausseandTim Down bb8bdd04af [web] Use icons from @phosphor-icons/react for the project-list (DS-Nav) (#22517)
* Use icons from `@phosphor-icons/react`

https://phosphoricons.com/

* Add the phosphor Plus icon to the tag list

* Add SignOut icon

* Use Phosphor icon for tags

* Fix icon color when active

* Add offset to dropdown menus so they're positioned like in Figma

---------

Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com>
GitOrigin-RevId: 039e98063d775d0348d227202d5ecd6a0bfb7b65
2024-12-17 09:04:57 +00:00
DavidandDomagoj Kriskovic 362521dd1e Show full edit/review mode dropdown on first load (#22465)
* Show full edit/review mode dropdown on first load

* Remove unneeded import

* rename localstorage value, inline event

---------

Co-authored-by: Domagoj Kriskovic <dom.kriskovic@overleaf.com>
GitOrigin-RevId: 7efb52d4b43588dd1ee8b7a6a5f703166b0c9b3a
2024-12-17 09:04:52 +00:00
DavidandDomagoj Kriskovic 4a8163b3f3 Add new trackedWrite frontend permission for review panel (#22486)
* Add new trackedWrite frontend permission for review panel

* Fix test lint

* Remove comment

* Fix codemirror tests

* hide file actions for reviewer

---------

Co-authored-by: Domagoj Kriskovic <dom.kriskovic@overleaf.com>
GitOrigin-RevId: 6aab5c662287a02750d81b3960bbdd9c98b325db
2024-12-17 09:04:48 +00:00
Kristina 8fa2e9ec96 Merge pull request #22447 from overleaf/kh-group-pricing-faq
[web] add group pricing change FAQ

GitOrigin-RevId: 50bbc097889fb90515fa27dd502c84f5ba3a23db
2024-12-16 09:05:47 +00:00
Antoine Clausse 555af767bd Add hover bg on navbar items (#22525)
GitOrigin-RevId: e220da99962abcaaac568f501875970747cd3d4b
2024-12-16 09:05:42 +00:00
M Fahru c25ee1d786 Merge pull request #22464 from overleaf/mf-add-padding-bottom-login-container
[web] BS5 login page - Add sufficient spacing to prevent cookie banner from covering the bottom text on mobile

GitOrigin-RevId: e5024cf124387b2670211cee8d28ef5e6b4fc85f
2024-12-16 09:05:31 +00:00
M Fahru d238e509c1 Merge pull request #22496 from overleaf/mf-login-register-use-social-button
[web] Use `.btn-social` for all login and register buttons that has icon on it

GitOrigin-RevId: a5590578ebf048b188d9f9ab3551907fdf5fe63d
2024-12-16 09:05:27 +00:00
M Fahru b0a47b6c6d Merge pull request #22467 from overleaf/mf-clean-up-register-styling-bs5
[web] Clean up register and login bs5 code

GitOrigin-RevId: fcdb32d1e1ad7d0fb2862bb2726688780e42fa7c
2024-12-16 09:05:23 +00:00
M Fahru 10e1c5b320 Merge pull request #22460 from overleaf/mf-notification-website-redesign-blue-link-color
[web] Set all link inside notification to use the default blue color for all website-redesigned non-application page

GitOrigin-RevId: d5e598f7b02ff132d9686a010ff55541346f7d2e
2024-12-16 09:05:18 +00:00
Antoine Clausse 90b16e4c8e [web] DS-Nav footer tweaks (#22482)
* Footer tweaks (add border, main-content 100vh)

* Update color to be the same as the sidebar `<hr>`

* Move the border to the larger div so it also separates with the navbar

* Update border color to be the same as the background

* Fixup lint

* Fixup main content padding on mobile view

See https://github.com/overleaf/internal/pull/22186#discussion_r1876087478

* Change the border color to neutral-20

* Use `--border-divider` which is the same color as --neutral-20 (`#e7e9ee`)

* Replace `@media (width >= 768px)` by `@include media-breakpoint-up(md)`

* Replace `min-height: 100dvh` by `min-height: 100%`

GitOrigin-RevId: 426869e9b96a1ee8245c487bb80ff01856521a34
2024-12-16 09:05:14 +00:00
Eric Mc Sween a323a5c915 Merge pull request #22527 from overleaf/revert-22471-em-tracked-deletes-at-same-position
Revert "Improve handling of tracked delete rejections"

GitOrigin-RevId: 444a5a73aa2b93162036dfc463cd76d9c463aadb
2024-12-16 09:05:10 +00:00
Antoine Clausse f2d6c73f75 [web] Update project-list Navbar for mobile (#22478)
* Control if nav items are shown with CSS instead of JS

* Fix navbar style for mobile view

* Update navbar toggle icon to close

* Hide "Projects" nav item from the navbar

* Add separator above the Help menuitem in the mobile navbar

* Adjust sidebar padding: 24px from the logo

GitOrigin-RevId: ba587645f56febc0da798269bd6aa8c2e1639c27
2024-12-16 09:05:02 +00:00
Eric Mc Sween 6737cfa38d Merge pull request #22471 from overleaf/em-tracked-deletes-at-same-position
Improve handling of tracked delete rejections

GitOrigin-RevId: 35857d0a3f739c0531223737b2b649c9e8033157
2024-12-16 09:04:58 +00:00
Domagoj Kriskovic db45323b93 Hide reviewer option from edit-member (#22499)
GitOrigin-RevId: 16f2b51a4856ef0f651b8b7973c34a7529d826cc
2024-12-16 09:04:53 +00:00
Antoine Clausse e5c97f1963 [web] Add box shadows to scrollable part of sidebar (#22400)
* Add box shadows to scrollable part of sidebar

* Fix lint

* Fix `isAtBottom` boolean on Firefox

* Throttle the `scroll` event

* Remove wrong and unnecessary comment

GitOrigin-RevId: 7bcbb7fc860ab32f44203b3ae9ff37a3fed069a8
2024-12-16 09:04:49 +00:00
Brian Gough 6d1a258e7b Merge pull request #22512 from overleaf/bg-fixed-linked-files
use history-v1 for fetching linked files

GitOrigin-RevId: 32c4a35ea8c1f745e0242237c57285b3edbbb984
2024-12-16 09:04:34 +00:00
Miguel Serrano e5cdc768b3 Merge pull request #22507 from overleaf/dependabot-maven-services-git-bridge-org.asynchttpclient-async-http-client-3.0.1
Bump org.asynchttpclient:async-http-client from 2.12.3 to 3.0.1 in /services/git-bridge

GitOrigin-RevId: cc375ff1ad1a3127aad2ac8b2987f1af3b1643b9
2024-12-16 09:04:29 +00:00
Miguel Serrano 303e85a72b Merge pull request #22492 from overleaf/msm-fix-flaky-e2e-jpg-preview
[SP] Wait for document being rendered before editor tests

GitOrigin-RevId: 4afa9b7d225ff19e6c10b061de4eef076bcd9a5d
2024-12-13 09:05:42 +00:00
Jimmy Domagala-Tang 8bda1d5b92 Merge pull request #22500 from overleaf/revert-19302-jdt-institution-buttons-temp
Revert "Jdt institution buttons temp"

GitOrigin-RevId: 751c587e2733ef8b8ef4e3b3c048233c73e214e1
2024-12-13 09:05:37 +00:00
Tim Down b2b398ba0d Merge pull request #22495 from overleaf/revert-22468-td-bs5-ieee-overall-theme
Revert "Always apply overall dark theme with IEEE-branded editor and tear down ieee-stylesheet feature flag"

GitOrigin-RevId: 223b4816b02ba96212ea7e779e16770cd4f16949
2024-12-13 09:05:33 +00:00
Jimmy Domagala-Tang 11de9a366c Merge pull request #19302 from overleaf/jdt-institution-buttons-temp
Jdt institution buttons temp

GitOrigin-RevId: 2b2e93014e2a219a633a7ce09a00033cc1157496
2024-12-13 09:05:28 +00:00
Tim Down 4cd624e6a5 Merge pull request #22468 from overleaf/td-bs5-ieee-overall-theme
Always apply overall dark theme with IEEE-branded editor and tear down ieee-stylesheet feature flag

GitOrigin-RevId: 80d10a911f3a188867db9b825f3ae8413f555b64
2024-12-13 09:05:24 +00:00
Brian Gough 9d4eeeea90 Merge pull request #22488 from overleaf/bg-add-filestore-request-logging
add filestore request logging

GitOrigin-RevId: 0ec5c413f0e88521e1da268699ee2ee281c560f1
2024-12-13 09:05:16 +00:00
ilkin-overleaf 09bbbfbb28 Merge pull request #22479 from overleaf/ii-manage-members-add-more-users-link
[web] Members management flexible licensing

GitOrigin-RevId: 8b0283db95c83c2ae1c0dd4e1e756980c168f152
2024-12-13 09:05:08 +00:00
Brian Gough 000017ecde Merge pull request #22481 from overleaf/bg-fix-blob-redirect-middleware
fix fileToBlobRedirectMiddleware internal redirect

GitOrigin-RevId: 874196d58f8b657d73a8e7f1ea4fef8290d48a10
2024-12-13 09:05:04 +00:00
Andrew Rumble 31e8a908ee Merge pull request #22334 from overleaf/ar-guard-against-integer-like-strings-when-working-with-postgres
[history-v1] Guard against non-postgres projectIds

GitOrigin-RevId: 5bf75c67424297f52f2abd9d0f0f14a0f79f8921
2024-12-13 09:04:59 +00:00
Andrew Rumble a92a37bc3c Merge pull request #22466 from overleaf/ar-backup-files-when-inserting
[history-v1] backup files when inserting

GitOrigin-RevId: e636bce178604978c6d41c083bf671795d20b5a1
2024-12-13 09:04:54 +00:00
Antoine Clausse b165e71ba9 [web] Update footer responsiveness with container queries (#22346)
* Remove padding around the footer

* Use CSS container queries instead of media queries on the full window

Container queries are supported by 92.76%	of web users, which can be an issue.
https://caniuse.com/css-container-queries

Though we do use them in other places

* Use `@supports` to check if `@container` can be used and use mixins

* Add the max sidebar width the fallback media query

* Update the footer responsiveness so we don't affect the default variant

GitOrigin-RevId: bed3e4244f1a97fd84740dcf87fb27c760be91ad
2024-12-12 09:06:09 +00:00
Antoine Clausse 62cfb68c1b [web] Add icon menus in the Sidebar (#22318)
* Add sidebar icons and menus (Help, Account)

* Place the account dropdown menu above the tooltip

* Hide tooltip when dropdown menu is shown

* Fixup tooltip position

* Add Digital Science link

* Add aria-labels on the dropdown toggles

* Update sidebar items spacings

- Add space between notification and DS icons
- Balance margin/padding in the scrollable part

* Revert changing the side of .dev-tool-bar-open-button

* Remove `!important` in link color

* Add Help tooltip

* Revert dropdown-menu z-index change

* Move `AccountMenuItems` to its own file

* Revert "Remove `!important` in link color"

This reverts commit b2de83f815d05cd1e224604d4ca355986ba76b99.

GitOrigin-RevId: 286266ea5348384f2592f748d3ae32c452558988
2024-12-12 09:06:05 +00:00
Jessica Lawshe 650d285105 Merge pull request #22080 from overleaf/jel-grid-padding
[web] Use `spacing-...` variables for row padding options

GitOrigin-RevId: 75aff5c9a2eb72897d5050a25986e532ef276e6c
2024-12-12 09:05:57 +00:00
Jessica Lawshe fc0c46cb2f Merge pull request #22029 from overleaf/jel-visual-with-content
[web] CMS BS5 - Add `Element | Visual with content`

GitOrigin-RevId: 9c1302aec4b1ea4726a07562b276503a7a31a7d8
2024-12-12 09:05:53 +00:00
Jessica Lawshe 15f8e07257 Merge pull request #22025 from overleaf/jel-click-event-interstitial-plans
[web] Add trigger attribute so that event is recorded

GitOrigin-RevId: 15e42297efca9d155442ed4aacbdbf1f4a35e074
2024-12-12 09:05:49 +00:00
M Fahru e99352df3e Merge pull request #22415 from overleaf/mf-bs5-login-migration
[web] Login page bootstrap 5 migration

GitOrigin-RevId: 5a69588e7978456e16a0aaad80d77478121c9481
2024-12-12 09:05:44 +00:00
M Fahru f9536cce52 Merge pull request #22414 from overleaf/mf-fix-styling-bs5-registration
[web] Fix small styling in bs5 register page

GitOrigin-RevId: 2027c79d04f65d1afbea23f23d998bb5d60e092b
2024-12-12 09:05:40 +00:00
M Fahru cacf2dbd73 Merge pull request #22290 from overleaf/as-bs5-homepage
Migrate homepage to Bootstrap 5

GitOrigin-RevId: 02f29964d770f512780c6f71229f246a5939657c
2024-12-12 09:05:36 +00:00
Mathias JakobsenandDavid Powell 1063dabf33 [web+document-updater] Allow appending to documents (#20745)
Co-authored-by: David Powell <david.powell@overleaf.com>
GitOrigin-RevId: f66283926e7da3edf83ada9316c3a001287e1b42
2024-12-12 09:05:31 +00:00
Andrew Rumble 52254b5695 Merge pull request #22459 from overleaf/revert-22392-ar-backup-files-when-inserting
Revert "[history-v1] backup files when inserting"

GitOrigin-RevId: f21d49dbc8909ab93bdde78c321672124bb13697
2024-12-12 09:05:27 +00:00
Antoine ClausseandTim Down 27792199f6 [web] Update project list page main content to DS-nav-bar design (#22307)
* Move some SCSS to project-list-default.scss

* Update project-list-ds-nav.tsx to match design and simplify the SCSS

* Fix survey-notification style: light on the sidebar, dark on the main content

* Replace `withHr` by `useSplitTestContext` hook

* Override the `navbar-btn-padding-h` override.

* Fixup main content padding

Co-authored-by: Tim Down <tim.down@overleaf.com>

* Add padding-top to the logo

* Fixup merges

Add changes from https://github.com/overleaf/internal/pull/22272

---------

Co-authored-by: Tim Down <tim.down@overleaf.com>
GitOrigin-RevId: 8dbc449afbf70388bcf3185413b35234acaad349
2024-12-12 09:05:23 +00:00
Antoine ClausseandTim Down 629579b840 [web] Update project list page layout and sidebar to new design (#22186)
* PoC DS nav project page shell

* Rename files: use `ds-nav` as a suffix

(really just moving code without changes)

* Update NavBar to the new design

* Small updates to project-list-ds-nav.tsx so it gets its basic shape

* Nest `.survey-notification` and `.project-list-sidebar-survey-wrapper` in the default classes to avoid interferences

* Create `SidebarDsNav`

* Add props to sidebar components so they work in both versions

* Update the SCSS code for the sidebar redesign

* Update subheader to "Organize Tags"

* Mute add affiliation font

* Remove `<aside className="project-list-sidebar-react">` and add sidebar max/min widths

* Fixup buttons padding

* Fix tests: add SplitTestProvider

* Fixup sidebar scroll div: add `flex: 1 1 auto`

* Make "Uncategorized" italic

* Update logo to SVG

* Optimize the svg
https://jakearchibald.github.io/svgomg/
9.12k → 4.92k 53.91%

---------

Co-authored-by: Tim Down <158919+timdown@users.noreply.github.com>
GitOrigin-RevId: 3d08b4b80291d9465fae87ffdf0c6a9f6deda554
2024-12-12 09:05:18 +00:00
Andrew Rumble 6404e3047d Merge pull request #22392 from overleaf/ar-backup-files-when-inserting
[history-v1] backup files when inserting

GitOrigin-RevId: 1649b2828899d67ee37c0ac331917c6d5424c803
2024-12-12 09:05:11 +00:00
David f8a1e7c43b Merge pull request #22398 from overleaf/dp-change-edit-mode-ui-part-2
Add ReviewModeSwitcher

GitOrigin-RevId: bfbbdac30530d859da0e8b5673357ba805b100ab
2024-12-12 09:05:06 +00:00
Andrew Rumble e6a2caa088 Merge pull request #22421 from overleaf/ar-pass-created-blob-for-filetree-uploads
[web] Pass createdBlob through for file creation everywhere

GitOrigin-RevId: 880bebd0a55e351a6a61555a46e80faef22db7cb
2024-12-12 09:05:02 +00:00
Domagoj Kriskovic f1c3ddb7c2 Use isReviewerRoleEnabled meta tag (#22437)
GitOrigin-RevId: e2f2529f09936a53087393d8f02968bdb5ea1acc
2024-12-12 09:04:51 +00:00
Domagoj Kriskovic 71a0b48a68 Set track changes state permissions for reviewer role (#22345) (#22436)
* Support for adding reviewer role

* added collaboratorsGetter tests

* emit toggle-track-changes when reviewer is added

* Add reviewer in change privilege level handler

GitOrigin-RevId: 88ec39f2b760b5d1ca6dc3a363df31c087268972
2024-12-12 09:04:46 +00:00
Miguel Serrano 0490a4bab2 Merge pull request #22440 from overleaf/msm-fix-templates-e2e
[SP] Fix templates tests

GitOrigin-RevId: b63279161db2da2c5b482ea61ae3968497e7c1e0
2024-12-11 09:05:04 +00:00
Lucie Germain f42ccd67f7 Merge pull request #22364 from overleaf/lg-server-ce-new-issue-note
New note about creating an issue in Server CE repo

GitOrigin-RevId: c004914eff95e594c5b4ba9e165caddb4deb526b
2024-12-11 09:05:00 +00:00
Jimmy Domagala-Tang a8724ff7a0 Merge pull request #22330 from overleaf/jdt-split-preview-charges
feat: splitting immediate charges into pre and post tax
GitOrigin-RevId: 67c96e7dbc4dbf0d73f62242b9710532f633dbef
2024-12-11 09:04:52 +00:00
Jimmy Domagala-Tang 0fc58be5fa Merge pull request #22410 from overleaf/jdt-enable-assistant-feature-overrides
Enable Error Assist on users w/ feature overrides

GitOrigin-RevId: 6a7359c9e91e1b5dcecf53d79e5975399df1c465
2024-12-11 09:04:48 +00:00
Thomas d8840bfe7f Merge pull request #22433 from overleaf/tm-suspend-users-script
Add script for bulk account suspension

GitOrigin-RevId: 434ac819c12a2a33c26baf963d8d8874b1864928
2024-12-11 09:04:40 +00:00
Eric Mc Sween ea96947df1 Merge pull request #22387 from overleaf/em-error-assist-paywalls
Make paywalls on standalone Error Assist redirect to interstitial page

GitOrigin-RevId: 1c6c0b314ca61af8aca8dc23cdc959fceafa13b2
2024-12-11 09:04:35 +00:00
Eric Mc Sween 5f11200f67 Merge pull request #22386 from overleaf/em-remove-v1-subscription-checks
Remove v1 subscription checks

GitOrigin-RevId: 32962e8a88e98c120c5c58a061f293205c14dc3a
2024-12-11 09:04:31 +00:00
ilkin-overleaf fd89836e9f Merge pull request #22371 from overleaf/ii-remove-sales-contact-form-from-subscription-group-controller
[web] Add seats sales contact

GitOrigin-RevId: a1c5826cc775aa51f201e6cc30a1b2a4dda7ee2b
2024-12-10 13:09:46 +00:00
Domagoj Kriskovic a038f451d4 Revert "Set track changes state permissions for reviewer role (#22345)" (#22431)
This reverts commit 6a03d2355b3fb7d7b755ed1d3ab1a080126cd2dc.

GitOrigin-RevId: 4e962bd9a547a9d6205460c9a8e9a0e835442be4
2024-12-10 13:09:42 +00:00
David f1893fa03a Show coloured squares next to collaborator names (#22406)
* Change font to content-primary

* Add user colour blocks to comments/track changes

* Format

GitOrigin-RevId: a9186e9c7c95dfe134bee2f756245275cfa9ea24
2024-12-10 13:09:37 +00:00
David 97cdc290c3 Adapt review panel header with new reviewer role (#22291)
* Adapt review panel header with new reviewer role

* Remove duplicate css property

* Update position-items

GitOrigin-RevId: a2e8dac0c1d90e6d5b3f13769909cddd69b5db14
2024-12-10 13:09:33 +00:00
David 3433b8ba90 Add border to review panel (#22407)
GitOrigin-RevId: 8b5f683500056c31055597fd85dcb492960a5f6f
2024-12-10 13:09:28 +00:00
David 524d743d6c Double the max lenght of a comment before truncating (#22409)
GitOrigin-RevId: 8c4314d0b3567e7c4bd963dadf2eb698d3df3565
2024-12-10 13:09:24 +00:00
Domagoj Kriskovic db9dba4b7a List projects where user is added as reviewer (#22347)
* Support for adding reviewer role

* added collaboratorsGetter tests

* emit toggle-track-changes when reviewer is added

* List projects where user is added as reviewer

GitOrigin-RevId: 8ec9e59e4c0b65167705b0a56be3e309ef6af3e7
2024-12-10 13:09:19 +00:00
Domagoj Kriskovic 53dc5fbafe Set track changes state permissions for reviewer role (#22345)
* Support for adding reviewer role

* added collaboratorsGetter tests

* emit toggle-track-changes when reviewer is added

* Add reviewer in change privilege level handler

GitOrigin-RevId: 6a03d2355b3fb7d7b755ed1d3ab1a080126cd2dc
2024-12-10 13:09:14 +00:00
Domagoj Kriskovic 576134abde Add isReviewerRoleEnabled meta value (#22402)
GitOrigin-RevId: f7e8a49bfdcc98b3dac83b63fe41752bf01b7885
2024-12-10 13:09:10 +00:00
Alf Eaton 751d9ad7a0 Upgrade PDF.js to v4.9.124 (#22337)
GitOrigin-RevId: c412c6d52dab572c08fe226acd274b6fdff365aa
2024-12-10 13:09:01 +00:00
John Lees-Miller cee0276eef Merge pull request #22418 from overleaf/jlm-spam-safe-length
Reduce spam safe project length

GitOrigin-RevId: 2bb128a24c4ad7630bf1c511d2e23a9bf45072ab
2024-12-10 09:05:29 +00:00
M Fahru c898e3f323 Merge pull request #22304 from overleaf/mf-clean-up-latam-v2-test
[web] Tear down LATAM geo-pricing v2 split test

GitOrigin-RevId: ca379c7ace5600aa31559c82e166c7ea67c6c26d
2024-12-10 09:05:22 +00:00
Domagoj Kriskovic 5a447aa349 [real-time] ensure tc is enabled when reviewer role is used (#22245)
* Support for adding reviewer role

* show reviewer in track changes user list

* added "review" in assertClientCanViewProject

* test if reviewer can read project

* added collaboratorsGetter tests

* eit toggle-track-changes when track changes changes

* [real-time] ensure tc is enabled when reviewer role is used

* use assertClientCanReviewProjectAndDoc, refactor _assertClientCanApplyUpdate

GitOrigin-RevId: 158bd1ff0d4b4977da950134f8ad8b3740855290
2024-12-10 09:05:18 +00:00
Domagoj Kriskovic 13e3a941f4 [real-time] make sure reviewer has permissions to read a project (#22317)
* added "review" in assertClientCanViewProject

* test if reviewer can read project

GitOrigin-RevId: 92a30f8b456bec9f0fc81a1361e454eecff838bd
2024-12-10 09:05:14 +00:00
Andrew Rumble ad8026038c Merge pull request #22397 from overleaf/revert-22320-revert-22213-ar-avoid-duplicate-blob-writes
Revert "Revert "Avoid duplicate blob writes""

GitOrigin-RevId: f6a0083c0edf9ede14dfb52dbf1809a843aa5ff4
2024-12-10 09:05:07 +00:00
Brian Gough 66447f959f Merge pull request #22391 from overleaf/bg-issue22370
Provide fallback in web for requests to file urls

GitOrigin-RevId: 793e8e138a08e28e097ac6dd0503333cc17375ab
2024-12-10 09:05:03 +00:00
ilkin-overleaf bd967ce1df Merge pull request #22379 from overleaf/ls-sync-with-recurly-after-mutation
sync with recurly after mutate subscription

GitOrigin-RevId: 451914f7bde344f82ad4523bee20f1af2297cbd8
2024-12-10 09:04:55 +00:00
Mathias Jakobsen e422cb9485 Merge pull request #22251 from overleaf/mj-papers-full-library
[third-party-references+web] Add full collection/library sync to Papers

GitOrigin-RevId: 5e0f49f59058096d2a03cbafd6b40e005e739746
2024-12-10 09:04:51 +00:00
Domagoj Kriskovic f39ca200b9 Support for adding reviewer role (#22314)
* Support for adding reviewer role

* added collaboratorsGetter tests

* emit toggle-track-changes when reviewer is added

GitOrigin-RevId: 5b831102d561f5dbc4b23ab9f6dc63e3a87ea103
2024-12-10 09:04:47 +00:00
David 9ed3861c70 Merge pull request #22287 from overleaf/dp-review-safari
Allow review panel entry buttons to be focused in safari

GitOrigin-RevId: 1f9854534394d2561b673857fde186058e4acf49
2024-12-10 09:04:43 +00:00
David e72a3cbc28 Merge pull request #22297 from overleaf/dp-bs5-dropdown-description-icon
Fix display of leading icons in dropdown items with a description

GitOrigin-RevId: bdb7bca62abef9d599a23364656b32599a909a90
2024-12-10 09:04:39 +00:00
Brian Gough a08d1b18dc Merge pull request #22378 from overleaf/bg-issue22368
Fix frontend to handle missing hashes for image preview

GitOrigin-RevId: e67300d9b08b02b1670cb3a7bbd4483cf4486f51
2024-12-10 09:04:29 +00:00
roo hutton 5a24d23930 Merge pull request #22309 from overleaf/rh-plan-annual-toggle
[web] Plans page period toggle improvements

GitOrigin-RevId: 8900d9ce9c2116fd11f9688ada93d11211df045f
2024-12-09 09:05:15 +00:00
CloudBuild ff656c8029 auto update translation
GitOrigin-RevId: 2772b7f7f08860f0e0c090a06a1c183ab08194d9
2024-12-09 09:05:11 +00:00
Domagoj Kriskovic f0716cdd36 Added db migration for reviewer_refs property (#22305)
GitOrigin-RevId: 6ff997c0bd442ba00ac7468718177f4a6bcdb3d5
2024-12-09 09:05:04 +00:00
Domagoj Kriskovic 6a6ef776d5 Revert "Update review entries in overview panel on collaborator changes (#22098)" (#22369)
This reverts commit e2d837efe889170dc055df69eae6b4e8f86cb5fc.

GitOrigin-RevId: e2c8637ffd64fc52f1a9cb36801f8688d42d4e0c
2024-12-09 09:05:00 +00:00
Domagoj Kriskovic e83963eefc Update review entries in overview panel on collaborator changes (#22098)
* remove unused "total" property

* add missing key

* added socket listeners

* remove accept-changes listener

* not using ranges context in overview

* fix lint error

* added comment

* add accept-changes listener

* rename to removeThreadHandler

* simplify docRanges useEffect

* refactor removeThreadHandler

* refactor accept-changes handler

* delete unnecessery event handlers

* remove edit-message listener

GitOrigin-RevId: e2d837efe889170dc055df69eae6b4e8f86cb5fc
2024-12-09 09:04:56 +00:00
Domagoj Kriskovic 174d62e4cc Improve positioning of "Add comment" tooltip when selecting entire line(s) (#22277)
* Avoid obscuring text with "Add comment" tooltip when selecting entire line

* tooltip position change on direction of selection

GitOrigin-RevId: d8cd301091104dae2422e34e14f90afd4c0927c4
2024-12-09 09:04:52 +00:00
Brian Gough 527f56599f Merge pull request #21706 from overleaf/bg-clear-projects-from-docupdater
clear inactive projects from docupdater when archiving

GitOrigin-RevId: 8fb11e6ebd29dfaafb62c10e07e774b90301b5ae
2024-12-09 09:04:44 +00:00
Thomas 630647e8e7 Merge pull request #22356 from overleaf/tm-remove-support-request-ratelimiter
Remove supportRequests ratelimiter (route already uses subscriptionRateLimiter)

GitOrigin-RevId: 008a7db40529b795d1dad9f5cf6859fe9011f637
2024-12-06 09:07:11 +00:00
CloudBuild 8112f3820c auto update translation
GitOrigin-RevId: 9eeb95fe75ebe9e823a45303554dd6a4e0e92205
2024-12-06 09:07:03 +00:00
Jimmy Domagala-Tang 2dcd1afcc5 Merge pull request #22360 from overleaf/jdt-fix-admin-panel-tests-ai
feat: updating test defaults
GitOrigin-RevId: 2be457097dcdebe13dd211f2ea24b45573b7744a
2024-12-06 09:06:58 +00:00
Jimmy Domagala-Tang 6ba4b0141a Merge pull request #22255 from overleaf/jdt-rm-free-suggestion-text-on-purchase
[Web] remove uses left indicator after potential add-on purchase

GitOrigin-RevId: c9c839b90eea62b9d0dbeb4ae81321f303582c2c
2024-12-06 09:06:53 +00:00
Jimmy Domagala-Tang 605a0394e5 Merge pull request #21899 from overleaf/jdt-rm-labs-refs-from-assistant
[Web] Remove references to labs from AI assistant copy

GitOrigin-RevId: 7d6a91de3bbf4328a995a353f2f3a0c9576a3dba
2024-12-06 09:06:42 +00:00
Jimmy Domagala-Tang 09fdf16471 Merge pull request #22357 from overleaf/jdt-em-remove-assist-on-dg
feat: remove addon from users when their subscription lapses
GitOrigin-RevId: 9435b4e7e10c76ea252040da4d273d9b4cef797b
2024-12-06 09:06:37 +00:00
Jimmy Domagala-Tang ab5a539c62 Merge pull request #22110 from overleaf/jdt-remove-assistant-from-labs
[Web] End Error Assist Labs Experiment

GitOrigin-RevId: 2570c07aea3d6b71dc59792cd2248cb890b415d3
2024-12-06 09:06:32 +00:00
M Fahru 3e0b447bc1 Merge pull request #22225 from overleaf/ds-register-bs-5-four
BS5 Migration - Migrating Registration page to BS5(4)

GitOrigin-RevId: 89f9158242714dca6fdbe0626a2c2c6e7174a010
2024-12-06 09:06:24 +00:00
M Fahru d42ecb46ab Merge pull request #22207 from overleaf/ds-register-bs-5-three
BS5 Migration - Migrating Registration page to BS5(3)

GitOrigin-RevId: debfb67978d39b87999ad201c6382b81d007fbe8
2024-12-06 09:06:20 +00:00
M Fahru c0af22b405 Merge pull request #22172 from overleaf/ds-register-bs-5-two
BS5 Migration - Migrating Registration page to BS5(2)

GitOrigin-RevId: 091cabaa665e49a17939b4896084b7bbe779b4ba
2024-12-06 09:06:15 +00:00
Mathias Jakobsen 2e534b4e17 Merge pull request #22240 from overleaf/mj-papers-write-and-cite
[third-party-references+web] Add papers to Write and Cite

GitOrigin-RevId: b9101b1ece301117a89a8b82a4b391265c2a9deb
2024-12-06 09:05:56 +00:00
Rebeka Dekany 1363045db2 Merge pull request #22272 from overleaf/rd-tag-dropdown-fix
[web] Tag dropdown menu should not be dismissed when hovering outside of it

GitOrigin-RevId: 0f0f903e07d657752e3476b9abea643bae65eb9e
2024-12-06 09:05:51 +00:00
Liangjun Song dfea9dacab Merge pull request #22146 from overleaf/ls-consider-flexible-licensing-on-payment-page
support new group plans in checkout flow

GitOrigin-RevId: ec6aff363e0eeb5d82067cea44479b5045258490
2024-12-06 09:05:43 +00:00
Liangjun Song 932f395932 Merge pull request #22184 from overleaf/ls-group-plan-upgrade-page
Group plan upgrade page

GitOrigin-RevId: 6c99173c013d84943276dbd43f468026c4d44558
2024-12-06 09:05:38 +00:00
Liangjun Song 5ad9ac439c Merge pull request #22336 from overleaf/ii-upgrade-my-plan-link
[web] Upgrade plan link fix

GitOrigin-RevId: 943475bfb06d70bfa472459353b4f7def7b17932
2024-12-06 09:05:34 +00:00
Rebeka Dekany 7493936bad Merge pull request #22310 from overleaf/ar-bump-mongoose-8.8.3
[web] Upgrade mongoose to 8.8.3

GitOrigin-RevId: 5540f7384b74daafa01522c23633587fc56a7faa
2024-12-06 09:05:25 +00:00
ilkin-overleaf ab4d8fe168 Merge pull request #21841 from overleaf/ii-flexible-group-licensing-add-seats
[web] Add seats to a group plan

GitOrigin-RevId: 53497d2cb7aa7d1e7dc8291e391b24f7a32eeece
2024-12-06 09:05:13 +00:00
roo hutton f856ddce87 Merge pull request #22120 from overleaf/rh-group-tab
Top-level group size and education discount selector in new plans page

GitOrigin-RevId: 1a1ecf3b4dc60e50b90ff399534bb58a16f22f82
2024-12-05 09:05:30 +00:00
Brian Gough 104ae341b1 Merge pull request #22327 from overleaf/bg-fix-copy-blob
fix bug that prevents copying blobs between different backends in history-v1

GitOrigin-RevId: 41140ad42d0d7c1beda83e588649127c22603dec
2024-12-05 09:05:22 +00:00
M Fahru c4e0294d36 Merge pull request #22027 from overleaf/mf-activate-plans-page-new-design-variant
[web] Activate plans page new-design variant for all users

GitOrigin-RevId: 7da3c973cded8597cadd691f5d6e928d31e8d26f
2024-12-05 09:05:18 +00:00
Jimmy Domagala-Tang c276fa00ae Merge pull request #22254 from overleaf/jdt-rm-addon-paywall
remove paywall for error assistant in favor of direct to checkout

GitOrigin-RevId: 2047f274371716733d586213defbf271d98d32fc
2024-12-05 09:05:14 +00:00
Jimmy Domagala-Tang c68d252508 Merge pull request #22259 from overleaf/jdt-assist-wording
Add unlimited to assist plan wording

GitOrigin-RevId: a15f10e618ab11f36f55c091d36dc4e61bff49d6
2024-12-05 09:05:10 +00:00
Eric Mc Sween e2478d14f1 Merge pull request #22224 from overleaf/em-group-ai-add-on
Give the Error Assistant to group admins with Error Assist

GitOrigin-RevId: 832d78968977a7c6f17a3a3c8409c506d96fdd48
2024-12-05 09:05:03 +00:00
Eric Mc Sween b68f758fd5 Merge pull request #22274 from overleaf/em-setup-recurly-add-ons
Set up assistant add-on only on group plans available in production

GitOrigin-RevId: a47c05443c5bf4a1bb1fb26d45a3705a544ba7c5
2024-12-05 09:04:59 +00:00
Eric Mc Sween 5ce7a785d1 Merge pull request #22282 from overleaf/em-no-ai-for-non-recurly-subs
Hide the AI feature from users with non-Recurly subscriptions

GitOrigin-RevId: 2bcd8da1c87eead577eb3321be4c1568e1fc29cf
2024-12-05 09:04:55 +00:00
Andrew Rumble ffa28b1a58 Merge pull request #22320 from overleaf/revert-22213-ar-avoid-duplicate-blob-writes
Revert "Avoid duplicate blob writes"

GitOrigin-RevId: 9f86bcea654cd3fa5f66fbdf42080e7f6e2861a7
2024-12-05 09:04:48 +00:00
Domagoj Kriskovic 511fe60a9c Revert "Support for adding reviewer role (#22137)" (#22293)
This reverts commit 54064a7f961fe06f188ab449cd469cdaaf01b20a.

GitOrigin-RevId: 1dabc635756aff465d2fe9aa0d18121b081df3b0
2024-12-04 09:05:12 +00:00
Andrew Rumble 40b781eb0a Merge pull request #22213 from overleaf/ar-avoid-duplicate-blob-writes
Avoid duplicate blob writes

GitOrigin-RevId: 5e7a472b235bae5ef84389dbbe791189e951908a
2024-12-04 09:05:08 +00:00
Domagoj Kriskovic f676eca2b8 Support for adding reviewer role (#22137)
* Support for adding reviewer role

* show reviewer in track changes user list

* added "review" in assertClientCanViewProject

* test if reviewer can read project

* added collaboratorsGetter tests

* eit toggle-track-changes when track changes changes

* Support for changing privilege to reviewers for invited users (#22159)

* Add reviewer in change privilege level handler

* added reviewer translation

* added acceptance tests

* fix tests

* Set track changes state permissions for reviewer role (#22167)

* Add reviewer in change privilege level handler

* added reviewer translation

* added acceptance tests

* fix tests

* Set track changes state permissions for reviewer role

* added authorization helper tests

* added ensureUserCanReviewProjectContent middleware

* allow changing track changes only with write permissions

* removed canUserReviewProjectContent

* List projects where user is added as a reviewer (#22249)

* List projects where user is added as reviewer

* list projects in /user/projects

* fix tests

GitOrigin-RevId: 54064a7f961fe06f188ab449cd469cdaaf01b20a
2024-12-04 09:05:00 +00:00
Tim Down 81aab71ffd Merge pull request #22133 from overleaf/td-bs5-current-file-bold
Make selected file in file tree bold in BS5

GitOrigin-RevId: 3353164455c3261ea52f9aee6cef3b1bc614ee4e
2024-12-04 09:04:55 +00:00
Tim Down b3edd2b6c6 Merge pull request #22288 from overleaf/td-history-dropdown-layout-fix
Fix history dropdown layout issue in Bootstrap 3

GitOrigin-RevId: 85709eaa45fd496128afb95738841894c5d211dd
2024-12-04 09:04:51 +00:00
Mathias Jakobsen 63a9e99375 Merge pull request #22204 from overleaf/mj-papers-linking
[web+third-party-references] Add linking to papers account

GitOrigin-RevId: dbf6a01b16ae661558da01549922294278dbda70
2024-12-04 09:04:47 +00:00
Andrew Rumble d1735f549c Merge pull request #22278 from overleaf/ar-improve-history-v1-get-project-blobs-errors
[history-v1] improve getProjectBlob errors

GitOrigin-RevId: 2148f002edc3f63e0236eb139df34a22d7eb33d5
2024-12-04 09:04:42 +00:00
roo hutton 172aeb59d1 Merge pull request #22260 from overleaf/rh-odc-students-never-used
Add student filter and country field to 'never used LaTeX' ODC script

GitOrigin-RevId: 9db298a48b7d70b59b81388ff93fc6c9575861d7
2024-12-03 09:04:59 +00:00
Brian Gough f267350a46 Merge pull request #22266 from overleaf/revert-22256-revert-22239-jpa-file-url-helper
Revert "Revert "[web] add helper for getting file URL from history w/ filestore fallback""

GitOrigin-RevId: 6c4825eebb4892ddcc000abc1415995c00d0c7a0
2024-12-03 09:04:51 +00:00
Antoine Clausse bde4da8aab [web] Reduce pre line height (#22182)
* Remove bad prop "divider" in DropdownDivider

* Reduce line height in log-entry-content-raw

Per https://digital-science.slack.com/archives/C05JM5NTHUP/p1732704056729519

* Decrease `pre` line-height to `--line-height-01` (body-xs)

GitOrigin-RevId: 584ba587d1fc3b8964b96722a6e72efc9fea1059
2024-12-03 09:04:47 +00:00
Antoine Clausse b308f8e9b4 Invert linked-file-icon so it's more visible (#22216)
GitOrigin-RevId: 8ad073166260029e4404cc37fdbb1ee2f8a41c11
2024-12-03 09:04:42 +00:00
Antoine ClausseandRebeka a6ec075f78 Increase checkSummaryValues ranges to fix flakiness (#22227)
Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>
GitOrigin-RevId: d6da0b1e66cf5cb4ef4dbed91ae468ffe5807e37
2024-12-02 09:06:22 +00:00
Thomas 85f4966d49 Merge pull request #22256 from overleaf/revert-22239-jpa-file-url-helper
Revert "[web] add helper for getting file URL from history w/ filestore fallback"

GitOrigin-RevId: 3feecb5291f574de058b51efd5c799e07d5ec851
2024-12-02 09:06:18 +00:00
M Fahru b1ec6dda35 Merge pull request #22199 from overleaf/mf-new-checkout-reduce-payment-container-top-padding
[web] Reduce top padding from 64px to 24px on new checkout page

GitOrigin-RevId: 018613057c08d57e967145f570e76b289b450985
2024-12-02 09:06:06 +00:00
M Fahru 10faeace77 Merge pull request #22198 from overleaf/mf-reduce-horizontal-padding-mobile-new-checkout-form
[web] Reduce horizontal padding on mobile device on new checkout form

GitOrigin-RevId: e4f5792b4e2c7b76734846c87a3154415539e21d
2024-12-02 09:06:02 +00:00
M Fahru 7cc94b0a2d Merge pull request #22197 from overleaf/mf-checkout-name-cases
[web] Use sentence case for all labels in new checkout page

GitOrigin-RevId: 1ae7b01fa6b00d6b4fb007bb908c6cfe35e619c5
2024-12-02 09:05:57 +00:00
M Fahru b24b6f0f95 Merge pull request #21834 from overleaf/mf-checkout-redesign-3d-secure
[web] New checkout page redesign 3d secure implementation

GitOrigin-RevId: ad93fc8a50b1567293cc30fee014eaaab1fb0fa5
2024-12-02 09:05:49 +00:00
Tim Down cc0fcc2a18 Merge pull request #22232 from overleaf/td-skip-sp-ce-learn-wiki-test
Temporarily skip failing learn wiki test

GitOrigin-RevId: 3c25f45a99ec6d22ab62cfa4384dedc078201373
2024-12-02 09:05:41 +00:00
Jakob Ackermann b9a56afe4c Merge pull request #22239 from overleaf/jpa-file-url-helper
[web] add helper for getting file URL from history w/ filestore fallback

GitOrigin-RevId: d77e6f1565fab407e1004a02c4bfdfe03a0214d7
2024-12-02 09:05:26 +00:00
Jakob Ackermann 8db1f2c9bc Merge pull request #22231 from overleaf/jpa-references-hash
[misc] references: read files from history-v1 w/ fallback to filestore

GitOrigin-RevId: e8e05fbe5e5ea9fe83c6b3b00e0ee85d038ff5f0
2024-12-02 09:05:22 +00:00
Alf Eaton aae03bdf6e Restrict editable files by number of characters (#20462)
GitOrigin-RevId: fad0c14444a9d382ad05c14921118ef3883ede79
2024-12-02 09:05:17 +00:00
Alf Eaton a82952f9df Show deprecated browser message to Safari 14 (#22124)
GitOrigin-RevId: 92ba1a900f990eb8ab20870f0909816a07a5af9c
2024-12-02 09:05:13 +00:00
Alf Eaton 0a169fa96f Upgrade @codemirror/lint to 6.8.4 (#22201)
GitOrigin-RevId: 1599b90c8648fa69d6f98d6064f8e48c79e4bd68
2024-12-02 09:05:08 +00:00
Brian Gough bb1072a3a4 Merge pull request #22219 from overleaf/jpa-handle-missing-hash
[web] gracefully handle missing hash when compiling

GitOrigin-RevId: a9b121716319117ead84b7fed9a67098f63fd9a7
2024-11-29 09:05:43 +00:00
Jakob Ackermann d19c5e236f Merge pull request #22208 from overleaf/jpa-clsi-hash
[misc] clsi: read files from history-v1 with fallback to filestore

GitOrigin-RevId: c54bb128780198c14e7a63818f39fad62ce65d4e
2024-11-29 09:05:39 +00:00
Jimmy Domagala-Tang f6cbcc51d8 Merge pull request #22142 from overleaf/jdt-enable-wf-on-commons
[Web] Toggle on Writefull commons targeting

GitOrigin-RevId: ede7f5397d1f110da006111ffcfd2eebb3626927
2024-11-29 09:05:34 +00:00
Brian Gough 1f8a710f0d Merge pull request #22161 from overleaf/bg-issue22125
Copy blobs when duplicating project

GitOrigin-RevId: a2965082ddaa621e10cfe831b2701a019e45a9ac
2024-11-29 09:05:16 +00:00
Jimmy Domagala-Tang 480ff65bef Merge pull request #22109 from overleaf/jdt-wf-auto-account-for-commons
[Web] Allow for Writefull to target non-enterprise commons

GitOrigin-RevId: e348498d7f1eb7c75807897b08649ae63e9daa8a
2024-11-29 09:05:11 +00:00
Andrew Rumble d97555a380 Merge pull request #22003 from overleaf/ar-handle-v1-outage-gracefully
[web] handle v1 outage gracefully

GitOrigin-RevId: 54f9800abf13846a39512224b898de6939be1d3a
2024-11-29 09:05:07 +00:00
Eric Mc Sween 9e1ac94ebf Merge pull request #22163 from overleaf/em-subscription-page-ai-add-on
Adapt the Your plan entry on the subscription page to groups and Commons

GitOrigin-RevId: 7352a90d2489de48d2711f2b8a364cdd5bb54eeb
2024-11-29 09:04:59 +00:00
Jakob Ackermann 892eaabdf7 Merge pull request #22202 from overleaf/jpa-tpds
[misc] tpds: read files from history-v1 with fallback to filestore

GitOrigin-RevId: afdde47e453b0cb07985392b5e2b03abf348debf
2024-11-29 09:04:54 +00:00
Davinder Singh cc60acd4ea Merge pull request #22131 from overleaf/ds-register-bs-5
BS5 Migration - Migrating Registration page to BS5

GitOrigin-RevId: e0bd9fa11fa363062454e8f328d53b0c2aef9cad
2024-11-29 09:04:50 +00:00
Jakob Ackermann 652b5aaab5 Merge pull request #22183 from overleaf/jpa-zip-from-hash
[web] build project zip using history-v1 blobs with filestore fallback

GitOrigin-RevId: 2e197ae83e7ac8bcfe44091c327b721825b13a05
2024-11-28 09:06:41 +00:00
Jakob Ackermann faff4f1d7e Merge pull request #22178 from overleaf/jpa-file-view-hash-2
[web] migrate file-view to download from history-v1 (via web) 2/2

GitOrigin-RevId: 93172cbbd2d19a55bb27f5b0ca0b494f815a3632
2024-11-28 09:06:37 +00:00
Jakob Ackermann ce0d5fd383 Merge pull request #22177 from overleaf/jpa-file-view-hash-1
[web] migrate file-view to download from history-v1 (via web) 1/2

GitOrigin-RevId: b787e90c57af5e2704b06ba63502aa6fc09ea1df
2024-11-28 09:06:33 +00:00
M Fahru 622d7bca79 Merge pull request #22140 from overleaf/mf-new-checkout-page-toc
[web] Add "terms of service" disclaimer text on new checkout page

GitOrigin-RevId: 8b5aad7c2ebfc5a9d9acab605276e4b81349e045
2024-11-28 09:06:28 +00:00
M Fahru a623faf260 Merge pull request #22139 from overleaf/mf-add-paypal-disclaimer
[web] Add paypal disclaimer text above submit button

GitOrigin-RevId: d31ae6cd38e5244613c27f18a9f04bc9cd322dd5
2024-11-28 09:06:24 +00:00
M Fahru 6f0b839354 Merge pull request #22136 from overleaf/mf-fix-spacing-checkout-page-redesign
[web] Fix spacing on checkout page redesign form

GitOrigin-RevId: eb85a37cf8ba9c2e32a78fa6585b5102b8c01bce
2024-11-28 09:06:19 +00:00
Eric Mc Sween 8096cd2408 Merge pull request #21897 from overleaf/jdt-assistant-events
Ai Error assistant events

GitOrigin-RevId: c70e5cecbc220fdfc63512680a76616dbd631c86
2024-11-28 09:06:15 +00:00
Eric Mc Sween 76097d17c4 Merge pull request #22165 from overleaf/em-hide-upgrade-button
Hide upgrade button for AI add-on + Group/Commons users

GitOrigin-RevId: 58cd522a1fa08f477fd6509f6d12a728309718d8
2024-11-28 09:06:11 +00:00
Eric Mc Sween a21db20631 Merge pull request #22164 from overleaf/em-subscription-case
Fix case in subscription related pages

GitOrigin-RevId: df5c1da01a2cc391d081b4dccf882dfe45276766
2024-11-28 09:05:50 +00:00
Tim Down 967c3e597c Merge pull request #21971 from overleaf/td-ds-nav-split-test
Add split test for DS unified nav

GitOrigin-RevId: d649661568f9c1de9d2fe47f4491540e80830ab3
2024-11-28 09:05:39 +00:00
Tim Down 68867d63b4 Merge pull request #21955 from overleaf/rd-bs5-loading-button
Buttons should not be interactive when they are disabled

GitOrigin-RevId: 2b8b1e8b317dc3b62200b48dac66df7eff8a7268
2024-11-28 09:05:35 +00:00
Brian Gough be90a3b2bb Merge pull request #22170 from overleaf/bg-history-v1-copy-blob
add copyBlob support to history-v1

GitOrigin-RevId: 797ea66c37ca938fc906c4dff7bb1c8bf14c031e
2024-11-28 09:05:30 +00:00
Mathias Jakobsen 0bec88cb2b Merge pull request #22168 from overleaf/mj-rm-events
[web] Add events when refreshing linked file and importing RM entry

GitOrigin-RevId: b9efcd1893f0a78a33ec325b306eccbaa44a77fe
2024-11-28 09:05:26 +00:00
David 044f52f937 Vertically center pdf in presentation mode (#22145)
* Vertically center pdf in presentation mode

* Ignore style lint error

GitOrigin-RevId: b46e6d414406d150e894b4c94ec0e94b61a0ce11
2024-11-28 09:05:22 +00:00
Domagoj Kriskovic a51126fb06 Fix history label timestamp used in restore file (#22068)
GitOrigin-RevId: 24e3b005664cecc017b610812cb4c666dfb55290
2024-11-28 09:05:18 +00:00
Kristina da411733b6 Merge pull request #22119 from overleaf/kh-hotjar-on-plans-and-checkout
[web] add hotjar to plans pages

GitOrigin-RevId: eb582a85200747754923f28e7d710a9072577d75
2024-11-28 09:05:10 +00:00
Jakob Ackermann 9357f51fcf Merge pull request #22092 from overleaf/jpa-jq
[history-v1] install jq in the docker image

GitOrigin-RevId: c47516b02d52b4def6cd0c793868175b5d4b16e4
2024-11-28 09:05:02 +00:00
Alf Eaton 078a3b8d05 Use --font-sans in the Visual Editor widgets (#22085)
GitOrigin-RevId: 64a480562b3e7d2fda7d41ed402511290f800f14
2024-11-28 09:04:54 +00:00
Tim Down 065464f722 Merge pull request #22147 from overleaf/td-bs5-beta-badge-special-cases
Alpha/beta badge fixes and change warning badge colours in Bootstrap 5

GitOrigin-RevId: f60610572c62607db7e5cf349c5791c3519c74ed
2024-11-27 09:05:04 +00:00
Tim Down d0ca742a93 Merge pull request #21956 from overleaf/td-link-underlines
Use CSS variable for link hover underlines

GitOrigin-RevId: 7fa82edab808ed593bb52126869f286673915e18
2024-11-27 09:05:00 +00:00
Jakob Ackermann 3d7254b419 Merge pull request #22153 from overleaf/jpa-backup-verifier-minimal
[history-v1] backup-verifier-app: initial revision

GitOrigin-RevId: 922c9f94cb7ca7c129e38fd6961d42bdff819cd8
2024-11-27 09:04:55 +00:00
Brian GoughandAntoine Clausse 6672372828 remove sentry from backend services (#20752)
* remove sentry from backend services - no longer required

* Remove Sentry integration from logging manager

* Remove Sentry from clsi default settings

* Remove `initializeErrorReporting` in libraries/logger

* Remove `@sentry/node` from `libraries/logger`

---------

Co-authored-by: Antoine Clausse <antoine.clausse@overleaf.com>
GitOrigin-RevId: 8149a885f5258804b93ae39cde7b7333e992532a
2024-11-27 09:04:50 +00:00
Jakob Ackermann 3d0f5188ae Merge pull request #22143 from overleaf/jpa-extra-test
[history-v1] back_fill_file_hash: add extra test

GitOrigin-RevId: dddc6fdf4a6a7608a8a096537ebf47fe360709a8
2024-11-27 09:04:34 +00:00
Jakob Ackermann 40603e0561 Merge pull request #22134 from overleaf/jpa-broken-file-trees
[history-v1] back_fill_file_hash: gracefully handle broken file-trees

GitOrigin-RevId: 463c785e98581364b107f3262951e7fa0fb88a0f
2024-11-26 09:05:51 +00:00
Jakob Ackermann b7d37b434a Merge pull request #22123 from overleaf/jpa-process-hashed
[history-v1] back_fill_file_hash: optionally process hashed files

GitOrigin-RevId: 53ebaa7b03166a6b1aacc0f985bb295c9ec04804
2024-11-26 09:05:47 +00:00
M Fahru 06d87f4590 Merge pull request #22034 from overleaf/mf-credit-card-card-payment-text
[web] Change `Credit card` text to `Card payment` to follow the default variant of the checkout page

GitOrigin-RevId: c425cb49bc227e7834ee13c5b4155b6fda530e1f
2024-11-26 09:05:40 +00:00
M Fahru 5fe4ab3c8d Merge pull request #22078 from overleaf/mf-checkout-page-form-submission
[web] New checkout page form submission

GitOrigin-RevId: 7cd41e6880a8d9ce24f7795f1870ea65dd9bd19a
2024-11-26 09:05:36 +00:00
Brian Gough fe7ce48e48 Merge pull request #22096 from overleaf/bg-issue21795
Extend file upload  to create history blobs

GitOrigin-RevId: b3efac7f58d4c027ca9131867e761837ce63facb
2024-11-26 09:05:29 +00:00
Tim Down ef72402df6 Merge pull request #22089 from overleaf/td-bs5-menu-item-reduce-height
Reduce the height of menu items in BS5 to 36px

GitOrigin-RevId: 0d6294f1713618bc97562c92ea877aaeac8b9698
2024-11-26 09:05:25 +00:00
Tim Down 794f4782c4 Merge pull request #21945 from overleaf/td-bs5-file-tree-font-size
Reduce file tree font size to 14px in Bootstrap 5

GitOrigin-RevId: 27289b00fa3def01ccf410649430e3826ac0b1bb
2024-11-26 09:05:20 +00:00
Tim Down 8cd6a0b2f1 Merge pull request #22015 from overleaf/td-bs5-beta-badge
[BS5] Use alpha and beta characters for alpha and beta badges

GitOrigin-RevId: d57bc4da8ac5142234bec50c56f6a1b98ececc6c
2024-11-26 09:05:16 +00:00
Tim Down 22b126fa94 Merge pull request #22074 from overleaf/td-bs5-pdf-notifications
Migrate pdf-preview-messages to BS5

GitOrigin-RevId: ed2672de3275988d05ec455c9a94d52ac75d7e94
2024-11-26 09:05:12 +00:00
Mathias Jakobsen 592e484098 Merge pull request #22087 from overleaf/mj-index-on-wc-rm-entry
[web] Re-index references after adding a RM entry with Write and Cite

GitOrigin-RevId: 6b2a93143486079dfc82af393e2c5621fed7a4ee
2024-11-26 09:05:08 +00:00
Eric Mc Sween 7dffcbf645 Merge pull request #22081 from overleaf/em-revert-file-dangling-comments
Fix comment restoration when restoring a doc

GitOrigin-RevId: 2288ab991ab4ddbe38320bf4ff42cde80ce40e52
2024-11-26 09:05:04 +00:00
Eric Mc Sween 0769998dd7 Merge pull request #22024 from overleaf/em-standalone-ai-add-on-is-not-premium
Do not hide upgrade buttons when on standalone AI add-on

GitOrigin-RevId: ec5cf42c051745d5ca1dff57f7cd27a89c21a6a9
2024-11-26 09:04:57 +00:00
Jakob Ackermann 0bd8729cc1 Merge pull request #22115 from overleaf/jpa-skip-get
[history-v1] back_fill_file_hash: optimize obtaining the DEK

GitOrigin-RevId: 6fc5218737551ae4e6152414c32560f545767091
2024-11-26 09:04:50 +00:00
Jakob Ackermann ed27af11f8 Merge pull request #22107 from overleaf/jpa-error-handling
[history-v1] back_fill_file_hash: error handling

GitOrigin-RevId: 2dbf52d015206cf42ca434b1f16221d6e0f2cc2b
2024-11-26 09:04:45 +00:00
Alf Eaton 0e12f9226f Patch PDF.js for blocked bug fix (#22014)
* Hoist pdfjs-dist
* Create pdfjs-dist+4.6.82.patch
* Hoist core-js

GitOrigin-RevId: 2cd91766dc351597de61ebbada0446561e17954b
2024-11-26 09:04:41 +00:00
Alf Eaton b4f624d8f6 Record events for shortcut usage (#22062)
GitOrigin-RevId: ff85e0719fca24a3723ea62119fa254226cd65c0
2024-11-26 09:04:37 +00:00
Alf Eaton a773a63c2a Move tooltip styles to EditorView.theme (#22069)
GitOrigin-RevId: b4495732d8f72f18b00f32fe952251391258f5d6
2024-11-26 09:04:33 +00:00
Antoine Clausse 6d6477401e Remove some dead file and copybara paths (#22102)
* Remove modules-main.js

* Remove history-migration from copy.bara.sky

GitOrigin-RevId: 947fb1d9655a296c228be09e7971c0060be0e5cc
2024-11-26 09:04:28 +00:00
Mathias Jakobsen 3e478c42f7 Merge pull request #21974 from overleaf/mj-autocomplete-sorting
[web] Fix results re-shuffling in Write and Cite

GitOrigin-RevId: be5cf337b16a80d7182b96a733c9c7663725bdd2
2024-11-25 09:05:42 +00:00
Jakob Ackermann 1a6bd670d4 Merge pull request #22104 from overleaf/jpa-graceful-shutdown-abort-retries
[history-v1] back_fill_file_hash: abort retries during graceful shutdown

GitOrigin-RevId: 0d52dde32e4a7bf2293f341644b7416e669b2bdc
2024-11-25 09:05:31 +00:00
Jakob Ackermann 651fad7401 Merge pull request #22099 from overleaf/jpa-timeout
[history-v1] back_fill_file_hash: increase S3 httpOptions.timeout

GitOrigin-RevId: cd01f78597c517c9530f14a5ccc6defe2b49446b
2024-11-25 09:05:26 +00:00
Eric Mc Sween 558b529caf Merge pull request #22030 from overleaf/em-subscription-change-pay-now-button
Implement the Pay Now button for upgrades to premium from the AI add-on

GitOrigin-RevId: 06e00662b877308c64ce5feaa5ce8f80f8f1b552
2024-11-25 09:05:11 +00:00
Eric Mc Sween b0c309e993 Merge pull request #22032 from overleaf/em-subscription-change-preview-404
Handle user without a subscription when asking for a change preview

GitOrigin-RevId: dab90720b292fd0cfb6dbb8a554797b9d2ac436b
2024-11-25 09:05:06 +00:00
Jakob Ackermann 838ae23b52 Merge pull request #22091 from overleaf/jpa-bad-file-trees
[history-v1] back_fill_file_hash: gracefully handle bad file-trees

GitOrigin-RevId: 0419c06b1ccf827f4c6c5170978a38659435f26f
2024-11-25 09:05:02 +00:00
Antoine Clausse 2b1df12052 [filestore] Replace delayShutdownMs by gracefulShutdownDelayInMs (#22077)
* Add a default 30s timeout for `delayShutdownMs`

`settings.delayShutdownMs` doesn't seem to be defined anywhere

Logs typically often this pair of entries:
```
INFO 2024-11-21T15:51:42.115Z [resource.labels.containerName: filestore] received interrupt, cleaning up
INFO 2024-11-21T15:51:42.120Z [resource.labels.containerName: filestore] shutdown timed out, exiting
```
This indicates that there is no delay between the interrupt signal and the shutdown. The 100ms delay also doesn't happen. We believe that the `server.close` callback is called after `server.closeAllConnections()`, and the `server closed` log is usually lost because of the process exiting immediately.

See: https://cloudlogging.app.goo.gl/WJQ6mc3gWwotVQya7

* Add timeout before exiting

* Replace `delayShutdownMs` by `gracefulShutdownDelayInMs`.

Looks like the error came from a wrong merge in https://github.com/overleaf/internal/pull/18756

We don't want a default 30s timeout for the shutdown, per https://github.com/overleaf/internal/pull/16888

GitOrigin-RevId: c1bdc8986f78a6e18e8b8b1fe60b33aa6ffef909
2024-11-22 09:06:27 +00:00
CloudBuild 46ae397fb9 auto update translation
GitOrigin-RevId: e49cdfd8b712f54ddba599595e4f7f582e4da67c
2024-11-22 09:06:19 +00:00
Jakob Ackermann c2b876372b Merge pull request #22070 from overleaf/jpa-args
[history-v1] refactor env vars to args for GNU-parallel usage

GitOrigin-RevId: 1ebfa3dfc25d36f2f86c22fa22e4864d55b511b2
2024-11-22 09:06:11 +00:00
Andrew Rumble 77831b60bf Merge pull request #22059 from overleaf/ar-update-node-18-in-recent-history-changes
[history-v1] Update more missed node 18 usages

GitOrigin-RevId: 481e3de95dc34ef2bca38302a3ff595a92cea6ed
2024-11-22 09:06:00 +00:00
Jakob Ackermann 69021ca4b0 Merge pull request #22061 from overleaf/jpa-reduce-idle-time
[history-v1] back_fill_file_hash: reduce idle time between batches

GitOrigin-RevId: 9b24bb882b158f33915d2e0ab2f82273eac09739
2024-11-22 09:05:55 +00:00
Domagoj Kriskovic fb45c3c144 Fix onKeyPress listener in AutoExpandingTextArea (#22040)
GitOrigin-RevId: 3fe870fe3aa16e6ed212ea4347a31e57444ad5e6
2024-11-22 09:05:51 +00:00
Domagoj Kriskovic f72c86e7fe Add "accept-changes" socket listener in ranges context (#22048)
GitOrigin-RevId: 0be5f3be1806aad29f44eec2e596af51e65263e7
2024-11-22 09:05:42 +00:00
Alf Eaton 3bbde49781 Merge pull request #22055 from overleaf/ae-restore-review-tooltips
Reapply "Allow position of review tooltip to be calculated automatically (#21803)"

GitOrigin-RevId: b6dff2d12627b04ff1859bd4765be01670256aa4
2024-11-22 09:05:33 +00:00
Liangjun Song 56f6f77ba2 Merge pull request #21782 from overleaf/ls-update-group-member-management-page
update group member management page for flexible licensing

GitOrigin-RevId: 605fb760a1f73763e49978cf4aea81bb88ffb425
2024-11-22 09:05:21 +00:00
Liangjun Song ac8d8d6edc Merge pull request #21957 from overleaf/ls-compute-immediate-charge-for-subscription-update
compute immediate charge for subscription update

GitOrigin-RevId: 4e5162660b26e6e9db69827a59aa8e0048fa7d5d
2024-11-22 09:05:12 +00:00
Kristina 583923a4d0 [web] Use btn-secondary on compile timeout notification (#21949)
* [web] Use btn-secondary on compile timeout notification
* fix update to wrong variant

GitOrigin-RevId: 9745ae17525e835c96f62471aa24a8ae9a1e7e93
2024-11-22 09:04:49 +00:00
Jakob Ackermann 4f25b0de91 Merge pull request #22028 from overleaf/jpa-logging
[misc] logging tweaks

GitOrigin-RevId: 7757b81b6c684955374038376035dc2bd272c4e8
2024-11-21 09:05:41 +00:00
CloudBuild a92a1f5a24 auto update translation
GitOrigin-RevId: d0c96096d7a9b3d690852a3ddce37f1403674e2b
2024-11-21 09:05:38 +00:00
M Fahru 0a46bdc2ac Merge pull request #21993 from overleaf/mf-payment-page-toggle-currency
[web] Create new `payment-page-toggle-currency` event on currency dropdown

GitOrigin-RevId: 58d26ded8930e4ffecbb8c3af89658ca9bd2a08e
2024-11-21 09:05:34 +00:00
M Fahru 16e65edd0d Merge pull request #21995 from overleaf/mf-disable-footer-tooltip-if-element-is-not-available
[web] Only trigger footer tooltip if target element is available

GitOrigin-RevId: e0aff735243369a0d2180174231951054f1ee533
2024-11-21 09:05:30 +00:00
M Fahru eefa0a792a Merge pull request #21992 from overleaf/mf-integrate-change-currency-new-checkout-page
[web] Integrate change currency to new checkout page

GitOrigin-RevId: cbb942062dbf408613f1a6b5f598947ca4a52370
2024-11-21 09:05:27 +00:00
M Fahru 21f930f73b Merge pull request #21990 from overleaf/mf-payment-page-view-segmentation
[web] Add new segmentation for `payment-page-view` event

GitOrigin-RevId: ed15ab83edc8a0642d3cec803c59a4a4437740ea
2024-11-21 09:05:23 +00:00
M Fahru 8facb017ed Merge pull request #21986 from overleaf/ds-checkout-redesign-tooltip-size
Checkout redesign - Reducing the size of tooltip on checkout redesign page

GitOrigin-RevId: 5bec7be4beccc153e4fc1d3ab20626cee9364750
2024-11-21 09:05:16 +00:00
Alf Eaton bc310ddd1e Revert "Allow position of review tooltip to be calculated automatically (#21803)" (#22022)
This reverts commit 7d285a9c76032a3238422e15a73ae4b819612b31.

GitOrigin-RevId: 792391619bd6f2a9483428088c31ece09a441b33
2024-11-21 09:05:12 +00:00
Jessica Lawshe 5df8cf7ce4 Merge pull request #20324 from overleaf/jel-plans-toggle
[web] Use input for period toggle on new plans

GitOrigin-RevId: 0e1b76d92aa2143eb6721b9b2cd19505803fb153
2024-11-21 09:05:09 +00:00
Jakob Ackermann 44e0428496 Merge pull request #22019 from overleaf/jpa-cleanup
[history-v1] back_fill_file_hash: cleanup BUFFER_DIR when done

GitOrigin-RevId: 6413292bbe8cca470919b740d7e2b45fc5e7d824
2024-11-21 09:05:05 +00:00
Jimmy Domagala-Tang 71112d2fdc Merge pull request #21938 from overleaf/jdt-checkout-success-add-on-wording
[Web] Adapt post checkout page for add-ons

GitOrigin-RevId: ee3ee28820f65977600a5aa47d85365148233bac
2024-11-21 09:05:01 +00:00
Eric Mc Sween 6e39885fde Merge pull request #21959 from overleaf/em-redeploy-ai-add-on-prs
Redeploy AI add-on PRs

GitOrigin-RevId: d234ac0862947e9ea8926055ad205e32a456dd2e
2024-11-21 09:04:57 +00:00
Eric Mc Sween 58e34617bc Merge pull request #21935 from overleaf/em-recurly-event-ai-add-on
Add an hasAiAddOn property to Recurly events sent to analytics

GitOrigin-RevId: a3cfc706001bab3ef06bfaf64d69533b1bc9840a
2024-11-21 09:04:53 +00:00
Jakob Ackermann 2e630e50dc Merge pull request #22017 from overleaf/jpa-process-all-projects
[history-v1] back_fill_file_hash: process all projects

GitOrigin-RevId: 41c3cd59022bbac09552684ef2a99c58f2235ac3
2024-11-21 09:04:50 +00:00
Jakob Ackermann 1fca37af61 Merge pull request #22016 from overleaf/jpa-fix-flaky-test
[history-v1] back_fill_file_hash: fix typo in tests and add comments

GitOrigin-RevId: a4055d7dd33ba584a2a86053470585f412392305
2024-11-21 09:04:46 +00:00
Jakob Ackermann 6de1817ef5 Merge pull request #22013 from overleaf/jpa-flush-mongo-queues-early
[history-v1] back_fill_file_hash: flush mongo write queues early

GitOrigin-RevId: 9b6c6ff9861945e69e42d15dc19f4c03c39193e9
2024-11-21 09:04:42 +00:00
Jakob Ackermann 73aea01f37 Merge pull request #21996 from overleaf/jpa-stream-pg-result
[history-v1] postgres: getProjectBlobsBatch: stream records

GitOrigin-RevId: 94ed6dfc4a263fd9369cd380e6cc25c7bbf6decc
2024-11-21 09:04:38 +00:00
Antoine ClausseandAlf Eaton e576ffd63c [web] Hide pdf-log-entry-content when empty + fixup search "count" color (#21977)
* Hide `PdfLogEntryContent` when there is no content

* Fixup in search "count": `--ol-blue-gray-4` doesn't exist in SCSS

* Update `AiErrorAssistant` with a `shouldRender` export, allowing to hide the element from the caller

* Revert "Update `AiErrorAssistant` with a `shouldRender` export, allowing to hide the element from the caller"

This reverts commit 01812fa2b108b94c99d250c9a39e4f3c41b36781.

* Hide .log-entry-content when empty, using CSS

Co-authored-by: Alf Eaton <alf.eaton@overleaf.com>

---------

Co-authored-by: Alf Eaton <alf.eaton@overleaf.com>
GitOrigin-RevId: c5096b362600058535bd645cf11dad255e941fb9
2024-11-21 09:04:34 +00:00
Antoine Clausse 485bccebef [web] Update loading spinner in IDE for BS5 (#21970)
* Update `LoadingPane` with `LoadingSpinner`

* Remove unused file no-open-doc-pane.tsx

* Remove translation `open_a_file_on_the_left`

GitOrigin-RevId: 9045443de6aaf19b1d4bf82cd2be3ba91ee53bf1
2024-11-21 09:04:31 +00:00
Antoine ClausseandTim Down 9e745ed7ae [web] Tear down Bootstrap 5 project dashboard feature flag (#21820)
* Remove `BootstrapVersionSwitcher`

* Remove `bsVersion`

* Remove `bootstrap-5-project-dashboard` from code

* Fix frontend test

* Fixup classname `"me-auto"`

Co-authored-by: Tim Down <tim.down@overleaf.com>

* Rename `handleClickBS5` to `handleClick`

Co-authored-by: Tim Down <tim.down@overleaf.com>

* Remove `bs3Props` from `project-list/components`

* Remove translation: `joining`

* Set `isBootstrap5()` to true in test, and update

---------

Co-authored-by: Tim Down <tim.down@overleaf.com>
GitOrigin-RevId: 94005bc8636c9235253758b8ac18a732ee1dbd77
2024-11-21 09:04:27 +00:00
Antoine Clausse b27b2808f2 [web] Fixup .mjs extension in scripts mentions (calls, comments, copybara) (#21969)
* Fixup `.mjs` extension in scripts mentions (calls, comments, copybara)

* Replace `.js` by `.*` in copy.bara.sky exclude

* Add `services/web/modules/modules-*.mjs` in copy.bara.sky glob

GitOrigin-RevId: b3ecb849b44bdf4257cc17f6985f8117a4d662ae
2024-11-21 09:04:23 +00:00
Eric Mc Sween 7e42b1f3eb Merge pull request #21989 from overleaf/em-dangling-comments-script
Script for deleting dangling comments in a project

GitOrigin-RevId: da947834d5a824bbf38ec8e98e212796faf66568
2024-11-21 09:04:19 +00:00
Jakob Ackermann 67ca6a74b2 Merge pull request #22004 from overleaf/jpa-default-s3-timeout
[history-v1] increase default HTTP timeout for backupPersistor

GitOrigin-RevId: 4bcf849488211f074a2200646b048e963070ee52
2024-11-21 09:04:11 +00:00
Alf Eaton 2304e6d32b Upgrade Lezer dependencies (#21987)
GitOrigin-RevId: 5eb834bb1144c499ea29539750f1b73edeeff2f8
2024-11-21 09:04:03 +00:00
Alf Eaton 598ccab8b4 Allow position of review tooltip to be calculated automatically (#21803)
* Remove view from textSelectedEffect
* Upgrade @codemirror/view to 6.34.3

GitOrigin-RevId: 7d285a9c76032a3238422e15a73ae4b819612b31
2024-11-21 09:03:59 +00:00
Miguel Serrano a5f38a8663 Merge pull request #21683 from overleaf/msm-sso-admin-checkbox
[web] Change Group SSO radio in admin panel to checkbox

GitOrigin-RevId: c4a07400c6f399724be0368108be24ec6df67efa
2024-11-21 09:03:52 +00:00
Miguel Serrano 3e0428d450 Merge pull request #21884 from overleaf/msm-remove-group-sso-enabled-flag
[web] Cleanup `GROUP_SSO_ENABLED` env variable

GitOrigin-RevId: b41ce989348c70c3b4ca59ebf4986edf059534aa
2024-11-21 09:03:43 +00:00
Miguel Serrano d825fbe44c Merge pull request #21434 from overleaf/msm-esm-oauth2-server
[web] Migrate `modules/oauth2-server` to ESM

GitOrigin-RevId: edc3b3bbba447dc2f897c66feaa835e04f52ec96
2024-11-21 09:03:39 +00:00
Andrew Rumble adecf0d5fe Merge pull request #21998 from overleaf/ar-fix-flaky-project-archive-test
[history-v1] Handle race condition in project archive test

GitOrigin-RevId: c32f4646f08223da0ed42068fa3fb613a6595b95
2024-11-21 09:03:35 +00:00
Miguel Serrano 623d88bee0 Merge pull request #21943 from overleaf/msm-ce-sp-noble
[CE/SP] Update phusion image to Noble (24.04)

GitOrigin-RevId: 6ff220210f9b40b5e68379dcaaf4bf97b20dd813
2024-11-21 09:03:28 +00:00
Jakob Ackermann 64fffb9d4d Merge pull request #21997 from overleaf/jpa-object-id-from-timestamp
[misc] add bin/object-id-from-timestamp helper

GitOrigin-RevId: e0eb5f90084dd6dd1d020f0b20fbd5fe9e9ede0f
2024-11-21 09:03:24 +00:00
Jakob Ackermann 0253130c36 Merge pull request #21972 from overleaf/jpa-get-project-blobs-batch
[history-v1] implement getProjectBlobsBatch

GitOrigin-RevId: f03dcc690ef63f72400ccf001c6e497bd4fbe790
2024-11-20 09:05:34 +00:00
Jakob Ackermann 4964d6414b Merge pull request #21982 from overleaf/jpa-cleanup
[history-v1] back_fill_file_hash: cleanup fs and graceful shutdown

GitOrigin-RevId: 362669ff988ad71fda713bf4896b1abcb36caf35
2024-11-20 09:05:30 +00:00
Jessica Lawshe 0b9b7da0e9 Merge pull request #21894 from overleaf/jel-cms-element-icon
[web] Website redesign stickers - update value in CMS to improve usability of element

GitOrigin-RevId: 07f3b4229da3ed0ed5b8ec350f2db16b49aa52e9
2024-11-20 09:05:26 +00:00
Mathias Jakobsen 17ea83937e Merge pull request #21975 from overleaf/mj-update-package-lock
Update package-locks

GitOrigin-RevId: 9e715207bdca01814e7d9833f6840dba26f2e366
2024-11-20 09:05:22 +00:00
M Fahru f59c3cd1e1 Merge pull request #21965 from overleaf/mf-integrate-form-checkout-company
[web] Integrate company details field into checkout page form

GitOrigin-RevId: 46d42f7acd2b2b55d0838ffd1e7351e86e08ff49
2024-11-20 09:05:15 +00:00
Jakob Ackermann 24f2388aa2 Merge pull request #21948 from overleaf/bg-jpa-back-fill-project-blobs
[history-v1] back_fill_file_hash: process blobs

GitOrigin-RevId: e54d0f8ab537ce43a12f9c972ba2ee82836073c8
2024-11-20 09:05:04 +00:00
Domagoj Kriskovic 99f77b2205 Fixed "Add comment" tooltip if cursor is out of viewport (#21852)
* Fixed "Add comment" tooltip if cursor is out of viewport

* account for cm-line padding when calulation tooltip pos

GitOrigin-RevId: f4b69a3bf83dd15c0304bfd6b37f3be8b07cd727
2024-11-20 09:05:00 +00:00
Jakob Ackermann fb36fff63d Merge pull request #21931 from overleaf/bg-get-all-blobs-for-project
add getProjectBlobs method to retrieve metadata for all blobs in a project

GitOrigin-RevId: 38f504a4fb56cd8ef8beaff1d8917ead26e85f5a
2024-11-20 09:04:56 +00:00
Jakob Ackermann 8e74d3c58c Merge pull request #21947 from overleaf/bg-jpa-back-fill-script-tweaks
[history-v1] back_fill_file_hash: performance tweaks

GitOrigin-RevId: c3d0c7906707fc902addcde64eaf41c24ceeece7
2024-11-20 09:04:51 +00:00
Antoine Clausse 87e7e3017a Migrate missing node:18 to node:20 (#21903)
GitOrigin-RevId: 0315d5df0ab1154d5ccadcbf11b09ec53df5728f
2024-11-20 09:04:47 +00:00
M Fahru a1d45aa264 Merge pull request #21942 from overleaf/ds-checkout-redesign-TrialCouponSummary
Checkout Redesign - Add the TrialCouponSummary component in redesign version

GitOrigin-RevId: 5d0483b403e13ce0a4d055ef449d4bc6938c42eb
2024-11-19 09:06:05 +00:00
M Fahru 8a8142414a Merge pull request #21915 from overleaf/as-checkout-address-fields
Add checkout redesign address fields

GitOrigin-RevId: c51c8ce32e0b33da8c768f61c6ce6170afec817e
2024-11-19 09:06:00 +00:00
Jessica Lawshe 931384c91d Merge pull request #21893 from overleaf/jel-font-color-option
[web] CMS BS5 - Add option to change font color

GitOrigin-RevId: 5fb4d7d3a910f30259748423922da0d2d67ee1cd
2024-11-19 09:05:56 +00:00
M Fahru 53955963ed Merge pull request #21901 from overleaf/mf-checkout-page-company-details
[web] Implement company details input fields in new checkout page

GitOrigin-RevId: b3a96a79046a8a5c684e6d986be2f467268db83f
2024-11-19 09:05:48 +00:00
M Fahru b3b94962b1 Merge pull request #21801 from overleaf/mf-checkout-page-card-element
[web] Checkout page redesign card input field UI

GitOrigin-RevId: 165116dc7b9d7998cd55c00075eba13731bea10e
2024-11-19 09:05:41 +00:00
M Fahru cf7ba7fb44 Merge pull request #21950 from overleaf/ds-checkout-redesign-renaming-editors-to-collaborators
Checkout page redesign - Renaming editors to collaborators

GitOrigin-RevId: 8c9538b9c9146e127ff6d490ec7eefaa25b2bdcf
2024-11-19 09:05:36 +00:00
M Fahru 4db676b4ee Merge pull request #21821 from overleaf/as-checkout-payment-switch
Add new version of payment method toggle for Checkout Redesign

GitOrigin-RevId: 0d5593e0b9fe90e9d5bfd47e07cbc675d7924da3
2024-11-19 09:05:32 +00:00
Eric Mc Sween ab36c80a26 Merge pull request #21954 from overleaf/em-revert-ai-add-on-deploy
Revert faulty AI add-on deploy

GitOrigin-RevId: 923ec89f01d4951596f83fcf58b820c39db1e54a
2024-11-19 09:05:27 +00:00
Jakob Ackermann 27076c50cc Merge pull request #21670 from overleaf/jpa-mongo-backend-types
[history-v1] add types to mongo BlobStore backend

GitOrigin-RevId: 7d91074eaa781904f7f3b56390aacee1800a7f67
2024-11-19 09:05:23 +00:00
Eric Mc Sween 087b612e16 Merge pull request #21869 from overleaf/em-repurchase-add-on
Repurchase the AI add-on when changing plans

GitOrigin-RevId: 1035e57af4c254fc73464f14010e4ba7e18cfe80
2024-11-19 09:05:18 +00:00
Eric Mc Sween d84d4dd093 Merge pull request #21937 from overleaf/em-total-per-year
Display "Total per year" for annual subscription change previews

GitOrigin-RevId: 90e6cd6ccc9f442b6ce1ec27f539202d2b6a7796
2024-11-19 09:05:14 +00:00
Eric Mc Sween 424fd5b591 Merge pull request #21839 from overleaf/em-subscription-change-preview-premium
Subscription preview for users with standalone AI add-on

GitOrigin-RevId: 636fa5aca8538bb95e79040d5c309dc505cfb17a
2024-11-19 09:05:09 +00:00
Eric Mc Sween 34fa1e12e7 Merge pull request #21898 from overleaf/em-ai-add-on-checkout-page
Adapt checkout page to standalone AI add-on

GitOrigin-RevId: ed877bc10c1dd4362c981000e0d783e370f3593a
2024-11-19 09:05:04 +00:00
Alf Eaton b617266c6d Merge pull request #21916 from overleaf/ae-spelling-cleanup
Spelling service cleanup

GitOrigin-RevId: 429071c6ad3cf55ae3cc6688cd1216ea7e9108fb
2024-11-19 09:05:00 +00:00
CloudBuild 3874cca29b auto update translation
GitOrigin-RevId: 474be90e5f927e55aeb441d33561509a17c22ad1
2024-11-18 09:06:45 +00:00
Jessica Lawshe dd18e1f91e Merge pull request #21863 from overleaf/jel-cms-row-cards
[web] Fix row options not applying when card option selected on row

GitOrigin-RevId: e191958f414b57d2033aa93b25bf9c0c2773299e
2024-11-18 09:06:37 +00:00
Jessica Lawshe f50aca2809 Merge pull request #21862 from overleaf/jel-wbr
[web] Add `<wbr />` so that text within brackets moves to new line

GitOrigin-RevId: 19a42ac02760528fdbb9557dc0ef96795eefb055
2024-11-18 09:06:33 +00:00
Jessica Lawshe 5c63188200 Merge pull request #21832 from overleaf/jel-search-badges
[web] Add tooltips when needed on badge links in gallery search results

GitOrigin-RevId: edcdcf8134698f17f607e003627a8b4123519b0b
2024-11-18 09:06:22 +00:00
Jessica Lawshe ade1b7f2bc Merge pull request #21890 from overleaf/jel-gallery-search
[web] Gallery search results title adjustments on smaller screens

GitOrigin-RevId: d07e042ba16457f806e7214081461e66635c7d51
2024-11-18 09:06:17 +00:00
Jakob Ackermann ca0a46b5bb Merge pull request #21928 from overleaf/jpa-handle-already-hard-deleted
[history-v1] backup-deletion-app: use deletedProjectOverleafHistoryId

GitOrigin-RevId: 169ba0fba71c42b0415e5fa40424547b054dd5b0
2024-11-18 09:06:13 +00:00
Jakob Ackermann dd15ade2b9 Merge pull request #21880 from overleaf/jpa-history-store
[history-v1] make HistoryStore generic and add backupHistoryStore

GitOrigin-RevId: 65d275de182dbcf5d4b6bf3c610b71b58db68e70
2024-11-18 09:05:48 +00:00
Jakob Ackermann 9cc6f2a9d5 Merge pull request #21829 from overleaf/jpa-backup-deletion
[history-v1] backup-deletion-app: initial revision

GitOrigin-RevId: 9e05c0e16595cb8d180861ef503c7b4522110d39
2024-11-18 09:05:44 +00:00
Jakob Ackermann 97b39ef98f Merge pull request #21681 from overleaf/jpa-back-fill-file-hash
[history-v1] add script for back filling hash into project file-tree

GitOrigin-RevId: 70ab8c72f3eea1062708e4471b4ad1c60317ad26
2024-11-18 09:05:39 +00:00
Jakob Ackermann d6e94d2586 Merge pull request #21908 from overleaf/jpa-storage-class
[object-persistor] s3: add support for setting storage class on upload

GitOrigin-RevId: dc5480a95ec7f1551f08848f7fa45f760d97ab22
2024-11-18 09:05:10 +00:00
Alf Eaton 36acad4d1b Rename $SectioningCommand to $SectioningCtrlSeq or $Section (#21534)
GitOrigin-RevId: 5b3173d82ec4c00fe69e2ab059bf48a872a4ca3e
2024-11-18 09:04:51 +00:00
Alf Eaton 2dee905361 Merge pull request #21535 from overleaf/ae-grammar-grouping
* Move $MathContainer grouping into the LaTeX grammar
* Remove $Environment grouping from NodeProp.group

GitOrigin-RevId: 96c74edd818bf84acf4b492702864c3c71a9bee3
2024-11-18 09:04:46 +00:00
Alf Eaton 79164f90d7 Fix "autocompile disabled" error in PDF preview (#21876)
GitOrigin-RevId: 3a7360b5d38614acf20353bd9bcdce8558472289
2024-11-18 09:04:41 +00:00
Jakob Ackermann 2be894c18a Merge pull request #21892 from overleaf/jpa-auto-gunzip
[object-persistor] add autoGunzip option to getObjectStream

GitOrigin-RevId: 21cd6c9ab349017ddb28d165238371d967ab9a59
2024-11-15 09:06:32 +00:00
Jakob Ackermann bd855044af Merge pull request #21891 from overleaf/jpa-consistent-getObjectSize-type
[object-persistor] gcs: return a number from getObjectSize

GitOrigin-RevId: f3e0e3269e789b0077c82014c42a4ca63cd84b39
2024-11-15 09:06:28 +00:00
CloudBuild b36bbdbd90 auto update translation
GitOrigin-RevId: 432b73d28a92e1128980964c0af43a656219f755
2024-11-15 09:06:24 +00:00
Jakob Ackermann 38b83d7edf Merge pull request #21881 from overleaf/jpa-missing-break
[object-persistor] s3SSEC: missing break statement in rootKEK discovery

GitOrigin-RevId: 3116a36006c9c7ae0b15593d8938fd559794a898
2024-11-15 09:06:14 +00:00
M Fahru 9dba1ccd8f Merge pull request #21854 from overleaf/as-checkout-name-fields
Add new Name fields for Checkout Redesign

GitOrigin-RevId: 448084e026a86510efe3c76c6663c0a770c24f8e
2024-11-15 09:06:07 +00:00
M Fahru e588b0748a Merge pull request #21728 from overleaf/as-checkout-currency-switcher
Add Bootstrap 5 Redesign variant of currency selector

GitOrigin-RevId: f0f4176f7d51835a7e15324be7cfcaab0af5bf36
2024-11-15 09:06:04 +00:00
M Fahru 1c10059c0a Merge pull request #21850 from overleaf/ds-payment-disclaimer-text
Checkout Redesign - Adding money back disclaimer text

GitOrigin-RevId: 5d5190c8fe8d1dd5254cc21498baa12d0bf18a4e
2024-11-15 09:06:00 +00:00
M Fahru 468278d621 Merge pull request #21757 from overleaf/ds-checkout-price-summary
Checkout redesign - Adding the price summary section on the left section of the page

GitOrigin-RevId: 2224b0ac0444afc1033fc007132cf69f4271c3b0
2024-11-15 09:05:56 +00:00
Andrew Rumble 11213d85fe Merge pull request #21883 from overleaf/ar-disable-keep-alive-remaining-services
Disable keepAlive in all services

GitOrigin-RevId: 9a3bac37e3fb09ee64b05cfda300dfe8d8672aad
2024-11-15 09:05:52 +00:00
Antoine Clausse c89002f1b8 [web] Migrate TPR promotions and form to BS5 (#21810)
* Update TPR promotions to BS5

* Remove unused class names

* Add responsive visibility in BS5

* Fix `OLFormControl` as `OLFormSelect`

With this update, it fixes the Select when importing from Mendeley or Zotero, in BS3 and BS5

* Use spacing variables in SCSS

GitOrigin-RevId: 8dd0e52a1674114bb3dc38fc4e3958a9c17ad5ac
2024-11-15 09:05:45 +00:00
Antoine Clausse 6b45dab5ad [web] Migrate Writefull notification to BS5 (#21814)
* Migrate Writefull notification to BS5

* Remove unused writefull classes in LESS file

GitOrigin-RevId: ed993df5e4f1abdfd7784308dda90e6596da60cf
2024-11-15 09:05:41 +00:00
Antoine Clausse bf26ef58a2 [web] Migrate "Manage Template" option in editor left menu to BS5 (#21799)
* Update manage template modal to BS5

* Update `ManageTemplateButton` to BS5

* Update `OLFormControl` prop types so it has its `as` props

* Update `LeftMenuButton` to BS5

* Fixup linting

* Update `ManageTemplateModalBody` style:

* Bold label
* Correct rows in BS3

* Set spinner color to `text-muted` instead of blue

* `npm run format:fix`

GitOrigin-RevId: c5311e4786b2859a8b7cf567d19cd3d7614dd3db
2024-11-15 09:05:37 +00:00
Antoine Clausse e038d5241e [web] Migrate all of the Git bridge modal in editor left menu to BS5 (#21786)
* Remove dead code: `GitBridgeOptionalTokensContent`

* Update git-brigde modal to BS5

* Update Check Icon to BS5

* Delete removed translations

GitOrigin-RevId: 6a2616939a307240994d5933f1e39bcdd3dfa053
2024-11-15 09:05:33 +00:00
Antoine Clausse 629435e87a Replace className="secondary" by variant="secondary" (#21672)
GitOrigin-RevId: a45532c2b4e927c3cc3a771eaf185ced4650f94c
2024-11-15 09:05:29 +00:00
Antoine ClausseandRebeka 1d4737ac69 [web] Changes to recompile button in Bootstrap 5 (#21586)
* Add Story for `PdfCompileButton`

* Set the CompileButton height so it's similar to BS3

* Add the CompileButton animations

* Remove `sm` from CompileButton: makes font size bigger

* Use MaterialIcon in compile-button dropdown-toggle

* Use MaterialIcon in LayoutDropdown

* Fix stripe alignment on Recompile button

* Set padding around dropdown caret

Per Alexandru's instructions

* Prevent border from disappearing on hover

* Set the padding of the compile button even on both sides

Before: left 12px, right 16px;
After: left 16px, right 16px;

* Change px values to spacing var

* Add some button classes for BS5 only

* Don't render the hidden "Compiling…" in BS5, it changes the button width

* Prevent `loading="[object Object]"` in the DOM

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>

---------

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>
GitOrigin-RevId: 34f1eed03e63f3459243a37c878612a623f321f8
2024-11-15 09:05:25 +00:00
Antoine ClausseandJakob Ackermann b0419a86f2 [web] Add audit logs for clear_sessions_set_must_reconfirm script, "must-reset-password-set" and "must-reset-password-unset" (#21776)
* Promisify clear_sessions_set_must_reconfirm.mjs

* Add test on PasswordResetTests.mjs

* Add `must-reset-password-unset` audit log

* Add `must-reset-password-set` audit log

* Add test ClearSessionsSetMustReconfirmTests.mjs

* Fixup bad copy-paste in test: `must-reset-password-set` -> `must-reset-password-unset`

* Check `must_reconfirm` before calling `removeReconfirmFlag`

Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>

* Fix unit test

* Use `promiseMapWithLimit`

* Add `{ script: true }` to AuditLog. Also use `undefined` instead of `null` for consistency

---------

Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>
GitOrigin-RevId: 522026c82196d263c196503d899b8c57b05b31dd
2024-11-15 09:05:21 +00:00
Jessica Lawshe da004d367b Merge pull request #21873 from overleaf/jel-website-redesign
[web] Don't underline entire body on hover

GitOrigin-RevId: 01612a11c0dd4d607d7c1aba5c89cbd97ae9a575
2024-11-15 09:05:08 +00:00
Eric Mc Sween 6c6ed06677 Merge pull request #21794 from overleaf/em-validate-plan-add-on
Add-on validation improvements

GitOrigin-RevId: 6812172fb431495ce34c2741c7c2c7c0d33685a6
2024-11-15 09:05:04 +00:00
Eric Mc Sween 571454bd71 Merge pull request #21745 from overleaf/em-subscription-change-preview-pay-now
Implement Pay Now button from the subscription change preview page

GitOrigin-RevId: b4b2835ecd366082af6b692b5e859f36091f98be
2024-11-15 09:05:00 +00:00
Mathias Jakobsen ec0d3c03f7 Merge pull request #21662 from overleaf/mj-ref-provider-text
[web] Update reference manager linking text

GitOrigin-RevId: b3614a7efead8cb2d6fb628dbfe8a750b4c39033
2024-11-15 09:04:53 +00:00
Tim Down 39a499b25a Merge pull request #21622 from overleaf/td-settings-link-colour
Enable redesign for account settings page and use application link colour

GitOrigin-RevId: dad039810256bda47061799ef56a9c87a663ab3d
2024-11-15 09:04:49 +00:00
Tim Down daaff1d9c6 Merge pull request #21815 from overleaf/td-bs5-references-search
[BS5] Migrate references search modal

GitOrigin-RevId: 65496840e32af09e5ae7351aa1789ebf5cac5083
2024-11-15 09:04:42 +00:00
Andrew Rumble 73b17dd694 Merge pull request #21627 from overleaf/ar-node-20
[all] node 20 upgrade v2

GitOrigin-RevId: aed13a800894717a796062e3dd4050e045040258
2024-11-15 09:04:32 +00:00
Alf Eaton eb693e41dc Fix Server CE dev environment (#21846)
GitOrigin-RevId: 456beadb67a3313262c1f4f88792719535b1991c
2024-11-15 09:04:28 +00:00
Jessica Lawshe 5f9790d762 Merge pull request #21802 from overleaf/jel-cms-card-body-margins
[web] CMS BS5 - Fix margins not getting removed when row is within a card

GitOrigin-RevId: 2cc8bde809d15936d99ccec7ed222166858b3ee4
2024-11-14 09:05:44 +00:00
Jimmy Domagala-Tang d93299d47d Merge pull request #21741 from overleaf/jdt-assist-paywall-routing
Direct users to the correct assistant add-on checkout

GitOrigin-RevId: 884d6e68458bc8f27ce79a4849f580a9ec0997fb
2024-11-14 09:05:36 +00:00
Jimmy Domagala-Tang 19dc975e3a Merge pull request #21699 from overleaf/jdt-hide-cancel-addon-when-cancelled-already
[Web] Handle add-on cancellation states on subscriptions page

GitOrigin-RevId: 2b834df6747560d54b7dc22e3870ee7a7e236498
2024-11-14 09:05:32 +00:00
Jimmy Domagala-Tang 1253d36dd3 Merge pull request #21690 from overleaf/jdt-ai-paywall-styles
Update freemium paywall cta with secondary styling

GitOrigin-RevId: d0d8105e8027d6002eac8bf0cbe0a173ea4a8053
2024-11-14 09:05:27 +00:00
Jimmy Domagala-Tang ad634c7e88 Merge pull request #21692 from overleaf/jdt-premium-secondary-button
Add premium-secondary button style

GitOrigin-RevId: 79ac9004a0b081eb1e7ac2af88ca1f976b997fe0
2024-11-14 09:05:19 +00:00
Jessica Lawshe 6e8cfb769f Merge pull request #21800 from overleaf/jel-cms-equal-col-height
[web] Fix equal column height on CMS BS5 pages

GitOrigin-RevId: 45ea490f1912cd621615e56bab4f1ffa3426c821
2024-11-13 09:05:51 +00:00
Jessica Lawshe 7977bc04cd Merge pull request #21765 from overleaf/jel-gallery-spacing
[web] Spacing updates on the gallery

GitOrigin-RevId: bf10c7ab5d8e05d54ac6834b1e5568c86b1ea767
2024-11-13 09:05:46 +00:00
M Fahru 2cf78229c0 Merge pull request #21768 from overleaf/mf-checkout-page-form-header
[web] Checkout page main header text

GitOrigin-RevId: 440e5e32c0377dcfeb1c3f466a47ea0b21517d31
2024-11-13 09:05:42 +00:00
M Fahru c5e1c63959 Merge pull request #21766 from overleaf/mf-checkout-main-layout-flexbox
[web] Use flex for layout of the new payment page to match figma width on the left card

GitOrigin-RevId: ca2b104ee50b7df0f352c3baaa610514e0432ffd
2024-11-13 09:05:38 +00:00
M Fahru 52eb08ae96 Merge pull request #21750 from overleaf/ds-checkout-left-section-description
Checkout redesign - Adding the left side description of the checkout page

GitOrigin-RevId: 62c3b9f7d9d4bec8f1d23cd760b76f1267089800
2024-11-13 09:05:34 +00:00
Andrew Rumble e5fd2a462c Convert references service to ES modules
GitOrigin-RevId: f904721ff81b291127fdc8750105846a9cf3ceb0
2024-11-13 09:05:23 +00:00
Andrew RumbleandJakob Ackermann ac84c582b1 Clear lock after every project structure test
Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>
GitOrigin-RevId: af64d6ce2c81df55923e73597c97de6f394d54bb
2024-11-13 09:05:11 +00:00
Christopher Hoskin 4324c4a089 Merge pull request #21554 from overleaf/ae-delete-spelling
Remove the spelling service

GitOrigin-RevId: ca7c17160e79d84740f32bbe9c73bc74c2714ffc
2024-11-13 09:05:00 +00:00
Alf Eaton da9de7fd9c Revert "Upgrade PDF.js to v4.8.69 (#21711)" (#21798)
This reverts commit 91e0298467034b651d013d73bc41a9efcae7a729.

GitOrigin-RevId: 35830409e1d58371922d58ca50932e1752351403
2024-11-13 09:04:55 +00:00
Eric Mc Sween eec87af5ff Merge pull request #21575 from overleaf/em-big-query-add-ons
Fix RAW.REC_subscription_history table in BigQuery

GitOrigin-RevId: 47507e17e819341a2663e4aadd8fea04b0e7a02d
2024-11-13 09:04:50 +00:00
Domagoj Kriskovic 8a90ffa3fb Add confirm modal on accept/reject selected changes (#21540)
* Add showGenericConfirmModal in ModalsContext

* Add confirm modal on accept/reject selected changes

* plural in translations

* change tooltip to include selected changes

* add _plural to all translated languages

* lowercase title/tooltip

* count replacements as single change

* use new translation key

GitOrigin-RevId: afadbe1eeb2a290688b96f2b5388485f40c958d0
2024-11-12 09:06:01 +00:00
Domagoj Kriskovic edb4e3d537 Improve selection detection for "Add comment" tooltip (#21731)
GitOrigin-RevId: cd13cacea0d6e45015997f3a831d0f127ddf8cd8
2024-11-12 09:05:57 +00:00
Jakob Ackermann 805c4f8321 Merge pull request #21764 from overleaf/jpa-esm-build-scripts
[misc] prepare linting for ESM files in services

GitOrigin-RevId: 468983ebff40617158bac28514381a6aaf725893
2024-11-12 09:05:50 +00:00
Jakob Ackermann 61c7c728ad Merge pull request #21755 from overleaf/jpa-history-initialize-project
[history-v1] tests: use createEmptyProject helper consistently

GitOrigin-RevId: 80d979091d80c53c780919700561849d9703368e
2024-11-12 09:05:46 +00:00
Alf Eaton 76c7c3e28e Fix dirtyState handling in ranges context (#21724)
GitOrigin-RevId: 44f3aa9efc6dbd0d34a2b0440054197398a62caf
2024-11-12 09:05:42 +00:00
Alf Eaton fe2ff49c72 Merge pull request #21756 from overleaf/rd-mobile-nav-ui
[web] Fix vertical padding of links in the main navigation on small screen sizes

GitOrigin-RevId: feebbada37df1185fb612423458f8ba1f1b1f3b3
2024-11-12 09:05:34 +00:00
Alf Eaton 66fee7a794 Only use the LaTeX indent service for when inserting a line break (#21530)
GitOrigin-RevId: 15c5e5afdee59badc833fe2deb13a80b3c409862
2024-11-12 09:05:30 +00:00
Alf Eaton 54ec174331 Upgrade PDF.js to v4.8.69 (#21711)
GitOrigin-RevId: 91e0298467034b651d013d73bc41a9efcae7a729
2024-11-12 09:05:23 +00:00
Miguel Serrano 53d84efb3a Revert "[web] Send email to support when skipping deleting pro group subscrip…" (#21780)
This reverts commit 8a4abe0742ab6a1c6b15bb17b5cc4863a11010b2.

GitOrigin-RevId: 2b91b8a127d195f4297fe99653fb69664b2a91a7
2024-11-12 09:05:18 +00:00
Miguel Serrano a6deee4961 Revert "[web] Prevent subscription downgrades (#19895)" (#21779)
This reverts commit b0ff548b4e1bf5843a96885b3176fdf11a49a2e1.

GitOrigin-RevId: b01c0800c62b83da8db2e01fc1fb6ca09e099c4d
2024-11-12 09:05:14 +00:00
Miguel Serrano 1b80f172d7 [web] Prevent subscription downgrades (#19895)
* Notify support when subscription deletion skipped

GitOrigin-RevId: b0ff548b4e1bf5843a96885b3176fdf11a49a2e1
2024-11-12 09:05:00 +00:00
CloudBuild 77cfdb391c auto update translation
GitOrigin-RevId: de1c41be6b92b9b2920932965f0845da783f301d
2024-11-12 09:04:55 +00:00
Jessica Lawsheandmserranom 4d8a6c5c9d [web] Send email to support when skipping deleting pro group subscription (#19971)
* Move group SSO enabled check up

So that we have this available when managed users is enabled. This will be useful in the following commit.

* Notify support when subscription deletion skipped

* Fix rebase conflicts

---------

Co-authored-by: mserranom <mserranom@gmail.com>
GitOrigin-RevId: 8a4abe0742ab6a1c6b15bb17b5cc4863a11010b2
2024-11-12 09:04:48 +00:00
Miguel Serrano 7f675ac006 Merge pull request #20936 from overleaf/msm-launchpad-esm
[web] Migrate `modules/launchpad` to ESM

GitOrigin-RevId: 6730aa82698e9d98d57e6ce53c91211b0dbb4740
2024-11-12 09:04:44 +00:00
Miguel Serrano 5170f28a4f Merge pull request #21648 from overleaf/msm-disable-ce-survey
[web] Remove CE Survey

GitOrigin-RevId: e492ced24b2c289a8d41f4e0e3215079ff5e7829
2024-11-12 09:04:39 +00:00
ilkin-overleaf 6345ec3b04 Merge pull request #21712 from overleaf/ii-flexible-group-licensing-confirmation-page
[web] Request confirmation page for flexible licensing

GitOrigin-RevId: 855dcbd46c645da75b8c641f0c49670b2e04df3f
2024-11-12 09:04:35 +00:00
Brian Gough fc84bdf68b Merge pull request #21751 from overleaf/bg-record-background-flush-operations
record background flush operations in project-history

GitOrigin-RevId: 80169b3f93a844d7162322ca21d605fffc64d687
2024-11-11 09:05:35 +00:00
M Fahru 2939282a7f Merge pull request #21725 from overleaf/ds-payment-page-layout
Checkout Redesign - adding the layout of the checkout page

GitOrigin-RevId: e48feed16b69e26ec3b4d1935c1db169c16172e9
2024-11-11 09:05:30 +00:00
Jessica Lawshe aa782b2737 Merge pull request #21733 from overleaf/jel-tooltip-badges
[web] Fix tooltips not always added to badge links

GitOrigin-RevId: d4e80f3bb62bce2083dec261ffd5634510310127
2024-11-11 09:05:26 +00:00
Domagoj Kriskovic 8b0b923063 Fix "show more/less" options in new review panel (#21700)
* Fix "show all/less" options in new review panel

* added newLineCharsLimit, inline options

* fix scss lint

GitOrigin-RevId: 98f29c76d4efda225515162cde0961e55acd5545
2024-11-11 09:05:21 +00:00
Mathias Jakobsen 595c60327e Merge pull request #21737 from overleaf/dp-eq-preview-beta-badge-v2
Update split test badge for math preview tooltip V3

GitOrigin-RevId: 9ff41f5bc68ba6cd4d7a1c7e8d5f1f725369c02a
2024-11-11 09:05:17 +00:00
Mathias Jakobsen cb72799fff [web] Add toast notifications to editor (#21567)
GitOrigin-RevId: 7f7ab83d4615f564c0e79bc2a05ca6cb9e5239fd
2024-11-11 09:05:12 +00:00
Alf Eaton a50d76f4ea Remove web /spelling/check endpoint (#21740)
GitOrigin-RevId: f10ebfec08ba1156eafce45078bc783ca934864d
2024-11-11 09:05:04 +00:00
Antoine Clausse 5821dc7273 [web] Fix main branch linting error (#21749)
* Sync package-lock

I get this change when running `make install && bin/npm i`

* Add `featureUsage` to LoggedOutUser keys

We might want to change this to something like this:

```
export type NullifyProperties<T> = {
  [P in keyof T]: undefined
}

export type LoggedOutUser = {
  id: null
} & NullifyProperties<Omit<User, 'id'>>
```

* Revert "Sync package-lock"

This reverts commit 982466eba3f8d72a388d248b66658be0350b2d09.

* Remove `canceledSubscription` types for now

This is breaking the build at the moment. We can work on creating a `Request` that matches our usages of it

GitOrigin-RevId: bb21baba6a074c2169af786a9e56b33beddddd2f
2024-11-11 09:04:56 +00:00
Antoine Clausse 7f48c67512 Add prefer-node-protocol ESLint rule (#21532)
* Add `unicorn/prefer-node-protocol`

* Fix `unicorn/prefer-node-protocol` ESLint errors

* Run `npm run format:fix`

* Add sandboxed-module sourceTransformers in mocha setups

Fix `no such file or directory, open 'node:fs'` in `sandboxed-module`

* Remove `node:` in the SandboxedModule requires

* Fix new linting errors with `node:`

GitOrigin-RevId: 68f6e31e2191fcff4cb8058dd0a6914c14f59926
2024-11-11 09:04:51 +00:00
Rebeka Dekany 4563273396 Merge pull request #21680 from overleaf/rd-dyslexic-font
Add OpenDyslexic Mono typeface font to the source editor

GitOrigin-RevId: 8826e51cfa50f1d5ffc2217fb86fb4d1dec21b92
2024-11-11 09:04:42 +00:00
Antoine Clausse 5462fcd128 [web] Set layout-react in Subscription pages (#21529)
* Update `User` type

* Set `layout-react`: `subscriptions/successful-subscription-react`

* Set `layout-react`: `subscriptions/canceled-subscription-react`

* Set `layout-react`: `subscriptions/dashboard-react`

* Set `layout-react`: `subscriptions/team/invite-managed`, `subscriptions/team/invite`, `subscriptions/team/invite_logged_out`

* Set `layout-react`: `subscriptions/team/group-invites`

* Add `header-footer-react` to subscription/base.js

* Fix: Replace `date-type` by `data-type`

* Fix SubscriptionControllerTests

GitOrigin-RevId: b9049a9093a700b3be1bf33809e3a1494022350a
2024-11-11 09:04:32 +00:00
Antoine Clausse 59a1cc2c7a Merge pull request #21718 from overleaf/td-bs5-nav-logged-out
[BS5] Add missing logged-out items to React nav bar

GitOrigin-RevId: 3dc681dcac46cdb68675f6034be56e2b96292c32
2024-11-11 09:04:21 +00:00
Antoine Clausse 455fbd8cc3 Update loading spinner in Chat (#21624)
GitOrigin-RevId: 6af510b7e229249dd5192ceba2ec88e95339cab5
2024-11-11 09:04:16 +00:00
Jakob Ackermann b257625f07 Merge pull request #21748 from overleaf/jpa-publish-mongo-utils
[copybara] publish mongo-utils library

GitOrigin-RevId: 0ef269f186ed645f7bcb9d948a4d1e591c687b31
2024-11-08 09:42:02 +00:00
Jakob Ackermann 252533b2fd Merge pull request #21668 from overleaf/jpa-mongo-utils
[mongo-utils] create new home for batchedUpdate helper

GitOrigin-RevId: 9f61c5e367a9f4cef63b5cc4c0bbbd3ef57c8ca8
2024-11-08 09:07:09 +00:00
Jakob Ackermann a3d8caf87b Merge pull request #21664 from overleaf/jpa-blob-hash
[overleaf-editor-core] stricter types for Blob interface

GitOrigin-RevId: 8595fce0d5c98074d2313be5a5634e80f92c68b5
2024-11-08 09:07:05 +00:00
Jakob Ackermann 122d89a831 Merge pull request #21660 from overleaf/jpa-s3-https
[object-persistor] s3: simplify using a custom CA for HTTPS endpoints

GitOrigin-RevId: 2c6a5312a842582e5e40e917ccc586392087cb7a
2024-11-08 09:07:00 +00:00
Jakob Ackermann 65dc6bf940 Merge pull request #21631 from overleaf/jpa-live-s3
[object-persistor] s3SSEC: make compatible with AWS S3

GitOrigin-RevId: 3cd1f5ec43141f15defe081fc916d2ca2d78ca01
2024-11-08 09:06:55 +00:00
Jakob Ackermann d5478c11ea Merge pull request #21623 from overleaf/jpa-s3-ssec-static-dek-path
[object-persistor] s3SSEC: use static path for DEK inside project folder

GitOrigin-RevId: 0c43ef8964c16d3e7638f17ff47b1c4641e439df
2024-11-08 09:06:51 +00:00
Jakob Ackermann a67560c26b Merge pull request #21589 from overleaf/jpa-s3-ssec-hkdf
[object-persistor] s3SSEC: add HKDF layer to KEK

GitOrigin-RevId: 1def9e378e1dfd90f449ad392b0db2101584e17f
2024-11-08 09:06:46 +00:00
Jakob Ackermann bec73ddfae Merge pull request #21543 from overleaf/jpa-s3-seec-kek-rotation
[object-persistor] s3SSEC: add support for (automatic) KEK rotation

GitOrigin-RevId: 315082e894c74e276a8efbc46b41ec7e102f9010
2024-11-08 09:06:42 +00:00
Jakob Ackermann 859901ac0c Merge pull request #21380 from overleaf/jpa-s3-ssec-backend
[object-persistor] add backend for SSE-C with S3 using KEK and DEK

GitOrigin-RevId: 9676f5cd5e08107c8c284b68b8d450a1c05bf1b1
2024-11-08 09:06:37 +00:00
CloudBuild 776647d62a auto update translation
GitOrigin-RevId: 96e1603b6e71d6cfbf5e9cdb47a9fe46be7e35e3
2024-11-08 09:06:32 +00:00
Domagoj Kriskovic 83bed793f5 Add sort:true when updating decorations for delete highlight (#21715)
GitOrigin-RevId: afd5aed5a4ea1ff7f9439155b5150b23666b0cc7
2024-11-08 09:06:28 +00:00
Domagoj Kriskovic 72f03b39c6 Hide "add comment" tooltip on mouse down (#21721)
* Hide "add comment" tooltip on mouse down

* using EditorView.domEventHandlers

GitOrigin-RevId: 48b7626d5c1be8a3fb0b1ee1fcc1bc7738f8dbc5
2024-11-08 09:06:23 +00:00
Jessica Lawshe ce8781e79f Merge pull request #21694 from overleaf/jel-tooltip-when-needed
[web] Only add tooltip to badge links if badge is clipped

GitOrigin-RevId: c99f3f0732ed6e8112c1af1063f64bcab152b00d
2024-11-08 09:06:19 +00:00
Jessica Lawshe d6281424f4 Merge pull request #21632 from overleaf/jel-badge-width
[web] Update `max-width` on tag links on template page and blog pages and add tooltips

GitOrigin-RevId: ba25d0850b693f72b36e9faca64025c60ebd44dd
2024-11-08 09:06:14 +00:00
Jessica Lawshe 5e58370b8c Merge pull request #21689 from overleaf/jel-fix-related-tags
[web] Fix gallery related tags height

GitOrigin-RevId: 11c2865edddf40768c8edfacef629ed281210e3d
2024-11-08 09:06:10 +00:00
David 637185025f Merge pull request #21722 from overleaf/dp-revert-badge-changes
Revert "Merge pull request #21687 from overleaf/dp-eq-preview-beta-ba…

GitOrigin-RevId: 8347b1bc3b02194bf5c2c657fc85ebefb3b0cf3a
2024-11-08 09:06:01 +00:00
Rebeka Dekany a0a164c4d0 Merge pull request #21709 from overleaf/rd-fix-command-tooltip-size
[web] Fix href command tooltip width in the editor

GitOrigin-RevId: d76e5961bd97ca16e47aa6b1eda68f4488caff69
2024-11-08 09:05:35 +00:00
David bd15e3cc5c Merge pull request #21687 from overleaf/dp-eq-preview-beta-badge
Update split test badge for math preview tooltip

GitOrigin-RevId: fbdc7b42d3ce51f405f75232fbfd357ee6afc2a3
2024-11-08 09:05:31 +00:00
Alf Eaton c6a186d436 Update E2E editor tests (#21704)
GitOrigin-RevId: a5613554f4942a8ec6d09423387cd0d93e9b1f6c
2024-11-08 09:05:19 +00:00
Alf Eaton 9659294459 Add hint_unicode_character rule (#21593)
GitOrigin-RevId: ba2c6f49c3b20c6fb4708dfd80000a216c3c4a77
2024-11-08 09:04:53 +00:00
Alf Eaton 31e7f113f8 Wrap all view.dispatch in setTimeout (#21590)
GitOrigin-RevId: a78e314683642e173c61b0bef95b30f5b96c82b5
2024-11-08 09:04:48 +00:00
Alf Eaton 9352b51d28 Keep PDF preview mounted while not visible (#21270)
GitOrigin-RevId: 266ecbb72a5238e1e977265e56c33880ec1a54be
2024-11-08 09:04:44 +00:00
Alf Eaton db8d7a7af0 Upgrade CodeMirror dependencies (#20618)
GitOrigin-RevId: c1d45e73784fd26db09e9930bc504d2d78c05b12
2024-11-08 09:04:39 +00:00
Jessica Lawshe 9cfec57c1d Merge pull request #21679 from overleaf/jel-template-mobile
[web] Go back to full width on mobile for gallery details

GitOrigin-RevId: 82ecefbd96d3693ec62ccfb70ed0eba2287bbc36
2024-11-07 09:05:21 +00:00
Jessica Lawshe 1e17fa7057 Merge pull request #21630 from overleaf/jel-template-labels-nowrap
[web] Don't wrap labels on template page

GitOrigin-RevId: 5c7fb124cf3f6c29ffc7ae3e6a8232f2b570a4b9
2024-11-07 09:05:14 +00:00
David dfcc805549 Merge pull request #21526 from overleaf/dp-dismiss-equation-preview
Add options to disable/hide equation preview

GitOrigin-RevId: 5f71b4c747bf27ae816bdfe32c6e3e5a42f99508
2024-11-07 09:05:07 +00:00
Eric Mc Sween d95981cb0c Merge pull request #21682 from overleaf/em-revert-ranges-tracker-changes
Revert RangesTracker fix for multiple tracked deletes at same position

GitOrigin-RevId: ee6ade406a86319f5551863e18ed40d508128ecb
2024-11-07 09:05:03 +00:00
Eric Mc Sween 29be4f66d4 Merge pull request #21556 from overleaf/em-subscription-change-interstitial
Add-on purchase preview page

GitOrigin-RevId: 660e39a94e6112af020ea783d6acf01a19432605
2024-11-07 09:04:49 +00:00
Eric Mc Sween bc1e3dacda Merge pull request #21643 from overleaf/em-tracked-deletes-at-same-position
Improve handling of tracked delete rejections

GitOrigin-RevId: 79308539f5e7af70f6292a0fd6352e882eac84dd
2024-11-07 09:04:45 +00:00
Jakob Ackermann c9a6724790 Merge pull request #21667 from overleaf/jpa-more-node-18-20-4
[misc] bump a few more Node.js versions to 18.20.4

GitOrigin-RevId: 6097d2a9d3df99b1c1ef0aa397762b09406808e3
2024-11-07 09:04:38 +00:00
Andrew Rumble 57d12dfb17 Update to node 18.20.4
GitOrigin-RevId: 4b613ea3973cb7944c3d414ea91bcf367dbf50a6
2024-11-07 09:04:31 +00:00
Andrew Rumble 7fb5d1f0f7 Remove ip from monorepo services
GitOrigin-RevId: ea734787fbf31fd667aebe928ecc1e9785ac1185
2024-11-07 09:04:27 +00:00
Andrew Rumble 22d3e4bc13 Merge pull request #21597 from overleaf/ar-fix-error-assistant-error-in-e2e-tests
[web] Make sure aiErrorAssistant exists before using

GitOrigin-RevId: 31a4a6a2aa152aee6620c8e44e44dea3c6bf3b44
2024-11-06 09:06:03 +00:00
Jessica Lawshe 80b3ad255d Merge pull request #21474 from overleaf/mf-add-device-segmentation-gallery-view-events
[web] Add `device` and `screen-breakpoint` segmentation to all gallery-related page view events

GitOrigin-RevId: 36cfb5c5d183645782efe8c66c09f476d5474253
2024-11-06 09:05:58 +00:00
Jessica Lawshe 551dad7c2c Merge pull request #21518 from overleaf/jel-template-title
[web] Badges inline with last line of title on template page

GitOrigin-RevId: cdaa7fd6dbaa2a37f3f60a17be280c3b92dac695
2024-11-06 09:05:47 +00:00
Jessica Lawshe bd0aa92c4f Merge pull request #21553 from overleaf/jel-plans-input
[web] Remove width on group license number input so that some browsers do not obscure option

GitOrigin-RevId: fbfa51104839c5345199a94a9f7dc34a62568988
2024-11-06 09:05:42 +00:00
Jessica Lawshe f0e989be0c Merge pull request #21468 from overleaf/jel-cms-group-spacing
[web] Spacing options for `Style | Group`  and `Element | Content` on CMS

GitOrigin-RevId: 78d7d8e29be81a1526e4eeceb50fe66846ed8a05
2024-11-06 09:05:38 +00:00
Jessica Lawshe 40af0fa84f Merge pull request #21552 from overleaf/jel-cms-rows
[web] Fix parent row styling applying to nested rows on CMS pages

GitOrigin-RevId: 047c24fcff4ac73b0d0db403d728e3e3e8876b6f
2024-11-06 09:05:33 +00:00
Jessica Lawshe c27dc70c80 Merge pull request #21516 from overleaf/jel-template-labels
[web] Use grid layout for template details

GitOrigin-RevId: 1f15dfcd9bc04bec5bd7e0b6a7b1230966def997
2024-11-06 09:05:29 +00:00
Alf Eaton 562a4e4ce6 Avoid spell checking list environment arguments (#21483)
GitOrigin-RevId: 8fe56c53b503abddcc4f0d996707e3df12309362
2024-11-06 09:05:17 +00:00
Alf Eaton 7fa8c01e31 Disable spell check in setlength arguments (#21491)
GitOrigin-RevId: 279f5df7c97b6a6caa5a344bf50b0747402cf61d
2024-11-06 09:05:13 +00:00
Alf Eaton a827f8835b Focus the editor after using the "Switch to editor" button (#21549)
GitOrigin-RevId: f94c6d266ec9c2c3e4a30ea2c34c937817b48596
2024-11-06 09:05:08 +00:00
Rebeka Dekany 09ad023161 Merge pull request #21561 from overleaf/rd-ide-paste
Migrate the editor pasted content popover to Bootstrap 5

GitOrigin-RevId: 2f89d0d6818e219dc5b786b5f21d4d47a91b06c8
2024-11-06 09:05:04 +00:00
CloudBuild 25123e310b auto update translation
GitOrigin-RevId: 782a872442f832078ea7951c10d8a6c4f29d7f28
2024-11-05 09:05:53 +00:00
Jimmy Domagala-Tang 9818912cb7 Merge pull request #20968 from overleaf/jdt-subscription-page-addons
feat: add all add-ons to price calculation in subs view model
GitOrigin-RevId: d03374192d735278c6459fc6341a72d0b0c7c3aa
2024-11-05 09:05:49 +00:00
Jimmy Domagala-Tang 811e935ced Merge pull request #21107 from overleaf/jdt-error-assistant-freemium
Convert Ai Error Assistant to a Freemium Model

GitOrigin-RevId: 348c19262928d7dde8236baf37663c85d91f101a
2024-11-05 09:05:45 +00:00
Jimmy Domagala-Tang 745695650c Merge pull request #21470 from overleaf/jdt-file-upload-limit-notif
[Web] Update 180 file upload limit notification style

GitOrigin-RevId: 860567d8e1218c0d2a89d019c116b59be15132e7
2024-11-05 09:05:41 +00:00
Tim Down 8e2ad427c8 Merge pull request #21502 from overleaf/td-bs5-file-outline-highlight
[BS5] Add highlight colours for file outline items

GitOrigin-RevId: e024d1bb093eb8bb56f63647d4753b2e626ec513
2024-11-05 09:05:34 +00:00
Tim Down f57704b844 Merge pull request #21566 from overleaf/td-bs5-website-redesign
Add website redesign query string override to arbitrary BS5 pages

GitOrigin-RevId: 72816f00d6e2e92dab21035097abc540689af1d3
2024-11-05 09:05:30 +00:00
Tim Down 571ece201f Merge pull request #21500 from overleaf/td-bs5-math-preview
[BS5] Migrate math preview

GitOrigin-RevId: 0da768afdd98f81554f6820049432283ca8f9735
2024-11-05 09:05:26 +00:00
Liangjun Song b00483653e Merge pull request #21568 from overleaf/ls-script-to-lowercase-external-user-id-lint-fix
fix lint error

GitOrigin-RevId: 4aac5657e46ba638737e9eba9c156ecc9e8bd1fd
2024-11-05 09:05:19 +00:00
Liangjun Song 7af96a49f6 Merge pull request #21547 from overleaf/ls-script-to-lowercase-external-user-id
script to lowercase external user ids

GitOrigin-RevId: 8651f638feab4a92c15fe3748377492d5107b539
2024-11-05 09:05:15 +00:00
Rebeka Dekany caa446f933 Merge pull request #21512 from overleaf/rd-insert-link
Migrate the editor command tooltips to Bootstrap 5

GitOrigin-RevId: 9e3b477608e334e6e8bc0e79710cd2b3878680e6
2024-11-05 09:05:09 +00:00
David 1c7e4ddcd2 Merge pull request #21450 from overleaf/dp-focus-entry
Refactor how ReviewPanel and TrackChangesWidget are rendered

GitOrigin-RevId: 0b206a2a70270a885befdcf2403da4e1af3aa9bf
2024-11-05 09:04:54 +00:00
Domagoj Kriskovic 21464f200e Hide tooltip on click in PDF controls menu (#21546)
GitOrigin-RevId: cfaebb7a55d2a80814c0e326b54f84f2e76a8879
2024-11-05 09:04:50 +00:00
Davinder Singh 684731638a Merge pull request #21195 from overleaf/ds-adding-tooltips-trigger-bs5
BS5 Migration - Adding tooltips trigger for BS5 styling

GitOrigin-RevId: 0a446af5bc72f28ec8e2512fd4b248a6b78221a2
2024-11-05 09:04:46 +00:00
Antoine Clausse eea27a36a4 [web] Add prefer-node-protocol ESLint rule (#21523)
* Add `unicorn/prefer-node-protocol`

* Revert non-web changes

* Run `npm run lint:fix` (prefer-node-protocol)

GitOrigin-RevId: c3cdd88ff9e6b3de6a4397d45935c4d026c1c1ed
2024-11-05 09:04:33 +00:00
Antoine ClausseandIlkin Ismailov 053831b48c [web] Spelling correction Dropdown to BS5 (#21493)
* Split `SpellingSuggestions` into a BS3 and BS5 version

* Migrate `B5SpellingSuggestions` to BS5

* Add `.dropdown-menu.dropdown-menu-unpositioned` styles

This makes the dropdown position itself without overflows

* Make spelling tooltip background transparent

* Migrate Cog icon to BS5

* Use `PolymorphicComponent`

Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com>

* Fix formatting

---------

Co-authored-by: Ilkin Ismailov <ilkin.ismailov@overleaf.com>
GitOrigin-RevId: aaa6c589637971031d13ac099f935fe2052e6989
2024-11-05 09:04:28 +00:00
CloudBuild d4fa37b75d auto update translation
GitOrigin-RevId: 021e0ba6562a33b9fa2d7e969e9f2b944bcd2a0d
2024-11-04 09:05:18 +00:00
Rebeka Dekany 850bbceab6 Merge pull request #21238 from overleaf/rd-github-sync
Migrate the Github Sync modal to Bootstrap 5

GitOrigin-RevId: a6178fc2e9c7072d28d0a1b094b42dff12944781
2024-11-04 09:05:14 +00:00
Rebeka Dekany d37cbf8edb Merge pull request #21515 from overleaf/rd-review-icon
Update review icon in the editor header to use Material Symbols in BS5

GitOrigin-RevId: 14fec744e9bf52b3c37a82164ec3340b4a9a4e3a
2024-11-04 09:05:07 +00:00
Rebeka Dekany e2d63a778b Merge pull request #21135 from overleaf/rd-dev-toolbar
Migrate the Dev Toolbar to Bootstrap 5

GitOrigin-RevId: c102883171e5e40c6b9a2f808f305ab1d4fb553f
2024-11-04 09:05:03 +00:00
Rebeka Dekany ccb639bcea Merge pull request #21497 from overleaf/rd-file-tree-line-break
[web] The file tree toolbar should not wrap onto two lines at small width

GitOrigin-RevId: ff2d3037b5f389ba104850d6674e0bc3a50867ee
2024-11-04 09:04:59 +00:00
Jakob Ackermann bf2ad1952c Merge pull request #21506 from overleaf/jpa-fix-batched-update-edge
[web] fix edge behavior of batchedUpdate

GitOrigin-RevId: 5d1c0b884aa02c52682d114fa66b2d9b201e724e
2024-11-04 09:04:55 +00:00
Tim Down 2402f9ea99 Merge pull request #21521 from overleaf/td-bs5-subscription-contact-error
[BS5] Remove redundant contact form import in subscription page

GitOrigin-RevId: f4e89d1afe59b65c3bbab3e2fffe3ebfeb774f71
2024-11-04 09:04:45 +00:00
ilkin-overleaf 1033e73844 Merge pull request #21477 from overleaf/ii-bs5-table-generator
[web] BS5 table generator

GitOrigin-RevId: 3fe10c05fa36f026c47ff4f54b15f5d76f7c509e
2024-11-04 09:04:41 +00:00
Andrew Rumble ba7d11d854 Merge pull request #21105 from overleaf/ar-es-module-helper-scripts
[web] ES module helper scripts

GitOrigin-RevId: ebbb123b6e7336215038156b83e96ad42869bb07
2024-11-04 09:04:30 +00:00
Andrew Rumble 0eaf02b4fa Merge pull request #21303 from overleaf/revert-21300-revert-20641-ar-organisation-mapping-analytics-pipeline
Revert "Revert "[web] [v1] Send salesforce modification events to analytics queues""

GitOrigin-RevId: cfcd7a6e25ad0902c699e1a34e8654347ebf71fb
2024-11-04 09:04:26 +00:00
CloudBuild 6f80ec0820 auto update translation
GitOrigin-RevId: 83a2122c927088c26c082ae23951663970f22d39
2024-11-01 09:06:00 +00:00
M Fahru 81395a9b9e Merge pull request #21452 from overleaf/mf-fix-bs5-navbar
[web] Add missing css rules for the `primary` navbar link item style

GitOrigin-RevId: a1e2428f994af52c8af01371eca39cc16526566c
2024-11-01 09:05:47 +00:00
M Fahru 51e41c99d8 Merge pull request #21418 from overleaf/mf-add-pagination-hover-transition
[web] Add transition to pagination on hover

GitOrigin-RevId: ce9c1ed70d8b494b493f3d1121369307728a4ca6
2024-11-01 09:05:43 +00:00
M Fahru 1547325073 Merge pull request #21377 from overleaf/mf-add-countryCode-to-view-plans-and-interstitial-page-new
[web] Add missing `countryCode` in new-design plans page and all variants of the interstitial payment page

GitOrigin-RevId: e3a410e89a6745d042f9747a01960618eb622733
2024-11-01 09:05:36 +00:00
M Fahru d0df44b190 Merge pull request #21446 from overleaf/jel-content-pages-btn
[web] Fix spacing between `.btn` on gallery pages

GitOrigin-RevId: f3603ffb0a64b69fd3f12eae74639599aa5f8c9a
2024-11-01 09:05:32 +00:00
Jakob Ackermann 9745c045ba Merge pull request #21510 from overleaf/jpa-dependency-cleanup
[web] dependency cleanup

GitOrigin-RevId: 5b1e0ace2b0acfd7b1b839520f7c24acda8027e3
2024-11-01 09:05:28 +00:00
Jakob Ackermann 5bb90dc6cb Merge pull request #21442 from overleaf/jpa-align-mongo-version
[misc] align all the mongodb dependency versions

GitOrigin-RevId: 1194fe57601af98bb61250a285bfc85b4b8179dd
2024-11-01 09:05:23 +00:00
Jakob Ackermann 0e4c87d131 Merge pull request #21441 from overleaf/jpa-batched-update-types
[web] add types to batchedUpdate

GitOrigin-RevId: a4ab8951bb43fbae6d90ac7a7afbaa781accdc39
2024-11-01 09:05:19 +00:00
Jakob Ackermann a7517eefcb Merge pull request #21427 from overleaf/jpa-populate-db-on-import
[web] populate db with collections on import, ahead of waitForDb() call

GitOrigin-RevId: 7eb4cd61c2052187acd9947d7060f54d9822d314
2024-11-01 09:05:15 +00:00
Jakob Ackermann 7b3e39f63f Merge pull request #21375 from overleaf/jpa-if-none-match
[object-persistor] add support for ifNoneMatch=* in sendStream

GitOrigin-RevId: 268f054ac1b6452105b02757cdec32bad00702fd
2024-11-01 09:05:11 +00:00
Jakob Ackermann a551a0e9f7 Merge pull request #21361 from overleaf/jpa-filestore-minio
[filestore] migrate to minio as S3 backend for running tests against

GitOrigin-RevId: aa098d8baa4445f5dec7d651b6cf5ed081b0a331
2024-11-01 09:05:07 +00:00
ilkin-overleaf e1149e80b3 Merge pull request #21480 from overleaf/ii-bs5-synctex-buttons
[web] BS5 synctex buttons cursor

GitOrigin-RevId: a397571e6b2d934c96e6d4477b68e049158806e5
2024-11-01 09:05:00 +00:00
Tim Down c531d55f29 Merge pull request #21431 from overleaf/td-bs5-pdf-zoom-arrow
[BS5] Change PDF zoom button so that arrow size matches text size

GitOrigin-RevId: e989cb96c67c0f14957696fc31fba2355230eb71
2024-11-01 09:04:56 +00:00
Tim Down 06c315760e Merge pull request #21127 from overleaf/td-bs5-upgrade-react-bootstrap
Upgrade react-bootstrap to 2.10.5

GitOrigin-RevId: 7dec4a603cb62226d4a298deca6c394a029b630c
2024-11-01 09:04:51 +00:00
Tim Down ce0fa69402 Merge pull request #21125 from overleaf/td-bs5-scss-tidy
Bootstrap 5 Sass code tidy

GitOrigin-RevId: 550add757c5bf1476446ad31c386c0a4e5522a9e
2024-11-01 09:04:47 +00:00
CloudBuild 36187aeecb auto update translation
GitOrigin-RevId: e3d4bb700ce1a8d13795495b174595ec1b87ffe7
2024-10-31 09:05:12 +00:00
Andrew Rumble df3be1bd5e Merge pull request #21288 from overleaf/ar-convert-modules-saas-authentication-to-es-modules
[web] Convert modules/saas-authentication to ES modules

GitOrigin-RevId: 5589bb2a7ad86da689994b6336cdac228de66c17
2024-10-31 09:05:08 +00:00
Eric Mc Sween 1acb0d1bcd Merge pull request #21274 from overleaf/em-recurly-client
Separate Recurly business logic

GitOrigin-RevId: 9c3b5ce61bdc7a6a5d3f507a31dc8919c882e476
2024-10-31 09:05:00 +00:00
Alf Eaton 3d5bceffee Disable spell check for figure environment optional argument (#21417)
GitOrigin-RevId: cbf6a072b9675a69176123d14ec34d97a0277b0a
2024-10-31 09:04:45 +00:00
Alf Eaton ea5b521882 Remove spell check split tests (#21382)
GitOrigin-RevId: 819fc94f55dc1d73e4f58e36dd594a5019c68439
2024-10-31 09:04:40 +00:00
CloudBuild bb465adba1 auto update translation
GitOrigin-RevId: f3d9c9621ae4b205c3860fa9a9afec87e74ac264
2024-10-30 09:05:11 +00:00
Andrew Rumble 79d80cc266 Merge pull request #21462 from overleaf/revert-18828-ac-node-20
Revert "Upgrade Node from `18.20.2` to `20.17.0`"

GitOrigin-RevId: cc12c33b4588caa2959817a113547d20d437d6f4
2024-10-30 09:05:07 +00:00
Jessica Lawshe 8f56f39ec8 Merge pull request #21445 from overleaf/jel-tagged-gallery-spacing
[web] Spacing updates on the tagged gallery page

GitOrigin-RevId: 0c51dbc820cf4e6e90487b01e5ae1862e00d7b17
2024-10-30 09:04:59 +00:00
Jessica Lawshe ae9ba2b775 Merge pull request #21411 from overleaf/jel-gallery
[web] "Back to ..." link text and hover effect on gallery search result images

GitOrigin-RevId: bfa21b17da7a3409139b1cf186b036ee65bf87eb
2024-10-30 09:04:51 +00:00
Eric Mc Sween 7444026cc3 Merge pull request #21310 from overleaf/em-validate-tracked-changes
Reapply "Sanity check for tracked changes in document-updater"

GitOrigin-RevId: e7b38d192f5202006f61bd015bba81d751af5413
2024-10-30 09:04:46 +00:00
Andrew Rumble a480df8a89 Merge pull request #18828 from overleaf/ac-node-20
Upgrade Node from `18.20.2` to `20.17.0`

GitOrigin-RevId: 0ba9b0921fc246a97d3da0aad7d48635c0e24ae8
2024-10-30 09:04:38 +00:00
Thomas 74bee7e30b Merge pull request #20415 from overleaf/tm-async-hooks
Proposal: Add promise interface for attaching module hooks and switch methods to be "Promise-first"
GitOrigin-RevId: 6740c18b75ebca79c24aa8b9867c8127b381b695
2024-10-29 09:06:02 +00:00
David ef90950cd3 Merge pull request #21439 from overleaf/dk-accept-reject-all-tooltip
Added tooltips to "Accept all" and "Reject all" options

GitOrigin-RevId: 62887e4e26964119cbb2c2aa140565c46aba94fe
2024-10-29 09:05:57 +00:00
David 7c613cdceb Merge pull request #21438 from overleaf/dp-edit-comment-popover
Dont select entry from textarea when review panel is mini

GitOrigin-RevId: 5900ae11ec01bb40100e19497557469e6dac1615
2024-10-29 09:05:53 +00:00
ilkin-overleaf 73f7f73396 Merge pull request #21428 from overleaf/ii-bs5-clear-search-button
[web] BS5 fix pointer-events style on form control icons

GitOrigin-RevId: 47a3da0333ca53ea1925d550fcf95dc730a5cb3b
2024-10-29 09:05:49 +00:00
Antoine Clausse 43e8467860 [web] Wrap Layout MenuItem description on a new line in BS5 (#21206)
* [storybook] Rerender when switching BS version

* Move comment to related code (bsStyle)

* Wrap the Layout MenuItem "subdued" text, using flex-column

* Create a Story for `LayoutDropdownButton`

* Center `.layout-dropdown .dropdown-item` vertically

* Remove unused classname `layout-dropdown-list`

* [storybook] Allow `detachable` to be passed as a prop

* Migrate `DetachDisabled` to BS5

* [storybook] Set actions for `^handle.*`, rename story

GitOrigin-RevId: 18509d259fad02a8aeb52132f1919e216b092b7e
2024-10-29 09:05:44 +00:00
Antoine Clausse 3734812557 [web] Migrate Detached PDF page to BS5 (#20920)
* Update ide-react-detached.pug for BS5

* Place the Recompile button tooltip to the bottom when in Detached layout

GitOrigin-RevId: 02dd23d38314e40585a435095b05231c8edd6849
2024-10-29 09:05:40 +00:00
Miguel Serrano b290510faf Merge pull request #21394 from overleaf/msm-esm-user-activation
[web] Migrate `modules/user-activate` to ESM

GitOrigin-RevId: e5ab3e9c53ea2d3f4ddfbc2200a889b8bb0db83c
2024-10-29 09:05:25 +00:00
Miguel Serrano 27c2e8b938 Merge pull request #21327 from overleaf/msm-optional-subnet-rate-limiter
[web] Add option to disable subnet rate limiting (+CE/SP Hotfix `5.2.1`)

GitOrigin-RevId: 78d60c9638cede729dd93c3c2421f55b34c0dbfe
2024-10-29 09:05:17 +00:00
ilkin-overleaf 25f4e6cf67 Merge pull request #21368 from overleaf/ii-bs5-text-formatting-button
[web] Text formatting dropdown toggle button style adjustments

GitOrigin-RevId: def94395f3f337f90e33fa42465377be3587d3ae
2024-10-29 09:05:05 +00:00
ilkin-overleaf 4445d918be Merge pull request #21389 from overleaf/ii-pdf-logs-pane-light-theme
[web] BS5 add light theme support to pdf logs

GitOrigin-RevId: 031278ce5ff34adda92ce4e08539fbe80cc70bfe
2024-10-29 09:05:01 +00:00
David 9d62c620fd Merge pull request #21410 from overleaf/dp-mini-panel-click
Prevent clicking on mini review panel entry popovers from opening the full panel

GitOrigin-RevId: a81ed154307750a756931d9fe5e893cd30d40c55
2024-10-29 09:04:56 +00:00
Tim Down 1b42fb7a89 Merge pull request #21391 from overleaf/td-bs5-symbol-palette
Migrate symbol palette to Bootstrap 5

GitOrigin-RevId: c014199d1266092a3cdf7df6e98a9a4d5f318c15
2024-10-29 09:04:52 +00:00
Davinder Singh 61e18e7266 Gallery redesign - Fixing the overflow of cta's in the layout on smaller screen on Gallery item page (#21405)
* adding flex-wrap to avoid overlapping of the buttons

* renaming classes to avoid modifying col-md-12 properties

GitOrigin-RevId: d000bd3c0b5be15f526ccbd1699cfe5679c0ddec
2024-10-29 09:04:47 +00:00
Mathias Jakobsen c9ed5f6a79 [web] Add mainBibliographyDocId to projects (#20842)
GitOrigin-RevId: 5358ef5cf0b9aaeadfe360c1bdc575fd1bf7344d
2024-10-29 09:04:42 +00:00
CloudBuild 9cafe8735d auto update translation
GitOrigin-RevId: 64e76a7de5ca253473033adc496a333bbbce26ed
2024-10-28 09:06:44 +00:00
CloudBuild 1404532cca auto update translation
GitOrigin-RevId: e1ddff24bf4784b7f23bb3846e358a5ccae0d96d
2024-10-28 09:06:40 +00:00
M Fahru 52bb22a794 Merge pull request #21378 from overleaf/mf-wrap-filter-navigation
[web] Adjust the styling of the navigation filter on devices with a small screen width on gallery page

GitOrigin-RevId: a404293a030aa60f2261ad2219bc7e55d885f042
2024-10-28 09:06:35 +00:00
Jessica Lawshe 597551859e Merge pull request #21386 from overleaf/jel-gallery-related-tags
[web] Use standard badge link CSS on related tags

GitOrigin-RevId: 6efe8add61e677c83fc3983cf7a7c9a1ac95b33c
2024-10-28 09:06:24 +00:00
Jessica Lawshe f91f423ae4 Merge pull request #21384 from overleaf/jel-gallery-badge-links
[web] Standardize CSS for badge links lists

GitOrigin-RevId: f0684cdd9b246c6fe1ab4b3c43121fa331933a66
2024-10-28 09:06:20 +00:00
Jessica Lawshe c5af43ee34 Merge pull request #21344 from overleaf/jel-back-link-text
[web] New translation keys for all lowercased words for back links on gallery

GitOrigin-RevId: 43757618e4136a40ef0ae7bfb6376437976f53c4
2024-10-28 09:06:15 +00:00
M Fahru a3ce640c7e Merge pull request #21379 from overleaf/jel-gallery-images-hover
[web] Clickable gallery images hover effect

GitOrigin-RevId: dfd992d970f9b0a2171bf598c27d474a06a5be74
2024-10-28 09:06:07 +00:00
M Fahru 94d14e3900 Merge pull request #21376 from overleaf/jel-spacing-gallery
[web] Fix spacing between sections, columns, and rows on gallery redesign

GitOrigin-RevId: 3c787baa7300c0f39705f71f8821f8da69a837a5
2024-10-28 09:06:03 +00:00
M Fahru 862fb9f2ae Merge pull request #21268 from overleaf/mf-new-gallery-search-result-badge
[web] Standardize `.badge` styling and HTML structure for both gallery-search and blog post page

GitOrigin-RevId: edfaceb61900897178654a920995e5c857fe7107
2024-10-28 09:05:55 +00:00
Domagoj Kriskovic 0329a18875 Show "add comment" tooltip below cursor if near viewport top (#21348)
* Scroll selection anchor into view when adding new comment

* check if cursor is near viewport edge

* Show "add comment" tooltip below cursor if near viewport top

GitOrigin-RevId: 0dc2234bc03b1d88a3719ba01a4a865f218b9bfa
2024-10-28 09:05:47 +00:00
DavidandDomagoj Kriskovic 44b2ca1830 Manually force blur on submitting an edited message (#21333)
* Return focus to parent entry element after message is edited

* Revert "Return focus to parent entry element after message is edited"

This reverts commit 96234a666e7e7c17b99a23a8a92ea030efe6083f.

* Manually force blur on submitting an edited message

* Show review panel entry header when editing comment (#21397)

* Show review panel entry header when editing comment

* edit comment spacing

* hide comment options when editing

---------

Co-authored-by: Domagoj Kriskovic <dom.kriskovic@overleaf.com>
GitOrigin-RevId: 66a8d1ed772cf91ea0f086bd08cdabaeb7456956
2024-10-28 09:05:43 +00:00
Domagoj Kriskovic 40ed104bce Disable drop-shadow on review panel entry when collapsed (#21399)
* Disable drop-shadow on review panel entry when collapsed

* use existing .review-panel-mini class

GitOrigin-RevId: 18428f37a7d048b8a63c5eaf6bf232f4cc5009b5
2024-10-28 09:05:38 +00:00
Domagoj Kriskovic 29c5bc8206 Focused and selected states for ReviewPanelEntry (#21354)
GitOrigin-RevId: 41e5ed1110d71eae51cbbde1e874dda133d666c8
2024-10-28 09:05:34 +00:00
Domagoj Kriskovic db23262611 Scroll selection anchor into view when adding new comment (#21328)
* Scroll selection anchor into view when adding new comment

* check if cursor is near viewport edge

GitOrigin-RevId: 57d4195f7ce1513a56249365b45b3959b4ea813f
2024-10-28 09:05:29 +00:00
Domagoj Kriskovic 4bcc7c9602 Update review panel entries on layout resize (#21323)
GitOrigin-RevId: db9b01609a2425952671e30fc20c16de4d3b36a8
2024-10-28 09:05:25 +00:00
Alf Eaton 34c3647244 Ignore a frequent unhandled promise rejection (#21383)
GitOrigin-RevId: 3c1360d6f4be1367aa77893ad8ef60760d6f9351
2024-10-28 09:05:21 +00:00
Alf Eaton c0d6a9c5f0 Use noSpellCheckProp NodeProp to exclude node types from spell check (#21335)
GitOrigin-RevId: 91ba72285b0f01c3c00fdb1a64c30e9ff67f72f5
2024-10-28 09:05:16 +00:00
Alf Eaton 516a7abc2a Wrap view.dispatch in setTimeout (#21365)
GitOrigin-RevId: 61c19e10f9529b4d7913f01c57281931533153d2
2024-10-28 09:05:12 +00:00
Jakob Ackermann 1407c9062d Merge pull request #21235 from overleaf/jpa-pug-lint
[web] detect duplicate meta tags in pug templates

GitOrigin-RevId: 0f1462b125244bf6da0a93438f44f9dd5a8d0cce
2024-10-28 09:05:07 +00:00
Jakob Ackermann 945a6a8155 Merge pull request #21234 from overleaf/jpa-pug-partials
[web] prefix file names of pug partials with underscore

GitOrigin-RevId: 956618f52e2639185d9f518c44d62f72ba0e222e
2024-10-28 09:05:03 +00:00
Alf Eaton 5c8daedf72 Increase the timeout for spell-check tests (#21385)
GitOrigin-RevId: 31013f9663a0464cfd22f32164e22f8d45e4c0d9
2024-10-28 09:04:46 +00:00
CloudBuild f822161b14 auto update translation
GitOrigin-RevId: cc87ce010583724e100b4f64d70598119dc6ce43
2024-10-25 08:07:03 +00:00
M Fahru 6c83f85d5d Merge pull request #21232 from overleaf/mf-remove-use-advanced-search
[web] Remove advance gallery search

GitOrigin-RevId: af39f63ac0483fe2540ba737f0239d0b503f87fe
2024-10-25 08:06:58 +00:00
Jessica Lawshe 5182e9a883 Merge pull request #21337 from overleaf/as-gallery-badge-underline
Remove underline on hover on gallery badges

GitOrigin-RevId: c83dc2f9e29650d11686a5e15b289391dc032e56
2024-10-25 08:06:50 +00:00
Jessica Lawshe 775ab9a8d1 Merge pull request #21352 from overleaf/as-gallery-tags-min-height
Set a minimum height on expanded tags container

GitOrigin-RevId: f8f537815a3b9b3e641b5e9d359964efa88f7808
2024-10-25 08:06:46 +00:00
Jessica Lawshe 4eef05a980 Merge pull request #21291 from overleaf/mf-change-caption-description-html-element
[web] Change gallery caption-description html element from div to p

GitOrigin-RevId: e9d5b699c0ada270a775223126d8c90cdc5992af
2024-10-25 08:06:41 +00:00
Jessica Lawshe 81663a1531 Merge pull request #21313 from overleaf/mf-spacing-featured-section
[web] Add correct spacing between popular-tags section, recent-docs section, and featured-docs section

GitOrigin-RevId: c04d2b09d85ac383efd8b3da2c53d5bd86a069f7
2024-10-25 08:06:37 +00:00
Jessica Lawshe 7a7533f794 Merge pull request #21116 from overleaf/mf-new-gallery-search-result-mobile
[web] Adjust search result styling for smaller screen width

GitOrigin-RevId: 6a16b0ca05358c6c83cc626c6103a6bffc98c33f
2024-10-25 08:06:32 +00:00
Jessica Lawshe fd778822f9 Merge pull request #21364 from overleaf/jel-gallery-list-img
[web] Remove image container on gallery items

GitOrigin-RevId: 2cd310df1ed99cc559286a5d8d9405eed2c440c3
2024-10-25 08:06:28 +00:00
Jessica Lawshe 0e607a95ee Merge pull request #21338 from overleaf/jel-image-drop-shadow-gallery
[web] Use larger drop shadow on gallery images

GitOrigin-RevId: 3a8a94def86cd1f77785326becb32d21a0804c0c
2024-10-25 08:06:23 +00:00
Liangjun Song 8293771f58 Merge pull request #21290 from overleaf/ls-scripts-to-esm-translations
Migrate scripts/translation to esm

GitOrigin-RevId: 475ec949f0ba238791df91de109169584e68c701
2024-10-25 08:06:12 +00:00
Jakob Ackermann 52edad6f12 Merge pull request #21322 from overleaf/jpa-skip-converted-cleanup
[filestore] remove unnecessary cleanup of converted files

GitOrigin-RevId: a46aaee473938209dc56d9fea90f96d09952ce47
2024-10-25 08:06:07 +00:00
Jakob Ackermann 29381cf054 Merge pull request #21321 from overleaf/jpa-reconfigure-filestore
[filestore] refactor acceptance tests

GitOrigin-RevId: a6bb1527220b1c062d980c79d2ccb62973b99d2c
2024-10-25 08:06:02 +00:00
Jakob Ackermann d1d65e65ad Merge pull request #21320 from overleaf/jpa-filestore-controller
[filestore] only call handler from controller

GitOrigin-RevId: 1d1bbe4e961b300a919ae79e3c760322304783bc
2024-10-25 08:05:57 +00:00
Jakob Ackermann e56e5442fd Merge pull request #21295 from overleaf/jpa-fix-filestore-tests
[filestore] fix conditional tests following sharing changes

GitOrigin-RevId: 7d804acb14942fb6d06ee38f782fc78796e9182e
2024-10-25 08:05:53 +00:00
Liangjun Song 14cd8f5479 Merge pull request #21282 from overleaf/ls-scripts-to-esm-5
Migrate rest of the scripts to esm

GitOrigin-RevId: 421f3ccd15342d34113be8d22e343d08533177ea
2024-10-25 08:05:41 +00:00
Liangjun Song e3b93f0a22 Merge pull request #21284 from overleaf/ls-scripts-to-esm-6
Migrate scripts/ukamf to esm

GitOrigin-RevId: e7318d9fb112304153912303649fc597ef7a19db
2024-10-25 08:05:37 +00:00
Tim Down 30eb5416f3 Merge pull request #21353 from overleaf/td-search-panel-focus
Pass main-field attribute through to form control in BS3

GitOrigin-RevId: 58ac2f4a18e098b35e4d4b14aa18eb013e4898e4
2024-10-25 08:05:32 +00:00
ilkin-overleaf ed8fc2747a Merge pull request #21281 from overleaf/ii-bs5-toolbar-items-border-radius
[web] BS5 toolbar buttons border radius

GitOrigin-RevId: b07a7bb16ab7a933dfa714a128f88f2ee006cf04
2024-10-25 08:05:27 +00:00
Mathias Jakobsen 4bc5a0f1d9 Merge pull request #21319 from overleaf/mj-select-controlled-null
[web] Allow Select to be controlled with no selection

GitOrigin-RevId: 15e5b643e30205124f8e807379ab7e540e2145d1
2024-10-25 08:05:23 +00:00
Tim Down 792c9774a5 Merge pull request #21347 from overleaf/td-document-diff-viewer-full-width
Make document diff viewer always take up the full width of its container

GitOrigin-RevId: cdb593700c403564bdf297ea838b279e7e73bba2
2024-10-25 08:05:18 +00:00
Alf Eaton 4bbde479a5 Avoid creating duplicate spell check marks on the edited line (#21331)
GitOrigin-RevId: 12726b47450be23f5a412a4c50cc2420af6f425f
2024-10-25 08:05:10 +00:00
Alf Eaton 5ec52e2e5b Avoid calling destroy on the PDF.js loading task (#21277)
GitOrigin-RevId: b315e78ff739d301583f2139109f3244abceade8
2024-10-25 08:05:05 +00:00
CloudBuild aa0fe5aeb3 auto update translation
GitOrigin-RevId: b8104bbfa04a27dd76db1b15d3e479807dc528a2
2024-10-24 08:06:38 +00:00
Jessica Lawshe 19e6ba98f0 Merge pull request #21228 from overleaf/as-gallery-related-tags
[web] Update gallery related tags styling and introduce Show More behaviour

GitOrigin-RevId: 7caef881c9a6f70437486e2bb080135d84f6742f
2024-10-24 08:06:34 +00:00
Eric Mc Sween 13ecddaef1 Merge pull request #20898 from overleaf/em-ai-add-on-setup-recurly
Script for setting up the Assistant add-on in Recurly

GitOrigin-RevId: 25a94961e4068456795b6be6b5e047efc65363fa
2024-10-24 08:06:29 +00:00
M Fahru 60cf8885b0 Merge pull request #21312 from overleaf/mf-gallery-search-author
[web] Add author of the template in search result on gallery redesign

GitOrigin-RevId: 6c5dfc039a31a22650f36bd264f0cb7133238ca2
2024-10-24 08:06:25 +00:00
M Fahru 9a142dd5ec Merge pull request #21306 from overleaf/mf-limit-gallery-summary-max-width-to-tagged-page
[web] Limit 828px max-width on gallery-summary to tagged pages only

GitOrigin-RevId: 48a0e342d403eff34cf47e71208b13af6e3f1cbd
2024-10-24 08:06:20 +00:00
M Fahru b12236576b Merge pull request #21286 from overleaf/mf-fix-layout-search-margin-top
[web] Remove margin-top on template gallery page without search

GitOrigin-RevId: 91335298b15f403e268f8e506ff373345922188b
2024-10-24 08:06:16 +00:00
Jessica Lawshe 4a10779064 Merge pull request #21311 from overleaf/jel-gallery-images
[web] Fix gallery placeholder not expanding full width while images download

GitOrigin-RevId: 5a943799d87bff967bd635b4dc98158d44569d9c
2024-10-24 08:06:12 +00:00
Jessica Lawshe 91d011e1f2 Merge pull request #21308 from overleaf/jel-back-links
[web] Use standard black link CSS for back links

GitOrigin-RevId: 7b26a9a4635ecbd722920407cd8cf900fc394172
2024-10-24 08:06:07 +00:00
Jessica Lawshe 74a475322e Merge pull request #21273 from overleaf/jel-tag-names
[web] Update popular tag names on dash to reflect new names

GitOrigin-RevId: 76e40103102934c260bca3728af66f28bfcba568
2024-10-24 08:06:03 +00:00
Tim Down 1b2385dfce Merge pull request #21259 from overleaf/td-bs5-editor-search
[BS5] Migrate Editor search panel

GitOrigin-RevId: 37605845d4efc27d6c0c3a11de12387e8e3262f4
2024-10-24 08:05:58 +00:00
ilkin-overleaf 2646fefce4 Merge pull request #21289 from overleaf/ii-bs5-figure-modal-improvements
[web] BS5 fix form text colour

GitOrigin-RevId: 8ff03f41cc3490eff0ea4c65a376ac572003fb9c
2024-10-24 08:05:54 +00:00
ilkin-overleaf 5791563ef0 Merge pull request #21263 from overleaf/ii-bs5-code-color
[web] Fix code tag colour in BS5

GitOrigin-RevId: 694640f33c8a614f470887f16f40f236cc7f9104
2024-10-24 08:05:50 +00:00
ilkin-overleaf 7f35ec9b6a Merge pull request #21260 from overleaf/ii-share-modal-role-dropdown
[web] BS5 share modal role dropdown click

GitOrigin-RevId: bb235564a42e737b0fafb4b6b3f47816440a5402
2024-10-24 08:05:45 +00:00
ilkin-overleaf 5c3d9117c5 Merge pull request #21240 from overleaf/ii-bs5-review-panel-old
[web] BS5 review panel old

GitOrigin-RevId: da018b8f2946afb21ab63da0003453e20781f04c
2024-10-24 08:05:41 +00:00
Davinder Singh 92a23b7e9d Gallery redesign - Making the changes on tagged page to match figma design (#21256)
* Adding max width for gallery-summary

* changin card background color

* removing row from within the card

* matching the padding of gray card with figma design

* removing row and spaced row to avoid extra padding and adding doc-rows-container

* adding grid for templates and removing some old styling

* adding .recent-templates-container to add the padding and margins

* deleting a comment and adding img border radius for the thumbnail

* adding margin-bottom on recent-templates-container

* adding .gallery-tagged-title-container to match the figma padding and then a fix was needed for the width of the filters

* renaming gallery-tagged-title-container to gallery-tagged-container-spacing and re-using it for Related tags container

* making recent heading as heading-xl to match figma

* adding badge styling and its container styling via .gallery-tagged-template-tags-container

* making two classes out of this class .gallery-tagged-container-spacing to add the styling for the h2 heading

* adding margin-bottom to match figma style

* making class generic and using it at multiple places

* removing some extra code

* removing grid styling because after rebase the layout was fixed with col classes

* adding rows back

* adding h2 instead of h3 and making them heading-xl

* adapting some changes after merge conflicts

* removing duplicate classname after rebase

GitOrigin-RevId: d02a0b1e2784fd96d2af2326700829879dacc464
2024-10-24 08:05:26 +00:00
Davinder Singh 11cb7dc24c Gallery redesign - Gallery item page redesign (#21034)
* adding .gallery at top level

* adding styling for heading and buttons

* removing padding under cta-links

* removing find more templates text

* adding field title styling

* adding .details-container for spacing between the content

* adding a colon after field-title

* moving tags styling into badge.scss file to make it more generic to use

* moving section tag one level below to use it as a flex containe for adding gap property

* adding field-description class

* fixing the image width

* adding some padding between the content

* renaming  a file to a more descriptive name

* adding .gallery-abstract class in the scss file

* adding colons in pug file

* adding previous-page-link and its container class

* moving paddings to larger screens only and adding a top margin for mobile screens]

* adding some spacing above tags on mobile view when heading and tags are vertically aligned

* adding styling to the badge and removing extra padding from h1 to match figma

* lint:fix

* swapping position of top-pick and official badges

* adding path and itemPlural

* removing unused top margin

GitOrigin-RevId: a5c9b731b69ecfe2b752015c410e10a0fec2c704
2024-10-24 08:05:21 +00:00
David d74981775c Merge pull request #21283 from overleaf/dp-keyboard-shortcuts
Add missing keyboard shortcuts to new review panel

GitOrigin-RevId: 78e3a63284b62c90e8a3803bd81fdf273f1a2ec9
2024-10-24 08:05:17 +00:00
David c872d97295 Merge pull request #21250 from overleaf/dp-resolved-comments-ui
UI tweaks for resolved comments menu

GitOrigin-RevId: 23df6f9f0374277c315d2fb9c9940dd92ec19f4e
2024-10-24 08:05:12 +00:00
David 1c5f5950fa Merge pull request #21208 from overleaf/dp-accept-reject-all-changes
Add options to accept/reject all changes to review tooltip

GitOrigin-RevId: 1cea76926d59d0354c8abaa6ba69b7e99c02fbe0
2024-10-24 08:05:08 +00:00
Domagoj Kriskovic c4b23b4d39 Add "usingNewReviewPanel" flag in store (#21279)
* Revert "Add isUsingNewReviewPanel flag for writefull (#21111)"

This reverts commit 3491e93ca70fa1db0c751872e233dfebdbe81423.

* add usingNewReviewPanel in store

* fix lint error

GitOrigin-RevId: 56d90a428a2cc45708b8b483dc60a62aae233a85
2024-10-24 08:05:03 +00:00
Antoine ClausseandRebeka b2e7477467 [web] Migrate AI Error Assistant to BS5 (#21129)
* [storybook] Rerender story when switching BS3/BS5

* [storybook] Add SCSS loader to storybook

* [storybook] Add some AI error assistant stories

* Rename ai-error-assistant.less to .scss

* Update less variables to sass

* Remove duplicated selector

* Replace react-bootstrap components by `OL...`

* Update Checkboxes after BS5 update

* Add IDs so clicking on labels work
* Add BS5 class name in SCSS

Note: `answer-not-detailed` is used twice in the Radios. I think it's a mistake: there should be another name for the "ai_feedback_the_suggestion_wasnt_the_best_fix_available" radio

* Rename ID `answer-not-detailed` -> `answer-not-best-fix`

* Pass name and value to BS3Radio/BS3Checkbox

* [storybook] Add delay before AI suggestion (shows the animation)

* Add a number after the checkbox/radio IDs, to allow multiple forms to be displayed

Without this, clicks on second form are updating the first form!

Another solution could be to wrap the input in the label, but it comes with other problems. See https://css-tricks.com/html-inputs-and-labels-a-love-story/

* [storybook] Update `LabsAiPromoBanner`

* Use CSS variables instead of hardcoded values

* Make radio input flex

* Replace `blue-10` by `bg-info-03`

* Fix `SuggestFixButton`

* Fix `AiErrorAssistantCopyCode`

* Fix button loading in BS5

* Use OLBadge

* Fix Button variants

* Update `suggestFixAction`

* Migrate Tooltip and Button to BS5 in LabsExperimentWidget

* Update BS3/BS5 button classname in AiErrorAssistantCopyCode

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>

* [storybook] Allow to choose props of `LabsExperimentWidget`

* Fixup `OLTooltip`: Display the tooltip on disabled button in BS5

* Update Tooltips to BS5

---------

Co-authored-by: Rebeka <rebeka.dekany@overleaf.com>
GitOrigin-RevId: 08d594e772c0a3b6db1c6081337cc2d079f478a5
2024-10-23 08:06:36 +00:00
Antoine ClausseandRebeka 30860ae9f9 [web] Migrate PDF Logs to BS5 (#21062)
* [web] Migrate Logs components JSX to Bootstrap 5

* [web] Migrate logs.less to logs.scss

* [web] Remove unused class names

* [storybook] Define default Bootstrap version in Storybook

This prevents some warning in the console

* [storybook] Update pdf-preview.stories.jsx

* [storybook] Add pdf-log-entry.stories.tsx

* [storybook] Force re-renders when switching BS version

* [web] Keep files dropdown menu in bounds

* [web] Make files dropdown items not bold in BS5

* [web] Revert unrelated change

* [web] Fixup PreviewLogsPaneMaxEntries

* [web] Add style for log-entry-content-link

* [web] Replace log-entry by OLNotification in `PdfCodeCheckFailedNotice`

* [web] Use `BootstrapVersionSwitcher` instead of `isBootstrap5`

* [web] Rename `DropdownBS3` to `BS3Dropdown`

* [web] Reuse variables for `toolbar-height` and `toolbar-small-height`

* [web] Set `id` on `DropdownToggle` not `Dropdown`

* [web] Set `log-entry-btn-expand-collapse` in BS3 only

* [web] Remove `block: true` from StartFreeTrialButton in BS3

* [web] Remove unnecessary CSS in `.log-entry-header-link`

* [web] Use semantic color names

* Migrate the downloadable pdf file list to Bootstrap 5

* Remove nested BootstrapVersionSwitcher, fix "key" prop

* Update roles to: `<li role="menuitem">` `<a role="link">`

* Update `log-entry-header-link`: variant ghost and fix colors

---------

Co-authored-by: Rebeka <o.dekany@gmail.com>
GitOrigin-RevId: 89848970ab5d8a8c135335386caf24363f69a34c
2024-10-23 08:06:32 +00:00
Antoine Clausse d77ca18b0b [web] Remove dead code: history-content & history-root (#20959)
They are duplicated by:
* services/web/frontend/js/features/ide-react/components/history.tsx
* services/web/frontend/js/features/ide-react/components/history-root.tsx

GitOrigin-RevId: c3f13ea9016530182ae623b06e91a9fdb2be7a87
2024-10-23 08:06:27 +00:00
CloudBuild 388f16169e auto update translation
GitOrigin-RevId: a7a23972ddc8c18eff2e2833ea06572cbce676fc
2024-10-23 08:06:23 +00:00
M Fahru a0ea00b692 Merge pull request #21108 from overleaf/mf-only-one-container-gallery-redesign
[web] Make sure gallery (tagged and non-tagged) page only have a single `.container` on each page

GitOrigin-RevId: df5272082a7f74dcc4051560692eaf715b49dc37
2024-10-23 08:06:19 +00:00
Andrew Rumble e75e9c4818 Revert "Send subscription -> salesforce/v1 links to analytics"
This reverts commit 52c02138f9ef8141850e2f8ce16f2bab1e7463b0.

GitOrigin-RevId: 022e828a8e41cc73c4087b94d51fa75dbe6cfdb5
2024-10-23 08:06:11 +00:00
Andrew Rumble 6f3c371435 Revert "Add an endpoint for rails to record salesforce mappings"
This reverts commit fcca974a69217dc885c458543a82b4dcc338d98b.

GitOrigin-RevId: cc7e2561a5f6b4866e5f69f4fb41ffb1bad07bb1
2024-10-23 08:06:06 +00:00
andrew rumble 2486f893eb Add an endpoint for rails to record salesforce mappings
GitOrigin-RevId: fcca974a69217dc885c458543a82b4dcc338d98b
2024-10-23 08:05:54 +00:00
andrew rumble 24b27e3863 Send subscription -> salesforce/v1 links to analytics
GitOrigin-RevId: 52c02138f9ef8141850e2f8ce16f2bab1e7463b0
2024-10-23 08:05:50 +00:00
Jessica Lawshe 2d87fe036d Merge pull request #21272 from overleaf/jel-gallery-categories-images
[web] Update categories images for gallery redesign

GitOrigin-RevId: 4a8afef62af5e873f63ce90f976fe924ba9ecbe9
2024-10-23 08:05:38 +00:00
Rebeka Dekany 200e7a75f0 Merge pull request #21226 from overleaf/rd-history-filetree
Migrate the history file tree to Bootstrap 5

GitOrigin-RevId: bb5443d91992ff7241ed5c8bb467fa553e55bb0f
2024-10-23 08:05:31 +00:00
Alf Eaton d0b5c2f307 Avoid sending ide-open-view-null-once event (#21247)
GitOrigin-RevId: 2f46fe26561bfa2eca36ad605cdd217514aba09d
2024-10-23 08:05:23 +00:00
Alf Eaton 98bf2ac055 Disable spell check setting when doc is read-only (#21253)
GitOrigin-RevId: 1053fefd953d4f60b1c2aef4170f99c6885c265d
2024-10-23 08:05:18 +00:00
Alf Eaton baed6cc291 Reapply "Remove spell check languages that are only available on the server (#21056)" (#21257)
* Reapply "Remove spell check languages that are only available on the server (#21056)"

This reverts commit a2273a5ff2eeb5660ae992c41e67b7b936dc4e26.

GitOrigin-RevId: 2dfdf87acdf17db894e921fe754c1520df6f01c1
2024-10-23 08:05:14 +00:00
Mathias Jakobsen 4589a192f6 Merge pull request #20565 from overleaf/mj-zotero-search-groups
[web] Add group searching to Zotero

GitOrigin-RevId: c61994a3d2fd871b644479617921c3282abe07c5
2024-10-23 08:05:06 +00:00
Liangjun Song 902ae750dc Merge pull request #21202 from overleaf/ls-scripts-to-esm-2
Migrate scripts folder to esm 2/x

GitOrigin-RevId: 1698bc4f13e026fa281d37a4914a2f997849c761
2024-10-23 08:04:53 +00:00
M Fahru f2ec640b06 Merge pull request #21113 from overleaf/mf-gallery-header-text-align-center
Center text for gallery-title, this is useful mainly for mobile view

GitOrigin-RevId: 49db14c627125d2c1e1d1f69173ac918d51f4f91
2024-10-22 08:07:57 +00:00
M Fahru ca6b5ae4ca Merge pull request #21214 from overleaf/mf-new-gallery-search-result-pagination
[web] Fix pagination in gallery search result

GitOrigin-RevId: 2c34afd7bff2f2a47cc585e68433ac3fa4f16589
2024-10-22 08:07:53 +00:00
M Fahru 0811e46b6c Merge pull request #21067 from overleaf/mf-new-gallery-search-result
[web] Implement new gallery search result

GitOrigin-RevId: afc33a07b5ea533b681acf18bd31112a2f48866a
2024-10-22 08:07:42 +00:00
Jessica Lawshe c37e6a17fb Merge pull request #21215 from overleaf/jel-redesign-black-links
[web] Consolidate black link CSS on pages using new design

GitOrigin-RevId: cdeccee0586efbf67e656828ed597e4441242edd
2024-10-22 08:07:34 +00:00
Jessica Lawshe 18739d122e Merge pull request #21144 from overleaf/jel-auto-width-mobile
[web] Add options for mobile horizontal column alignment and column gaps on CMS BS5 pages

GitOrigin-RevId: 21cf6e181ea6622b06db73c32a4889327146032c
2024-10-22 08:07:30 +00:00
Jessica Lawshe 96ff76dc43 Merge pull request #21219 from overleaf/jel-tagged-gallery-description
[web] Set a max width for the tag description

GitOrigin-RevId: a1af998ff305805f3e6dfba5ae1b2bff38ab54ba
2024-10-22 08:07:26 +00:00
Jessica Lawshe 620969b606 Merge pull request #21217 from overleaf/jel-title-casing
[web] Use sentence casing on gallery "Templates" filter view header

GitOrigin-RevId: d3926efec4cae91ae86121ef3f6d56bb01799284
2024-10-22 08:07:21 +00:00
Jessica Lawshe 270796ffe8 Merge pull request #21211 from overleaf/jel-cms-remove-deprecated
[web] Removed deprecated CMS list element

GitOrigin-RevId: 9d711a2772b9a179c59ea04d6eaadc2313b8987e
2024-10-22 08:07:13 +00:00
Jessica Lawshe c00835692b Merge pull request #21148 from overleaf/jel-gallery-categories
[web] Begin "Categories" style update on gallery redesign

GitOrigin-RevId: 4af7da520485c47d54c2a0d004fd53edd7e93cc6
2024-10-22 08:07:09 +00:00
Andrew Rumble b5cd5bd8fa Revert "[web] Migrate modules/server-ce-scripts to ESM"
GitOrigin-RevId: 61d971396b801e7bb3da1c5af7bd5ea4d91f3c9f
2024-10-22 08:07:04 +00:00
Jessica Lawshe ab6ee04022 Merge pull request #21102 from overleaf/as-gallery-row-styling
Update Gallery Item styling

GitOrigin-RevId: abe5cc73a3d2ea14bf2e02eefb89ccc4d99c020e
2024-10-22 08:07:00 +00:00
Miguel Serrano 4fd0c41665 Merge pull request #21239 from overleaf/msm-jetty-update
[git-bridge] Update Jetty `9.x` to the latest version

GitOrigin-RevId: b9571ed368c159ee8d7d8f22fefc5c33559f8c6f
2024-10-22 08:06:49 +00:00
Alf Eaton 508ed8ad1d Merge pull request #21251 from overleaf/ae-revert-no-session
Revert "Remove spell check languages that are only available on the server (#21056)"

GitOrigin-RevId: 6f77aa92f1b7d7181cec7d470c8e6604b1e90fe3
2024-10-22 08:06:45 +00:00
ilkin-overleaf a443713b55 Merge pull request #21230 from overleaf/ii-bs5-review-panel-new-add-comment-button
[web] BS5 new review panel add comment button

GitOrigin-RevId: f08686ca431bac3d3df055afd4468bef94656d9c
2024-10-22 08:06:34 +00:00
Alf Eaton 9fdbd5cfb5 Add state.Prec to editor:extensions export (#21222)
GitOrigin-RevId: b8680926a9885f19ebc9227de678674da1765158
2024-10-22 08:06:29 +00:00
Alf Eaton 6c4fac68ca Use Intl.Segmenter when available for identifying words to spell check (#21225)
GitOrigin-RevId: f261ae331e0b1f87f4e88a512b25c8798f0b02c6
2024-10-22 08:06:25 +00:00
Alf Eaton 04dbb7d2f2 Remove spell check languages that are only available on the server (#21056)
GitOrigin-RevId: cfe10a18af8149327754b3a2e62883c7ebc04bfc
2024-10-22 08:06:20 +00:00
Miguel Serrano c4edd2fffa Merge pull request #21154 from overleaf/msm-esm-ce-scrits
[web] Migrate `modules/server-ce-scripts` to ESM

GitOrigin-RevId: 8856f83b12d5d092e51e5765763737259c4b3985
2024-10-22 08:05:58 +00:00
David c7eafd69c2 Merge pull request #21014 from overleaf/dk-review-panel-tc-widget
Add "Track changes is On" button when review panel is closed

GitOrigin-RevId: a165201f611860ba531f2eeb3d89f83a695cd017
2024-10-22 08:05:50 +00:00
Domagoj Kriskovic 64460681b8 Fix delete comment/thread in the new review panel (#21199)
GitOrigin-RevId: 95d4db64d2f837322d84a81cbd129ec02ee135a2
2024-10-22 08:05:46 +00:00
Domagoj Kriskovic 1e16de13bc Fix change and insert range decorations background color (#21131)
GitOrigin-RevId: 4bbc7abdc4c52ea31e26ea3fd8cf43d8c9620d47
2024-10-22 08:05:42 +00:00
Domagoj Kriskovic c606f04cce Sort track changes and comments in overview mode (#21099)
GitOrigin-RevId: 795d30b56e57970363512170f504ab51bd104c93
2024-10-22 08:05:37 +00:00
Domagoj Kriskovic 332e2a38c9 Fix review panel entry focus handler (#21075)
* Fix review panel entry focus handler

* dont check position

* remove event.target checks

* Revert "remove event.target checks"

This reverts commit 3f511e47b6922260666c6952b692f6f0a29d5912.

GitOrigin-RevId: 9271df9cdb36a040d59a97c88f21d6e923ac0404
2024-10-22 08:05:33 +00:00
Domagoj Kriskovic 94d78e68cd Box shadow on review panel entry hover and focus (#21055)
* Box shadow on review panel entry hover and focus

* fix formatting

* added box-shadow in scss

* css priority

* fix styling lint

GitOrigin-RevId: fdf4ff0fbef6c9a924e83d40703958eb28caaa49
2024-10-22 08:05:29 +00:00
Domagoj Kriskovic 42eea0017d Update track change decoration to be cursor-like (#21047)
* Update track change decoration to be cursor-like

* use red-50 color

GitOrigin-RevId: 8c8a2cb9c6abc99aa1d2dace705dba3feeda07fa
2024-10-22 08:05:24 +00:00
Domagoj Kriskovic db3c69fbcd Fix review panel header positioning in Firefox and Safari (#20995)
* Fix review panel header positioning in Firefox and Safari

* update scss

GitOrigin-RevId: 5427f91f077104639a72f608c8d7572ab7d08a8c
2024-10-22 08:05:20 +00:00
David 87f714f7c3 Merge pull request #21164 from overleaf/dp-add-comment-keyboard-shortcut
Add keyboard shortcut (cmd+shift+c) for adding a new comment

GitOrigin-RevId: 20359426f45e90b09cbc887bac3096adf1b3141a
2024-10-22 08:05:15 +00:00
David 31154bb9f5 Merge pull request #21065 from overleaf/dp-limit-track-change
Truncate text in a tracked change

GitOrigin-RevId: a3c070f0ca2f51545151934d25a26a10c99b7465
2024-10-22 08:05:11 +00:00
David efa376f4f4 Merge pull request #21120 from overleaf/dp-overview-entry-gap
Adjust size of gap between review panel entries to 4px

GitOrigin-RevId: a09a6fde0e8eb15e0c753e436a1c09434581d6d8
2024-10-22 08:05:07 +00:00
David af7e388c41 Merge pull request #21122 from overleaf/dp-rp-hide-edit
Hide edit option for other user's comments

GitOrigin-RevId: 317fa57402dfbe2e949fa7b196cbbe246f88257d
2024-10-22 08:05:02 +00:00
David a2ea76f19f Merge pull request #21201 from overleaf/dp-toolbar-ui
Style adjustments for add comment tooltip

GitOrigin-RevId: 7fdc008fea4a191ff8bacca9a77e23cd55faac5a
2024-10-22 08:04:57 +00:00
CloudBuild 28f12eeec2 auto update translation
GitOrigin-RevId: c046e9647f5890e8bbc635df756cdfee6eb97110
2024-10-21 08:04:54 +00:00
Liangjun Song 30b5b74f79 Merge pull request #21229 from overleaf/ls-apply-es-specific-rule-to-migrations-and-scripts
apply es specific lint rule to migrations and scripts folder

GitOrigin-RevId: cd307b30a93028273988b9d0ee5727c73f8103b7
2024-10-21 08:04:50 +00:00
Liangjun Song 26f3f3e2e2 Merge pull request #21097 from overleaf/ls-scripts-to-esm-1
Migrate scripts folder to esm 1/x

GitOrigin-RevId: 4a4bc9a161f144fdb40ce3f2a0a9313b36c6df81
2024-10-21 08:04:42 +00:00
ilkin-overleaf 8bc374c916 Merge pull request #21115 from overleaf/ii-bs5-review-panel
[web] BS5 review panel new

GitOrigin-RevId: c65d17d0053858bd74984ba746a620b89d900606
2024-10-21 08:04:37 +00:00
Tim Down f84b205b4b Merge pull request #21203 from overleaf/td-bs5-nav-overflow
[BS5] Prevent nav items shrinking and therefore wrapping when space is limited

GitOrigin-RevId: ac071863532a779fd99760638bf904ffce4a21fe
2024-10-21 08:04:29 +00:00
CloudBuild 2ae03cc993 auto update translation
GitOrigin-RevId: beee0dc7b92c2ae73eba58991163cd335bc00559
2024-10-18 08:06:09 +00:00
Eric Mc Sween b2d991d74a Merge pull request #21212 from overleaf/revert-20969-ac-subscription-layout-react
Revert "[web] Set Subscription pages to have `layout-react`"

GitOrigin-RevId: eaf3a651160e278adcb103864c5ea81ea3e35aa7
2024-10-18 08:06:05 +00:00
Antoine ClausseandJakob Ackermann 2c7530a6cf [web] Set Subscription pages to have layout-react (#20969)
* [web] Set Subscription pages to have `layout-react`

* [web] import `header-footer-react` in Subscription pages (!!)

* [web] Add `ol-user` meta tag to the subscription pages (!!)

⚠️ invite_logged_out.pug should be updated instead of setting the user as `{}`

* [web] Fix unit test

* [web] Update User types to handle a logged out user, add `LOGGED_OUT_USER` const

* [web] Add type `User` to `getSessionUser`

* [web] Remove `LOGGED_OUT_USER` const

* [web] Just pass `{ id: null }` as the user

* [web] Remove comment in pugs, it breaks things

* [web] Don't pass the full user to the frontend!!!

Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>

---------

Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com>
GitOrigin-RevId: 1768f1f13de924a18be43c1a08614000500dcbec
2024-10-18 08:05:53 +00:00
Alf Eaton 1b2f5af1c0 Display current spell check language and option to change it (#21138)
GitOrigin-RevId: 87cf140a7e3e719125eb6d2df23d6c6bd6631fe8
2024-10-18 08:05:48 +00:00
Alf Eaton b5015b82c2 Move Hotjar to the editor page (#21132)
GitOrigin-RevId: efb2c7841af76084566341b6c5f0afac9a965331
2024-10-18 08:05:43 +00:00
Alf Eaton 620f31d6a6 Restore singleton pdfCachingTransportFactory (#21194)
GitOrigin-RevId: 3c1d71ba4fdd07f0774534fbe3a99b2d47dfa962
2024-10-18 08:05:39 +00:00
Alf Eaton 3b354462a7 Restore MaterialSymbolsRoundedSlice font (#21130)
GitOrigin-RevId: 15ca2ba4d5afd4fcc02d11220905166abbe30dd5
2024-10-18 08:05:34 +00:00
Alf Eaton 978ef6bd92 Enable remaining client-side dictionaries (#21192)
GitOrigin-RevId: da45ae4a93e99a0bb720e09a37c8e291c057cab9
2024-10-18 08:05:29 +00:00
Jessica Lawshe 4f9a056bea Merge pull request #21146 from overleaf/jel-begin-card
[web] Spacing adjustments around "\begin {now}" card on gallery and blog

GitOrigin-RevId: 822a91bb156222b61cbf671d78522fc942d4e5b4
2024-10-18 08:05:17 +00:00
Thomas febc4b6438 Merge pull request #21049 from overleaf/tm-web-unhandledrejection
Add unhandledRejection handler when catchErrors is true

GitOrigin-RevId: 7ec1512a8705e6f7cf6480b70427f5bf5d1438b4
2024-10-18 08:05:04 +00:00
M Fahru e782ba2fee Merge pull request #21083 from overleaf/mf-new-blog-add-shadow
[web] Add box-shadow to every video in all blog pages

GitOrigin-RevId: b2d3180dd44cdc59845049a5d326b83209572078
2024-10-17 08:07:25 +00:00
M Fahru 317aedd929 Merge pull request #21082 from overleaf/mf-blog-new-image-rounded
[web] Add border-radius to every image inside .blog-content (blog post page) and `.blog-content-preview` (blog list page)

GitOrigin-RevId: 6f805513504b1e4468862018e6f62070a8adcfe0
2024-10-17 08:07:20 +00:00
M Fahru f1859afc4b Merge pull request #21081 from overleaf/mf-blog-read-more-spacing-top
[web] Update spacing between blog preview and "read more" link in blog list page

GitOrigin-RevId: ee9184017f0862fac849d9ca2c4f6bcabdad5bff
2024-10-17 08:07:16 +00:00
M Fahru 69e63f2c74 Merge pull request #21060 from overleaf/mf-fix-question-mark-login
[web] Add a missing question mark from a sentence in login page

GitOrigin-RevId: d222a5ecab8dae0e95bd25f9607e7c8071daba90
2024-10-17 08:07:11 +00:00
M Fahru be43bd2d20 Merge pull request #21019 from overleaf/mf-new-gallery-search-style
[web] Implement the new gallery search form style

GitOrigin-RevId: e9986344ac554a45c20e61454f2e20997a8e741a
2024-10-17 08:07:07 +00:00
M Fahru 0e41f8cf4c Merge pull request #21110 from overleaf/jel-cms-containers
[web] Remove extra horizontal padding on CMS pages

GitOrigin-RevId: 8f6a768ab8f3a4206ad14045cd75ed33aa335dd4
2024-10-17 08:07:02 +00:00
M Fahru 2f762838e7 Merge pull request #21109 from overleaf/jel-contact-form-labels
[web] Use sentence case for labels on CMS sales contact forms

GitOrigin-RevId: 119eb9cf9db8932de369ce56b9ed2494a72a1ea3
2024-10-17 08:06:58 +00:00
M Fahru ad745e5dc8 Merge pull request #21058 from overleaf/as-gallery-back-link
Add back link to all gallery items

GitOrigin-RevId: 083b61f6cb95426184b3d2a2b9e2353efe1108a2
2024-10-17 08:06:53 +00:00
M Fahru 72b1954939 Merge pull request #21026 from overleaf/as-gallery-begin-card
Move begin_now_card mixin to generic location and add to template gallery

GitOrigin-RevId: 6167e7063ecb18b9465613c0a25bbbdd83b5727a
2024-10-17 08:06:49 +00:00
M Fahru 518920c129 Merge pull request #20855 from overleaf/as-web-visited-color
Update link-web-visited colour in BS5

GitOrigin-RevId: dba27c51c3a53b0f14a9bf704f0f5b9a503db66d
2024-10-17 08:06:44 +00:00
Andrew Rumble ad9c0446e2 Changes to support converted features
GitOrigin-RevId: 5f46cbf77c6f814820231b9cbfab9906dab6270d
2024-10-17 08:06:22 +00:00
Andrew Rumble 2bfb55a305 Update tests
GitOrigin-RevId: 9272720e0f6865c54257c43bd98d8e6003251aa2
2024-10-17 08:06:17 +00:00
Andrew Rumble 9490251251 Update acceptance tests
GitOrigin-RevId: cf8bc3f86ccff15df8e20ceda6842dad8538d5e3
2024-10-17 08:06:13 +00:00
Andrew Rumble c6c62088cc Migrate Features to ES modules
GitOrigin-RevId: 4e9d3176b4b5a5504afc102e569a27d7788864a3
2024-10-17 08:06:08 +00:00
Alf Eaton fac23dbbdc Merge pull request #20982 from overleaf/ae-font-folders
Organise and update web fonts

GitOrigin-RevId: f82a695bd7a4d16e4df83c2a297bf7d2393914a8
2024-10-17 08:05:59 +00:00
Alf Eaton a238b8eee4 Use ol_spell_check_language tag for error reporting (#21126)
GitOrigin-RevId: 11580f8dca22b0d4858dc5db36827b69a3637371
2024-10-17 08:05:55 +00:00
Tim Down 17b66e495f Merge pull request #21028 from overleaf/td-bs5-history-header
Migrate history header to Bootstrap 5

GitOrigin-RevId: de875cc698b0892d87d6f120131fc7fc3dc24e51
2024-10-17 08:05:50 +00:00
Tim Down 76f8680db0 Merge pull request #21013 from overleaf/td-bs5-history-document-diff-viewer
Migrate document diff viewer to Bootstrap 5

GitOrigin-RevId: 361e6398a09a5ec5c48aced02f27d9896567b539
2024-10-17 08:05:45 +00:00
Davinder Singh 43965828c8 Merge pull request #21027 from overleaf/ds-gallery-redesign-no-articles-found-3
Gallery redesign - Updating the tagged page with no articles found

GitOrigin-RevId: dfddfa29c84520093a35fec5017b4ad09634b617
2024-10-17 08:05:41 +00:00
Davinder Singh 75aa3764ea CMS BS5 Migration - Migrating about.less to about.scss (#20783)
* copying the styling from about.less into about.scss

* adding closest spacing available in BS5

GitOrigin-RevId: c4470ab1972762a025a42d581a6dee3c28ba7e2d
2024-10-17 08:05:36 +00:00
Miguel Serrano a753d3c1d9 Merge pull request #21114 from overleaf/msm-add-missing-test-base
[web] check `web/test` folder on `esm-check-migration.js`

GitOrigin-RevId: 0665f208664fc969932d627c994d986c2f97d51a
2024-10-17 08:05:32 +00:00
Andrew Rumble d2e6608f01 Convert export_institution_chat script to ES module
GitOrigin-RevId: 8570922654049edb514f8091421e5be2f04988cd
2024-10-17 08:04:59 +00:00
1673 changed files with 57071 additions and 143585 deletions
+3 -1
View File
@@ -14,6 +14,8 @@ When submitting an issue please describe the issue as clearly as possible, inclu
reproduce the bug, which situations it appears in, what you expected to happen, and what actually happens.
If you can include a screenshot for front end issues that is very helpful.
**Note**: If you are using [www.overleaf.com](www.overleaf.com) and have a problem, or if you would like to request a new feature, please contact the Support team at support@overleaf.com. Raise an issue here only to report bugs in the Community Edition release of Overleaf.
Pull Requests
-------------
@@ -34,7 +36,7 @@ Please see [our security policy](https://github.com/overleaf/overleaf/security/p
Contributor License Agreement
-----------------------------
Before we can accept any contributions of code, we need you to agree to our
Before we can accept any contributions of code, we need you to agree to our
[Contributor License Agreement](https://docs.google.com/forms/d/e/1FAIpQLSef79XH3mb7yIiMzZw-yALEegS-wyFetvjTiNBfZvf_IHD2KA/viewform?usp=sf_link).
This is to ensure that you own the copyright of your contribution, and that you
agree to give us a license to use it in both the open source version, and the version
+851 -18
View File
@@ -14,30 +14,866 @@
<a href="#license">License</a>
</p>
<img src="doc/screenshot.png" alt="A screenshot of a project being edited in Overleaf Community Edition">
<img src="doc/screenshot.png" alt="A screenshot of a project being edited in Overleaf Extended Community Edition">
<p align="center">
Figure 1: A screenshot of a project being edited in Overleaf Community Edition.
Figure 1: A screenshot of a project being edited in Overleaf Extended Community Edition.
</p>
## Community Edition
[Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. We run a hosted version at [www.overleaf.com](https://www.overleaf.com), but you can also run your own local version, and contribute to the development of Overleaf.
[Overleaf](https://www.overleaf.com) is an open-source online real-time collaborative LaTeX editor. Overleaf runs a hosted version at [www.overleaf.com](https://www.overleaf.com), but you can also run your own local version, and contribute to the development of Overleaf.
## Extended Community Edition
The present "extended" version of Overleaf CE includes:
- Sandboxed Compiles with TeX Live image selection
- LDAP authentication
- SAML authentication
- OpenID Connect authentication
- Real-time track changes and comments
- Autocomplete of reference keys
- Symbol Palette
## Enterprise
If you want help installing and maintaining Overleaf in your lab or workplace, we offer an officially supported version called [Overleaf Server Pro](https://www.overleaf.com/for/enterprises). It also includes more features for security (SSO with LDAP or SAML), administration and collaboration (e.g. tracked changes). [Find out more!](https://www.overleaf.com/for/enterprises)
## Keeping up to date
Sign up to the [mailing list](https://mailchi.mp/overleaf.com/community-edition-and-server-pro) to get updates on Overleaf releases and development.
If you want help installing and maintaining Overleaf in your lab or workplace, Overleaf offers an officially supported version called [Overleaf Server Pro](https://www.overleaf.com/for/enterprises).
## Installation
We have detailed installation instructions in the [Overleaf Toolkit](https://github.com/overleaf/toolkit/).
Detailed installation instructions can be found in the [Overleaf Toolkit](https://github.com/overleaf/toolkit/).
To run a custom image, add a file named docker-compose.override.yml with the following or similar content into the `overleaf-toolkit/config directory`:
## Upgrading
```yml
---
version: '2.2'
services:
sharelatex:
image: sharelatex/sharelatex:ext-ce
volumes:
- ../config/certs:/overleaf/certs
```
Here, the attached volume provides convenient access for the container to the certificates needed for SAML or LDAP authentication.
If you are upgrading from a previous version of Overleaf, please see the [Release Notes section on the Wiki](https://github.com/overleaf/overleaf/wiki#release-notes) for all of the versions between your current version and the version you are upgrading to.
If you want to build a Docker image of the extended CE based on the upstream v5.3.1 codebase, you can check out the corresponding tag by running:
```
git checkout v5.3.1-ext-v1
```
After building the image, switch to the latest state of the repository and check the `server-ce/hotfix` directory. If a subdirectory matching your version (e.g., `5.3.1`) exists, build a patched image.
Alternatively, you can download a prebuilt image from Docker Hub:
```
docker pull overleafcep/sharelatex:5.3.1-ext-v1
```
Make sure to update the image name in overleaf-toolkit/config/docker-compose.override.yml accordingly.
## Sandboxed Compiles
To enable sandboxed compiles (also known as "Sibling containers"), set the following configuration options in `overleaf-toolkit/config/overleaf.rc`:
```
SERVER_PRO=true
SIBLING_CONTAINERS_ENABLED=true
```
The following environment variables are used to specify which TeX Live images to use for sandboxed compiles:
- `ALL_TEX_LIVE_DOCKER_IMAGES` **(required)**
* A comma-separated list of TeX Live images to use. These images will be downloaded or updated.
To skip downloading the images, set `SIBLING_CONTAINERS_PULL=false` in `config/overleaf.rc`.
- `ALL_TEX_LIVE_DOCKER_IMAGE_NAMES`
* A comma-separated list of friendly names for the images. If omitted, the version name will be used (e.g., `latest-full`).
- `TEX_LIVE_DOCKER_IMAGE` **(required)**
* The default TeX Live image that will be used for compiling new projects. The environment variable `ALL_TEX_LIVE_DOCKER_IMAGES` must include this image.
Users can select the image for their project in the project menu.
Here is an example where the default TeX Live image is `latest-full` from Docker Hub, but the `TL2023-historic` image can be used for older projects:
```
ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texlive:latest-full, texlive/texlive:TL2023-historic
ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=TeXLive 2024, TeXLive 2023
TEX_LIVE_DOCKER_IMAGE=texlive/texlive:latest-full
```
For additional details refer to
[Server Pro: Sandboxed Compiles](https://github.com/overleaf/overleaf/wiki/Server-Pro:-Sandboxed-Compiles) and
[Toolkit: Sandboxed Compiles](https://github.com/overleaf/toolkit/blob/master/doc/sandboxed-compiles.md).
When the compilation takes place in a dedicated container, it is relatively safe to permit running external commands from inside the TeX
file during compilation. This is required for packages like `minted`. For this purpose, the following environment variable can be used:
- `TEX_COMPILER_EXTRA_FLAGS`
* A list of extra flags for TeX compiler. Example: `-shell-escape -file-line-error`
<details>
<summary><h4>Sample variables.env file</h4></summary>
```
OVERLEAF_APP_NAME="Our Overleaf Instance"
ENABLED_LINKED_FILE_TYPES=project_file,project_output_file
# Enables Thumbnail generation using ImageMagick
ENABLE_CONVERSIONS=true
# Disables email confirmation requirement
EMAIL_CONFIRMATION_DISABLED=true
## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768
## Set for TLS via nginx-proxy
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true
OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Our Overleaf Instance
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com
OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]
OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
OVERLEAF_EMAIL_SMTP_PORT=587
OVERLEAF_EMAIL_SMTP_SECURE=false
# OVERLEAF_EMAIL_SMTP_USER=
# OVERLEAF_EMAIL_SMTP_PASS=
# OVERLEAF_EMAIL_SMTP_NAME=
OVERLEAF_EMAIL_SMTP_LOGGER=false
OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x
OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true
########################
## Sandboxed Compiles ##
########################
ALL_TEX_LIVE_DOCKER_IMAGES=texlive/texlive:latest-full, texlive/texlive:TL2023-historic
ALL_TEX_LIVE_DOCKER_IMAGE_NAMES=TeXLive 2024, TeXLive 2023
TEX_LIVE_DOCKER_IMAGE=texlive/texlive:latest-full
TEX_COMPILER_EXTRA_FLAGS=-shell-escape
```
</details>
## Authentication Methods
The following authentication methods are supported: local authentication, LDAP authentication, SAML authentication,
and OpenID Connect (OIDC) authentication. Local authentication is always active. The environment variable `EXTERNAL_AUTH`
specifies which external authentication methods are activated. The value of this variable is a list. If the list includes `ldap`, `saml`, or `oidc`,
then LDAP authentication, SAML authentication, and OIDC authentication will be activated, respectively.
For example: `EXTERNAL_AUTH=ldap saml oidc`
This configuration activates all available authentication methods, although this is rarely necessary.
<details>
<summary><h3>Local Authentication</h3></summary>
Password of local users stored in the MongoDB database. An admin user can create a new local user. For details, visit the
[wiki of Overleaf project](https://github.com/overleaf/overleaf/wiki/Creating-and-managing-users).
It is possible to enforce password restrictions on local users:
* `OVERLEAF_PASSWORD_VALIDATION_MIN_LENGTH`: The minimum length required
* `OVERLEAF_PASSWORD_VALIDATION_MAX_LENGTH`: The maximum length allowed
* `OVERLEAF_PASSWORD_VALIDATION_PATTERN`: is used to validate password strength
- `abc123` – password requires 3 letters and 3 numbers and be at least 6 characters long
- `aA` – password requires lower and uppercase letters and be at least 2 characters long
- `ab$3` – it must contain letters, digits and symbols and be at least 4 characters long
- There are 4 groups of characters: letters, UPPERcase letters, digits, symbols. Anything that is neither a letter nor a digit is considered to be a symbol.
</details>
<details>
<summary><h3>LDAP Authentication</h3></summary>
Internally, Overleaf LDAP uses the [passport-ldapauth](https://github.com/vesse/passport-ldapauth) library. Most of these configuration options are passed through to the `server` config object which is used to configure `passport-ldapauth`. If you are having issues configuring LDAP, it is worth reading the README for `passport-ldapauth` to understand the configuration it expects.
When using Local and LDAP authentication methods, a user enters a `username` and `password` in the login form. If LDAP authentication is enabled, it is attempted first:
1. An LDAP user is searched for in the LDAP directory using the filter defined by `OVERLEAF_LDAP_SEARCH_FILTER` and authenticated.
2. If authentication is successful, the Overleaf users database is checked for a user with the primary email address that matches the email address of the authenticated LDAP user:
- If a matching user is found, the `hashedPassword` field for this user is deleted (if it exists). This ensures that the user can only log in via LDAP authentication in the future.
- If no matching user is found, a new Overleaf user is created using the email, first name, and last name retrieved from the LDAP server.
3. If LDAP authentication fails or is unsuccessful, local authentication is attempted.
#### Environment Variables
- `OVERLEAF_LDAP_URL` **(required)**
* URL of the LDAP server.
- Example: `ldaps://ldap.example.com:636` (LDAP over SSL)
- Example: `ldap://ldap.example.com:389` (unencrypted or STARTTLS, if configured).
- `OVERLEAF_LDAP_EMAIL_ATT`
* The email attribute returned by the LDAP server, default `mail`. Each LDAP user must have at least one email address.
If multiple addresses are provided, only the first one will be used.
- `OVERLEAF_LDAP_FIRST_NAME_ATT`
* The property name holding the first name of the user which is used in the application, usually `givenName`.
- `OVERLEAF_LDAP_LAST_NAME_ATT`
* The property name holding the family name of the user which is used in the application, usually `sn`.
- `OVERLEAF_LDAP_NAME_ATT`
* The property name holding the full name of the user, usually `cn`. If either of the two previous variables is not defined,
the first and/or last name of the user is extracted from this variable. Otherwise, it is not used.
- `OVERLEAF_LDAP_PLACEHOLDER`
* The placeholder for the login form, defaults to `Username`.
- `OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN`
* If set to `true`, updates the LDAP user `first_name` and `last_name` field on login, and turn off the user details form on the `/user/settings`
page for LDAP users. Otherwise, details will be fetched only on first login.
- `OVERLEAF_LDAP_BIND_DN`
* The distinguished name of the LDAP user that should be used for the LDAP connection
(this user should be able to search/list accounts on the LDAP server),
e.g., `cn=ldap_reader,dc=example,dc=com`. If not defined, anonymous binding is used.
- `OVERLEAF_LDAP_BIND_CREDENTIALS`
* Password for `OVERLEAF_LDAP_BIND_DN`.
- `OVERLEAF_LDAP_BIND_PROPERTY`
* Property of the user to bind against the client, defaults to `dn`.
- `OVERLEAF_LDAP_SEARCH_BASE` **(required)**
* The base DN from which to search for users. E.g., `ou=people,dc=example,dc=com`.
- `OVERLEAF_LDAP_SEARCH_FILTER`
* LDAP search filter with which to find a user. Use the literal '{{username}}' to have the given username be interpolated in for the LDAP search.
- Example: `(|(uid={{username}})(mail={{username}}))` (user can login with email or with login name).
- Example: `(sAMAccountName={{username}})` (Active Directory).
- `OVERLEAF_LDAP_SEARCH_SCOPE`
* The scope of the search can be `base`, `one`, or `sub` (default).
- `OVERLEAF_LDAP_SEARCH_ATTRIBUTES`
* JSON array of attributes to fetch from the LDAP server, e.g., `["uid", "mail", "givenName", "sn"]`.
By default, all attributes are fetched.
- `OVERLEAF_LDAP_STARTTLS`
* If `true`, LDAP over TLS is used.
- `OVERLEAF_LDAP_TLS_OPTS_CA_PATH`
* Path to the file containing the CA certificate used to verify the LDAP server's SSL/TLS certificate. If there are multiple certificates, then
it can be a JSON array of paths to the certificates. The files must be accessible to the docker container.
- Example (one certificate): `/overleaf/certs/ldap_ca_cert.pem`
- Example (multiple certificates): `["/overleaf/certs/ldap_ca_cert1.pem", "/overleaf/certs/ldap_ca_cert2.pem"]`
- `OVERLEAF_LDAP_TLS_OPTS_REJECT_UNAUTH`
* If `true`, the server certificate is verified against the list of supplied CAs.
- `OVERLEAF_LDAP_CACHE`
* If `true`, then up to 100 credentials at a time will be cached for 5 minutes.
- `OVERLEAF_LDAP_TIMEOUT`
* How long the client should let operations live for before timing out, ms (Default: Infinity).
- `OVERLEAF_LDAP_CONNECT_TIMEOUT`
* How long the client should wait before timing out on TCP connections, ms (Default: OS default).
- `OVERLEAF_LDAP_IS_ADMIN_ATT` and `OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE`
* When both environment variables are set, the login process updates `user.isAdmin = true` if the LDAP profile contains the attribute specified by
`OVERLEAF_LDAP_IS_ADMIN_ATT` and its value either matches `OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE` or is an array containing `OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE`,
otherwise `user.isAdmin` is set to `false`. If either of these variables is not set, then the admin status is only set to `true` during admin user
creation in Launchpad.
The following five variables are used to configure how user contacts are retrieved from the LDAP server.
- `OVERLEAF_LDAP_CONTACTS_FILTER`
* The filter used to search for users in the LDAP server to be loaded into contacts. The placeholder '{{userProperty}}' within the filter is replaced with the value of
the property specified by `OVERLEAF_LDAP_CONTACTS_PROPERTY` from the LDAP user initiating the search. If not defined, no users are retrieved from the LDAP server into contacts.
- `OVERLEAF_LDAP_CONTACTS_SEARCH_BASE`
* Specifies the base DN from which to start searching for the contacts. Defaults to `OVERLEAF_LDAP_SEARCH_BASE`.
- `OVERLEAF_LDAP_CONTACTS_SEARCH_SCOPE`
* The scope of the search can be `base`, `one`, or `sub` (default).
- `OVERLEAF_LDAP_CONTACTS_PROPERTY`
* Specifies the property of the user object that will replace the '{{userProperty}}' placeholder in the `OVERLEAF_LDAP_CONTACTS_FILTER`.
- `OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE`
* Specifies the value of the `OVERLEAF_LDAP_CONTACTS_PROPERTY` if the search is initiated by a non-LDAP user. If this variable is not defined, the resulting filter
will match nothing. The value `*` can be used as a wildcard.
<details>
<summary><h5>Example</h5></summary>
OVERLEAF_LDAP_CONTACTS_FILTER=(gidNumber={{userProperty}})
OVERLEAF_LDAP_CONTACTS_PROPERTY=gidNumber
OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE=1000
The above example results in loading into the contacts of the current LDAP user all LDAP users who have the same UNIX `gid`. Non-LDAP users will have all LDAP users with UNIX `gid=1000` in their contacts.
</details>
<details>
<summary><h4>Sample variables.env file</h4></summary>
```
OVERLEAF_APP_NAME="Our Overleaf Instance"
ENABLED_LINKED_FILE_TYPES=project_file,project_output_file
# Enables Thumbnail generation using ImageMagick
ENABLE_CONVERSIONS=true
# Disables email confirmation requirement
EMAIL_CONFIRMATION_DISABLED=true
## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768
## Set for TLS via nginx-proxy
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true
OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Our Overleaf Instance
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com
OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]
OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
OVERLEAF_EMAIL_SMTP_PORT=587
OVERLEAF_EMAIL_SMTP_SECURE=false
# OVERLEAF_EMAIL_SMTP_USER=
# OVERLEAF_EMAIL_SMTP_PASS=
# OVERLEAF_EMAIL_SMTP_NAME=
OVERLEAF_EMAIL_SMTP_LOGGER=false
OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x
OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true
#################
## LDAP for CE ##
#################
EXTERNAL_AUTH=ldap
OVERLEAF_LDAP_URL=ldap://ldap.example.com:389
OVERLEAF_LDAP_STARTTLS=true
OVERLEAF_LDAP_TLS_OPTS_CA_PATH=/overleaf/certs/ldap_ca_cert.pem
OVERLEAF_LDAP_SEARCH_BASE=ou=people,dc=example,dc=com
OVERLEAF_LDAP_SEARCH_FILTER=(|(uid={{username}})(mail={{username}}))
OVERLEAF_LDAP_BIND_DN=cn=ldap_reader,dc=example,dc=com
OVERLEAF_LDAP_BIND_CREDENTIALS=GoodNewsEveryone
OVERLEAF_LDAP_EMAIL_ATT=mail
OVERLEAF_LDAP_FIRST_NAME_ATT=givenName
OVERLEAF_LDAP_LAST_NAME_ATT=sn
# OVERLEAF_LDAP_NAME_ATT=cn
OVERLEAF_LDAP_SEARCH_ATTRIBUTES=["uid", "sn", "givenName", "mail"]
OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN=true
OVERLEAF_LDAP_PLACEHOLDER='Username or email address'
OVERLEAF_LDAP_IS_ADMIN_ATT=mail
OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE=admin@example.com
OVERLEAF_LDAP_CONTACTS_FILTER=(gidNumber={{userProperty}})
OVERLEAF_LDAP_CONTACTS_PROPERTY=gidNumber
OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE='*'
```
</details>
<details>
<summary><i>Deprecated variables</i></summary>
**These variables will be removed soon**, use `OVERLEAF_LDAP_IS_ADMIN_ATT` and `OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE` instead.
The following variables are used to determine if the user has admin rights.
Please note: the user gains admin status if the search result is not empty, not when the user is explicitly included in the search results.
- `OVERLEAF_LDAP_ADMIN_SEARCH_BASE`
* Specifies the base DN from which to start searching for the admin group. If this variable is defined,
`OVERLEAF_LDAP_ADMIN_SEARCH_FILTER` must also be defined for the search to function properly.
- `OVERLEAF_LDAP_ADMIN_SEARCH_FILTER`
* Defines the LDAP search filter used to identify the admin group. The placeholder `{{dn}}` within the filter
is replaced with the value of the property specified by `OVERLEAF_LDAP_ADMIN_DN_PROPERTY`. The placeholder `{{username}}` is also supported.
- `OVERLEAF_LDAP_ADMIN_DN_PROPERTY`
* Specifies the property of the user object that will replace the '{{dn}}' placeholder
in the `OVERLEAF_LDAP_ADMIN_SEARCH_FILTER`, defaults to `dn`.
- `OVERLEAF_LDAP_ADMIN_SEARCH_SCOPE`
* The scope of the LDAP search can be `base`, `one`, or `sub` (default)
<details>
<summary><h5>Example</h5></summary>
In the following example admins are members of a group `admins`, the objectClass of the entry `admins` is `groupOfNames`:
OVERLEAF_LDAP_ADMIN_SEARCH_BASE='cn=admins,ou=group,dc=example,dc=com'
OVERLEAF_LDAP_ADMIN_SEARCH_FILTER='(member={{dn}})'
In the following example admins are members of a group 'admins', the objectClass of the entry `admins` is `posixGroup`:
OVERLEAF_LDAP_ADMIN_SEARCH_BASE='cn=admins,ou=group,dc=example,dc=com'
OVERLEAF_LDAP_ADMIN_SEARCH_FILTER='(memberUid={{username}})'
In the following example admins are users with UNIX gid=1234:
OVERLEAF_LDAP_ADMIN_SEARCH_BASE='ou=people,dc=example,dc=com'
OVERLEAF_LDAP_ADMIN_SEARCH_FILTER='(&(gidNumber=1234)(uid={{username}}))'
In the following example admin is the user with `uid=someuser`:
OVERLEAF_LDAP_ADMIN_SEARCH_BASE='ou=people,dc=example,dc=com'
OVERLEAF_LDAP_ADMIN_SEARCH_FILTER='(&(uid=someuser)(uid={{username}}))'
The filter
OVERLEAF_LDAP_ADMIN_SEARCH_FILTER='(uid=someuser)'
where `someuser` is the uid of an existing user, will always produce a non-empty search result.
As a result, **every user will be granted admin rights**, not just `someuser`, as one might expect.
</details>
</details>
</details>
<details>
<summary><h3>SAML Authentication</h3></summary>
Internally, Overleaf SAML module uses the [passport-saml](https://github.com/node-saml/passport-saml) library, most of the following
configuration options are passed through to `passport-saml`. If you are having issues configuring SAML, it is worth reading the README
for `passport-saml` to get a feel for the configuration it expects.
When using the SAML authentication method, a user is redirected to the Identity Provider (IdP) authentication site.
If the IdP successfully authenticates the user, the Overleaf users database is checked for a record containing a `samlIdentifiers` field structured as follows:
```
samlIdentifiers: [
{
externalUserId: "...",
providerId: "1",
userIdAttribute: "..."
}
]
```
The `externalUserId` must match the value of the property specified by `userIdAttribute` in the user profile returned by the IdP server.
If no matching record is found, the database is searched for a user with the primary email address matching the email in the IdP user profile:
- If such a user is found, the `hashedPassword` field is deleted to disable local authentication, and the `samlIdentifiers` field is added.
- If no matching user is found, a new user is created with the email address and `samlIdentifiers` from the IdP profile.
**Note:** Currently, only one SAML IdP is supported. The `providerId` field in `samlIdentifiers` is fixed to `'1'`.
#### Environment Variables
- `OVERLEAF_SAML_IDENTITY_SERVICE_NAME`
* Display name for the identity service, used on the login page (default: `Log in with SAML IdP`).
- `OVERLEAF_SAML_USER_ID_FIELD`
* The value of this attribute will be used by Overleaf as the external user ID, defaults to `nameID`.
- `OVERLEAF_SAML_EMAIL_FIELD`
* Name of the Email field in user profile, defaults to `nameID`.
- `OVERLEAF_SAML_FIRST_NAME_FIELD`
* Name of the firstName field in user profile, defaults to `givenName`.
- `OVERLEAF_SAML_LAST_NAME_FIELD`
* Name of the lastName field in user profile, defaults to `lastName`
- `OVERLEAF_SAML_UPDATE_USER_DETAILS_ON_LOGIN`
* If set to `true`, updates the user `first_name` and `last_name` field on login,
and turn off the user details form on `/user/settings` page.
- `OVERLEAF_SAML_ENTRYPOINT` **(required)**
* Entrypoint URL for the SAML identity service.
- Example: `https://idp.example.com/simplesaml/saml2/idp/SSOService.php`
- Azure Example: `https://login.microsoftonline.com/8b26b46a-6dd3-45c7-a104-f883f4db1f6b/saml2`
- `OVERLEAF_SAML_ISSUER` **(required)**
* The Issuer name.
- `OVERLEAF_SAML_AUDIENCE`
* Expected saml response Audience, defaults to value of `OVERLEAF_SAML_ISSUER`.
- `OVERLEAF_SAML_IDP_CERT` **(required)**
* Path to a file containing the Identity Provider's public certificate, used to validate the signatures of incoming SAML responses. If the Identity Provider has multiple valid signing certificates, then
it can be a JSON array of paths to the certificates.
- Example (one certificate): `/overleaf/certs/idp_cert.pem`
- Example (multiple certificates): `["/overleaf/certs/idp_cert.pem", "/overleaf/certs/idp_cert_old.pem"]`
- `OVERLEAF_SAML_PUBLIC_CERT`
* Path to a file containing public signing certificate used to embed in auth requests in order for the IdP to validate the signatures of the incoming SAML Request. It's required when setting up the [metadata endpoint](#metadata-for-the-identity-provider)
when the strategy is configured with a `OVERLEAF_SAML_PRIVATE_KEY`. A JSON array of paths to certificates can be provided to support certificate rotation. When supplying an array of certificates, the first entry in the array should match the
current `OVERLEAF_SAML_PRIVATE_KEY`. Additional entries in the array can be used to publish upcoming certificates to IdPs before changing the `OVERLEAF_SAML_PRIVATE_KEY`.
- `OVERLEAF_SAML_PRIVATE_KEY`
* Path to a file containing a PEM-formatted private key matching the `OVERLEAF_SAML_PUBLIC_CERT` used to sign auth requests sent by passport-saml.
- `OVERLEAF_SAML_DECRYPTION_CERT`
* Path to a file containing public certificate, used for the [metadata endpoint](#metadata-for-the-identity-provider).
- `OVERLEAF_SAML_DECRYPTION_PVK`
* Path to a file containing private key matching the `OVERLEAF_SAML_DECRYPTION_CERT` that will be used to attempt to decrypt any encrypted assertions that are received.
- `OVERLEAF_SAML_SIGNATURE_ALGORITHM`
* Optionally set the signature algorithm for signing requests,
valid values are 'sha1' (default), 'sha256' (prefered), 'sha512' (most secure, check if your IdP supports it).
- `OVERLEAF_SAML_ADDITIONAL_PARAMS`
* JSON dictionary of additional query params to add to all requests.
- `OVERLEAF_SAML_ADDITIONAL_AUTHORIZE_PARAMS`
* JSON dictionary of additional query params to add to 'authorize' requests.
- Example: `{"some_key": "some_value"}`
- `OVERLEAF_SAML_IDENTIFIER_FORMAT`
* Name identifier format to request from the identity provider (default: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`).
If using `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`, ensure the `OVERLEAF_SAML_EMAIL_FIELD` envirionment variable is defined.
If `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` is required, you must also define the `OVERLEAF_SAML_ID_FIELD` environment variable,
which can, for example, be set to the user's email address.
- `OVERLEAF_SAML_ACCEPTED_CLOCK_SKEW_MS`
* Time in milliseconds of skew that is acceptable between client and server when checking OnBefore and NotOnOrAfter assertion
condition validity timestamps. Setting to -1 will disable checking these conditions entirely. Default is 0.
- `OVERLEAF_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX`
* `AttributeConsumingServiceIndex` attribute to add to AuthnRequest to instruct the IdP which attribute set to attach
to the response ([link](http://blog.aniljohn.com/2014/01/data-minimization-front-channel-saml-attribute-requests.html)).
- `OVERLEAF_SAML_AUTHN_CONTEXT`
* JSON array of name identifier format values to request auth context. Default: `["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"]`.
- `OVERLEAF_SAML_FORCE_AUTHN`
* If `true`, the initial SAML request from the service provider specifies that the IdP should force re-authentication of the user,
even if they possess a valid session.
- `OVERLEAF_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT`
* If `true`, do not request a specific auth context. For example, you can this this to `true` to allow additional contexts such as password-less logins (`urn:oasis:names:tc:SAML:2.0:ac:classes:X509`). Support for additional contexts is dependant on your IdP.
- `OVERLEAF_SAML_AUTHN_REQUEST_BINDING`
* If set to `HTTP-POST`, will request authentication from IdP via HTTP POST binding, otherwise defaults to HTTP-Redirect.
- `OVERLEAF_SAML_VALIDATE_IN_RESPONSE_TO`
* If `always`, then InResponseTo will be validated from incoming SAML responses.
* If `never`, then InResponseTo won't be validated (default).
* If `ifPresent`, then InResponseTo will only be validated if present in the incoming SAML response.
- `OVERLEAF_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS`
* Defines the expiration time when a Request ID generated for a SAML request will not be valid if seen
in a SAML response in the `InResponseTo` field. Default: 28800000 (8 hours).
- `OVERLEAF_SAML_LOGOUT_URL`
* base address to call with logout requests (default: `entryPoint`).
- Example: `https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php`
- `OVERLEAF_SAML_ADDITIONAL_LOGOUT_PARAMS`
* JSON dictionary of additional query params to add to 'logout' requests.
- `OVERLEAF_SAML_IS_ADMIN_FIELD` and `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`
* When both environment variables are set, the login process updates `user.isAdmin = true` if the profile returned by the SAML IdP contains the attribute specified by
`OVERLEAF_SAML_IS_ADMIN_FIELD` and its value either matches `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE` or is an array containing `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`,
otherwise `user.isAdmin` is set to `false`. If either of these variables is not set, then the admin status is only set to `true` during admin user
creation in Launchpad.
#### Metadata for the Identity Provider
The current version of Overleaf CE includes and endpoint to retrieve Service Provider Metadata: `http://my-overleaf-instance.com/saml/meta`
The Identity Provider will need to be configured to recognize the Overleaf server as a "Service Provider". Consult the documentation for your SAML server for instructions on how to do this.
Below is an example of appropriate Service Provider metadata:
<details>
<summary><h5>ol-meta.xml</h5></summary>
```
<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
entityID="MyOverleaf"
ID="_b508c83b7dda452f5b269383fb391107116f8f57">
<SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" AuthnRequestsSigned="true" WantAssertionsSigned="true">
<KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MII...
[skipped]
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<KeyDescriptor use="encryption">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MII...
[skipped]
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
</KeyDescriptor>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://my-overleaf-instance.com/saml/logout/callback"/>
<NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
<AssertionConsumerService index="1"
isDefault="true"
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://my-overleaf-instance.com/saml/login/callback"/>
</SPSSODescriptor>
</EntityDescriptor>
```
</details>
Note the certificates, `AssertionConsumerService.Location`, `SingleLogoutService.Location` and `EntityDescriptor.entityID`
and set as appropriate in your IdP configuration, or send the metadata file to the IdP admin.
<details>
<summary><h4>Sample variables.env file</h4></summary>
```
OVERLEAF_APP_NAME="Our Overleaf Instance"
ENABLED_LINKED_FILE_TYPES=project_file,project_output_file
# Enables Thumbnail generation using ImageMagick
ENABLE_CONVERSIONS=true
# Disables email confirmation requirement
EMAIL_CONFIRMATION_DISABLED=true
## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768
## Set for TLS via nginx-proxy
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true
OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Our Overleaf Instance
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com
OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]
OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
OVERLEAF_EMAIL_SMTP_PORT=587
OVERLEAF_EMAIL_SMTP_SECURE=false
# OVERLEAF_EMAIL_SMTP_USER=
# OVERLEAF_EMAIL_SMTP_PASS=
# OVERLEAF_EMAIL_SMTP_NAME=
OVERLEAF_EMAIL_SMTP_LOGGER=false
OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x
OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true
#################
## SAML for CE ##
#################
EXTERNAL_AUTH=saml
OVERLEAF_SAML_IDENTITY_SERVICE_NAME='Log in with My IdP'
OVERLEAF_SAML_EMAIL_FIELD=mail
OVERLEAF_SAML_FIRST_NAME_FIELD=givenName
OVERLEAF_SAML_LAST_NAME_FIELD=sn
OVERLEAF_SAML_ENTRYPOINT=https://idp.example.com/simplesamlphp/saml2/idp/SSOService.php
OVERLEAF_SAML_CALLBACK_URL=https://my-overleaf-instance.com/saml/login/callback
OVERLEAF_SAML_LOGOUT_URL=https://idp.example.com/simplesamlphp/saml2/idp/SingleLogoutService.php
OVERLEAF_SAML_LOGOUT_CALLBACK_URL=https://my-overleaf-instance.com/saml/logout/callback
OVERLEAF_SAML_ISSUER=MyOverleaf
OVERLEAF_SAML_IDP_CERT=/overleaf/certs/idp_cert.pem
OVERLEAF_SAML_PUBLIC_CERT=/overleaf/certs/myol_cert.pem
OVERLEAF_SAML_PRIVATE_KEY=/overleaf/certs/myol_key.pem
OVERLEAF_SAML_DECRYPTION_CERT=/overleaf/certs/myol_decr_cert.pem
OVERLEAF_SAML_DECRYPTION_PVK=/overleaf/certs/myol_decr_key.pem
OVERLEAF_SAML_IS_ADMIN_FIELD=mail
OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE=overleaf.admin@example.com
```
</details>
</details>
<details>
<summary><h3>OIDC Authentication</h3></summary>
Internally, Overleaf OIDC module uses the [passport-openidconnect](https://github.com/jaredhanson/passport-openidconnect) library.
If you are having issues configuring OpenID Connect, it is worth reading the README for `passport-openidconnect` to get a feel for the configuration it expects.
When using the OIDC authentication method, a user is redirected to the Identity Provider (IdP) authentication site.
If the IdP successfully authenticates the user, the Overleaf users database is checked for a record containing a `thirdPartyIdentifiers` field structured as follows:
```
thirdPartyIdentifiers: [
{
externalUserId: "...",
externalData: null,
providerId: "..."
}
]
```
The `externalUserId` must match the user ID in the profile returned by the IdP server (see the `OVERLEAF_OIDC_USER_ID_FIELD` environment variable), and `providerId`
must match the ID of the OIDC provider (see the `OVERLEAF_OIDC_PROVIDER_ID`).
If no matching record is found, the database is searched for a user with the primary email address matching the email in the IdP user profile:
- If such a user is found, the `thirdPartyIdentifiers` field is updated.
- If no matching user is found, a new user is created with the email address and `thirdPartyIdentifiers` from the IdP profile.
In both cases, the user is said to be 'linked' to the external OIDC user. The user can be unlinked from the OIDC provider on the `/user/settings` page.
#### Environment Variables
The values of the following five required variables can be found using `.well-known/openid-configuration` endpoint of your OpenID Provider (OP).
- `OVERLEAF_OIDC_ISSUER` **(required)**
- `OVERLEAF_OIDC_AUTHORIZATION_URL` **(required)**
- `OVERLEAF_OIDC_TOKEN_URL` **(required)**
- `OVERLEAF_OIDC_USER_INFO_URL` **(required)**
- `OVERLEAF_OIDC_LOGOUT_URL` **(required)**
The values of the following two required variables will be provided by the admin of your OP
- `OVERLEAF_OIDC_CLIENT_ID` **(required)**
- `OVERLEAF_OIDC_CLIENT_SECRET` **(required)**
- `OVERLEAF_OIDC_SCOPE`
* Default: `openid profile email`
- `OVERLEAF_OIDC_PROVIDER_ID`
* Arbitrary ID of the OP, defaults to `oidc`.
- `OVERLEAF_OIDC_PROVIDER_NAME`
* The name of the OP, used in the `Linked Accounts` section of the `/user/settings` page, defaults to `OIDC Provider`.
- `OVERLEAF_OIDC_IDENTITY_SERVICE_NAME`
* Display name for the identity service, used on the login page (default: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
- `OVERLEAF_OIDC_PROVIDER_DESCRIPTION`
* Description of OP, used in the `Linked Accounts` section (default: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
- `OVERLEAF_OIDC_PROVIDER_INFO_LINK`
* `Learn more` URL in the OP description, default: no `Learn more` link in the description.
- `OVERLEAF_OIDC_PROVIDER_HIDE_NOT_LINKED`
* Do not show OP on the `/user/settings` page, if the user's account is not linked with the OP, default `false`.
- `OVERLEAF_OIDC_USER_ID_FIELD`
* The value of this attribute will be used by Overleaf as the external user ID, defaults to `id`.
- `OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN`
* If set to `true`, updates the user `first_name` and `last_name` field on login,
and disables the user details form on `/user/settings` page.
- `OVERLEAF_OIDC_IS_ADMIN_FIELD` and `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`
* When both environment variables are set, the login process updates `user.isAdmin = true` if the profile returned by the OP contains the attribute specified by
`OVERLEAF_OIDC_IS_ADMIN_FIELD` and its value matches `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`, otherwise `user.isAdmin` is set to `false`.
If `OVERLEAF_OIDC_IS_ADMIN_FIELD` is `email` then the value of the attribute `emails[0].value` is used for match checking.
<details>
<summary><h4>Sample variables.env file</h4></summary>
```
OVERLEAF_APP_NAME="Our Overleaf Instance"
ENABLED_LINKED_FILE_TYPES=project_file,project_output_file
# Enables Thumbnail generation using ImageMagick
ENABLE_CONVERSIONS=true
# Disables email confirmation requirement
EMAIL_CONFIRMATION_DISABLED=true
## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768
## Set for TLS via nginx-proxy
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true
OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Our Overleaf Instance
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com
OVERLEAF_LEFT_FOOTER=[{"text": "Contact your support team", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "url":"https://github.com/yu-i-i/overleaf-cep"}]
OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
OVERLEAF_EMAIL_SMTP_PORT=587
OVERLEAF_EMAIL_SMTP_SECURE=false
# OVERLEAF_EMAIL_SMTP_USER=
# OVERLEAF_EMAIL_SMTP_PASS=
# OVERLEAF_EMAIL_SMTP_NAME=
OVERLEAF_EMAIL_SMTP_LOGGER=false
OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
OVERLEAF_CUSTOM_EMAIL_FOOTER=This system is run by department x
OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true
#################
## OIDC for CE ##
#################
EXTERNAL_AUTH=oidc
OVERLEAF_OIDC_PROVIDER_ID=oidc
OVERLEAF_OIDC_ISSUER=https://keycloak.provider.com/realms/example
OVERLEAF_OIDC_AUTHORIZATION_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/auth
OVERLEAF_OIDC_TOKEN_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/token
OVERLEAF_OIDC_USER_INFO_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/userinfo
OVERLEAF_OIDC_LOGOUT_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/logout
OVERLEAF_OIDC_CLIENT_ID=Overleaf-OIDC
OVERLEAF_OIDC_CLIENT_SECRET=DoNotUseThisATGgaAcTgCcATgGATTACAagGtTCaGcGTAG
OVERLEAF_OIDC_IDENTITY_SERVICE_NAME='Log in with Keycloak OIDC Provider'
OVERLEAF_OIDC_PROVIDER_NAME=OIDC Keycloak Provider
OVERLEAF_OIDC_PROVIDER_INFO_LINK=https://openid.net
OVERLEAF_OIDC_IS_ADMIN_FIELD=email
OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=overleaf.admin@example.com
OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=false
```
</details>
</details>
## Overleaf Docker Image
@@ -45,8 +881,8 @@ This repo contains two dockerfiles, [`Dockerfile-base`](server-ce/Dockerfile-bas
`sharelatex/sharelatex-base` image, and [`Dockerfile`](server-ce/Dockerfile) which builds the
`sharelatex/sharelatex` (or "community") image.
The Base image generally contains the basic dependencies like `wget` and
`aspell`, plus `texlive`. We split this out because it's a pretty heavy set of
The Base image generally contains the basic dependencies like `wget`, plus `texlive`.
We split this out because it's a pretty heavy set of
dependencies, and it's nice to not have to rebuild all of that every time.
The `sharelatex/sharelatex` image extends the base image and adds the actual Overleaf code
@@ -60,14 +896,11 @@ in which to run the Overleaf services. Baseimage uses the `runit` service
manager to manage services, and we add our init-scripts from the `server-ce/runit`
folder.
## Contributing
Please see the [CONTRIBUTING](CONTRIBUTING.md) file for information on contributing to the development of Overleaf.
## Authors
[The Overleaf Team](https://www.overleaf.com/about)
<br>
Extensions for CE by: [yu-i-i](https://github.com/yu-i-i/overleaf-cep)
## License
+2 -1
View File
@@ -13,7 +13,8 @@ NOTIFICATIONS_HOST=notifications
PROJECT_HISTORY_HOST=project-history
REALTIME_HOST=real-time
REDIS_HOST=redis
SPELLING_HOST=spelling
REFERENCES_HOST=references
SESSION_SECRET=foo
WEBPACK_HOST=webpack
WEB_API_PASSWORD=overleaf
WEB_API_USER=overleaf
+11
View File
@@ -112,6 +112,17 @@ services:
- ../services/real-time/app.js:/overleaf/services/real-time/app.js
- ../services/real-time/config:/overleaf/services/real-time/config
references:
command: ["node", "--watch", "app.js"]
environment:
- NODE_OPTIONS=--inspect=0.0.0.0:9229
ports:
- "127.0.0.1:9236:9229"
volumes:
- ../services/references/app:/overleaf/services/references/app
- ../services/references/config:/overleaf/services/references/config
- ../services/references/app.js:/overleaf/services/references/app.js
web:
command: ["node", "--watch", "app.js", "--watch-locales"]
environment:
+5 -8
View File
@@ -8,7 +8,6 @@ volumes:
mongo-data:
redis-data:
sharelatex-data:
spelling-cache:
web-data:
history-v1-buckets:
@@ -124,14 +123,12 @@ services:
volumes:
- redis-data:/data
spelling:
references:
build:
context: ..
dockerfile: services/spelling/Dockerfile
dockerfile: services/references/Dockerfile
env_file:
- dev.env
volumes:
- spelling-cache:/overleaf/services/spelling/cache
web:
build:
@@ -146,7 +143,7 @@ services:
- EMAIL_CONFIRMATION_DISABLED=true
- NODE_ENV=development
- OVERLEAF_ALLOW_PUBLIC_ACCESS=true
command: ["node", "app.js"]
command: ["node", "app.mjs"]
volumes:
- sharelatex-data:/var/lib/overleaf
- web-data:/overleaf/services/web/data
@@ -163,13 +160,13 @@ services:
- notifications
- project-history
- real-time
- spelling
- references
webpack:
build:
context: ..
dockerfile: services/web/Dockerfile
target: dev
target: webpack
command: ["npx", "webpack", "serve", "--config", "webpack.config.dev-env.js"]
ports:
- "127.0.0.1:80:3808"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 587 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
@@ -5,6 +5,6 @@ access-token-encryptor
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
@@ -1,5 +1,5 @@
const { promisify } = require('util')
const crypto = require('crypto')
const { promisify } = require('node:util')
const crypto = require('node:crypto')
const ALGORITHM = 'aes-256-ctr'
@@ -1,4 +1,13 @@
const chai = require('chai')
const chaiAsPromised = require('chai-as-promised')
const SandboxedModule = require('sandboxed-module')
chai.use(chaiAsPromised)
SandboxedModule.configure({
sourceTransformers: {
removeNodePrefix: function (source) {
return source.replace(/require\(['"]node:/g, "require('")
},
},
})
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ fetch-utils
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+3 -3
View File
@@ -1,9 +1,9 @@
const _ = require('lodash')
const { Readable } = require('stream')
const { Readable } = require('node:stream')
const OError = require('@overleaf/o-error')
const fetch = require('node-fetch')
const http = require('http')
const https = require('https')
const http = require('node:http')
const https = require('node:https')
/**
* @import { Response } from 'node-fetch'
@@ -1,7 +1,7 @@
const { expect } = require('chai')
const { FetchError, AbortError } = require('node-fetch')
const { Readable } = require('stream')
const { once } = require('events')
const { Readable } = require('node:stream')
const { once } = require('node:events')
const { TestServer } = require('./helpers/TestServer')
const selfsigned = require('selfsigned')
const {
@@ -24,13 +24,17 @@ const pems = selfsigned.generate(attrs, { days: 365 })
const PRIVATE_KEY = pems.private
const PUBLIC_CERT = pems.cert
const dns = require('dns')
const dns = require('node:dns')
const _originalLookup = dns.lookup
// Custom DNS resolver function
dns.lookup = (hostname, options, callback) => {
if (hostname === 'example.com') {
// If the hostname is our test case, return the ip address for the test server
callback(null, '127.0.0.1', 4)
if (options?.all) {
callback(null, [{ address: '127.0.0.1', family: 4 }])
} else {
callback(null, '127.0.0.1', 4)
}
} else {
// Otherwise, use the default lookup
_originalLookup(hostname, options, callback)
@@ -1,9 +1,9 @@
const express = require('express')
const bodyParser = require('body-parser')
const { EventEmitter } = require('events')
const http = require('http')
const https = require('https')
const { promisify } = require('util')
const { EventEmitter } = require('node:events')
const http = require('node:http')
const https = require('node:https')
const { promisify } = require('node:util')
class TestServer {
constructor() {
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ logger
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+1 -1
View File
@@ -1,5 +1,5 @@
const { fetchString } = require('@overleaf/fetch-utils')
const fs = require('fs')
const fs = require('node:fs')
class LogLevelChecker {
constructor(logger, defaultLevel) {
+1 -12
View File
@@ -1,7 +1,6 @@
const Stream = require('stream')
const Stream = require('node:stream')
const bunyan = require('bunyan')
const GCPManager = require('./gcp-manager')
const SentryManager = require('./sentry-manager')
const Serializers = require('./serializers')
const {
FileLogLevelChecker,
@@ -33,10 +32,6 @@ const LoggingManager = {
return this
},
initializeErrorReporting(dsn, options) {
this.sentryManager = new SentryManager()
},
/**
* @param {Record<string, any>|string} attributes - Attributes to log (nice serialization for err, req, res)
* @param {string} [message] - Optional message
@@ -68,9 +63,6 @@ const LoggingManager = {
})
}
this.logger.error(attributes, message, ...Array.from(args))
if (this.sentryManager) {
this.sentryManager.captureExceptionRateLimited(attributes, message)
}
},
/**
@@ -98,9 +90,6 @@ const LoggingManager = {
*/
fatal(attributes, message) {
this.logger.fatal(attributes, message)
if (this.sentryManager) {
this.sentryManager.captureException(attributes, message, 'fatal')
}
},
_getOutputStreamConfig() {
-1
View File
@@ -23,7 +23,6 @@
"@google-cloud/logging-bunyan": "^5.1.0",
"@overleaf/fetch-utils": "*",
"@overleaf/o-error": "*",
"@sentry/node": "^6.13.2",
"bunyan": "^1.8.14"
},
"devDependencies": {
-106
View File
@@ -1,106 +0,0 @@
const Serializers = require('./serializers')
const RATE_LIMIT_MAX_ERRORS = 5
const RATE_LIMIT_INTERVAL_MS = 60000
class SentryManager {
constructor(dsn, options) {
this.Sentry = require('@sentry/node')
this.Sentry.init({ dsn, ...options })
// for rate limiting on sentry reporting
this.lastErrorTimeStamp = 0
this.lastErrorCount = 0
}
captureExceptionRateLimited(attributes, message) {
const now = Date.now()
// have we recently reported an error?
const recentSentryReport =
now - this.lastErrorTimeStamp < RATE_LIMIT_INTERVAL_MS
// if so, increment the error count
if (recentSentryReport) {
this.lastErrorCount++
} else {
this.lastErrorCount = 0
this.lastErrorTimeStamp = now
}
// only report 5 errors every minute to avoid overload
if (this.lastErrorCount < RATE_LIMIT_MAX_ERRORS) {
// add a note if the rate limit has been hit
const note =
this.lastErrorCount + 1 === RATE_LIMIT_MAX_ERRORS
? '(rate limited)'
: ''
// report the exception
this.captureException(attributes, message, `error${note}`)
}
}
captureException(attributes, message, level) {
// handle case of logger.error "message"
if (typeof attributes === 'string') {
attributes = { err: new Error(attributes) }
}
// extract any error object
let error = Serializers.err(attributes.err || attributes.error)
// avoid reporting errors twice
for (const key in attributes) {
const value = attributes[key]
if (value instanceof Error && value.reportedToSentry) {
return
}
}
// include our log message in the error report
if (error == null) {
if (typeof message === 'string') {
error = { message }
}
} else if (message != null) {
attributes.description = message
}
// report the error
if (error != null) {
// capture attributes and use *_id objects as tags
const tags = {}
const extra = {}
for (const key in attributes) {
let value = attributes[key]
if (Serializers[key]) {
value = Serializers[key](value)
}
if (key.match(/_id/) && typeof value === 'string') {
tags[key] = value
}
extra[key] = value
}
// OError integration
extra.info = error.info
delete error.info
// Sentry wants to receive an Error instance.
const errInstance = new Error(error.message)
Object.assign(errInstance, error)
try {
// send the error to sentry
this.Sentry.captureException(errInstance, { tags, extra, level })
// put a flag on the errors to avoid reporting them multiple times
for (const key in attributes) {
const value = attributes[key]
if (value instanceof Error) {
value.reportedToSentry = true
}
}
} catch (err) {
// ignore Sentry errors
}
}
}
}
module.exports = SentryManager
+5
View File
@@ -8,4 +8,9 @@ chai.use(sinonChai)
SandboxedModule.configure({
globals: { Buffer, JSON, console, process },
sourceTransformers: {
removeNodePrefix: function (source) {
return source.replace(/require\(['"]node:/g, "require('")
},
},
})
@@ -1,5 +1,5 @@
const Path = require('path')
const { promisify } = require('util')
const Path = require('node:path')
const { promisify } = require('node:util')
const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
const { expect } = require('chai')
@@ -1,7 +1,7 @@
const SandboxedModule = require('sandboxed-module')
const bunyan = require('bunyan')
const { expect } = require('chai')
const path = require('path')
const path = require('node:path')
const sinon = require('sinon')
const MODULE_PATH = path.join(__dirname, '../../logging-manager.js')
@@ -43,20 +43,14 @@ describe('LoggingManager', function () {
.stub()
.returns(this.GCEMetadataLogLevelChecker),
}
this.SentryManager = {
captureException: sinon.stub(),
captureExceptionRateLimited: sinon.stub(),
}
this.LoggingManager = SandboxedModule.require(MODULE_PATH, {
requires: {
bunyan: this.Bunyan,
'./log-level-checker': this.LogLevelChecker,
'./sentry-manager': sinon.stub().returns(this.SentryManager),
},
})
this.loggerName = 'test'
this.logger = this.LoggingManager.initialize(this.loggerName)
this.logger.initializeErrorReporting('test_dsn')
})
afterEach(function () {
@@ -160,13 +154,6 @@ describe('LoggingManager', function () {
})
})
describe('logger.error', function () {
it('should report errors to Sentry', function () {
this.logger.error({ foo: 'bar' }, 'message')
expect(this.SentryManager.captureExceptionRateLimited).to.have.been.called
})
})
describe('ringbuffer', function () {
beforeEach(function () {
this.logBufferMock = [
@@ -1,247 +0,0 @@
const Path = require('path')
const SandboxedModule = require('sandboxed-module')
const { expect } = require('chai')
const sinon = require('sinon')
const MODULE_PATH = Path.join(__dirname, '../../sentry-manager.js')
describe('SentryManager', function () {
beforeEach(function () {
this.clock = sinon.useFakeTimers(Date.now())
this.Sentry = {
init: sinon.stub(),
captureException: sinon.stub(),
}
this.SentryManager = SandboxedModule.require(MODULE_PATH, {
requires: {
'@sentry/node': this.Sentry,
},
})
this.sentryManager = new this.SentryManager('test_dsn')
})
afterEach(function () {
this.clock.restore()
})
describe('captureExceptionRateLimited', function () {
it('should report a single error to sentry', function () {
this.sentryManager.captureExceptionRateLimited({ foo: 'bar' }, 'message')
expect(this.Sentry.captureException).to.have.been.calledOnce
})
it('should report the same error to sentry only once', function () {
const error1 = new Error('this is the error')
this.sentryManager.captureExceptionRateLimited(
{ foo: error1 },
'first message'
)
this.sentryManager.captureExceptionRateLimited(
{ bar: error1 },
'second message'
)
expect(this.Sentry.captureException).to.have.been.calledOnce
})
it('should report two different errors to sentry individually', function () {
const error1 = new Error('this is the error')
const error2 = new Error('this is the error')
this.sentryManager.captureExceptionRateLimited(
{ foo: error1 },
'first message'
)
this.sentryManager.captureExceptionRateLimited(
{ bar: error2 },
'second message'
)
expect(this.Sentry.captureException).to.have.been.calledTwice
})
it('for multiple errors should only report a maximum of 5 errors to sentry', function () {
for (let i = 0; i < 10; i++) {
this.sentryManager.captureExceptionRateLimited(
{ foo: 'bar' },
'message'
)
}
expect(this.Sentry.captureException).to.have.callCount(5)
})
it('for multiple errors with a minute delay should report 10 errors to sentry', function () {
for (let i = 0; i < 10; i++) {
this.sentryManager.captureExceptionRateLimited(
{ foo: 'bar' },
'message'
)
}
expect(this.Sentry.captureException).to.have.callCount(5)
// allow a minute to pass
this.clock.tick(61 * 1000)
for (let i = 0; i < 10; i++) {
this.sentryManager.captureExceptionRateLimited(
{ foo: 'bar' },
'message'
)
}
expect(this.Sentry.captureException).to.have.callCount(10)
})
})
describe('captureException', function () {
it('should remove the path from fs errors', function () {
const fsError = new Error(
"Error: ENOENT: no such file or directory, stat '/tmp/3279b8d0-da10-11e8-8255-efd98985942b'"
)
fsError.path = '/tmp/3279b8d0-da10-11e8-8255-efd98985942b'
this.sentryManager.captureException({ err: fsError }, 'message', 'error')
expect(this.Sentry.captureException).to.have.been.calledWith(
sinon.match.has(
'message',
'Error: ENOENT: no such file or directory, stat'
)
)
})
it('should sanitize error', function () {
const err = {
name: 'CustomError',
message: 'hello',
_oErrorTags: [{ stack: 'here:1', info: { one: 1 } }],
stack: 'here:0',
info: { key: 'value' },
code: 42,
signal: 9,
path: '/foo',
}
this.sentryManager.captureException({ err }, 'message', 'error')
const expectedErr = {
name: 'CustomError',
message: 'hello',
stack: 'here:0\nhere:1',
code: 42,
signal: 9,
path: '/foo',
}
expect(this.Sentry.captureException).to.have.been.calledWith(
sinon.match(expectedErr),
sinon.match({
tags: sinon.match.any,
level: sinon.match.any,
extra: {
description: 'message',
info: sinon.match({
one: 1,
key: 'value',
}),
},
})
)
// Chai is very picky with comparing Error instances. Go the long way of comparing all the fields manually.
const gotErr = this.Sentry.captureException.args[0][0]
for (const [key, wanted] of Object.entries(expectedErr)) {
expect(gotErr).to.have.property(key, wanted)
}
})
it('should sanitize request', function () {
const req = {
ip: '1.2.3.4',
method: 'GET',
url: '/foo',
headers: {
referer: 'abc',
'content-length': 1337,
'user-agent': 'curl',
authorization: '42',
},
}
this.sentryManager.captureException({ req }, 'message', 'error')
const expectedReq = {
remoteAddress: '1.2.3.4',
method: 'GET',
url: '/foo',
headers: {
referer: 'abc',
'content-length': 1337,
'user-agent': 'curl',
},
}
expect(this.Sentry.captureException).to.have.been.calledWith(
sinon.match({
message: 'message',
}),
sinon.match({
tags: sinon.match.any,
level: sinon.match.any,
extra: {
info: sinon.match.any,
req: expectedReq,
},
})
)
expect(this.Sentry.captureException.args[0][1].extra.req).to.deep.equal(
expectedReq
)
})
it('should sanitize response', function () {
const res = {
statusCode: 417,
body: Buffer.from('foo'),
getHeader(key) {
expect(key).to.be.oneOf(['content-length'])
if (key === 'content-length') return 1337
},
}
this.sentryManager.captureException({ res }, 'message', 'error')
const expectedRes = {
statusCode: 417,
headers: {
'content-length': 1337,
},
}
expect(this.Sentry.captureException).to.have.been.calledWith(
sinon.match({
message: 'message',
}),
sinon.match({
tags: sinon.match.any,
level: sinon.match.any,
extra: {
info: sinon.match.any,
res: expectedRes,
},
})
)
expect(this.Sentry.captureException.args[0][1].extra.res).to.deep.equal(
expectedRes
)
})
describe('reportedToSentry', function () {
it('should mark the error as reported to sentry', function () {
const err = new Error()
this.sentryManager.captureException({ err }, 'message')
expect(this.Sentry.captureException).to.have.been.called
expect(err.reportedToSentry).to.equal(true)
})
it('should mark two errors as reported to sentry', function () {
const err1 = new Error()
const err2 = new Error()
this.sentryManager.captureException({ err: err1, err2 }, 'message')
expect(this.Sentry.captureException).to.have.been.called
expect(err1.reportedToSentry).to.equal(true)
expect(err2.reportedToSentry).to.equal(true)
})
it('should not mark arbitrary objects as reported to sentry', function () {
const err = new Error()
const ctx = { foo: 'bar' }
this.sentryManager.captureException({ err, ctx }, 'message')
expect(this.Sentry.captureException).to.have.been.called
expect(ctx.reportedToSentry).not.to.exist
})
})
})
})
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ metrics
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+1 -1
View File
@@ -88,7 +88,7 @@ function initializeProfileAgent() {
}
function initializePrometheus() {
const os = require('os')
const os = require('node:os')
const promClient = require('prom-client')
promClient.register.setDefaultLabels({ app: APP_NAME, host: os.hostname() })
promClient.collectDefaultMetrics({ timeout: 5000, prefix: '' })
+2 -2
View File
@@ -6,8 +6,8 @@
* logged along with the corresponding information from /proc/net/tcp.
*/
const fs = require('fs')
const diagnosticsChannel = require('diagnostics_channel')
const fs = require('node:fs')
const diagnosticsChannel = require('node:diagnostics_channel')
const SOCKET_MONITOR_INTERVAL = 60 * 1000
// set the threshold for logging leaked sockets in minutes, defaults to 15
+6 -6
View File
@@ -11,13 +11,13 @@ const seconds = 1000
// In Node 0.10 the default is 5, which means only 5 open connections at one.
// Node 0.12 has a default of Infinity. Make sure we have no limit set,
// regardless of Node version.
require('http').globalAgent.maxSockets = Infinity
require('https').globalAgent.maxSockets = Infinity
require('node:http').globalAgent.maxSockets = Infinity
require('node:https').globalAgent.maxSockets = Infinity
const SOCKETS_HTTP = require('http').globalAgent.sockets
const SOCKETS_HTTPS = require('https').globalAgent.sockets
const FREE_SOCKETS_HTTP = require('http').globalAgent.freeSockets
const FREE_SOCKETS_HTTPS = require('https').globalAgent.freeSockets
const SOCKETS_HTTP = require('node:http').globalAgent.sockets
const SOCKETS_HTTPS = require('node:https').globalAgent.sockets
const FREE_SOCKETS_HTTP = require('node:http').globalAgent.freeSockets
const FREE_SOCKETS_HTTPS = require('node:https').globalAgent.freeSockets
// keep track of set gauges and reset them in the next collection cycle
const SEEN_HOSTS_HTTP = new Set()
@@ -1,6 +1,6 @@
const { promisify } = require('util')
const os = require('os')
const http = require('http')
const { promisify } = require('node:util')
const os = require('node:os')
const http = require('node:http')
const { expect } = require('chai')
const Metrics = require('../..')
@@ -316,7 +316,7 @@ async function checkSummaryValues(key, values) {
for (const quantile of Object.keys(values)) {
expect(found[quantile]).to.be.within(
values[quantile] - 5,
values[quantile] + 5,
values[quantile] + 15,
`quantile: ${quantile}`
)
}
+1 -1
View File
@@ -5,7 +5,7 @@
*/
const chai = require('chai')
const { expect } = chai
const path = require('path')
const path = require('node:path')
const modulePath = path.join(__dirname, '../../../event_loop.js')
const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
+1 -1
View File
@@ -1,4 +1,4 @@
const Path = require('path')
const Path = require('node:path')
const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
+1
View File
@@ -0,0 +1 @@
node_modules/
+3
View File
@@ -0,0 +1,3 @@
# managed by monorepo$ bin/update_build_scripts
.npmrc
+1
View File
@@ -0,0 +1 @@
20.18.0
@@ -1,9 +1,11 @@
const { ObjectId } = require('mongodb-legacy')
const {
db,
waitForDb,
READ_PREFERENCE_SECONDARY,
} = require('../../app/src/infrastructure/mongodb')
// @ts-check
/* eslint-disable no-console */
const { ObjectId, ReadPreference } = require('mongodb')
const READ_PREFERENCE_SECONDARY =
process.env.MONGO_HAS_SECONDARIES === 'true'
? ReadPreference.secondary.mode
: ReadPreference.secondaryPreferred.mode
const ONE_MONTH_IN_MS = 1000 * 60 * 60 * 24 * 31
let ID_EDGE_PAST
@@ -15,16 +17,38 @@ let BATCH_RANGE_START
let BATCH_RANGE_END
let BATCH_MAX_TIME_SPAN_IN_MS
/**
* @typedef {import("mongodb").Collection} Collection
* @typedef {import("mongodb-legacy").Collection} LegacyCollection
* @typedef {import("mongodb").Document} Document
* @typedef {import("mongodb").FindOptions} FindOptions
* @typedef {import("mongodb").UpdateFilter<Document>} UpdateDocument
*/
/**
* @typedef {Object} BatchedUpdateOptions
* @property {string} [BATCH_DESCENDING]
* @property {string} [BATCH_LAST_ID]
* @property {string} [BATCH_MAX_TIME_SPAN_IN_MS]
* @property {string} [BATCH_RANGE_END]
* @property {string} [BATCH_RANGE_START]
* @property {string} [BATCH_SIZE]
* @property {string} [VERBOSE_LOGGING]
*/
/**
* @param {BatchedUpdateOptions} options
*/
function refreshGlobalOptionsForBatchedUpdate(options = {}) {
options = Object.assign({}, options, process.env)
BATCH_DESCENDING = options.BATCH_DESCENDING === 'true'
BATCH_SIZE = parseInt(options.BATCH_SIZE, 10) || 1000
BATCH_SIZE = parseInt(options.BATCH_SIZE || '1000', 10) || 1000
VERBOSE_LOGGING = options.VERBOSE_LOGGING === 'true'
if (options.BATCH_LAST_ID) {
BATCH_RANGE_START = new ObjectId(options.BATCH_LAST_ID)
BATCH_RANGE_START = objectIdFromInput(options.BATCH_LAST_ID)
} else if (options.BATCH_RANGE_START) {
BATCH_RANGE_START = new ObjectId(options.BATCH_RANGE_START)
BATCH_RANGE_START = objectIdFromInput(options.BATCH_RANGE_START)
} else {
if (BATCH_DESCENDING) {
BATCH_RANGE_START = ID_EDGE_FUTURE
@@ -32,10 +56,12 @@ function refreshGlobalOptionsForBatchedUpdate(options = {}) {
BATCH_RANGE_START = ID_EDGE_PAST
}
}
BATCH_MAX_TIME_SPAN_IN_MS =
parseInt(options.BATCH_MAX_TIME_SPAN_IN_MS, 10) || ONE_MONTH_IN_MS
BATCH_MAX_TIME_SPAN_IN_MS = parseInt(
options.BATCH_MAX_TIME_SPAN_IN_MS || ONE_MONTH_IN_MS.toString(),
10
)
if (options.BATCH_RANGE_END) {
BATCH_RANGE_END = new ObjectId(options.BATCH_RANGE_END)
BATCH_RANGE_END = objectIdFromInput(options.BATCH_RANGE_END)
} else {
if (BATCH_DESCENDING) {
BATCH_RANGE_END = ID_EDGE_PAST
@@ -45,23 +71,32 @@ function refreshGlobalOptionsForBatchedUpdate(options = {}) {
}
}
async function getNextBatch({
/**
* @param {Collection | LegacyCollection} collection
* @param {Document} query
* @param {ObjectId} start
* @param {ObjectId} end
* @param {Document} projection
* @param {FindOptions} findOptions
* @return {Promise<Array<Document>>}
*/
async function getNextBatch(
collection,
query,
start,
end,
projection,
findOptions,
}) {
findOptions
) {
if (BATCH_DESCENDING) {
query._id = {
$gt: end,
$lt: start,
$lte: start,
}
} else {
query._id = {
$gt: start,
$lt: end,
$lte: end,
}
}
return await collection
@@ -72,21 +107,61 @@ async function getNextBatch({
.toArray()
}
/**
* @param {Collection | LegacyCollection} collection
* @param {Array<Document>} nextBatch
* @param {UpdateDocument} update
* @return {Promise<void>}
*/
async function performUpdate(collection, nextBatch, update) {
return collection.updateMany(
await collection.updateMany(
{ _id: { $in: nextBatch.map(entry => entry._id) } },
update
)
}
/**
* @param {string} input
* @return {ObjectId}
*/
function objectIdFromInput(input) {
if (input.includes('T')) {
const t = new Date(input).getTime()
if (Number.isNaN(t)) throw new Error(`${input} is not a valid date`)
return objectIdFromMs(t)
} else {
return new ObjectId(input)
}
}
/**
* @param {ObjectId} objectId
* @return {string}
*/
function renderObjectId(objectId) {
return `${objectId} (${objectId.getTimestamp().toISOString()})`
}
/**
* @param {number} ms
* @return {ObjectId}
*/
function objectIdFromMs(ms) {
return ObjectId.createFromTime(ms / 1000)
}
/**
* @param {ObjectId} id
* @return {number}
*/
function getMsFromObjectId(id) {
return id.getTimestamp().getTime()
}
/**
* @param {ObjectId} start
* @return {ObjectId}
*/
function getNextEnd(start) {
let end
if (BATCH_DESCENDING) {
@@ -103,6 +178,10 @@ function getNextEnd(start) {
return end
}
/**
* @param {Collection | LegacyCollection} collection
* @return {Promise<ObjectId|null>}
*/
async function getIdEdgePast(collection) {
const [first] = await collection
.find({})
@@ -111,24 +190,32 @@ async function getIdEdgePast(collection) {
.limit(1)
.toArray()
if (!first) return null
// Go 1s further into the past in order to include the first entry via
// Go one second further into the past in order to include the first entry via
// first._id > ID_EDGE_PAST
return objectIdFromMs(Math.max(0, getMsFromObjectId(first._id) - 1000))
}
/**
* @param {Collection | LegacyCollection} collection
* @param {Document} query
* @param {UpdateDocument | ((batch: Array<Document>) => Promise<void>)} update
* @param {Document} [projection]
* @param {FindOptions} [findOptions]
* @param {BatchedUpdateOptions} [batchedUpdateOptions]
*/
async function batchedUpdate(
collectionName,
collection,
query,
update,
projection,
findOptions,
batchedUpdateOptions
) {
await waitForDb()
const collection = db[collectionName]
ID_EDGE_PAST = await getIdEdgePast(collection)
if (!ID_EDGE_PAST) {
console.warn(`The collection ${collectionName} appears to be empty.`)
console.warn(
`The collection ${collection.collectionName} appears to be empty.`
)
return 0
}
refreshGlobalOptionsForBatchedUpdate(batchedUpdateOptions)
@@ -143,14 +230,14 @@ async function batchedUpdate(
while (start !== BATCH_RANGE_END) {
let end = getNextEnd(start)
nextBatch = await getNextBatch({
nextBatch = await getNextBatch(
collection,
query,
start,
end,
projection,
findOptions,
})
findOptions
)
if (nextBatch.length > 0) {
end = nextBatch[nextBatch.length - 1]._id
updated += nextBatch.length
@@ -162,7 +249,7 @@ async function batchedUpdate(
)}`
)
} else {
console.error(`Running update on batch ending ${end}`)
console.error(`Running update on batch ending ${renderObjectId(end)}`)
}
if (typeof update === 'function') {
@@ -171,20 +258,36 @@ async function batchedUpdate(
await performUpdate(collection, nextBatch, update)
}
}
console.error(`Completed batch ending ${end}`)
console.error(`Completed batch ending ${renderObjectId(end)}`)
start = end
}
return updated
}
/**
* @param {Collection | LegacyCollection} collection
* @param {Document} query
* @param {UpdateDocument | ((batch: Array<Object>) => Promise<void>)} update
* @param {Document} [projection]
* @param {FindOptions} [findOptions]
* @param {BatchedUpdateOptions} [batchedUpdateOptions]
*/
function batchedUpdateWithResultHandling(
collection,
query,
update,
projection,
options
findOptions,
batchedUpdateOptions
) {
batchedUpdate(collection, query, update, projection, options)
batchedUpdate(
collection,
query,
update,
projection,
findOptions,
batchedUpdateOptions
)
.then(processed => {
console.error({ processed })
process.exit(0)
@@ -196,6 +299,9 @@ function batchedUpdateWithResultHandling(
}
module.exports = {
READ_PREFERENCE_SECONDARY,
objectIdFromInput,
renderObjectId,
batchedUpdate,
batchedUpdateWithResultHandling,
}
+10
View File
@@ -0,0 +1,10 @@
mongo-utils
--dependencies=None
--docker-repos=gcr.io/overleaf-ops
--env-add=
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
View File
+30
View File
@@ -0,0 +1,30 @@
{
"name": "@overleaf/mongo-utils",
"version": "0.0.1",
"description": "utilities to help working with mongo",
"main": "index.js",
"scripts": {
"test": "npm run lint && npm run format && npm run types:check && npm run test:unit",
"test:unit": "mocha --exit test/**/*.{js,cjs}",
"lint": "eslint --ext .js --ext .cjs --ext .ts --max-warnings 0 --format unix .",
"lint:fix": "eslint --fix --ext .js --ext .cjs --ext .ts .",
"format": "prettier --list-different $PWD/'**/*.{js,cjs,ts}'",
"format:fix": "prettier --write $PWD/'**/*.{js,cjs,ts}'",
"test:ci": "npm run test:unit",
"types:check": "tsc --noEmit"
},
"author": "Overleaf (https://www.overleaf.com)",
"license": "AGPL-3.0-only",
"dependencies": {
"mongodb": "6.10.0",
"mongodb-legacy": "6.1.3"
},
"devDependencies": {
"chai": "^4.3.6",
"mocha": "^10.2.0",
"sandboxed-module": "^2.0.4",
"sinon": "^9.2.4",
"sinon-chai": "^3.7.0",
"typescript": "^5.0.4"
}
}
+11
View File
@@ -0,0 +1,11 @@
const chai = require('chai')
const sinonChai = require('sinon-chai')
const SandboxedModule = require('sandboxed-module')
// Chai configuration
chai.should()
chai.use(sinonChai)
SandboxedModule.configure({
globals: { Buffer, JSON, console, process },
})
+7
View File
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.backend.json",
"include": [
"**/*.js",
"**/*.cjs"
]
}
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ o-error
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+1 -1
View File
@@ -70,7 +70,7 @@ sayHi3(43, (err, result) => {
}
})
const promisify = require('util').promisify
const promisify = require('node:util').promisify
demoDatabase.findUserAsync = promisify(demoDatabase.findUser)
async function sayHi4NoHandling(userId) {
+1 -1
View File
@@ -1,5 +1,5 @@
const { expect } = require('chai')
const { promisify } = require('util')
const { promisify } = require('node:util')
const OError = require('..')
+1 -1
View File
@@ -23,7 +23,7 @@ exports.expectError = function OErrorExpectError(e, expected) {
).to.be.true
expect(
require('util').types.isNativeError(e),
require('node:util').types.isNativeError(e),
'error should be recognised by util.types.isNativeError'
).to.be.true
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ object-persistor
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+3 -2
View File
@@ -24,7 +24,8 @@
"@overleaf/logger": "*",
"@overleaf/metrics": "*",
"@overleaf/o-error": "*",
"aws-sdk": "^2.718.0",
"@overleaf/stream-utils": "*",
"aws-sdk": "^2.1691.0",
"fast-crc32c": "overleaf/node-fast-crc32c#aae6b2a4c7a7a159395df9cc6c38dfde702d6f51",
"glob": "^7.1.6",
"range-parser": "^1.2.1",
@@ -35,7 +36,7 @@
"chai-as-promised": "^7.1.1",
"mocha": "^10.2.0",
"mock-fs": "^5.2.0",
"mongodb": "^6.1.0",
"mongodb": "6.10.0",
"sandboxed-module": "^2.0.4",
"sinon": "^9.2.4",
"sinon-chai": "^3.7.0",
@@ -1,6 +1,12 @@
const { NotImplementedError } = require('./Errors')
module.exports = class AbstractPersistor {
/**
* @param location
* @param target
* @param {string} source
* @return {Promise<void>}
*/
async sendFile(location, target, source) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'sendFile',
@@ -10,6 +16,13 @@ module.exports = class AbstractPersistor {
})
}
/**
* @param location
* @param target
* @param {NodeJS.ReadableStream} sourceStream
* @param {Object} opts
* @return {Promise<void>}
*/
async sendStream(location, target, sourceStream, opts = {}) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'sendStream',
@@ -22,12 +35,12 @@ module.exports = class AbstractPersistor {
/**
* @param location
* @param name
* @param {Object} opts
* @param {Number} opts.start
* @param {Number} opts.end
* @return {Promise<Readable>}
* @param {Object} [opts]
* @param {Number} [opts.start]
* @param {Number} [opts.end]
* @return {Promise<NodeJS.ReadableStream>}
*/
async getObjectStream(location, name, opts) {
async getObjectStream(location, name, opts = {}) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'getObjectStream',
location,
@@ -36,6 +49,11 @@ module.exports = class AbstractPersistor {
})
}
/**
* @param {string} location
* @param {string} name
* @return {Promise<string>}
*/
async getRedirectUrl(location, name) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'getRedirectUrl',
@@ -44,7 +62,13 @@ module.exports = class AbstractPersistor {
})
}
async getObjectSize(location, name) {
/**
* @param {string} location
* @param {string} name
* @param {Object} opts
* @return {Promise<number>}
*/
async getObjectSize(location, name, opts) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'getObjectSize',
location,
@@ -52,7 +76,13 @@ module.exports = class AbstractPersistor {
})
}
async getObjectMd5Hash(location, name) {
/**
* @param {string} location
* @param {string} name
* @param {Object} opts
* @return {Promise<string>}
*/
async getObjectMd5Hash(location, name, opts) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'getObjectMd5Hash',
location,
@@ -60,7 +90,14 @@ module.exports = class AbstractPersistor {
})
}
async copyObject(location, fromName, toName) {
/**
* @param {string} location
* @param {string} fromName
* @param {string} toName
* @param {Object} opts
* @return {Promise<void>}
*/
async copyObject(location, fromName, toName, opts) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'copyObject',
location,
@@ -69,6 +106,11 @@ module.exports = class AbstractPersistor {
})
}
/**
* @param {string} location
* @param {string} name
* @return {Promise<void>}
*/
async deleteObject(location, name) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'deleteObject',
@@ -77,7 +119,13 @@ module.exports = class AbstractPersistor {
})
}
async deleteDirectory(location, name) {
/**
* @param {string} location
* @param {string} name
* @param {string} [continuationToken]
* @return {Promise<void>}
*/
async deleteDirectory(location, name, continuationToken) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'deleteDirectory',
location,
@@ -85,7 +133,13 @@ module.exports = class AbstractPersistor {
})
}
async checkIfObjectExists(location, name) {
/**
* @param {string} location
* @param {string} name
* @param {Object} opts
* @return {Promise<boolean>}
*/
async checkIfObjectExists(location, name, opts) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'checkIfObjectExists',
location,
@@ -93,7 +147,13 @@ module.exports = class AbstractPersistor {
})
}
async directorySize(location, name) {
/**
* @param {string} location
* @param {string} name
* @param {string} [continuationToken]
* @return {Promise<number>}
*/
async directorySize(location, name, continuationToken) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'directorySize',
location,
+4
View File
@@ -5,6 +5,8 @@ class WriteError extends OError {}
class ReadError extends OError {}
class SettingsError extends OError {}
class NotImplementedError extends OError {}
class AlreadyWrittenError extends OError {}
class NoKEKMatchedError extends OError {}
module.exports = {
NotFoundError,
@@ -12,4 +14,6 @@ module.exports = {
ReadError,
SettingsError,
NotImplementedError,
AlreadyWrittenError,
NoKEKMatchedError,
}
+28 -9
View File
@@ -1,20 +1,26 @@
const crypto = require('crypto')
const fs = require('fs')
const fsPromises = require('fs/promises')
const crypto = require('node:crypto')
const fs = require('node:fs')
const fsPromises = require('node:fs/promises')
const globCallbacks = require('glob')
const Path = require('path')
const { PassThrough } = require('stream')
const { pipeline } = require('stream/promises')
const { promisify } = require('util')
const Path = require('node:path')
const { PassThrough } = require('node:stream')
const { pipeline } = require('node:stream/promises')
const { promisify } = require('node:util')
const AbstractPersistor = require('./AbstractPersistor')
const { ReadError, WriteError } = require('./Errors')
const { ReadError, WriteError, NotImplementedError } = require('./Errors')
const PersistorHelper = require('./PersistorHelper')
const glob = promisify(globCallbacks)
module.exports = class FSPersistor extends AbstractPersistor {
constructor(settings = {}) {
if (settings.storageClass) {
throw new NotImplementedError(
'FS backend does not support storage classes'
)
}
super()
this.useSubdirectories = Boolean(settings.useSubdirectories)
}
@@ -36,6 +42,14 @@ module.exports = class FSPersistor extends AbstractPersistor {
}
async sendStream(location, target, sourceStream, opts = {}) {
if (opts.ifNoneMatch === '*') {
// The standard library only has fs.rename(), which does not support exclusive flags.
// Refuse to act on this write operation.
throw new NotImplementedError(
'Overwrite protection required by caller, but it is not available is FS backend. Configure GCS or S3 backend instead, get in touch with support for further information.'
)
}
const targetPath = this._getFsPath(location, target)
try {
@@ -55,7 +69,7 @@ module.exports = class FSPersistor extends AbstractPersistor {
throw PersistorHelper.wrapError(
err,
'failed to write stream',
{ location, target },
{ location, target, ifNoneMatch: opts.ifNoneMatch },
WriteError
)
}
@@ -63,6 +77,11 @@ module.exports = class FSPersistor extends AbstractPersistor {
// opts may be {start: Number, end: Number}
async getObjectStream(location, name, opts = {}) {
if (opts.autoGunzip) {
throw new NotImplementedError(
'opts.autoGunzip is not supported by FS backend. Configure GCS or S3 backend instead, get in touch with support for further information.'
)
}
const observer = new PersistorHelper.ObserverStream({
metric: 'fs.ingress', // ingress to us from disk
bucket: location,
+34 -10
View File
@@ -1,17 +1,28 @@
const fs = require('fs')
const { pipeline } = require('stream/promises')
const { PassThrough } = require('stream')
const fs = require('node:fs')
const { pipeline } = require('node:stream/promises')
const { PassThrough } = require('node:stream')
const { Storage, IdempotencyStrategy } = require('@google-cloud/storage')
const { WriteError, ReadError, NotFoundError } = require('./Errors')
const {
WriteError,
ReadError,
NotFoundError,
NotImplementedError,
} = require('./Errors')
const asyncPool = require('tiny-async-pool')
const AbstractPersistor = require('./AbstractPersistor')
const PersistorHelper = require('./PersistorHelper')
const Logger = require('@overleaf/logger')
const zlib = require('node:zlib')
module.exports = class GcsPersistor extends AbstractPersistor {
constructor(settings) {
super()
if (settings.storageClass) {
throw new NotImplementedError(
'Use default bucket class for GCS instead of settings.storageClass'
)
}
super()
this.settings = settings
// endpoint settings will be null by default except for tests
@@ -78,10 +89,14 @@ module.exports = class GcsPersistor extends AbstractPersistor {
writeOptions.metadata = writeOptions.metadata || {}
writeOptions.metadata.contentEncoding = opts.contentEncoding
}
const fileOptions = {}
if (opts.ifNoneMatch === '*') {
fileOptions.generation = 0
}
const uploadStream = this.storage
.bucket(bucketName)
.file(key)
.file(key, fileOptions)
.createWriteStream(writeOptions)
await pipeline(readStream, observer, uploadStream)
@@ -97,7 +112,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
throw PersistorHelper.wrapError(
err,
'upload to GCS failed',
{ bucketName, key },
{ bucketName, key, ifNoneMatch: opts.ifNoneMatch },
WriteError
)
}
@@ -113,12 +128,14 @@ module.exports = class GcsPersistor extends AbstractPersistor {
.file(key)
.createReadStream({ decompress: false, ...opts })
let contentEncoding
try {
await new Promise((resolve, reject) => {
stream.on('response', res => {
switch (res.statusCode) {
case 200: // full response
case 206: // partial response
contentEncoding = res.headers['content-encoding']
return resolve()
case 404:
return reject(new NotFoundError())
@@ -139,7 +156,11 @@ module.exports = class GcsPersistor extends AbstractPersistor {
}
// Return a PassThrough stream with a minimal interface. It will buffer until the caller starts reading. It will emit errors from the source stream (Stream.pipeline passes errors along).
const pass = new PassThrough()
pipeline(stream, observer, pass).catch(() => {})
const transformer = []
if (contentEncoding === 'gzip' && opts.autoGunzip) {
transformer.push(zlib.createGunzip())
}
pipeline(stream, observer, ...transformer, pass).catch(() => {})
return pass
}
@@ -176,7 +197,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
.bucket(bucketName)
.file(key)
.getMetadata()
return metadata.size
return parseInt(metadata.size, 10)
} catch (err) {
throw PersistorHelper.wrapError(
err,
@@ -285,7 +306,10 @@ module.exports = class GcsPersistor extends AbstractPersistor {
)
}
return files.reduce((acc, file) => Number(file.metadata.size) + acc, 0)
return files.reduce(
(acc, file) => parseInt(file.metadata.size, 10) + acc,
0
)
}
async checkIfObjectExists(bucketName, key) {
@@ -1,8 +1,8 @@
const AbstractPersistor = require('./AbstractPersistor')
const Logger = require('@overleaf/logger')
const Metrics = require('@overleaf/metrics')
const Stream = require('stream')
const { pipeline } = require('stream/promises')
const Stream = require('node:stream')
const { pipeline } = require('node:stream/promises')
const { NotFoundError, WriteError } = require('./Errors')
// Persistor that wraps two other persistors. Talks to the 'primary' by default,
@@ -0,0 +1,458 @@
// @ts-check
const Crypto = require('node:crypto')
const Stream = require('node:stream')
const fs = require('node:fs')
const { promisify } = require('node:util')
const { WritableBuffer } = require('@overleaf/stream-utils')
const { S3Persistor, SSECOptions } = require('./S3Persistor.js')
const {
AlreadyWrittenError,
NoKEKMatchedError,
NotFoundError,
NotImplementedError,
ReadError,
} = require('./Errors')
const logger = require('@overleaf/logger')
const Path = require('node:path')
const generateKey = promisify(Crypto.generateKey)
const hkdf = promisify(Crypto.hkdf)
const AES256_KEY_LENGTH = 32
/**
* @typedef {import('aws-sdk').AWSError} AWSError
*/
/**
* @typedef {Object} Settings
* @property {boolean} automaticallyRotateDEKEncryption
* @property {string} dataEncryptionKeyBucketName
* @property {boolean} ignoreErrorsFromDEKReEncryption
* @property {(bucketName: string, path: string) => string} pathToProjectFolder
* @property {() => Promise<Array<RootKeyEncryptionKey>>} getRootKeyEncryptionKeys
*/
/**
* Helper function to make TS happy when accessing error properties
* AWSError is not an actual class, so we cannot use instanceof.
* @param {any} err
* @return {err is AWSError}
*/
function isAWSError(err) {
return !!err
}
/**
* @param {any} err
* @return {boolean}
*/
function isForbiddenError(err) {
if (!err || !(err instanceof ReadError || err instanceof NotFoundError)) {
return false
}
const cause = err.cause
if (!isAWSError(cause)) return false
return cause.statusCode === 403
}
class RootKeyEncryptionKey {
/** @type {Buffer} */
#keyEncryptionKey
/** @type {Buffer} */
#salt
/**
* @param {Buffer} keyEncryptionKey
* @param {Buffer} salt
*/
constructor(keyEncryptionKey, salt) {
if (keyEncryptionKey.byteLength !== AES256_KEY_LENGTH) {
throw new Error(`kek is not ${AES256_KEY_LENGTH} bytes long`)
}
this.#keyEncryptionKey = keyEncryptionKey
this.#salt = salt
}
/**
* @param {string} prefix
* @return {Promise<SSECOptions>}
*/
async forProject(prefix) {
return new SSECOptions(
Buffer.from(
await hkdf(
'sha256',
this.#keyEncryptionKey,
this.#salt,
prefix,
AES256_KEY_LENGTH
)
)
)
}
}
class PerProjectEncryptedS3Persistor extends S3Persistor {
/** @type {Settings} */
#settings
/** @type {Promise<Array<RootKeyEncryptionKey>>} */
#availableKeyEncryptionKeysPromise
/**
* @param {Settings} settings
*/
constructor(settings) {
if (!settings.dataEncryptionKeyBucketName) {
throw new Error('settings.dataEncryptionKeyBucketName is missing')
}
super(settings)
this.#settings = settings
this.#availableKeyEncryptionKeysPromise = settings
.getRootKeyEncryptionKeys()
.then(rootKEKs => {
if (rootKEKs.length === 0) throw new Error('no root kek provided')
return rootKEKs
})
}
async ensureKeyEncryptionKeysLoaded() {
await this.#availableKeyEncryptionKeysPromise
}
/**
* @param {string} bucketName
* @param {string} path
* @return {{dekPath: string, projectFolder: string}}
*/
#buildProjectPaths(bucketName, path) {
const projectFolder = this.#settings.pathToProjectFolder(bucketName, path)
const dekPath = Path.join(projectFolder, 'dek')
return { projectFolder, dekPath }
}
/**
* @param {string} projectFolder
* @return {Promise<SSECOptions>}
*/
async #getCurrentKeyEncryptionKey(projectFolder) {
const [currentRootKEK] = await this.#availableKeyEncryptionKeysPromise
return await currentRootKEK.forProject(projectFolder)
}
/**
* @param {string} bucketName
* @param {string} path
*/
async getDataEncryptionKeySize(bucketName, path) {
const { projectFolder, dekPath } = this.#buildProjectPaths(bucketName, path)
for (const rootKEK of await this.#availableKeyEncryptionKeysPromise) {
const ssecOptions = await rootKEK.forProject(projectFolder)
try {
return await super.getObjectSize(
this.#settings.dataEncryptionKeyBucketName,
dekPath,
{ ssecOptions }
)
} catch (err) {
if (isForbiddenError(err)) continue
throw err
}
}
throw new NoKEKMatchedError('no kek matched')
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<CachedPerProjectEncryptedS3Persistor>}
*/
async forProject(bucketName, path) {
return new CachedPerProjectEncryptedS3Persistor(
this,
await this.#getDataEncryptionKeyOptions(bucketName, path)
)
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<CachedPerProjectEncryptedS3Persistor>}
*/
async forProjectRO(bucketName, path) {
return new CachedPerProjectEncryptedS3Persistor(
this,
await this.#getExistingDataEncryptionKeyOptions(bucketName, path)
)
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<CachedPerProjectEncryptedS3Persistor>}
*/
async generateDataEncryptionKey(bucketName, path) {
return new CachedPerProjectEncryptedS3Persistor(
this,
await this.#generateDataEncryptionKeyOptions(bucketName, path)
)
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<SSECOptions>}
*/
async #generateDataEncryptionKeyOptions(bucketName, path) {
const dataEncryptionKey = (
await generateKey('aes', { length: 256 })
).export()
const { projectFolder, dekPath } = this.#buildProjectPaths(bucketName, path)
await super.sendStream(
this.#settings.dataEncryptionKeyBucketName,
dekPath,
Stream.Readable.from([dataEncryptionKey]),
{
// Do not overwrite any objects if already created
ifNoneMatch: '*',
ssecOptions: await this.#getCurrentKeyEncryptionKey(projectFolder),
contentLength: 32,
}
)
return new SSECOptions(dataEncryptionKey)
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<SSECOptions>}
*/
async #getExistingDataEncryptionKeyOptions(bucketName, path) {
const { projectFolder, dekPath } = this.#buildProjectPaths(bucketName, path)
let res
let kekIndex = 0
for (const rootKEK of await this.#availableKeyEncryptionKeysPromise) {
const ssecOptions = await rootKEK.forProject(projectFolder)
try {
res = await super.getObjectStream(
this.#settings.dataEncryptionKeyBucketName,
dekPath,
{ ssecOptions }
)
break
} catch (err) {
if (isForbiddenError(err)) {
kekIndex++
continue
}
throw err
}
}
if (!res) throw new NoKEKMatchedError('no kek matched')
const buf = new WritableBuffer()
await Stream.promises.pipeline(res, buf)
if (kekIndex !== 0 && this.#settings.automaticallyRotateDEKEncryption) {
const ssecOptions = await this.#getCurrentKeyEncryptionKey(projectFolder)
try {
await super.sendStream(
this.#settings.dataEncryptionKeyBucketName,
dekPath,
Stream.Readable.from([buf.getContents()]),
{ ssecOptions }
)
} catch (err) {
if (this.#settings.ignoreErrorsFromDEKReEncryption) {
logger.warn({ err, dekPath }, 'failed to persist re-encrypted DEK')
} else {
throw err
}
}
}
return new SSECOptions(buf.getContents())
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<SSECOptions>}
*/
async #getDataEncryptionKeyOptions(bucketName, path) {
try {
return await this.#getExistingDataEncryptionKeyOptions(bucketName, path)
} catch (err) {
if (err instanceof NotFoundError) {
try {
return await this.#generateDataEncryptionKeyOptions(bucketName, path)
} catch (err2) {
if (err2 instanceof AlreadyWrittenError) {
// Concurrent initial write
return await this.#getExistingDataEncryptionKeyOptions(
bucketName,
path
)
}
throw err2
}
}
throw err
}
}
async sendStream(bucketName, path, sourceStream, opts = {}) {
const ssecOptions =
opts.ssecOptions ||
(await this.#getDataEncryptionKeyOptions(bucketName, path))
return await super.sendStream(bucketName, path, sourceStream, {
...opts,
ssecOptions,
})
}
async getObjectStream(bucketName, path, opts = {}) {
const ssecOptions =
opts.ssecOptions ||
(await this.#getExistingDataEncryptionKeyOptions(bucketName, path))
return await super.getObjectStream(bucketName, path, {
...opts,
ssecOptions,
})
}
async getObjectSize(bucketName, path, opts = {}) {
const ssecOptions =
opts.ssecOptions ||
(await this.#getExistingDataEncryptionKeyOptions(bucketName, path))
return await super.getObjectSize(bucketName, path, { ...opts, ssecOptions })
}
async getObjectStorageClass(bucketName, path, opts = {}) {
const ssecOptions =
opts.ssecOptions ||
(await this.#getExistingDataEncryptionKeyOptions(bucketName, path))
return await super.getObjectStorageClass(bucketName, path, {
...opts,
ssecOptions,
})
}
async directorySize(bucketName, path, continuationToken) {
// Note: Listing a bucket does not require SSE-C credentials.
return await super.directorySize(bucketName, path, continuationToken)
}
async deleteDirectory(bucketName, path, continuationToken) {
// Note: Listing/Deleting a prefix does not require SSE-C credentials.
await super.deleteDirectory(bucketName, path, continuationToken)
const { projectFolder, dekPath } = this.#buildProjectPaths(bucketName, path)
if (projectFolder === path) {
await super.deleteObject(
this.#settings.dataEncryptionKeyBucketName,
dekPath
)
}
}
async getObjectMd5Hash(bucketName, path, opts = {}) {
// The ETag in object metadata is not the MD5 content hash, skip the HEAD request.
opts = { ...opts, etagIsNotMD5: true }
return await super.getObjectMd5Hash(bucketName, path, opts)
}
async copyObject(bucketName, sourcePath, destinationPath, opts = {}) {
const ssecOptions =
opts.ssecOptions ||
(await this.#getDataEncryptionKeyOptions(bucketName, destinationPath))
const ssecSrcOptions =
opts.ssecSrcOptions ||
(await this.#getExistingDataEncryptionKeyOptions(bucketName, sourcePath))
return await super.copyObject(bucketName, sourcePath, destinationPath, {
...opts,
ssecOptions,
ssecSrcOptions,
})
}
/**
* @param {string} bucketName
* @param {string} path
* @return {Promise<string>}
*/
async getRedirectUrl(bucketName, path) {
throw new NotImplementedError('signed links are not supported with SSE-C')
}
}
/**
* Helper class for batch updates to avoid repeated fetching of the project path.
*
* A general "cache" for project keys is another alternative. For now, use a helper class.
*/
class CachedPerProjectEncryptedS3Persistor {
/** @type SSECOptions */
#projectKeyOptions
/** @type PerProjectEncryptedS3Persistor */
#parent
/**
* @param {PerProjectEncryptedS3Persistor} parent
* @param {SSECOptions} projectKeyOptions
*/
constructor(parent, projectKeyOptions) {
this.#parent = parent
this.#projectKeyOptions = projectKeyOptions
}
/**
* @param {string} bucketName
* @param {string} path
* @param {string} fsPath
*/
async sendFile(bucketName, path, fsPath) {
return await this.sendStream(bucketName, path, fs.createReadStream(fsPath))
}
/**
* @param {string} bucketName
* @param {string} path
* @param {NodeJS.ReadableStream} sourceStream
* @param {Object} opts
* @param {string} [opts.contentType]
* @param {string} [opts.contentEncoding]
* @param {number} [opts.contentLength]
* @param {'*'} [opts.ifNoneMatch]
* @param {SSECOptions} [opts.ssecOptions]
* @param {string} [opts.sourceMd5]
* @return {Promise<void>}
*/
async sendStream(bucketName, path, sourceStream, opts = {}) {
return await this.#parent.sendStream(bucketName, path, sourceStream, {
...opts,
ssecOptions: this.#projectKeyOptions,
})
}
/**
* @param {string} bucketName
* @param {string} path
* @param {Object} opts
* @param {number} [opts.start]
* @param {number} [opts.end]
* @param {boolean} [opts.autoGunzip]
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<NodeJS.ReadableStream>}
*/
async getObjectStream(bucketName, path, opts = {}) {
return await this.#parent.getObjectStream(bucketName, path, {
...opts,
ssecOptions: this.#projectKeyOptions,
})
}
}
module.exports = {
PerProjectEncryptedS3Persistor,
CachedPerProjectEncryptedS3Persistor,
RootKeyEncryptionKey,
}
@@ -1,15 +1,20 @@
const Logger = require('@overleaf/logger')
const { SettingsError } = require('./Errors')
const GcsPersistor = require('./GcsPersistor')
const S3Persistor = require('./S3Persistor')
const { S3Persistor } = require('./S3Persistor')
const FSPersistor = require('./FSPersistor')
const MigrationPersistor = require('./MigrationPersistor')
const {
PerProjectEncryptedS3Persistor,
} = require('./PerProjectEncryptedS3Persistor')
function getPersistor(backend, settings) {
switch (backend) {
case 'aws-sdk':
case 's3':
return new S3Persistor(settings.s3)
case 's3SSEC':
return new PerProjectEncryptedS3Persistor(settings.s3SSEC)
case 'fs':
return new FSPersistor({
useSubdirectories: settings.useSubdirectories,
@@ -1,9 +1,9 @@
const Crypto = require('crypto')
const Stream = require('stream')
const { pipeline } = require('stream/promises')
const Crypto = require('node:crypto')
const Stream = require('node:stream')
const { pipeline } = require('node:stream/promises')
const Logger = require('@overleaf/logger')
const Metrics = require('@overleaf/metrics')
const { WriteError, NotFoundError } = require('./Errors')
const { WriteError, NotFoundError, AlreadyWrittenError } = require('./Errors')
const _128KiB = 128 * 1024
const TIMING_BUCKETS = [
@@ -26,12 +26,14 @@ const SIZE_BUCKETS = [
*/
class ObserverStream extends Stream.Transform {
/**
* @param {string} metric prefix for metrics
* @param {string} bucket name of source/target bucket
* @param {string} hash optional hash algorithm, e.g. 'md5'
* @param {Object} opts
* @param {string} opts.metric prefix for metrics
* @param {string} opts.bucket name of source/target bucket
* @param {string} [opts.hash] optional hash algorithm, e.g. 'md5'
*/
constructor({ metric, bucket, hash = '' }) {
constructor(opts) {
super({ autoDestroy: true })
const { metric, bucket, hash = '' } = opts
this.bytes = 0
this.start = performance.now()
@@ -138,6 +140,10 @@ async function verifyMd5(persistor, bucket, key, sourceMd5, destMd5 = null) {
}
function wrapError(error, message, params, ErrorType) {
params = {
...params,
cause: error,
}
if (
error instanceof NotFoundError ||
['NoSuchKey', 'NotFound', 404, 'AccessDenied', 'ENOENT'].includes(
@@ -146,6 +152,13 @@ function wrapError(error, message, params, ErrorType) {
(error.response && error.response.statusCode === 404)
) {
return new NotFoundError('no such file', params, error)
} else if (
params.ifNoneMatch === '*' &&
(error.code === 'PreconditionFailed' ||
error.response?.statusCode === 412 ||
error instanceof AlreadyWrittenError)
) {
return new AlreadyWrittenError(message, params, error)
} else {
return new ErrorType(message, params, error)
}
+286 -53
View File
@@ -1,5 +1,6 @@
const http = require('http')
const https = require('https')
// @ts-check
const http = require('node:http')
const https = require('node:https')
if (http.globalAgent.maxSockets < 300) {
http.globalAgent.maxSockets = 300
}
@@ -7,27 +8,92 @@ if (https.globalAgent.maxSockets < 300) {
https.globalAgent.maxSockets = 300
}
const Crypto = require('node:crypto')
const Metrics = require('@overleaf/metrics')
const AbstractPersistor = require('./AbstractPersistor')
const PersistorHelper = require('./PersistorHelper')
const { pipeline, PassThrough } = require('stream')
const fs = require('fs')
const { pipeline, PassThrough } = require('node:stream')
const fs = require('node:fs')
const S3 = require('aws-sdk/clients/s3')
const { URL } = require('url')
const { URL } = require('node:url')
const { WriteError, ReadError, NotFoundError } = require('./Errors')
const zlib = require('node:zlib')
/**
* Wrapper with private fields to avoid revealing them on console, JSON.stringify or similar.
*/
class SSECOptions {
#keyAsBuffer
#keyMD5
/**
* @param {Buffer} keyAsBuffer
*/
constructor(keyAsBuffer) {
this.#keyAsBuffer = keyAsBuffer
this.#keyMD5 = Crypto.createHash('md5').update(keyAsBuffer).digest('base64')
}
getPutOptions() {
return {
SSECustomerKey: this.#keyAsBuffer,
SSECustomerKeyMD5: this.#keyMD5,
SSECustomerAlgorithm: 'AES256',
}
}
getGetOptions() {
return {
SSECustomerKey: this.#keyAsBuffer,
SSECustomerKeyMD5: this.#keyMD5,
SSECustomerAlgorithm: 'AES256',
}
}
getCopyOptions() {
return {
CopySourceSSECustomerKey: this.#keyAsBuffer,
CopySourceSSECustomerKeyMD5: this.#keyMD5,
CopySourceSSECustomerAlgorithm: 'AES256',
}
}
}
class S3Persistor extends AbstractPersistor {
/** @type {Map<string, S3>} */
#clients = new Map()
module.exports = class S3Persistor extends AbstractPersistor {
constructor(settings = {}) {
super()
settings.storageClass = settings.storageClass || {}
this.settings = settings
}
/**
* @param {string} bucketName
* @param {string} key
* @param {string} fsPath
* @return {Promise<void>}
*/
async sendFile(bucketName, key, fsPath) {
return await this.sendStream(bucketName, key, fs.createReadStream(fsPath))
await this.sendStream(bucketName, key, fs.createReadStream(fsPath))
}
/**
* @param {string} bucketName
* @param {string} key
* @param {NodeJS.ReadableStream} readStream
* @param {Object} opts
* @param {string} [opts.contentType]
* @param {string} [opts.contentEncoding]
* @param {number} [opts.contentLength]
* @param {'*'} [opts.ifNoneMatch]
* @param {SSECOptions} [opts.ssecOptions]
* @param {string} [opts.sourceMd5]
* @return {Promise<void>}
*/
async sendStream(bucketName, key, readStream, opts = {}) {
try {
const observeOptions = {
@@ -39,42 +105,71 @@ module.exports = class S3Persistor extends AbstractPersistor {
// observer will catch errors, clean up and log a warning
pipeline(readStream, observer, () => {})
// if we have an md5 hash, pass this to S3 to verify the upload
/** @type {S3.PutObjectRequest} */
const uploadOptions = {
Bucket: bucketName,
Key: key,
Body: observer,
}
if (this.settings.storageClass[bucketName]) {
uploadOptions.StorageClass = this.settings.storageClass[bucketName]
}
if (opts.contentType) {
uploadOptions.ContentType = opts.contentType
}
if (opts.contentEncoding) {
uploadOptions.ContentEncoding = opts.contentEncoding
}
if (opts.contentLength) {
uploadOptions.ContentLength = opts.contentLength
}
if (opts.ifNoneMatch === '*') {
uploadOptions.IfNoneMatch = '*'
}
if (opts.ssecOptions) {
Object.assign(uploadOptions, opts.ssecOptions.getPutOptions())
}
// if we have an md5 hash, pass this to S3 to verify the upload - otherwise
// we rely on the S3 client's checksum calculation to validate the upload
const clientOptions = {}
let computeChecksums = false
if (opts.sourceMd5) {
uploadOptions.ContentMD5 = PersistorHelper.hexToBase64(opts.sourceMd5)
} else {
clientOptions.computeChecksums = true
computeChecksums = true
}
await this._getClientForBucket(bucketName, clientOptions)
.upload(uploadOptions, { partSize: this.settings.partSize })
.promise()
if (this.settings.disableMultiPartUpload) {
await this._getClientForBucket(bucketName, computeChecksums)
.putObject(uploadOptions)
.promise()
} else {
await this._getClientForBucket(bucketName, computeChecksums)
.upload(uploadOptions, { partSize: this.settings.partSize })
.promise()
}
} catch (err) {
throw PersistorHelper.wrapError(
err,
'upload to S3 failed',
{ bucketName, key },
{ bucketName, key, ifNoneMatch: opts.ifNoneMatch },
WriteError
)
}
}
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} [opts]
* @param {number} [opts.start]
* @param {number} [opts.end]
* @param {boolean} [opts.autoGunzip]
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<NodeJS.ReadableStream>}
*/
async getObjectStream(bucketName, key, opts) {
opts = opts || {}
@@ -85,6 +180,9 @@ module.exports = class S3Persistor extends AbstractPersistor {
if (opts.start != null && opts.end != null) {
params.Range = `bytes=${opts.start}-${opts.end}`
}
if (opts.ssecOptions) {
Object.assign(params, opts.ssecOptions.getGetOptions())
}
const observer = new PersistorHelper.ObserverStream({
metric: 's3.ingress', // ingress from S3 to us
bucket: bucketName,
@@ -93,18 +191,21 @@ module.exports = class S3Persistor extends AbstractPersistor {
const req = this._getClientForBucket(bucketName).getObject(params)
const stream = req.createReadStream()
let contentEncoding
try {
await new Promise((resolve, reject) => {
req.on('httpHeaders', statusCode => {
req.on('httpHeaders', (statusCode, headers) => {
switch (statusCode) {
case 200: // full response
case 206: // partial response
return resolve()
case 403: // AccessDenied is handled the same as NoSuchKey
contentEncoding = headers['content-encoding']
return resolve(undefined)
case 403: // AccessDenied
return // handled by stream.on('error') handler below
case 404: // NoSuchKey
return reject(new NotFoundError())
return reject(new NotFoundError('not found'))
default:
return reject(new Error('non success status: ' + statusCode))
// handled by stream.on('error') handler below
}
})
// The AWS SDK is forwarding any errors from the request to the stream.
@@ -122,23 +223,32 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
// Return a PassThrough stream with a minimal interface. It will buffer until the caller starts reading. It will emit errors from the source stream (Stream.pipeline passes errors along).
const pass = new PassThrough()
pipeline(stream, observer, pass, err => {
const transformer = []
if (contentEncoding === 'gzip' && opts.autoGunzip) {
transformer.push(zlib.createGunzip())
}
pipeline(stream, observer, ...transformer, pass, err => {
if (err) req.abort()
})
return pass
}
/**
* @param {string} bucketName
* @param {string} key
* @return {Promise<string>}
*/
async getRedirectUrl(bucketName, key) {
const expiresSeconds = Math.round(this.settings.signedUrlExpiryInMs / 1000)
try {
const url = await this._getClientForBucket(
bucketName
).getSignedUrlPromise('getObject', {
Bucket: bucketName,
Key: key,
Expires: expiresSeconds,
})
return url
return await this._getClientForBucket(bucketName).getSignedUrlPromise(
'getObject',
{
Bucket: bucketName,
Key: key,
Expires: expiresSeconds,
}
)
} catch (err) {
throw PersistorHelper.wrapError(
err,
@@ -149,6 +259,12 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
/**
* @param {string} bucketName
* @param {string} key
* @param {string} [continuationToken]
* @return {Promise<void>}
*/
async deleteDirectory(bucketName, key, continuationToken) {
let response
const options = { Bucket: bucketName, Prefix: key }
@@ -169,8 +285,8 @@ module.exports = class S3Persistor extends AbstractPersistor {
)
}
const objects = response.Contents.map(item => ({ Key: item.Key }))
if (objects.length) {
const objects = response.Contents?.map(item => ({ Key: item.Key || '' }))
if (objects?.length) {
try {
await this._getClientForBucket(bucketName)
.deleteObjects({
@@ -200,12 +316,22 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
async getObjectSize(bucketName, key) {
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} opts
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<S3.HeadObjectOutput>}
*/
async #headObject(bucketName, key, opts = {}) {
const params = { Bucket: bucketName, Key: key }
if (opts.ssecOptions) {
Object.assign(params, opts.ssecOptions.getGetOptions())
}
try {
const response = await this._getClientForBucket(bucketName)
.headObject({ Bucket: bucketName, Key: key })
return await this._getClientForBucket(bucketName)
.headObject(params)
.promise()
return response.ContentLength
} catch (err) {
throw PersistorHelper.wrapError(
err,
@@ -216,19 +342,51 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
async getObjectMd5Hash(bucketName, key) {
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} opts
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<number>}
*/
async getObjectSize(bucketName, key, opts = {}) {
const response = await this.#headObject(bucketName, key, opts)
return response.ContentLength || 0
}
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} opts
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<string | undefined>}
*/
async getObjectStorageClass(bucketName, key, opts = {}) {
const response = await this.#headObject(bucketName, key, opts)
return response.StorageClass
}
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} opts
* @param {SSECOptions} [opts.ssecOptions]
* @param {boolean} [opts.etagIsNotMD5]
* @return {Promise<string>}
*/
async getObjectMd5Hash(bucketName, key, opts = {}) {
try {
const response = await this._getClientForBucket(bucketName)
.headObject({ Bucket: bucketName, Key: key })
.promise()
const md5 = S3Persistor._md5FromResponse(response)
if (md5) {
return md5
if (!opts.etagIsNotMD5) {
const response = await this.#headObject(bucketName, key, opts)
const md5 = S3Persistor._md5FromResponse(response)
if (md5) {
return md5
}
}
// etag is not in md5 format
Metrics.inc('s3.md5Download')
return await PersistorHelper.calculateStreamMd5(
await this.getObjectStream(bucketName, key)
await this.getObjectStream(bucketName, key, opts)
)
} catch (err) {
throw PersistorHelper.wrapError(
@@ -240,6 +398,11 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
/**
* @param {string} bucketName
* @param {string} key
* @return {Promise<void>}
*/
async deleteObject(bucketName, key) {
try {
await this._getClientForBucket(bucketName)
@@ -256,12 +419,27 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
async copyObject(bucketName, sourceKey, destKey) {
/**
* @param {string} bucketName
* @param {string} sourceKey
* @param {string} destKey
* @param {Object} opts
* @param {SSECOptions} [opts.ssecSrcOptions]
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<void>}
*/
async copyObject(bucketName, sourceKey, destKey, opts = {}) {
const params = {
Bucket: bucketName,
Key: destKey,
CopySource: `${bucketName}/${sourceKey}`,
}
if (opts.ssecSrcOptions) {
Object.assign(params, opts.ssecSrcOptions.getCopyOptions())
}
if (opts.ssecOptions) {
Object.assign(params, opts.ssecOptions.getPutOptions())
}
try {
await this._getClientForBucket(bucketName).copyObject(params).promise()
} catch (err) {
@@ -274,9 +452,16 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
async checkIfObjectExists(bucketName, key) {
/**
* @param {string} bucketName
* @param {string} key
* @param {Object} opts
* @param {SSECOptions} [opts.ssecOptions]
* @return {Promise<boolean>}
*/
async checkIfObjectExists(bucketName, key, opts) {
try {
await this.getObjectSize(bucketName, key)
await this.getObjectSize(bucketName, key, opts)
return true
} catch (err) {
if (err instanceof NotFoundError) {
@@ -291,6 +476,12 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
/**
* @param {string} bucketName
* @param {string} key
* @param {string} [continuationToken]
* @return {Promise<number>}
*/
async directorySize(bucketName, key, continuationToken) {
try {
const options = {
@@ -304,7 +495,8 @@ module.exports = class S3Persistor extends AbstractPersistor {
.listObjectsV2(options)
.promise()
const size = response.Contents.reduce((acc, item) => item.Size + acc, 0)
const size =
response.Contents?.reduce((acc, item) => (item.Size || 0) + acc, 0) || 0
if (response.IsTruncated) {
return (
size +
@@ -326,15 +518,38 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
_getClientForBucket(bucket, clientOptions) {
return new S3(
this._buildClientOptions(
this.settings.bucketCreds?.[bucket],
clientOptions
/**
* @param {string} bucket
* @param {boolean} computeChecksums
* @return {S3}
* @private
*/
_getClientForBucket(bucket, computeChecksums = false) {
/** @type {S3.Types.ClientConfiguration} */
const clientOptions = {}
const cacheKey = `${bucket}:${computeChecksums}`
if (computeChecksums) {
clientOptions.computeChecksums = true
}
let client = this.#clients.get(cacheKey)
if (!client) {
client = new S3(
this._buildClientOptions(
this.settings.bucketCreds?.[bucket],
clientOptions
)
)
)
this.#clients.set(cacheKey, client)
}
return client
}
/**
* @param {Object} bucketCredentials
* @param {S3.Types.ClientConfiguration} clientOptions
* @return {S3.Types.ClientConfiguration}
* @private
*/
_buildClientOptions(bucketCredentials, clientOptions) {
const options = clientOptions || {}
@@ -356,7 +571,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
if (this.settings.endpoint) {
const endpoint = new URL(this.settings.endpoint)
options.endpoint = this.settings.endpoint
options.sslEnabled = endpoint.protocol === 'https'
options.sslEnabled = endpoint.protocol === 'https:'
}
// path-style access is only used for acceptance tests
@@ -370,9 +585,22 @@ module.exports = class S3Persistor extends AbstractPersistor {
}
}
if (options.sslEnabled && this.settings.ca && !options.httpOptions?.agent) {
options.httpOptions = options.httpOptions || {}
options.httpOptions.agent = new https.Agent({
rejectUnauthorized: true,
ca: this.settings.ca,
})
}
return options
}
/**
* @param {S3.HeadObjectOutput} response
* @return {string|null}
* @private
*/
static _md5FromResponse(response) {
const md5 = (response.ETag || '').replace(/[ "]/g, '')
if (!md5.match(/^[a-f0-9]{32}$/)) {
@@ -382,3 +610,8 @@ module.exports = class S3Persistor extends AbstractPersistor {
return md5
}
}
module.exports = {
S3Persistor,
SSECOptions,
}
+5
View File
@@ -25,4 +25,9 @@ SandboxedModule.configure({
},
},
globals: { Buffer, Math, console, process, URL },
sourceTransformers: {
removeNodePrefix: function (source) {
return source.replace(/require\(['"]node:/g, "require('")
},
},
})
@@ -1,10 +1,10 @@
const crypto = require('crypto')
const crypto = require('node:crypto')
const { expect } = require('chai')
const mockFs = require('mock-fs')
const fs = require('fs')
const fsPromises = require('fs/promises')
const Path = require('path')
const StreamPromises = require('stream/promises')
const fs = require('node:fs')
const fsPromises = require('node:fs/promises')
const Path = require('node:path')
const StreamPromises = require('node:stream/promises')
const SandboxedModule = require('sandboxed-module')
const Errors = require('../../src/Errors')
@@ -1,4 +1,4 @@
const { EventEmitter } = require('events')
const { EventEmitter } = require('node:events')
const sinon = require('sinon')
const chai = require('chai')
const { expect } = chai
@@ -45,11 +45,11 @@ describe('GcsPersistorTests', function () {
files = [
{
metadata: { size: 11, md5Hash: '/////wAAAAD/////AAAAAA==' },
metadata: { size: '11', md5Hash: '/////wAAAAD/////AAAAAA==' },
delete: sinon.stub(),
},
{
metadata: { size: 22, md5Hash: '/////wAAAAD/////AAAAAA==' },
metadata: { size: '22', md5Hash: '/////wAAAAD/////AAAAAA==' },
delete: sinon.stub(),
},
]
@@ -63,7 +63,7 @@ describe('GcsPersistorTests', function () {
read() {
if (this.err) return this.emit('error', this.err)
this.emit('response', { statusCode: this.statusCode })
this.emit('response', { statusCode: this.statusCode, headers: {} })
}
}
@@ -302,7 +302,7 @@ describe('GcsPersistorTests', function () {
})
it('should return the object size', function () {
expect(size).to.equal(files[0].metadata.size)
expect(size).to.equal(11)
})
it('should pass the bucket and key to GCS', function () {
@@ -1,7 +1,7 @@
const chai = require('chai')
const { expect } = chai
const SandboxedModule = require('sandboxed-module')
const StreamPromises = require('stream/promises')
const StreamPromises = require('node:stream/promises')
const MODULE_PATH = '../../src/PersistorFactory.js'
@@ -32,7 +32,7 @@ describe('PersistorManager', function () {
Settings = {}
const requires = {
'./GcsPersistor': GcsPersistor,
'./S3Persistor': S3Persistor,
'./S3Persistor': { S3Persistor },
'./FSPersistor': FSPersistor,
'@overleaf/logger': {
info() {},
@@ -3,7 +3,7 @@ const chai = require('chai')
const { expect } = chai
const SandboxedModule = require('sandboxed-module')
const Errors = require('../../src/Errors')
const { EventEmitter } = require('events')
const { EventEmitter } = require('node:events')
const MODULE_PATH = '../../src/S3Persistor.js'
@@ -91,8 +91,22 @@ describe('S3PersistorTests', function () {
createReadStream() {
setTimeout(() => {
if (this.notFoundSSEC) {
// special case for AWS S3: 404 NoSuchKey wrapped in a 400. A single request received a single response, and multiple httpHeaders events are triggered. Don't ask.
this.emit('httpHeaders', 400, {})
this.emit('httpHeaders', 404, {})
ReadStream.emit('error', S3NotFoundError)
return
}
if (this.err) return ReadStream.emit('error', this.err)
this.emit('httpHeaders', this.statusCode)
this.emit('httpHeaders', this.statusCode, {})
if (this.statusCode === 403) {
ReadStream.emit('error', S3AccessDeniedError)
}
if (this.statusCode === 404) {
ReadStream.emit('error', S3NotFoundError)
}
})
return ReadStream
}
@@ -133,7 +147,7 @@ describe('S3PersistorTests', function () {
deleteObjects: sinon.stub().returns(EmptyPromise),
getSignedUrlPromise: sinon.stub().resolves(redirectUrl),
}
S3 = sinon.stub().returns(S3Client)
S3 = sinon.stub().callsFake(() => Object.assign({}, S3Client))
Hash = {
end: sinon.stub(),
@@ -159,7 +173,7 @@ describe('S3PersistorTests', function () {
crypto,
},
globals: { console, Buffer },
}))(settings)
}).S3Persistor)(settings)
})
describe('getObjectStream', function () {
@@ -338,6 +352,34 @@ describe('S3PersistorTests', function () {
})
})
describe("when the file doesn't exist -- SSEC", function () {
let error, stream
beforeEach(async function () {
S3GetObjectRequest.notFoundSSEC = 404
try {
stream = await S3Persistor.getObjectStream(bucket, key)
} catch (err) {
error = err
}
})
it('does not return a stream', function () {
expect(stream).not.to.exist
})
it('throws a NotFoundError', function () {
expect(error).to.be.an.instanceOf(Errors.NotFoundError)
})
it('wraps the error', function () {
expect(error.cause).to.exist
})
it('stores the bucket and key in the error', function () {
expect(error.info).to.include({ bucketName: bucket, key })
})
})
describe('when access to the file is denied', function () {
let error, stream
@@ -359,7 +401,7 @@ describe('S3PersistorTests', function () {
})
it('wraps the error', function () {
expect(error.cause).to.exist
expect(error.cause).to.equal(S3AccessDeniedError)
})
it('stores the bucket and key in the error', function () {
@@ -985,4 +1027,22 @@ describe('S3PersistorTests', function () {
})
})
})
describe('_getClientForBucket', function () {
it('should return same instance for same bucket', function () {
const a = S3Persistor._getClientForBucket('foo')
const b = S3Persistor._getClientForBucket('foo')
expect(a).to.equal(b)
})
it('should return different instance for different bucket', function () {
const a = S3Persistor._getClientForBucket('foo')
const b = S3Persistor._getClientForBucket('bar')
expect(a).to.not.equal(b)
})
it('should return different instance for same bucket different computeChecksums', function () {
const a = S3Persistor._getClientForBucket('foo', false)
const b = S3Persistor._getClientForBucket('foo', true)
expect(a).to.not.equal(b)
})
})
})
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
@@ -5,6 +5,6 @@ overleaf-editor-core
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+9 -4
View File
@@ -40,6 +40,11 @@ class Blob {
static NotFoundError = NotFoundError
/**
* @param {string} hash
* @param {number} byteLength
* @param {number} [stringLength]
*/
constructor(hash, byteLength, stringLength) {
this.setHash(hash)
this.setByteLength(byteLength)
@@ -63,14 +68,14 @@ class Blob {
/**
* Hex hash.
* @return {?String}
* @return {String}
*/
getHash() {
return this.hash
}
setHash(hash) {
assert.maybe.match(hash, Blob.HEX_HASH_RX, 'bad hash')
assert.match(hash, Blob.HEX_HASH_RX, 'bad hash')
this.hash = hash
}
@@ -83,13 +88,13 @@ class Blob {
}
setByteLength(byteLength) {
assert.maybe.integer(byteLength, 'bad byteLength')
assert.integer(byteLength, 'bad byteLength')
this.byteLength = byteLength
}
/**
* Utf-8 length of the blob content, if it appears to be valid UTF-8.
* @return {?number}
* @return {number|undefined}
*/
getStringLength() {
return this.stringLength
@@ -10,7 +10,7 @@ const Change = require('./change')
class ChangeNote {
/**
* @param {number} baseVersion the new base version for the change
* @param {?Change} change
* @param {Change} [change]
*/
constructor(baseVersion, change) {
assert.integer(baseVersion, 'bad baseVersion')
+1 -1
View File
@@ -95,7 +95,7 @@ class File {
/**
* @param {number} byteLength
* @param {number?} stringLength
* @param {number} [stringLength]
* @param {Object} [metadata]
* @return {File}
*/
@@ -47,7 +47,7 @@ class FileData {
/** @see File.createHollow
* @param {number} byteLength
* @param {number|null} stringLength
* @param {number} [stringLength]
*/
static createHollow(byteLength, stringLength) {
if (stringLength == null) {
@@ -63,20 +63,14 @@ class FileData {
*/
static createLazyFromBlobs(blob, rangesBlob) {
assert.instance(blob, Blob, 'FileData: bad blob')
if (blob.getStringLength() == null) {
return new BinaryFileData(
// TODO(das7pad): see call-sites
// @ts-ignore
blob.getHash(),
blob.getByteLength()
)
const stringLength = blob.getStringLength()
if (stringLength == null) {
return new BinaryFileData(blob.getHash(), blob.getByteLength())
}
return new LazyStringFileData(
// TODO(das7pad): see call-sites
// @ts-ignore
blob.getHash(),
rangesBlob?.getHash(),
blob.getStringLength()
stringLength
)
}
@@ -142,12 +142,8 @@ class StringFileData extends FileData {
trackedChanges: this.trackedChanges.toRaw(),
}
const rangesBlob = await blobStore.putObject(ranges)
// TODO(das7pad): Provide interface that guarantees hash exists?
// @ts-ignore
return { hash: blob.getHash(), rangesHash: rangesBlob.getHash() }
}
// TODO(das7pad): Provide interface that guarantees hash exists?
// @ts-ignore
return { hash: blob.getHash() }
}
}
@@ -109,7 +109,7 @@ class History {
* @param {BlobStore} blobStore
* @param {number} [concurrency] applies separately to files, changes and
* operations
* @return {Promise.<Object>}
* @return {Promise<import('overleaf-editor-core/lib/types').RawHistory>}
*/
async store(blobStore, concurrency) {
assert.maybe.number(concurrency, 'bad concurrency')
@@ -27,7 +27,7 @@ class V2DocVersions {
}
/**
* @return {?RawV2DocVersions}
* @return {RawV2DocVersions|null}
*/
toRaw() {
if (!this.data) return null
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ promise-utils
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+9 -3
View File
@@ -1,4 +1,4 @@
const { promisify, callbackify } = require('util')
const { promisify, callbackify } = require('node:util')
const pLimit = require('p-limit')
module.exports = {
@@ -253,8 +253,14 @@ function expressifyErrorHandler(fn) {
* Map values in `array` with the async function `fn`
*
* Limit the number of unresolved promises to `concurrency`.
* @template T
* @template V
* @param {number} concurrency
* @param {Array<T>} array
* @param {(arg: T) => Promise<V>} fn
* @return {Promise<Array<Awaited<V>>>}
*/
function promiseMapWithLimit(concurrency, array, fn) {
async function promiseMapWithLimit(concurrency, array, fn) {
const limit = pLimit(concurrency)
return Promise.all(array.map(x => limit(() => fn(x))))
return await Promise.all(array.map(x => limit(() => fn(x))))
}
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ ranges-tracker
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+3 -3
View File
@@ -1,8 +1,8 @@
const { promisify } = require('util')
const { promisify } = require('node:util')
const metrics = require('@overleaf/metrics')
const logger = require('@overleaf/logger')
const os = require('os')
const crypto = require('crypto')
const os = require('node:os')
const crypto = require('node:crypto')
const HOST = os.hostname()
const PID = process.pid
+3 -3
View File
@@ -1,8 +1,8 @@
const { callbackify, promisify } = require('util')
const { callbackify, promisify } = require('node:util')
const metrics = require('@overleaf/metrics')
const logger = require('@overleaf/logger')
const os = require('os')
const crypto = require('crypto')
const os = require('node:os')
const crypto = require('node:crypto')
const async = require('async')
const HOST = os.hostname()
+1 -1
View File
@@ -5,6 +5,6 @@ redis-wrapper
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+3 -3
View File
@@ -1,6 +1,6 @@
const crypto = require('crypto')
const os = require('os')
const { promisify } = require('util')
const crypto = require('node:crypto')
const os = require('node:os')
const { promisify } = require('node:util')
const Redis = require('ioredis')
+9
View File
@@ -0,0 +1,9 @@
const SandboxedModule = require('sandboxed-module')
SandboxedModule.configure({
sourceTransformers: {
removeNodePrefix: function (source) {
return source.replace(/require\(['"]node:/g, "require('")
},
},
})
@@ -6,8 +6,8 @@
*/
require('chai').should()
const SandboxedModule = require('sandboxed-module')
const assert = require('assert')
const path = require('path')
const assert = require('node:assert')
const path = require('node:path')
const sinon = require('sinon')
const modulePath = path.join(__dirname, './../../../index.js')
const redisLockerModulePath = path.join(__dirname, './../../../RedisLocker.js')
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+2 -2
View File
@@ -1,6 +1,6 @@
/* eslint-disable no-console */
const fs = require('fs')
const Path = require('path')
const fs = require('node:fs')
const Path = require('node:path')
const { merge } = require('./merge')
const CWD = process.cwd()
+1 -1
View File
@@ -5,6 +5,6 @@ settings
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+1 -1
View File
@@ -1 +1 @@
18.20.2
20.18.0
+1 -1
View File
@@ -5,6 +5,6 @@ stream-utils
--env-pass-through=
--esmock-loader=False
--is-library=True
--node-version=18.20.2
--node-version=20.18.0
--public-repo=False
--script-version=4.5.0
+6 -6
View File
@@ -1,8 +1,8 @@
const { Writable, Readable, PassThrough, Transform } = require('stream')
const { Writable, Readable, PassThrough, Transform } = require('node:stream')
/**
* A writable stream that stores all data written to it in a node Buffer.
* @extends stream.Writable
* @extends Writable
* @example
* const { WritableBuffer } = require('@overleaf/stream-utils')
* const bufferStream = new WritableBuffer()
@@ -43,7 +43,7 @@ class WritableBuffer extends Writable {
/**
* A readable stream created from a string.
* @extends stream.Readable
* @extends Readable
* @example
* const { ReadableString } = require('@overleaf/stream-utils')
* const stringStream = new ReadableString('hello world')
@@ -66,7 +66,7 @@ class SizeExceededError extends Error {}
/**
* Limited size stream which will emit a SizeExceededError if the size is exceeded
* @extends stream.Transform
* @extends Transform
*/
class LimitedStream extends Transform {
constructor(maxSize) {
@@ -93,7 +93,7 @@ class AbortError extends Error {}
/**
* TimeoutStream which will emit an AbortError if it exceeds a user specified timeout
* @extends stream.PassThrough
* @extends PassThrough
*/
class TimeoutStream extends PassThrough {
constructor(timeout) {
@@ -111,7 +111,7 @@ class TimeoutStream extends PassThrough {
/**
* LoggerStream which will call the provided logger function when the stream exceeds a user specified limit. It will call the provided function again when flushing the stream and it exceeded the user specified limit before.
* @extends stream.Transform
* @extends Transform
*/
class LoggerStream extends Transform {
/**
+8142 -4874
View File
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -5,6 +5,8 @@
"patch-package": "^8.0.0"
},
"devDependencies": {
"@types/chai": "^4.3.0",
"@types/chai-as-promised": "^7.1.8",
"@types/mocha": "^10.0.6",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
@@ -19,6 +21,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-unicorn": "^56.0.0",
"prettier": "3.3.3",
"typescript": "^5.5.4"
},
@@ -63,7 +66,6 @@
"services/project-history",
"services/real-time",
"services/references",
"services/spelling",
"services/templates",
"services/third-party-datastore",
"services/third-party-references",
+23
View File
@@ -0,0 +1,23 @@
diff --git a/node_modules/@node-saml/node-saml/lib/saml.js b/node_modules/@node-saml/node-saml/lib/saml.js
index fba15b9..a5778cb 100644
--- a/node_modules/@node-saml/node-saml/lib/saml.js
+++ b/node_modules/@node-saml/node-saml/lib/saml.js
@@ -336,7 +336,8 @@ class SAML {
const requestOrResponse = request || response;
(0, utility_1.assertRequired)(requestOrResponse, "either request or response is required");
let buffer;
- if (this.options.skipRequestCompression) {
+ // logout requestOrResponse must be compressed anyway
+ if (this.options.skipRequestCompression && operation !== "logout") {
buffer = Buffer.from(requestOrResponse, "utf8");
}
else {
@@ -495,7 +496,7 @@ class SAML {
try {
xml = Buffer.from(container.SAMLResponse, "base64").toString("utf8");
doc = await (0, xml_1.parseDomFromString)(xml);
- const inResponseToNodes = xml_1.xpath.selectAttributes(doc, "/*[local-name()='Response']/@InResponseTo");
+ const inResponseToNodes = xml_1.xpath.selectAttributes(doc, "/*[local-name()='Response' or local-name()='LogoutResponse']/@InResponseTo");
if (inResponseToNodes) {
inResponseTo = inResponseToNodes.length ? inResponseToNodes[0].nodeValue : null;
await this.validateInResponseTo(inResponseTo);
+64
View File
@@ -0,0 +1,64 @@
diff --git a/node_modules/ldapauth-fork/lib/ldapauth.js b/node_modules/ldapauth-fork/lib/ldapauth.js
index 85ecf36a8b..a7d07e0f78 100644
--- a/node_modules/ldapauth-fork/lib/ldapauth.js
+++ b/node_modules/ldapauth-fork/lib/ldapauth.js
@@ -69,6 +69,7 @@ function LdapAuth(opts) {
this.opts.bindProperty || (this.opts.bindProperty = 'dn');
this.opts.groupSearchScope || (this.opts.groupSearchScope = 'sub');
this.opts.groupDnProperty || (this.opts.groupDnProperty = 'dn');
+ this.opts.tlsStarted = false;
EventEmitter.call(this);
@@ -108,21 +109,7 @@ function LdapAuth(opts) {
this._userClient.on('error', this._handleError.bind(this));
var self = this;
- if (this.opts.starttls) {
- // When starttls is enabled, this callback supplants the 'connect' callback
- this._adminClient.starttls(this.opts.tlsOptions, this._adminClient.controls, function(err) {
- if (err) {
- self._handleError(err);
- } else {
- self._onConnectAdmin();
- }
- });
- this._userClient.starttls(this.opts.tlsOptions, this._userClient.controls, function(err) {
- if (err) {
- self._handleError(err);
- }
- });
- } else if (opts.reconnect) {
+ if (opts.reconnect && !this.opts.starttls) {
this.once('_installReconnectListener', function() {
self.log && self.log.trace('install reconnect listener');
self._adminClient.on('connect', function() {
@@ -384,6 +371,28 @@ LdapAuth.prototype._findGroups = function(user, callback) {
*/
LdapAuth.prototype.authenticate = function(username, password, callback) {
var self = this;
+ if (this.opts.starttls && !this.opts.tlsStarted) {
+ // When starttls is enabled, this callback supplants the 'connect' callback
+ this._adminClient.starttls(this.opts.tlsOptions, this._adminClient.controls, function (err) {
+ if (err) {
+ self._handleError(err);
+ } else {
+ self._onConnectAdmin(function(){self._handleAuthenticate(username, password, callback);});
+ }
+ });
+ this._userClient.starttls(this.opts.tlsOptions, this._userClient.controls, function (err) {
+ if (err) {
+ self._handleError(err);
+ }
+ });
+ } else {
+ self._handleAuthenticate(username, password, callback);
+ }
+};
+
+LdapAuth.prototype._handleAuthenticate = function (username, password, callback) {
+ this.opts.tlsStarted = true;
+ var self = this;
if (typeof password === 'undefined' || password === null || password === '') {
return callback(new Error('no password given'));
+5 -1
View File
@@ -4,6 +4,9 @@
"standard",
"prettier"
],
"plugins": [
"unicorn"
],
"parserOptions": {
"ecmaVersion": 2020
},
@@ -12,7 +15,8 @@
},
"rules": {
// Do not allow importing of implicit dependencies.
"import/no-extraneous-dependencies": "error"
"import/no-extraneous-dependencies": "error",
"unicorn/prefer-node-protocol": "error"
},
"overrides": [
// Extra rules for Cypress tests
+2 -3
View File
@@ -2,7 +2,7 @@
# Overleaf Base Image (sharelatex/sharelatex-base)
# --------------------------------------------------
FROM phusion/baseimage:jammy-1.0.4
FROM phusion/baseimage:noble-1.0.0
# Makes sure LuaTex cache is writable
# -----------------------------------
@@ -25,13 +25,12 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
unattended-upgrades \
build-essential wget net-tools unzip time imagemagick optipng strace nginx git python3 python-is-python3 zlib1g-dev libpcre3-dev gettext-base libwww-perl ca-certificates curl gnupg \
qpdf \
aspell aspell-en aspell-af aspell-am aspell-ar aspell-ar-large aspell-bg aspell-bn aspell-br aspell-ca aspell-cs aspell-cy aspell-da aspell-de aspell-de-1901 aspell-el aspell-eo aspell-es aspell-et aspell-eu-es aspell-fa aspell-fo aspell-fr aspell-ga aspell-gl-minimos aspell-gu aspell-he aspell-hi aspell-hr aspell-hsb aspell-hu aspell-hy aspell-id aspell-is aspell-it aspell-kk aspell-kn aspell-ku aspell-lt aspell-lv aspell-ml aspell-mr aspell-nl aspell-no aspell-nr aspell-ns aspell-pa aspell-pl aspell-pt aspell-pt-br aspell-ro aspell-ru aspell-sk aspell-sl aspell-ss aspell-st aspell-sv aspell-tl aspell-tn aspell-ts aspell-uk aspell-uz aspell-xh aspell-zu \
# upgrade base-image, batch all the upgrades together, rather than installing them on-by-one (which is slow!)
&& unattended-upgrade --verbose --no-minimal-upgrade-steps \
# install Node.js https://github.com/nodesource/distributions#nodejs
&& mkdir -p /etc/apt/keyrings \
&& curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
&& apt-get update \
&& apt-get install -y nodejs \
\
+4 -4
View File
@@ -11,22 +11,22 @@ cd /overleaf/services/web
case "$TASK" in
user:create-admin)
echo "The grunt command is deprecated, run the create-user script using node instead"
node modules/server-ce-scripts/scripts/create-user --admin "$@"
node modules/server-ce-scripts/scripts/create-user.mjs --admin "$@"
;;
user:delete)
echo "The grunt command is deprecated, run the delete-user script using node instead"
node modules/server-ce-scripts/scripts/delete-user "$@"
node modules/server-ce-scripts/scripts/delete-user.mjs "$@"
;;
check:mongo)
echo "The grunt command is deprecated, run the check-mongodb script using node instead"
node modules/server-ce-scripts/scripts/check-mongodb
node modules/server-ce-scripts/scripts/check-mongodb.mjs
;;
check:redis)
echo "The grunt command is deprecated, run the check-redis script using node instead"
node modules/server-ce-scripts/scripts/check-redis
node modules/server-ce-scripts/scripts/check-redis.mjs
;;
*)
+1 -1
View File
@@ -9,6 +9,6 @@ export HISTORY_V1_HOST=127.0.0.1
export NOTIFICATIONS_HOST=127.0.0.1
export PROJECT_HISTORY_HOST=127.0.0.1
export REALTIME_HOST=127.0.0.1
export SPELLING_HOST=127.0.0.1
export REFERENCES_HOST=127.0.0.1
export WEB_HOST=127.0.0.1
export WEB_API_HOST=127.0.0.1

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