51 Commits

Author SHA1 Message Date
Edouard Vanbelle 7918fff47b refactor(msg-bus): prefer MessageBus as Realtime 2026-09-11 00:28:04 +02:00
Edouard Vanbelle 1d280c161c feat(asyncapi): generate ts types according asyncapi 2026-09-10 21:50:15 +02:00
Edouard Vanbelle a2d27a61fe test(message-bus): test basic scenario
use a helper to run scenario in hurl like style
2026-09-10 01:13:33 +02:00
Edouard Vanbelle 5c956c9bde feat(bundled-binary): add a test 2026-08-29 11:57:48 +02:00
Edouard Vanbelle 390aa31443 feat(cli): merge oxicloud binary and cli
this feature to simplify the creation of only 1 binary for multiple architecture
2026-08-29 11:57:48 +02:00
Edouard Vanbelle a99a6806b5 ci: always build main branch into docker with main label
purpose is to let users test before waiting any new tag

note: build will occurs only on AtalayaLabs repos or if ENABLE_DOCKER_PUBLISH is true
2026-08-26 22:11:39 +02:00
Edouard Vanbelle 9e94cb398c test(dpop): OPAQUE + DPOP required for e2e tests 2026-08-09 12:31:39 +02:00
Edouard Vanbelle 6a5b8980ae chore(migration): update the migration timestamp 2026-08-04 07:18:40 +02:00
Edouard Vanbelle 921cbef152 test(oidc): test back-channel logout 2026-08-03 22:26:43 +02:00
Edouard Vanbelle 7663f803d3 fix: fix services accessig directly to localstorage
Prevent services accessing directly to localstorage and prefer using an astraction layer
to expose full blob. The abstraction layer (dedup services) will cover backend storage
election (local, s3, ...), encryption, etc

This change permit audio_metadata_service, media_metadaa_service, face_indexing_service to handle
blobs without worring of the backend.

note: prefered way to handle blob is the streamed way. Some services may not have this possibility
2026-08-02 22:20:46 +02:00
Dionisio Pozo 8ba2d81297 Merge pull request #651 from EdouardVanbelle/feat/recoverable-jobs
feat(recoverable jobs): add engine + consistency jobs
2026-07-30 10:30:39 +02:00
Edouard Vanbelle 394708c9a1 feat(recov. job): add drive consistency service 2026-07-29 01:25:15 +02:00
Edouard Vanbelle 2315a54154 ci: add protection on merge and db migration
this is a protection to prevent the merge of any branch adding a database
migration with an timestamp earlier than the current targetted branch
2026-07-28 22:07:45 +02:00
Bradley Nelson 9f4bc54113 Merge upstream/main into feat/external-file-mounts
Resolve conflicts between the external-file-mounts feature and upstream's
D5/D7 refactor (per-file provenance, keyset pagination, cross-drive move
gates, resource-access hook, folder-cascade lifecycle hook).

Key resolutions:
- FolderService::new now takes (repo, authz, file_lifecycle, mount_router);
  all callers + DI updated.
- FileRetrievalService / FileManagementService keep both the mount_router
  and the new resource_access_hook / drive_repo / storage_usage wiring.
- list_files_batch_with_perms: adapt the mount branch from offset- to
  keyset (after_name) pagination, mirroring paginate_mount_entries.
- download_file_impl: keep upstream's &HeaderMap + `impl IntoResponse + use<>`
  signature, retain the mount-download branch.
- Mount DTOs: the retired `owner_id` field maps onto created_by/updated_by
  (the mount owner) — the fields the frontend now uses for owner display.
- admin/+page.svelte: keep upstream's user-delete modal + the 'mounts' tab.
- Bump memmap2 0.9.10 -> 0.9.11 (RUSTSEC critical advisory fix) and
  regenerate Cargo.lock against the merged Cargo.toml.
2026-07-21 17:09:36 -06:00
M.Schmidt 6215f37bf6 fix: dedupe IdP auto-redirect and fix CSP/bfcache bug on the SPA shell
- Extract tryAutoRedirectToIdp() on the login page so onMount's redirect
  guard and the post-setup flow share one check instead of drifting.
- Fix a real bug: 304 Not Modified responses carry no Content-Type, so
  is_html misclassified them and attached the strict headerless CSP,
  which browsers merge into the cached 200's effective headers and
  defeat the SPA's hash-based CSP on revalidated repeat visits.
- Add Cache-Control: no-store on the SPA shell to opt out of bfcache,
  preventing a pre-deploy shell (stale inline hydration script + CSP
  hash) from being resurrected byte-for-byte across the OIDC redirect's
  full-page navigations.
- Add a manual, human-run SSO-only script/env (ports 8090/1081) since
  the automated oidc.hurl suite keeps password login enabled and never
  exercises the auto-redirect guard.
2026-07-16 23:16:22 +02:00
Edouard Vanbelle 7de83de0a9 chore(ci): wire caldav/carddav test suite 2026-07-15 07:55:31 +02:00
Edouard Vanbelle a9e05ec47c test: full caldav + carddav test suite 2026-07-14 22:01:31 +02:00
Edouard Vanbelle 0296d157a3 chore: remove deprecated playwright wrapped 2026-07-13 21:21:26 +02:00
Edouard Vanbelle 7e34045ff8 feat(drive): fix webdav back-compat
add env variable `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX`
    which is by default:
    `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX="@drive"`

    so `/webdav/` -> points to user's personal drive (**backward compatibilit**y)
    `/web/dav/@drive/{uuid|drive name}/` points to the respective drive

    if admins want directly `/webdav/` pointing to list of drives they need to:
    `OXICLOUD_WEBDAV_DRIVE_LISTING_PREFIX=""`

    + ensure lock is per user (RFC 4918 §9.11)

    fix: #554
2026-07-06 22:14:50 +02:00
Edouard Vanbelle f2dc567bcd chore(justfile): api-test: add litmus webdav
play listmus webdav test only if found locally
2026-06-30 23:21:28 +02:00
Edouard Vanbelle ada4b021bf test(oidc): test OIDC login and refresh flow
- ensure Oxicloud s correctly functional with OIDC login
    - refresh token works
    - givenname, familyname, picture are imported in users' informations
    - test relogin (server is not using same path)
    - test email verified
    - test admin group provided from IdP
2026-06-28 23:22:37 +02:00
Bradley Nelson 94e5aec4af test(mounts): cover download range logic + add just coverage recipe
- Extract the WebDAV/REST mount-download Range decision (parse + validate +
  satisfiable) into a pure `plan_mount_range`, unit-tested across no-range,
  malformed, inclusive, open-ended, suffix, and out-of-bounds cases. This was
  the one untested branch of `download_mount_file` (its I/O deps are already
  integration-covered).
- Add `just coverage [filter]` and `just coverage-integration [filter]`
  recipes wrapping cargo-llvm-cov (HTML + summary; integration variant adds
  the testcontainers tests).
2026-06-25 01:11:45 -06:00
Bradley Nelson e3823ce470 test(e2e): Playwright + Vitest coverage harness and test instrumentation
Add an end-to-end and unit test suite for the SvelteKit frontend:

- Playwright e2e specs (tests/e2e/spa) with a throwaway container stack,
  codegen scenarios, and an Istanbul-based coverage report pipeline.
- Vitest unit tests across API endpoints, components, stores and composables.
- `data-testid` hooks on interactive elements (AppShell, FileViewer,
  ShareDialog, search, photos, files breadcrumbs, login/Nextcloud flows,
  public share pages) so the e2e suite can target them deterministically.
- Serve the SPA app-shell CSP from a <meta> policy (svelte.config.js) plus a
  middleware that skips the CSP header on HTML; move the Nextcloud Login Flow
  v2 grant page to the SvelteKit /nextcloud/login route.
- `just front-codegen` recipe and start-server-spa.sh harness.

Make the test environment robust and consistent:
- Install a deterministic in-memory localStorage/sessionStorage in the Vitest
  setup so storage behaves identically across Node versions (Node 26 ships a
  native Web Storage global that otherwise shadows jsdom's).
- Pin devenv to Node 26 + PostgreSQL 18 and pin every CI job to Node 26.3.0
  so the dev shell and CI run the same toolchain versions.

Repair the API/WebDAV (hurl) suite, which had drifted from the backend:
- Migrate the removed `/api/folders/{id}/listing` endpoint to `/resources`
  (cursor-paginated `{items:[{resource_type,resource}]}` shape) across the
  batch-copy, grants, nested-group, and WebDAV NC tests + the dav_helpers
  wipe routine.
- Stop photos_etag from uploading the dedup-tracked fixture so the dedup
  blob-lifecycle test can own its content-addressed blob exclusively.
- dedup_create now asserts the idempotent same-content re-upload (201 +
  existing file id) instead of the stale 409 expectation.

Generated coverage reports, nyc output and the e2e server runtime data dir
are gitignored rather than committed.
2026-06-22 00:05:06 -06:00
DioCrafts 54639d466a chore(frontend): remove the legacy vanilla-JS frontend and its tooling
The SvelteKit app under /frontend has fully superseded the legacy
vanilla-JS/CSS frontend in /static, which was only ever served by a
debug `cargo run` / `PROFILE=dev` and never shipped to production.
Remove it together with the whole subsystem that existed only to
support it (~54k lines).

Frontend & assets:
- Delete /static (js/, css/, *.html, sw.js, basemaps/, locales symlink).
- Relocate the brand/PWA assets (logo/, favicon.ico, manifest.webmanifest)
  to frontend/static/ so they ship with the SPA. This also fixes the
  favicon, which app.html referenced but was missing from the prod bundle.
- Migrate the Nextcloud login-flow redirects from /nextcloud-error.html
  to the SvelteKit /nextcloud/error route.

Web layer:
- Simplify resolve_static_path: drop the PROFILE=dev branch; always prefer
  the Vite static-dist/ build, fall back to the configured path.
- Resolve i18n locales from the served SPA dir with a frontend/static
  fallback so `just dev` works without a prior build.

Build:
- Prune build.rs from 1262 to ~70 lines (git metadata only); the Rust asset
  pipeline and the OXICLOUD_RUST_ASSETS rollback flag are gone.
- Drop the now-unused build-dependencies (oxc_*, lightningcss).
- Remove the COPY static lines from the Dockerfile (cacher + builder).

Tooling & docs:
- Delete biome.json, jsconfig.json, tools/check-*.py, identifier.sh.
- Remove the legacy front-* justfile recipes; repoint the design-system
  scripts (locales, dead-tokens, brand-drift, token-docs) at the frontend,
  and drop check-contrast/check-headings (coupled to the old token
  taxonomy / multi-page HTML).
- Repoint docs/DESIGN-SYSTEM.md links; remove 5 superseded docs/plan/*.

Backend dead code:
- Remove the dead `folder_repo` field from FileBlobWriteRepository.
- Remove the deprecated GET /api/folders/{id}/listing endpoint
  (superseded by /resources).

Verified: cargo clippy (all-features/all-targets) clean, cargo test
--workspace 448 passed, cargo fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 03:20:10 +02:00
Edouard Vanbelle 14b63c9bd9 chore(ci): use same pg version 18 2026-06-19 16:06:38 +02:00
Claude 047e0f06ff Merge main (Photos/People/Places + ReBAC) into the SvelteKit rewrite
Bring the feature-rich main branch into the frontend Svelte rewrite
(PR #478, base bcn/frontend-svelte-rewrite). main moved well ahead of the
PR's branch point (b8a0018): it added the Places photo-map and People
(faces) backends, photos enhancements, the ReBAC→role-grants migration,
load tests, and more.

Conflicts resolved (4 files):
- Dockerfile: combine the explicit --bin allowlist (defence-in-depth from
  main) with the SPA copy from the frontend build stage (PR).
- .github/workflows/ci.yml: keep the PR's Svelte frontend job
  (svelte-check + eslint + stylelint + prettier + vitest); the legacy
  static/-targeted tsc/locale/icon advisory steps don't fit the new
  working-directory: frontend job and svelte-check supersedes them.
- justfile: keep both the new fe-* / dev recipes (PR) and the load-* k6
  recipes (main).
- static/locales: keep the PR's symlink (-> ../frontend/static/locales);
  main's new photos/people locale keys are folded into the Svelte locale
  files alongside the ported views.

Backend (people/places/faces handlers, routes, DI, migrations) merged
cleanly. `cargo check --bins` passes. The new Places/People UI is not yet
in the Svelte app; that is ported in follow-up commits.
2026-06-19 12:45:22 +00:00
Edouard Vanbelle 0ef4c624c5 chore(load): start implementation of load tests
initial test from Ed's nuc:

    metric                                          pctl  baseline    current     delta    status
    -----------------------------------------------------------------------------------------------
    folder_cascade.list_depth1                      p50   0.3ms       0.3ms       -6.3%    ok
    folder_cascade.list_depth1                      p95   2.3ms       0.5ms       -75.7%   ok
    folder_cascade.list_depth1                      p99   4.7ms       2.5ms       -48.1%   ok
    folder_cascade.list_depth4                      p50   0.4ms       0.3ms       -10.0%   ok
    folder_cascade.list_depth4                      p95   0.9ms       0.6ms       -31.2%   ok
    folder_cascade.list_depth4                      p99   2.4ms       1.0ms       -56.7%   ok
    folder_cascade.list_depth8                      p50   0.3ms       0.3ms       -8.8%    ok
    folder_cascade.list_depth8                      p95   0.6ms       0.5ms       -22.2%   ok
    folder_cascade.list_depth8                      p99   1.9ms       0.5ms       -71.5%   ok
    folder_cascade.list_depth_deep                  p50   0.3ms       0.3ms       -5.0%    ok
    folder_cascade.list_depth_deep                  p95   0.6ms       0.5ms       -18.6%   ok
    folder_cascade.list_depth_deep                  p99   2.0ms       0.7ms       -67.2%   ok
    share_cascade_rebac.list_grants                 p50   0.4ms       0.3ms       -27.6%   ok
    share_cascade_rebac.list_grants                 p95   1.2ms       0.5ms       -57.0%   ok
    share_cascade_rebac.list_grants                 p99   1.7ms       1.1ms       -36.7%   ok
    share_cascade_rebac.fetch_as_grantee_depth1     p50   0.5ms       0.5ms       -11.1%   ok
    share_cascade_rebac.fetch_as_grantee_depth1     p95   1.1ms       0.7ms       -41.2%   ok
    share_cascade_rebac.fetch_as_grantee_depth1     p99   3.0ms       1.3ms       -58.3%   ok
    share_cascade_rebac.fetch_as_grantee_depth4     p50   0.5ms       0.5ms       -13.7%   ok
    share_cascade_rebac.fetch_as_grantee_depth4     p95   1.4ms       0.7ms       -50.5%   ok
    share_cascade_rebac.fetch_as_grantee_depth4     p99   2.2ms       1.1ms       -49.3%   ok
    share_cascade_rebac.fetch_as_grantee_depth8     p50   0.5ms       0.4ms       -16.0%   ok
    share_cascade_rebac.fetch_as_grantee_depth8     p95   0.9ms       0.7ms       -26.1%   ok
    share_cascade_rebac.fetch_as_grantee_depth8     p99   1.5ms       0.9ms       -40.1%   ok
    share_cascade_rebac.fetch_as_grantee_depth_deep p50   0.5ms       0.4ms       -17.3%   ok
    share_cascade_rebac.fetch_as_grantee_depth_deep p95   1.0ms       0.7ms       -31.2%   ok
    share_cascade_rebac.fetch_as_grantee_depth_deep p99   1.6ms       0.8ms       -49.4%   ok
    subject_group_nested.fetch_as_member_depth1     p50   0.5ms       0.4ms       -8.4%    ok
    subject_group_nested.fetch_as_member_depth1     p95   0.6ms       0.6ms       -10.2%   ok
    subject_group_nested.fetch_as_member_depth1     p99   1.4ms       0.6ms       -55.2%   ok
    subject_group_nested.fetch_as_member_depth4     p50   0.5ms       0.5ms       -7.9%    ok
    subject_group_nested.fetch_as_member_depth4     p95   0.6ms       0.6ms       -4.0%    ok
    subject_group_nested.fetch_as_member_depth4     p99   0.7ms       0.6ms       -2.2%    ok
    subject_group_nested.fetch_as_member_depth8     p50   0.5ms       0.4ms       -8.9%    ok
    subject_group_nested.fetch_as_member_depth8     p95   0.5ms       0.6ms       +7.1%    ok
    subject_group_nested.fetch_as_member_depth8     p99   0.6ms       0.7ms       +10.3%   ok
    subject_group_nested.fetch_as_member_depth_deep p50   0.5ms       0.4ms       -7.6%    ok
    subject_group_nested.fetch_as_member_depth_deep p95   0.6ms       0.5ms       -11.9%   ok
    subject_group_nested.fetch_as_member_depth_deep p99   0.6ms       0.7ms       +8.9%    ok
2026-06-18 09:38:25 +02:00
Bradley Nelson 89e14f8f9e visual continunity 2026-06-17 22:07:18 -06:00
Bradley Nelson daa3010458 init new frontend 2026-06-17 17:06:30 -06:00
Bradley Nelson 803150635c add frontend 2026-06-16 21:26:36 -06:00
Bradley Nelson 87d68c5b6f init plugins 2026-06-16 17:57:57 -06:00
Edouard Vanbelle f55779875a chore(justfile): bring design system check into front-test 2026-06-16 15:31:23 +02:00
Edouard Vanbelle b1455b5583 chore(wasm): check, clippy, test, CI 2026-06-15 15:53:43 +02:00
DioCrafts 81a93a489b feat: photo/video capture-date pipeline + premium UI/UX overhaul
Backend — Photos timeline now groups by real capture date instead of upload time. New MediaMetadataService (FileLifecycleHook) extracts EXIF DateTimeOriginal from images and container creation_time from videos (mov/mp4/mkv) via nom-exif, timezone-correct (OffsetTimeOriginal), persisting captured_at so the existing media_sort_date trigger takes over. Adds POST /admin/photos/metadata/reextract to backfill existing media. Falls back to upload date when no embedded date exists.

Frontend — premium grid cards: combined metadata line (relative date · size, owner avatar when shared), custom selection checkbox with a clear checked state, uniform full-width 4:3 thumbnail tiles independent of filename length, centered file-type icons, and a hit-test fix so checkbox/star/kebab clicks reach the controls (the decorative thumbnail no longer captures pointer events). Notification messages internationalised across all 16 locales. Broader polish: design tokens, a11y/focus-visible states, brand + PWA assets.

Chore — bump semver-compatible dependencies (cargo upgrade); add nom-exif 3.6.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 00:24:27 +02:00
Edouard Vanbelle 8b08b081c5 chore(ci): check icons and i18n 2026-06-05 14:18:41 +02:00
Edouard Vanbelle d2dedcbb00 fix(integration-test): ensure integration tests are runned on a separate DB to avoid polution 2026-05-31 23:53:40 +02:00
Edouard Vanbelle e169f53218 test(integration): add integration test on subject group 2026-05-31 22:45:09 +02:00
Edouard Vanbelle 804cb7c6af fix(build): improve builder to use CSS from html rather an hardcoded list 2026-05-29 13:48:22 +02:00
Edouard Vanbelle 7ddbbc94cc test(e2e): update all images and grow snapshot comparaison sensitivity 2026-05-27 11:35:42 +02:00
Edouard Vanbelle 80425aed03 chore(justfile): add 'front-check' for lazy devs 2026-05-25 22:47:01 +02:00
Edouard Vanbelle a181d4081e ci: add typescript check (no emit, check only types are fully declared) 2026-05-19 10:18:40 +02:00
Edouard Vanbelle fac184ccfe style(front/js): apply types on all objects
- reduce amount of warnings in IDE
    - maximize API type mapping with static/js/core/types.js
2026-05-19 10:18:33 +02:00
Edouard Vanbelle f7946028f4 tests: add webdav tests 2026-05-13 15:55:34 +02:00
Edouard Vanbelle 8ab537797a test(api): add API test on contacts
next will be to add CI on it
2026-05-11 00:53:29 +02:00
Edouard Vanbelle 3c3d24ac72 test: initial end to end test with playwright 2026-05-08 21:41:28 +02:00
Edouard Vanbelle 46e823ffda chore: move specific CI audit rules into global .cargo/audit.toml 2026-05-04 14:23:01 +02:00
Edouard Vanbelle fde8d9d69f chore: add audit in justfile 2026-05-04 14:01:00 +02:00
Edouard Vanbelle 3a315ae75d chore(rust): use same params for clippy as the CI + correct clippy warnings 2026-04-27 20:25:33 +02:00
Edouard Vanbelle d01b2c6ec4 refactor(css): use variable rather direct color 2026-04-14 13:33:51 +02:00
Edouard Vanbelle 4fbb8883af chore(claude): add frontend part to CLAUDE.md + .claudeignore for security 2026-04-08 16:25:46 +02:00