Commit Graph
2589 Commits
Author SHA1 Message Date
Mathieu Agopian 693bcb4a24 🚨(migration) Refactor to fix lint issues
Use a dict lookup for import helpers instead of a huge match statement.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 11:31:26 +02:00
Mathieu Agopian cc5fe4e27d ✨(migration) import_migration management command imports mentions
Straightfoward import of mentions

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 11:21:37 +02:00
Mathieu Agopian 1cf1384a08 ✨(migration) import_migration management command imports reconciliations
Straightforward import of user reconciliations.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 11:21:37 +02:00
Mathieu Agopian f8c7e02887 ✨(migration) import_migration management command imports comments
Straightforward import of threads, comments and reactions.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 11:08:24 +02:00
Mathieu Agopian 954c3170eb ✨(migration) import_migration management command imports Favorites
Straightforward DocumentFavorite import

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 11:00:57 +02:00
Mathieu Agopian c2d9600189 ✨(migration) import_migration management command imports AskForAccess
Straightforward DocumentAskForAccess import

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 10:59:58 +02:00
Mathieu Agopian a87005e00b ✨(migration) import_migration management command imports LinkTrace
Straightforward LinkTrace imports

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 10:57:37 +02:00
Mathieu Agopian bb2b17e3a0 ✨(migration) import_migration management command imports Invitations
Import the table as is, bypassing the `clean()` that doesn't create an
Invitation for an existing user.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 10:46:27 +02:00
Mathieu Agopian fd9bd90948 ✨(migration) import_migration management command imports DocumentAccess
Import DocumentAccess, remapping user FK if needed

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 10:32:30 +02:00
Mathieu Agopian 5e6159954b ✨(migration) import_migration management command also imports documents
Document are only imported if not already existing.
The source path (computed using TreeBeard) is reconstructed so as not to
overwrite the ones in the target instance.

The `duplicated_from_id` field is not imported for now, it would require
a second pass over all documents.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-07 10:22:36 +02:00
Mathieu Agopian 4c57676fb2 ✨(migration) add import_migration management command and import users
Users that already exist aren't duplicated, instead the imported UUID is
stored in a mapping dict so all the future imported models will have
their users' FK rewritten to the existing UUID instead of the imported
one.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:51:30 +02:00
Mathieu Agopian 39b899643b ✨(migration) export management command also exports mentions
Export mentions of users in documents, and whether they've already been
notified by email

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian 49c31f5b3a ✨(migration) export management command also exports user reconciliations
Export user reconciliations when a user had two accounts

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian 17060f9489 ✨(migration) export management command also exports comments
Export user threads, comments and reactions

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian 9d0187dbff ✨(migration) export management command also exports DocumentAskForAccess
Export the access requests

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian bc8aadec53 ✨(migration) export management command also exports DocumentFavorite
Export the favorites

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian ce17a69d72 ✨(migration) export management command also exports link traces
Export documents opened by authenticated users using a link share

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian 581795e9d1 ✨(migration) export management command also exports invitations
Export invitations to access a document

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian dedb4f6579 ✨(migration) export management command also exports DocumentAccess
Export the document accesses

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:23 +02:00
Mathieu Agopian 7abbb722dc ✨(migration) export management command also exports documents
This only exports the documents metadata. The media lives in S3, the
content lives in either S3 or yhub depending on if the migration to the
yhub collaboration server has already occured.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:22 +02:00
Mathieu Agopian 2c37e042f3 ✨(migration) add export_migration management command and export users
This is the first model to be exported. Dynamically export any existing
field of the model, this way this management command should be able to
run on any version.

Signed-off-by: Mathieu Agopian <mathieu@agopian.info>
2026-10-06 17:06:22 +02:00
Anthony LC 6e5dee38e9 🐛(frontend) cache hashed next static assets and revalidate html
Files under /_next/static/ carry a content hash in their name but were
served without Cache-Control, so browsers fell back to heuristic freshness
and revalidated each of the ~45 files of a page with a conditional request.
Serve them with a one-year immutable lifetime.

HTML pages, service-worker.js and public files keep a stable name: send
Cache-Control: no-cache so the browser revalidates them and always gets
the chunk list and service worker of the current release. The headers are
repeated in every location, as nginx drops the inherited add_header
directives as soon as a location defines its own.

Closes #2770

Signed-off-by: Anthony LC <anthony.le-courric@mail.numerique.gouv.fr>
2026-10-05 16:34:08 +02:00
Manuel Raynaud 2bd30312cd ⚡️(backend) coalesce and pace the resets of collaboration connections
For big documents, calling yhub for each sub documents can be a big
amount of request at the same time. We decided to group reset by batch
in the path order and call again the reset celery task with a delay to
continue.

Fix #2656
2026-10-05 14:15:07 +02:00
Manuel Raynaud 64338d55d0 🐛(backend) reset the collaboration connections on every access change
Reset to the collaboration server when an access is changed was
partially made. There is still action in the application that does not
cover this like when a document is moved or soft deleted.
Instead of doing the reset in the viewset and searching for every action
it should be made, we are making it now in the model to miss new or
modified path acting on an access. For detecting when a bulk
update/delete is made on the access model, we use existing
signal.
2026-10-05 14:15:06 +02:00
Roee SivanandAnthony LC 1983951843 🐛(frontend) keep login and logout out of the service worker cache
The login and logout navigations (authenticate/, callback/, logout/,
logout-callback/) reach the service worker on the same origin, and the
catch-all api route cached their redirects. When the network step
failed, the worker answered authenticate/ with a cached redirect that
carried an OIDC state already used, so the login failed: a 400 on the
callback before django-lasuite 0.0.30.

Give these urls their own NetworkOnly route, registered before the
catch-all one, so they never read or write the cache. ApiPlugin stays
on it, so the offline mutations are still replayed before a logout
ends the session.

Fixes #2477

Signed-off-by: Roee Sivan <roee.sivan@post.runi.ac.il>
2026-10-05 11:21:37 +02:00
renovate[bot]andGitHub 5d38f95e8d ⬆️(dependencies) update @ai-sdk/openai to v3.0.119 2026-10-05 01:06:19 +00:00
Anthony LC 861065301a ⬆️(dependency) upgrade lib0 from 0.2.114 to 0.2.119
Snyk has created this PR to upgrade lib0 from 0.2.114 to 0.2.119.

See this package in yarn:
lib0
2026-10-02 17:56:16 +02:00
Anthony LC 03838c14d4 ✅(e2e) improve e2e sub-page handling
A test was getting flaky, and was blocking the CI pipeline.
This change improves the handling of sub-pages in
the e2e tests to make them more reliable.
2026-10-02 15:59:13 +02:00
Thomas RaméandAnthony LC 5adfdee0d3 🐛(dev) missing default network for podman compose usage
Some services, like celery-dev, attach to the `default` network
explicitly, next to `lasuite`. Docker compose creates that implicit
network on its own. Podman compose does not when the top-level
`networks` section is declared without it, so `compose up` failed on
the unknown `default` network.

Declare `default: {}` so that the network exists with both tools.
2026-10-02 15:44:34 +02:00
Anthony LC 925ececab6 🐛(frontend) select a single language in the language picker
The language picker marked an option as selected when it matched the
current language, falling back to a match on the language alone. With the
current language zh-tw, the zh-cn option matched too, so several regions
of a language were selected at once, and the legacy picker could show the
label of the wrong one. Now that zh-cn and zh-tw are separate frontend
translations, this shows up for the Chinese locales, and it would for any
language with several regions (en-us/en-gb, pt-pt/pt-br).

Add getClosestLocale, which returns the one available locale closest to
the current language (the exact match first, then the first region of the
language), and use it in both pickers to select the option and to display
the current label.
2026-10-02 12:12:53 +02:00
Anthony LC c39c51a756 🌐(i18n) update translated strings
Pull the translations from Crowdin with the new locale-based export, so
that the frontend translations reflect the new taxonomy: zh-CN and zh-TW
are now two distinct entries (zh-cn and zh-tw) in translations.json
instead of a single "zh" one, and the backend .po files are refreshed.
2026-10-02 12:12:52 +02:00
Anthony LC da95cce985 🌐(i18n) key crowdin frontend exports by locale
Crowdin exported the frontend translations to a folder named after
%two_letters_code%, so every regional variant of a language landed in the
same folder: zh-CN and zh-TW both gave "zh", and the last one downloaded
overwrote the other. Mapping the Chinese locales apart would have fixed
only that pair, and each new variant (pt-BR, es-MX, en-GB...) would have
needed its own entry.

Use %locale% instead, which is unique per locale, like the backend already
does with %locale_with_underscore%. format-deploy keeps the keys of
translations.json as they are today (fr, de...) and only keeps the region
(zh-cn, zh-tw) when several locales of the same language are translated.
The language detection and the language picker already match a locale
exactly before falling back to its language, so they need no change.

The export pattern is stored by Crowdin with the source file: the sources
must be uploaded again before the next download, and the zh-CN data that
was polluted with Traditional Chinese still needs to be re-uploaded.

Fixes #2749
2026-10-02 12:12:52 +02:00
Ovgodd 8a7416cb3e 💄(frontend) redesign 401 error standalone page
Reuse the 404 standalone layout and keep the existing sign-in flow.
2026-10-02 11:42:23 +02:00
Ovgodd 2a4131a188 🐛(frontend) keep caption and alignment when replacing an image
The antivirus loader rebuilt the image block with an empty caption and
left alignment, so both were lost after a replace.

Signed-off-by: Ovgodd <c.gromoff@gmail.com>
2026-10-02 11:02:29 +02:00
Gene WoodandAnthony LC 6a3fd49348 📝(docs) fix markdown typo in installation README
Signed-off-by: Gene Wood <gene_wood@cementhorizon.com>
2026-10-02 10:25:35 +02:00
Manuel RaynaudandAnthony LC 9de17b3f82 👷(ci) cancel the superseded runs of a pull request
adding a concurrency group will now stop running CI if a new push is
made on the same branch.
2026-10-01 16:29:43 +02:00
Manuel RaynaudandAnthony LC 670cbe4beb 👷(ci) check the load-test tooling: swarm, canary, k6 and dashboards
Add missing jobs to run the tests in swarm and canary projects. For k6
the project is inspected using k6 docker image and for the grafana
dashboard we check if the generated dashboard equals the one existing.
2026-10-01 16:29:43 +02:00
Manuel RaynaudandAnthony LC d11d911c77 👷(ci) lint, typecheck, build and test the collaboration server
The CI was not setup for yhub, we added the missing jobs: lint, test and
typecheck
2026-10-01 16:29:42 +02:00
Anthony LC a2e7f4118c ⬆️(Dockerfile) bump Playwright base image to v1.63.0
The Playwright base image in the Dockerfile has been
updated from v1.62.1 to v1.63.0, in order to follow the
version of the `playwright` package in package.json.
2026-10-01 11:25:19 +02:00
Anthony LC 978a8205ea 🔒️(js) fix security warning
High:
- @xmldom/xmldom (13 advisories, CVE-2026-83612…)
- fast-uri GHSA-f65p-4m7j-42xc and 5 more
- js-yaml CVE-2026-84375
- browserslist CVE-2026-73089, CVE-2026-73088
- svgo CVE-2026-84370
- ws CVE-2026-48779

Moderate:
- vitest CVE-2026-84373
- qs CVE-2026-82562, CVE-2026-82417
- fflate CVE-2026-45820
- baseline-browser-mapping CVE-2026-45819
- colord GHSA-2wm5-q62r-hmrv

Low:
- @ai-sdk/provider-utils CVE-2026-8769
- postcss-selector-parser CVE-2026-9358
2026-10-01 11:25:18 +02:00
Anthony LC 3be8a858f2 ⬇️(frontend) downgrade blocknote dependencies to 0.54.0
The export feature is not working correctly with
the newer version, so we are downgrading to 0.54.0.
We need to refactorize the code to be compatible
with typst in order to work correctly.
2026-10-01 11:06:33 +02:00
Anthony LC 30dc14f78d ✅(dependency) add vite dependency
Recent upgrade of Vitest dependency needed
Vite dependency in order to work with the latest
Vitest features.
2026-10-01 11:06:33 +02:00
Anthony LC 77ea3b2c8e 🚨(dependency) update ui-kit tokens
We bumped the UI-kit dependency, we need to update
the UI-kit tokens accordingly.
2026-10-01 11:06:33 +02:00
renovate[bot]andAnthony LC 7e219dd8e4 ⬆️(dependencies) update js dependencies 2026-10-01 10:05:46 +02:00
renovate[bot]andGitHub bd71ed87e1 ⬆️(dependencies) update dompurify to v3.4.16 [SECURITY] 2026-09-30 19:59:40 +00:00
renovate[bot]andGitHub 976cd6c09b ⬆️(dependencies) update PyJWT to v2.15.0 [SECURITY] 2026-09-30 21:27:45 +02:00
renovate[bot]andGitHub b59abd5420 ⬆️(dependencies) update PyJWT to v2.14.0 [SECURITY] 2026-09-30 16:47:15 +00:00
Manuel RaynaudandGitHub af4c363c2a ⬆️(backend) upgrade django-lasuite to version 0.0.30
Upgrade django-lasuite to version 0.0.30 and add the new settings
OIDC_OP_LOGOUT_USE_POST in our settings.
2026-09-30 12:57:40 +00:00
MarrrrrrrrryandGitHub ad2908a693 🐛(backend) compensate document duplication failures
Duplicating a document tree made two calls to the collaboration server
per node, all inside the database transaction: it held locks for the
duration of every call, and a failure midway left the documents already
created on the collaboration server behind, as orphans nothing can
reach anymore.
    
The duplication now runs in two phases. The structure is first
replicated in a transaction that makes no call to the collaboration
server, then each duplicate is seeded with the content of its source.
A failure while seeding deletes what was seeded - the deletion of the
collaboration server is idempotent and never refused - and removes the
replicated documents, so neither side keeps an orphan.
    
Signed-off-by: Marrrrrrrrry <34876935+Marrrrrrrrry@users.noreply.github.com>
2026-09-30 10:09:53 +00:00
MarrrrrrrrryandGitHub 1794650e6d 🐛(yhub) bound the calls the server makes to the backend
`backendFetch` had no timeout: a backend that hangs hangs every
websocket
upgrade and fallback poll with it, piling up under load. The three
auth-path
calls it serves (`users/me`, `documents/{id}`, `accesses/me`) waited
forever,
so a slow backend took the whole collaboration service down with it.

Signed-off-by: Marrrrrrrrry <34876935+Marrrrrrrrry@users.noreply.github.com>
2026-09-30 08:24:32 +00:00