Commit Graph
1114 Commits
Author SHA1 Message Date
Nicolas Clerc df47d3ccf9 (backend) add user reconciliation models
Merge an inactive account's content into the active one once both email
addresses are confirmed, so users keep a single account.
2026-05-27 17:36:47 +02:00
Nicolas Clerc fcf459d536 (backend) add generic send_email method on user model
The user reconciliation flow needs to send templated emails to users.
2026-05-27 08:02:08 +02:00
Nicolas Clerc 06d841c5a1 🔥(backend) drop deprecated numchild columns from item
The _deprecated_numchild and _deprecated_numchild_folder fields were
kept temporarily to preserve the underlying columns during the tree
model transition. The columns are no longer read or written, so the
fields and their columns can now be removed.
2026-05-26 09:25:17 +02:00
RolletQuentinandManuel Raynaud 3293ce5269 🐛(backend) replace VersionId by Etag for WOPI
When we try to get the VersionId from the s3 response
but this one is not send by the s3 storage (garage for example),
we get a 500 error.
To fix this issue we use the ETag sent by the object storage to track
the version id. This ETag is present also when versionning is not
implemented.

Co-authored-by: RolletQuentin <rolletquen@gmail.com>
2026-05-18 14:25:39 +02:00
renovate[bot]andNicolas Clerc 4ecc4d7a46 ⬆️(dependencies) update django to v5.2.14 [SECURITY] 2026-05-13 10:03:25 +02:00
Manuel Raynaud 90a5dff1f9 ⬆️(dependencies) update urllib3 to v2.7.0 [SECURITY]
Update to patch CVE CVE-2026-44431 and CVE-2026-44432
2026-05-12 15:02:51 +02:00
Nathan Vasse 74b0f84ea0 ♻️(frontend) move mime imports to ui-kit
Some imports were re exported from the mime type file. Let's
import directly from ui-kit.
2026-05-11 14:58:06 +02:00
Nathan Vasse 18d8b22eb7 📝(doc) update changelog
Update the changelog based on the recent commits about
file previewer.
2026-05-11 14:48:22 +02:00
Nathan Vasse 10d72079ae (frontend) replace per-format preview tests with smoke tests
Detailed FilePreview behavior is now covered by Playwright CT inside
the ui-kit repo, so the drive e2e suite only keeps integration smoke
checks: upload -> open -> render for PDF, image, video, audio, plus
prev/next navigation across files.
2026-05-06 17:19:45 +02:00
Nathan Vasse 3ddd7e5db5 ♻️(frontend) replace custom file preview with ui-kit FilePreview
The ui-kit ships a complete FilePreview (PDF, image, video, audio,
WOPI, error/unsupported, navigation, controls), so we drop the in-app
implementation under features/ui/preview/ and keep only a thin
CustomFilesPreview wrapper that maps Item to FilePreviewType, plugs
in the share modal, info sidebar and posthog event.

The WOPI editor is moved to its own features/wopi/ folder and
openWopiInNewTab now takes a FilePreviewType to match the ui-kit
onOpenInEditor callback. The file_preview translation block moves to
the ui-kit too.
2026-05-06 17:19:45 +02:00
Nathan Vasse b7d635b7bf ♻️(frontend) delegate file icons to ui-kit FileIcon
The ui-kit now ships FileIcon along with mime-category and icon-set
utilities, so we drop the local catalog (MIME_MAP, KNOWN_EXTENSIONS,
getMimeCategory, getIconByMimeType, FolderIcon, WorkspaceIcon) and
keep only the drive-specific extensions: folders and suspicious
uploads, exposed through getItemExtendedIcon. ItemIcon falls back to
ui-kit FileIcon for everything else.
2026-05-06 17:19:45 +02:00
Nathan Vasse d99116edb8 ⬆️(frontend) upgrade ui-kit version
Upgrade to the latest version that includes FileIcon, mimetype utils
and FilePreview.
2026-05-06 17:19:45 +02:00
Manuel Raynaud 9add4753d1 🔖(minor) bump release version 0.18.0
Added

- (backend) add organization metrics to usage API
- (backend) add entitlements context and can_upload reason
- (frontend) add entitlement disclaimer modal
- (frontend) render PDF previews at per-page dimensions

Fixed

- 🐛(backend) accept CDFV2 mimetype from newer libmagic
- 🐛(backend) better transaction management on duplicate action

Removed

- 🔥(backend) remove mirroring feature
v0.18.0-preprod v0.18.0
2026-05-04 16:47:06 +02:00
Nathan Vasse 6569287391 (backend) capture item_duplicate posthog event
Duplication is currently invisible to product analytics because the
event is fired from the API rather than the UI. Emit it from the
viewset right after the duplicate row is created so the duplicated
item context (workspace, mimetype, ...) is attached to the event.
2026-05-04 15:58:32 +02:00
Nathan Vasse 1e97297ae2 (frontend) capture column type change posthog event
Track when users customize their column layout so product can see
which columns get adopted vs ignored. The event carries the slot
plus old and new column types to support funnel analysis.
2026-05-04 15:49:53 +02:00
Nathan Vasse 4cc02f7959 (frontend) match event properties in posthog e2e helper
Asserting only on the event name is not enough when the same event is
emitted from multiple call sites with different payloads. Expose
expectEventSentWithProps so specs can pin down the expected slot or
context, and keep the captured properties available alongside the
existing names array.
2026-05-04 15:49:53 +02:00
Manuel Raynaud d6e27ba5a1 🔊(backend) log wopi max expected file size in get_file_content action
In the get_file_content action we want to log the received max expected
file size when this one is lower than the file size the user wants to
edit. This will help us to correctly configure the WOPI host.
2026-05-04 14:33:18 +02:00
e35549707c (settings) Allow configuring PKCE for the SSO
Co-Authored-by: Tom Hubrecht <github@mail.hubrecht.ovh>
2026-04-30 08:15:46 +02:00
Manuel Raynaud 68abb54dbb 🐛(backend) better transaction management on duplicate action
On the duplicate action we are using the decorator @transaction.atomic
to be sure that the duplicated item and its accesses are correctly
created. The problem with that is that the celery task doing the file
duplication on the object storage can be executed before the transaction
is commited leading to an error saying that the duplicated_item does not
exists.
2026-04-29 22:07:56 +02:00
Nathan Vasse 6049113dfe 🐛(backend) accept CDFV2 mimetype from newer libmagic
Scalingo's Ubuntu runtime ships a newer libmagic that returns
application/CDFV2 for legacy .doc/.xls/.ppt files, where Alpine's
older libmagic (used in our Docker image) returns the older label
application/x-ole-storage. Both describe the same OLE2 / Composite
Document File V2 container.

detect_mimetype() already treats application/x-ole-storage as a
generic content-detection result and falls back to extension-based
detection (yielding application/msword, application/vnd.ms-excel,
etc.). Without the same handling for CDFV2, legacy .doc uploads on
Scalingo are rejected by the mimetype allow-list with
"mimetype not allowed application/CDFV2 for filename ...".
2026-04-29 12:15:02 +02:00
Nathan Vasse 7a95dcf38a 📝(doc) update changelog
Fix the mis-added entries inside the previous release back to
the unreleased one. And add new entry for the pdf mixed pages
size rendering.
2026-04-29 11:37:08 +02:00
Nathan Vasse 679805b244 (frontend) add e2e tests for mixed PDF page sizes
Cover the per-page-dimensions path with a 17-page fixture
spanning portrait, landscape, square, wide-banner and tall-strip
ratios. Asserts that rendered pages and thumbnails match each
page's real aspect ratio, that page-input jumps land precisely
across mixed ratios, and that the virtual-list total height
matches the sum of per-page heights.
2026-04-29 11:02:53 +02:00
Nathan Vasse 7c17132f8e (frontend) render PDF previews at per-page dimensions
Pages were laid out with a hardcoded A4 portrait ratio, so
landscape, square and extreme-ratio pages rendered with wrong
row heights and page-input jumps could land on a neighbour.

A new usePdfPageDimensions hook lazily fetches each page's
viewport from pdfjs and dedupes concurrent requests. The main
viewer and thumbnail sidebar now size rows from the cache and
fall back to A4 only until real dimensions arrive. Page-input
jumps await the prefix's dimensions before computing the scroll
offset so the viewport center lands inside the requested page.
2026-04-29 11:02:53 +02:00
Nathan Vasse 59292f6052 📝(doc) update changelog
Record the metrics filter, entitlement payload additions, and the
frontend disclaimer feature shipped on this branch, alongside the
already-landed organization metrics entry.
2026-04-29 10:39:31 +02:00
Nathan Vasse 019016865a (frontend) add e2e tests for entitlement disclaimers
Cover visibility rules (enabled / disabled / flagged reasons), the
seen-flag lifecycle, the showPotentialOperators branch with and
without signupUrl, and the OK-click close interaction.
2026-04-29 10:39:31 +02:00
Nathan Vasse ef675df5a2 (frontend) add entitlement disclaimer modal
Show a one-shot modal when the user's can_upload is blocked for a
recoverable reason (not_activated / no_organization), with an optional
list of potential operators where they can self-register. Tracks
"seen" per disclaimer in localStorage so users are not nagged on
every load, but re-shows the disclaimer if the underlying entitlement
changes and then regresses.
2026-04-29 10:26:54 +02:00
Nathan Vasse 6a19b0922e (frontend) type entitlement reason and context
Type the new backend fields (\`can_upload.reason\`, \`context\`) and
the new \`FRONTEND_ENTITLEMENTS_DISCLAIMERS\` config key so downstream
components can consume them with no casts.
2026-04-29 10:17:25 +02:00
Nathan Vasse ba4558e1ca (backend) expose FRONTEND_ENTITLEMENTS_DISCLAIMERS config
Add a dict-shaped config exposed to the frontend so operators can
enable or disable entitlement disclaimers per reason without code
changes. Also pin the Test settings to the local entitlements backend
so test runs do not depend on external state.
2026-04-29 10:17:25 +02:00
Nathan Vasse aa099068e9 (backend) add organization metrics to usage API
Add account_type=organization support to the usage metrics
endpoint. When requested, the API filters users by a shared
OIDC claim (account_id_key/account_id_value) and returns
aggregated storage across all matching users.

Add handling of account_id_key/account_id_value pair, allowing
filtering on allowed parameters in a more generic way. At the
moment `account_email` filter is still needed.

Also include the context of the entitlement in the /entitlements
response.
2026-04-29 10:17:25 +02:00
Nathan Vasse 8360aeca88 ♻️(backend) accept a queryset in storage compute backend
Change compute_storage_used signature from a single user
to a queryset of users. This enables aggregating storage
usage across multiple users, which is needed for
organization-level metrics.
2026-04-29 10:17:25 +02:00
Nathan Vasse 62b8341dd7 ♻️(backend) refactor entitlements into backend package
Restructure the entitlements module from flat files into a
backends/ package with a factory pattern. This enables
constructor kwargs injection for backend configuration.

Rename ANCT backend to DeployCenter to match the actual
service name, and rename Dummy backend to Static for clarity.
The factory now passes ENTITLEMENTS_BACKEND_PARAMETERS to
the backend constructor, making configuration more explicit
and testable.

Some request parameters get updated because of changes on
deploy center side that need to be reflected in services.
2026-04-29 10:17:25 +02:00
renovate[bot]andGitHub 39963b1332 ⬆️(dependencies) update python dependencies 2026-04-27 02:11:45 +00:00
Manuel Raynaud 805ef77521 🔥(backend) remove mirroring feature
The mirroring feature was hard to maintain and not performant. We should
rely on external tools made for that like RClone.
2026-04-23 17:42:48 +02:00
Manuel Raynaud 3ca5b0e296 🔖(minor) bump release version 0.17.0
Added

- (backend) make invitation validity duration configurable via env var
- (frontend) enhance upload toast with progress, errors and cancel support
- (frontend) add ErrorIcon component and support numeric icon sizes
- (frontend) make file upload abortable in driver layer
- (frontend) files preview v2
- 🔧(project) add DJANGO_EMAIL_URL_APP environment variable

Fixed

- 🐛(frontend) add actions menu on mobile My Files page
- 🐛(frontend) show actual selection count in hard delete modal
- 🐛(frontend) Responsive broken with long filters in search #659
- 🐛(front) set size and variant on trash navigate modal #666
- 🐛(frontend) fix uploads continuing after parent folder deletion
- 🐛(frontend) fix SDK picker link reach promotion
- 🐛(backend) route share invitation link to file view for files
- 🐛(frontend) fix "+ New" menu in read-only folders and virtual tabs
- 🐛(frontend) range selection freezes when there are many items in the list
- 🐛(backend) fix openapi schema for item access endpoints
- 🐛(backend) load jwks url when OIDC_RS_PRIVATE_KEY_STR is set
v0.17.0-preprod v0.17.0
2026-04-23 15:43:49 +02:00
Nathan Panchout 3731033f5b 🔧(project) add DJANGO_EMAIL_URL_APP environment variable
Share invitation emails embedded `Site.domain` directly, producing
schemeless links that mail clients failed to resolve. Introduce a
`DJANGO_EMAIL_URL_APP` environment variable holding the app's
absolute URL used when building invitation links, with a fallback
on the current Site domain when unset. Wire it in dev env, helm
dev values, the helm example and the env reference.
2026-04-23 12:05:26 +02:00
Nathan Panchout af8ba1031f 🐛(backend) route share invitation link to file view for files
Clicking the invitation link for a shared file opened the folder
explorer page with an empty children listing, because
`Item.send_email` hardcoded `/explorer/items/<uuid>/` regardless of
the item type.

Branch on `item.type` to use the dedicated file route
`/explorer/items/files/<uuid>/` already served by nginx and used by
the in-app share-link copy button.
2026-04-23 12:05:23 +02:00
Nathan Vasse 77a67db6d8 (frontend) add e2e tests for SDK picker selection
Cover the two main picker outcomes: cancelling leaves the item
private, and confirming exposes a publicly reachable URL. The
reach check opens the returned URL in a fresh anonymous context
and waits for the download event, since the backend serves
attachments with Content-Disposition and navigation aborts.

To run the test in CI, build the drive SDK package and start the
sdk-consumer dev server before the playwright job.
2026-04-22 16:00:15 +02:00
Nathan Vasse a12771fe08 🐛(frontend) fix SDK picker link reach promotion
Switch to useMutationUpdateLinkConfiguration and preserve the
item's existing link_role. Also add the missing sdk.explorer.cancel
translations for en and nl so the Cancel button label renders
correctly. This should have been done when migration to this new
API route. The existing update did not have any effect.
2026-04-22 16:00:15 +02:00
Manuel Raynaud d120171944 🐛(backend) load jwks url when OIDC_RS_PRIVATE_KEY_STR is set
When the resource server is enabled and the backend used is
JWTResourceServerBackend, then the API should expose a JWKS endpoint
to share the RSA public key to the OIDC provider. Everything is made
in the Django LaSuite library, but the URL is not included in the
Drive URLs. This commit adds it when the setting OIDC_RS_PRIVATE_KEY_STR
is set.
2026-04-22 13:37:30 +02:00
renovate[bot]andGitHub d3cb848448 ⬆️(dependencies) update pytest to v9.0.3 [SECURITY] 2026-04-22 10:22:45 +00:00
Nathan Vasse 352e19580e (backend) make invitation validity duration configurable via env
The invitation validity duration was hardcoded to 7 days. Expose it as
an INVITATION_VALIDITY_DURATION env var so operators can tune it per
deployment without patching settings. Default remains 7 days.
2026-04-22 10:09:31 +02:00
renovate[bot]andNathan Vasse 6cc9c4de9c ⬆️(dependencies) update vite to v6.4.2 [SECURITY] 2026-04-21 14:38:00 +02:00
renovate[bot]andNathan Vasse bb1a018e21 ⬆️(dependencies) update next to v15.5.15 [SECURITY] 2026-04-21 11:48:51 +02:00
Nathan Vasse 6655b8fbe8 🐛(backend) fix openapi schema for item access endpoints
`ItemAccessViewSet.get_serializer_class` depends on `self.item`, which
reads `self.kwargs["resource_id"]`. This is unavailable during
drf-spectacular introspection, so spectacular fails to resolve the
serializer and drops the requestBody for POST/PUT/PATCH operations.

Declare the schema statically via `@extend_schema` and
`@extend_schema_view` so the generated OpenAPI exposes the proper
request and response payloads for item access endpoints.
2026-04-21 10:24:18 +02:00
Nathan Panchout 5966e14c46 🐛(frontend) fix range selection freeze on large folders
Drop selectedItems / selectedItemsMap from GlobalExplorerContext and
move every call-site to the selection store introduced in the previous
commit. Rows of the embedded explorer grid are extracted into a memoed
EmbeddedExplorerGridRow that subscribes to its own id via
useIsItemSelected, and the name/actions/mobile cells are memoed and
read their selection status the same way.

High-level consumers that only need a boolean or a count use
useHasSelection / useSelectionCount so they no longer re-render on
every marquee tick:

- AppExplorerInner uses useHasSelection to toggle the selection bar
- ExplorerDndProvider splits the count consumers into dedicated child
  components (drag overlay and move confirmation modal)
- useTableKeyboardNavigation subscribes imperatively through
  selectionStore.subscribe so the focus effect runs without
  invalidating the host component

EmbeddedExplorer creates its own local store so the move modal and the
SDK picker keep their selection scoped and do not leak into the main
explorer selection.

Fixes #124
2026-04-20 17:09:53 +02:00
Nathan Panchout 3bae4e7d3b (frontend) add explorer selection store with per-id listeners
Introduce a lightweight external store compatible with
useSyncExternalStore. It exposes:

- a global subscription for consumers that need the full list or count
- per-id subscriptions so a row can bail out automatically when its own
  isSelected boolean has not changed
- setSelectedItems that diffs the previous and next id maps and
  notifies only the listeners whose status actually flipped

No React state, no context fan-out: a marquee tick that flips N rows
notifies exactly N listeners instead of invalidating the whole tree.
2026-04-20 17:09:53 +02:00
Nathan Panchout 3a730b87cf 📝(frontend) document explorer selection store architecture
Add an architecture doc covering the rationale behind the selection
store refactor: why React Context did not scale to 200+ rows during a
marquee drag, why useSyncExternalStore with per-id listeners enables
automatic bailout, and how global vs embedded scopes are wired.

Lives under docs/architecture/ for long-term reference.
2026-04-20 17:09:53 +02:00
Nathan Panchout 7ef7d56317 (front) add e2e tests for "+ New" fallback to My Files
Cover the four scenarios of the new "+ New" behavior:
- folder creation from a read-only shared folder redirects into the
  newly created folder under My Files
- document creation from a read-only shared folder redirects to the
  My Files view with the new file listed
- folder creation from the Recent / Shared with me / Starred virtual
  tabs creates in My Files
- folder creation in a writable folder still happens in place, with
  no fallback redirect
2026-04-20 15:58:53 +02:00
Nathan Panchout faee0de673 🐛(front) fix "+ New" menu in read-only folders and virtual tabs
The "+ New" dropdown used to hide all its entries when the user lacked
children_create on the current folder, leaving an empty popover. On
virtual tabs (Recent, My Files, Shared with me, Starred) there is no
real current folder either, so the same empty state could be reached.

Always populate the menu and, when the user cannot create in place,
fall back to creating the item in "My Files" (no parent). After a
fallback creation we redirect:
- into the new folder for folder creation
- to the My Files view for file creation, since a file is not a
  navigable route
The new item is pre-selected in both cases.
2026-04-20 15:58:53 +02:00
Nathan Vasse 26a522f2ae 🔧(ci) exclude ts file from print job
This job was detecting some legit code as false positive
for print statements.
2026-04-20 15:21:01 +02:00