Commit Graph
719 Commits
Author SHA1 Message Date
Kevin JahnsandAnthony LC 46f8a24326 (collaboration) test the legacy migrations against a real yhub
Cover both paths off the legacy Django store end to end: the lazy seed on
first access, and the migrate endpoint replaying every S3 version. The tests
need no database — the admin JWT short-circuits document authorization, so a
fixture is an S3 object on a random uuid — and read the timeline through
yhub 0.5.0's `Accept: application/json`, which spares python a lib0 decoder.
CI grows a valkey service and starts a collaboration server alongside the
backend test job; the tests skip themselves when nothing answers on the new
COLLABORATION_API_URL setting, so `make test` without the dev stack still
passes.

Writing them turned up three things worth fixing in the server.

Backend reads now seed too. getAccessType short-circuited on the admin token
before reaching the legacy store, so a server-side read of an unmigrated
document answered with an empty one, and a create-ydoc against it would have
written a second lineage beside the content the first user access was about
to seed in.

Seeding no longer decides access; the backend's answer alone does. A legacy
object that cannot be migrated — it does not decode, or it exceeds the size
we load — opens as a new document instead of denying, since no retry can fix
it and refusing would leave the document unopenable by anyone. The cause is
logged once per attempt with the bucket, key and stack, and every later access
logs that it admitted a caller without migrating.

That made the failure classifier dangerous, so it is inverted. It was an
allowlist of retryable errors — eight socket errnos — which left every way S3
can refuse (AccessDenied on a rotated key, NoSuchBucket, a region redirect)
counting as "this object is unusable". Denying, that was survivable; opening
empty, one misscoped credential would fork every document touched during the
window. Now only a failure raised while interpreting bytes we already hold is
permanent, marked at the throw site, and everything else answers a retryable
503. Guessing wrong that way costs a retry; the other way costs the document.

The admin seed is also fenced to the org and to main, like the user path
above it. The legacy store is branchless — {docid}/file is main — and the
bookkeeping is per document, so seeding ?branch=draft would have written
main's content into an orphan room and left the real one permanently empty.

Signed-off-by: Kevin Jahns <kevin.jahns@protonmail.com>
2026-09-01 15:27:46 +02:00
Anthony LC 6dab2c174c 🛂(backend) add audience to jwt
Add audience to the jwt, scoping the token to it
prevents an admin JWT issued for another backend
service from being replayed against y-provider.
2026-09-01 15:16:22 +02:00
Anthony LC 99afd9f7cc 🛂(django) use jwt token for converter services
The Y_PROVIDER_API_KEY shared secret is replaced by a
signed admin JWT when Django calls the y-provider
conversion endpoint.
2026-09-01 15:16:22 +02:00
Manuel RaynaudandAnthony LC d3fe8de9d0 🔥(backend) remove CollaborationService and can-edit endpoint
The CollaborationService was doing nothing since we started the
migration to yhub, all the code using it is now removed. Also the
`can-edit` endpoint and all the safeguard mechanism relying on the
presence of other users connected to the websocket will not be used
anymore, it will be possible to replace all of this with yhub, so all
this code is also removed.
2026-09-01 15:15:36 +02:00
Manuel RaynaudandAnthony LC a071ebb040 (backend) add a method to create a dedicated admin token
For now the only token we will need is ont with the admin claim set to
True. To not repeat the creation of this token again and again, we
created a dedicated method to issue this token in the JWTService class.
2026-09-01 15:15:35 +02:00
Manuel RaynaudandAnthony LC 5db236dd8c (backend) publish the JWT public key on a JWKS endpoint
The yhub service will need our public key in order to validate the jwt
token we will used. We choose to expose a jwks endpoint as it is a
standard wat to do this.
2026-09-01 15:15:35 +02:00
Manuel RaynaudandAnthony LC 7c4a260a15 (backend) add a service generating cached RS256 JWT tokens
We want to generate jwt token using the RS256 algotrithm. This token
will be used for internal call with the yhub service.
2026-09-01 15:15:34 +02:00
Kevin JahnsandAnthony LC a50c824caa ♻️(collaboration) switch collaboration server from hocuspocus to yhub
Signed-off-by: Kevin Jahns <kevin.jahns@protonmail.com>
2026-09-01 15:14:54 +02:00
Anthony LC 4e6d28e259 ♻️(frontend) update ui logo Docs
The logo Docs seems to have again changed in the
design system. We update the logo part accordingly
to the new design system logo.
2026-08-26 10:32:03 +02:00
Anthony LC 02195154a0 🔖(release) minor 5.5.0
Added:
- ️(frontend) restore skip to content link after header redesign
- 🌐(i18n) rename cn_CN to zh_CN, add eo_PL and zh_TW locales
- (backend) conditional email notification in server to server api
- (backend) profile api using django-silk

Changed:
- ️(frontend) use semantic `<dl>` structure in document info card
- ️(frontend) replace onboarding assets with webm and webp
- 💄(frontend) use the same highlight color for cells and moves
- ️(backend) optimize media_auth endpoint
- 🚸(frontend) print from document options menu

Fixed:
- 🐛(frontend) refresh pins after document deletion and restoration
- 🐛(frontend) redirect homepage to login when homepage feat
  is disabled
- 🐛(backend) ignore CSPs for API docs in development
- 🐛(frontend) export images embedded with a relative url
- 🐛(y-provider) fix sentry init
- 🐛(backend) handle object storage metadata keys case-insensitively
- 🐛(keycloak) fix database env variables in the self-hosting example
- 🐛(helm) show the database error while jobs wait for it to be ready
2026-08-24 21:40:18 +02:00
AntoLCandAnthony LC c8ed9ec349 🌐(i18n) update translated strings
Update translated files with new translations
2026-08-24 14:51:36 +02:00
Anthony LC 1df56199c6 🌐(i18n) add Polish language to django system
A new language has been added to the Django system,
allowing for Polish translations and localization
support.
We need to initialize the Polish language files before
being able to download the translations from
Crowdin. This commit includes the initial setup for
the Polish language, including the necessary configuration
files and directory structure.
2026-08-24 14:37:36 +02:00
Manuel Raynaud 4111e4e5ed ️(backend) optimize media_auth cpu usage
Once the sql queries improved we have still a bottleneck on large
concurrent requests on this endpoint. We notive in the profiles generated
that lot of time was spent in creating a new s3 client instance on each
request. django_storage use a thread local cache for signed and unsigned
connection, but using uvicorn we have a new thread for each request, so
on each request a new s3 client is generated and it appears to be an
expensive operation. To fix this issue, we cache the client and share it
accross all the thread and requests.
2026-08-20 17:28:31 +02:00
Manuel Raynaud 7372c4610f ️(backend) optimize media_auth sql queries
On the media_auth endpoint the first bottleneck we have is with
postgresql. We are looking for too much data and no index is used on the
attachments colum. When the lookup filter on the attachement columns, a
full scan is made on all the document table looking for each element in
the array, this operation is really expensive. To fix this we created a
GIN index on the attachments column. Also the readable_per_se lookup was
selecting too much data combined with the filter_descendants function.
We remove the usage of the filter_descendants, we choose to first fetch
all the paths where the attachment is found, this operation is fast
thanks to the new index, split all the paths in candidate paths and then
filter readable_per_se queryset with these paths. All these
modifications make the endpoint faster.
2026-08-20 16:28:31 +02:00
Manuel Raynaud f714c7fae3 (backend) profile api using django-silk
We have performance issue with the media_auth endpoint. We need to
monitor and profile this endpoint to understand what is happening. We
decided to install and configure django-silk. By default django-silk is
not enabled and not accessible, once enabled migration must be run and
the /silk/ endpoint will be accessible only using a super user.
To have relecant profiles and monitor we must have a database comparable
to a production one because we are facing a scaling issue. Unless a
million documents probably nothing is happening, for this we added
several management commands to help us. A first one to anonymize a
database than can be reused without any risk to leak PII data, can be
called using python manage.py anonymize_database with some mandatory
options. An other command to generate a database profile, this command
should be run on a production database, this profile can then be used by
the generate_volumetry to populate a development database with same
volumetry than describe in the profile.
2026-08-20 16:21:36 +02:00
risk-altandAnthony LC fb984abab3 🐛(backend) handle object storage metadata keys case-insensitively
Object storage metadata keys are case insensitive per the S3
specification, but implementations don't agree on the case they give
back. When head_object returns a capitalized "Status", updating the
attachment status added a second, lowercase entry instead of replacing
it, and the copy request ended up carrying two x-amz-meta-status
headers. Ceph RadosGW loses one of them behind a proxy, which
invalidates the request signature.

The same assumption was made when reading the status back in media-auth
and media-check, where an attachment stored on such a backend stayed in
"processing" forever.

Metadata read from the storage is now normalized to lowercase keys
before being consumed or copied over.

Signed-off-by: risk-alt <aldu6974@gmail.com>
2026-08-14 11:30:52 +02:00
Julien Maupetit b297d79c32 🐛(backend) ignore CSPs for API docs in development
With Content Security Policies activated, swagger (and redoc)
auto-generated API documentation is no longer accessible even locally.
To restore this feature, we've excluded CSP for related URLs only in
the `Development` configuration.
2026-08-05 10:39:48 +02:00
Manuel Raynaud 1e56b5e162 ⬆️(backend) upgrade pylint to version 4.0.6
pylint-django is now compatible with latest version of pylint, we can
upgrade it safely.
2026-08-04 10:16:51 +02:00
Manuel Raynaud f7d06e45e5 🚨(backend) lint code with new ruff 0.16
New ruff version need to lint the code again and adapt exceptions
2026-08-04 10:16:51 +02:00
Manuel Raynaud a57fb7cbde ♻️(backend) remove deprecation warning from pydantic-ai library
Since pydantic-ai has ben upgraded deprecation warning were present in
the logs. This commint change how the instrumentation is enabled to be
compatible with hoe pydantic-ai manage it. Also prompt system are
ignored when they come from the front, like we are doing and dropped. To
maintain the system prompt we use the instruction parameter instead.
2026-08-04 10:16:51 +02:00
Manuel Raynaud 050591e2ee ⬆️(backend) upgrade pydantic-ai-slim and remove mistralai
We upgraded pydantic-ai-slim to the latest version and add mistral has
extra dependency. Doing this, the direct dependance to mistral can be
removed and will be managed with pidantic-ai-slim package. The import of
mistralai has changed, we have to updagre them from mistralai to
mistralai.client
2026-08-04 10:16:50 +02:00
Manuel Raynaud 7439e3f94c 🔧(backend) allow all python 3.14 versions
We don't want to restrict to the higher 3.14 version but for all
available 3.14 versions.
2026-08-04 10:16:50 +02:00
renovate[bot]andManuel Raynaud 0f823b50fb ⬆️(dependencies) update python dependencies 2026-08-04 10:16:49 +02:00
Florent Chehab edf26d6321 (backend) conditional email notification in server to server api
Add send_notification_email flag (defaults to True) on
the ServerCreateDocumentSerializer so that we can bypass
sending the email notification when creating a document
with the server to server API.

Signed-off-by: Florent Chehab <flo@nextmile.fr>
2026-08-03 10:54:31 +02:00
exyoneandAnthony LC 126818fc15 🌐(i18n) rename cn_CN to zh_CN, add eo_PL and zh_TW locales
We have renamed the Chinese locale from `cn_CN`
to `zh_CN` to align with standard locale naming
conventions.
Additionally, we have added support for two new
locales: Esperanto (`eo_PL`) and
Traditional Chinese (`zh_TW`).
2026-07-21 10:19:01 +02:00
Anthony LCandManuel Raynaud 57ad4f4be8 🔖(release) patch 5.4.1
Changed:
- ♻️(backend) reset collaboration connection in cascade for all children

Fixed:
- 💄(frontend) fix some UI/UX in the left panel
- 🐛(frontend) fix tree dnd firefox
2026-07-09 18:22:20 +02:00
Anthony LC 5a705b045b 💄(frontend) fix some UI/UX in the left panel
- Collapse panel button is now:
  - fully clickable,
  - the title is hidden
  - when the doc title is visible
  - when small mobile the title is hidden
- Add button login when logout whatever the device
- Fix flickering logo
- New icon name to avoid cache
2026-07-09 17:46:12 +02:00
Manuel Raynaud d35b81a6ed ♻️(backend) reset collaboration connection in cascade for all children
When an access is updated or deleted, or a link_configuration is
changed, the collaration_service is used to reset the connection in the
collaboration server. As accesses and link_configuration are inherited
in a Docs tree, if the user is connected to a child, the connection is
not reset. This commit fix this issue by calling the reset on every
children in the tree.
2026-07-09 14:46:11 +02:00
Manuel Raynaud d1db000c76 🔧(backend) configure logging with propagate set to True
In the settings, the logging has set the propagate property to False.
While writing tests it wasn't possible to assert log was made using the
caplog fixtures because this propagate is set to False. Changing it to
True allow to correctly tests that a log is made using the caplog
fixture.
2026-07-09 14:45:04 +02:00
Anthony LC 0659cc5247 🔖(minor) release 5.4.0
Added:
- (y-provider) preserve callouts, PDFs, page breaks, interlinking
  links and commented text on HTML/markdown export
- (frontend) add a user menu
- (frontend) new header and responsive harmonization
- (backend) add management command to reset a Document

Changed:
- ️(frontend) hide mobile left panel from screen readers when collapsed
- ️(frontend) enable blocknote heading ids for toc anchors
- ️(frontend) focus export modal on format select
- ️(frontend) configurable legal submenu in HelpMenu, remove Crisp
- ♻️(frontend) new create button for docs
- ️(frontend) align search modal field label with placeholder
- 🚚(frontend) move Waffle to bottom left
- ️(frontend) remove redundant aria-label on table of contents links
- ♻️(core) fix typo in settings COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
- ♻️(backend) scope document search by document id instead of path

Fixed:
- 🐛(backend) prevent owner from leaving a soft-deleted document
- 🐛(frontend) fix removed item in the tree
- 🐛(frontend) fix service worker causing reload on tab focus
- 🐛(backend) update restore ability for inherited deletion
- 🔧(dev) make the dev stack domain-agnostic
- 🐛(frontend) stop force index redirect when delete doc
- 🐛(frontend) fix CTA on move modal on mobile

Removed:
- 🔥(backend) remove unused default authentication backend
2026-07-08 10:55:43 +02:00
AntoLCandAnthony LC 11f3dcb635 🌐(i18n) update translated strings
Update translated files with new translations
2026-07-08 09:34:59 +02:00
Manuel Raynaud 9ef4a15f5e ♻️(backend) scope document search by document id instead of path
The search in a document tree was triggered by the usage of the document
path. The path is something guessable by incrementing it you can
discover public documents. We decided to change this to use the document
id which is not guessable and prevent discovering public documents.
Thanks to @maboukerfa for discovering it.
2026-07-07 11:21:47 +02:00
Anthony LC 6a6154659f 💄(frontend) improve ui/ux before release
Following the recommendations of the design team,
we lightly improved some UI/UX elements to be
more consistent and user-friendly before the
next release.

It includes the following changes:
- add a background to the grid
- add a fadein to the header buttons
- reduce the generic size icon
- add a title to the doc item
2026-07-07 10:57:20 +02:00
Anthony LC 6a84430a4f 🔧(dev) make the dev stack domain-agnostic
Keycloak's hostname, its client's redirect/web
origins, and Django's CSRF trusted origins were
hardcoded to localhost, so the dev stack was
only reachable from that exact origin.
It is now possible to run the dev stack depending
what is configured in the env files.
2026-07-06 17:10:55 +02:00
Manuel Raynaud b01e6d58fd ♻️(core) fix typo in settings COLLABORATION_WS_NOT_CONNECTED_READY_ONLY
The settings COLLABORATION_WS_NOT_CONNECTED_READY_ONLY contains a typo.
We don't want to see READY_ONLY but READ_ONLY. This commit fix the typo
and change everywhere in the codebase the settings name.
2026-07-06 08:55:21 +02:00
Anthony LC c82ff199f1 ♻️(frontend) replace header by floating header
We replace the header by a floating header, to have more
space for the content and in fine to have more
harmony between the doc and the doc-grid, in mobile view
or not.
The layout have to be adapted, as well the legacy home
page.
2026-07-03 17:42:19 +02:00
Manuel RaynaudandGitHub debb253fa5 (backend) add management command to reset a Document
We need a management command to reset a Document to an initial state and
deletes everything related to it. This command can be usefull to reset a
demo for example.
2026-07-03 15:10:04 +00:00
Manuel RaynaudandGitHub 336d530014 🛂(backend) remove unused default authentication backend
The authentication backend
mozilla_django_oidc.contrib.drf.OIDCAuthentication
is present in the default authentication classes for the REST_FRAMEWORK
settings. This backend should not be used by our application and can
lead to the usage of our main api with an access_token instead of the
cookie session.
We need to override the drf SessionAuthentication backend to implement
the authenticate_header method. Without this, a 403 status code is
returned, but it is not valid. It must a be 401
2026-07-03 13:18:51 +00:00
Dakshesh JainandGitHub 6ec541f5cb 🐛(backend) update restore ability for inherited deletion
Updated the restore ability so that only directly deleted documents can
be restored. This prevents the restore action from being exposed for
child documents whose parent is deleted. This PR addresses #2127.
2026-06-30 10:01:07 +00:00
Amine BOUKERFAandGitHub 36dced1e56 🐛(backend) prevent owner from leaving a soft-deleted document
Owners could leave trashed documents via the leave endpoint, deleting
their `DocumentAccess` and all subtree access. When the last owner
leaves a document it creates an orphan as no owners remains in the doc.

Signed-off-by: BOUKERFA Mohamed El Amine <boukerfa.ma@gmail.com>
2026-06-29 13:04:04 +00:00
Cyril b05d220b7a (frontend) add support with mailto link in help menu
Add configurable support_mailto in theme customization to open
the user's email client from the help menu.
2026-06-23 13:38:28 +02:00
Cyril b9e4df7bd6 🔥(frontend) remove Crisp from the project
Remove Crisp chat SDK, provider, analytics, session management
and all related references across the codebase.
2026-06-23 13:37:50 +02:00
Cyril 31749b3051 ️(frontend) add configurable legal submenu in help menu
Expose legal page URLs in theme customization under help.legal_links.
2026-06-23 13:37:17 +02:00
Manuel Raynaud a8d67f34c4 🔖(minor) release 5.3.0
Added

- (backend) add limit on distinct reactions per comment #1978
- (frontend) leave a document #2410
- (frontend) add top parent on sub docs search #1952
- (frontend) unauthenticated users can search #2407
- (backend) specific user delete method to delete its relations #2437

Changed

- 👷(CI) remove test-e2e-other-browser job #2404
- ️(frontend) use heading element for pinned documents section title #2380
- ️(frontend) use anchor links for table of contents entries #2390
- ️(frontend) improve presenter mode screen reader and keyboard support #2383
- ️(frontend) link export modal name to its heading #2422

Fixed

- 🐛(frontend) overlap of block menu dropdown #2406
- ️(backend) fix N+1 queries when serializing thread comments #2415
2026-06-19 15:57:23 +02:00
github-actions[bot]andManuel Raynaud 1fa3aaa8ae 🌐(i18n) update translated strings
update translated strings
2026-06-19 15:57:22 +02:00
renovate[bot]andGitHub 87fbcbaceb ⬆️(dependencies) update PyJWT to v2.13.0 [SECURITY] 2026-06-19 12:28:35 +00:00
Manuel Raynaud 82013a84b6 ♻️(backend) change how a user is deleted in the admin
In the admin there were 2 ways to delete a user : by the actions select
box and the button on its change view. Both are leading to a failure. To
fix it, both way are removed and we implemented a custom action calling
the user.delete method with all the specific workflow we implemented.
2026-06-19 11:53:32 +02:00
Manuel Raynaud ed0dce66c5 (backend) specific user delete method to delete its relations
Deleting a user is not possible when it has created docs because the
on_delete on the Document class id RESTRICT and we don't want to change
it. We decided to have a specific workflow for correctly delete a user.
The document where the user is the sole owner must be deleted, the other
only the owner access must be deleted. For the remaining Documents where
the user is the creator, we set it to `null`, then the user can be
delete, remaining relations are deleted in cascade.
2026-06-19 11:53:32 +02:00
Manuel Raynaud b417a57418 ♻️(backend) use user_id instead of user relation in sharing module
In the sharing module, the user model was used instead of working with
the user id. Only the user id is used in this module, forcing in the
module calling this functions to load the user model for nothing and
doing a N+1 query.
2026-06-19 11:53:30 +02:00
Mohamed El Amine BOUKERFAandManuel Raynaud 51364e3d3c (frontend) add UI support for reaction limit on comments
Prevent users from adding more reactions once the per-message
limit has been exceeded. It Disables reaction buttons
when limit is reached

Signed-off-by: Mohamed El Amine BOUKERFA <boukerfa.ma@gmail.com>
2026-06-15 08:56:45 +02:00