Edouard Vanbelle
dfb21b746d
feat(openapi): show explicitly path requiring bearerAuth
2026-05-28 00:48:20 +02:00
Edouard Vanbelle
eb95567a7d
feat(authz): test & cover batch cases
...
┌────────────────────────────────┬─────────────────────────────────┬───────────────────────┬─────────────────┬──────────────────────────────┐
│ Endpoint │ Phase 3A no-grant │ Phase 3B Viewer │ Phase 3C Editor │ Phase 3D Admin │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/files/get │ 400 (all failed) │ 200 (2 successful) │ — │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/files/move │ 400 │ 400 (no Update) │ 200 │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/files/copy │ 400 │ — │ 200 │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/files/delete │ 400 │ 400 │ 400 (no Delete) │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/folders/get │ 400 │ 200 │ — │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/folders/create │ 400 │ — │ 201 │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/folders/move │ 400 │ — │ 200 │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/folders/copy │ 400 │ — │ 200 │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/folders/delete │ 400 │ — │ 400 (no Delete) │ 200 │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/trash │ 400 │ — │ — │ 400 (owner-only, documented) │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ POST /api/batch/download │ 404 (NotFound) │ 200 + application/zip │ — │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ GET /api/batch/download?... │ 404 │ 200 + zip │ — │ — │
├────────────────────────────────┼─────────────────────────────────┼───────────────────────┼─────────────────┼──────────────────────────────┤
│ Phase 3E lifecycle cleanup │ grants table empty after delete │ │ │ │
└────────────────────────────────┴─────────────────────────────────┴───────────────────────┴─────────────────┴──────────────────────────────┘
2026-05-21 20:30:58 +02:00
Edouard Vanbelle
2f49daa4ee
feat(folders): implement copy_folders taking care of ownership
2026-05-12 00:22:51 +02:00
Edouard Vanbelle
0cb641ab20
feat(openapi): add new entry used by drag & drop
2026-05-04 22:41:29 +02:00
Edouard Vanbelle
fbd59a1f38
feat(ui): permit drag&drop to the operating system
...
a drop outside of the browser will:
- upload the file if only 1 file selected
- upload a .zip of the directory or multiple selection (browsers do not permit multiple upload yet)
note: I had to create a new handler because a post request to /api/batch/download is possible via JS but it will create a memory blob in the browser, during the drag action.
This may exhaust the browser's memory if heavy files
This will initiate zip creation from the server even if drop is canceled
The best approach is to add a handler supporting GET calls, this call will be triggered by the browser on drop action outside of it's window
2026-05-04 22:31:20 +02:00
Edouard Vanbelle
d0c6bd6a73
feat(openapi): upgrade code to gnerate openapi on all path
2026-05-04 12:02:33 +02:00
Edouard Vanbelle
badf35f08f
chore: remove all executable attributes on non bash files
2026-04-01 23:14:42 +02:00
Diocrafts
06ed0455ce
perf: migrate all user/session/auth IDs from VARCHAR(36) to native UUID
...
- Schema: all ~15 VARCHAR(36) columns → UUID with DEFAULT gen_random_uuid()
- Domain entities: User, Session, DeviceCode, AppPassword, Share → id: Uuid
- DTOs: CurrentUser.id → Uuid (API boundary DTOs keep String for JSON)
- Auth middleware: parse JWT claims.sub (String) → Uuid at boundary
- All repository traits, port traits, service impls updated end-to-end
- Handlers: pass Uuid by value (Copy, 16 bytes) instead of String refs
- Settings chain: updated_by column → Uuid (was text, caused setup crash)
- Removed ~650 lines of String↔Uuid conversion boilerplate
- Eliminates per-request heap allocations for ID cloning
- 16-byte binary comparison vs 36-byte string comparison in all queries
- Native UUID indexing in PostgreSQL (btree on 16 bytes vs 36-char text)
85 files changed, 1090 insertions(+), 1739 deletions(-)
2026-03-07 14:59:32 +01:00
Dionisio
f2d35ca792
feat: auto-persist JWT secret, remove setup token requirement
...
- JWT secret auto-generates and persists to <STORAGE_PATH>/.jwt_secret
- Remove setup token: first admin setup is open until system initialized
- Fix schema.sql: move CREATE EXTENSION pg_trgm/ltree to top
- Update login UI and auth.js to remove setup token fields
2026-03-05 22:12:53 +01:00
zjean
190527edfb
style: apply rustfmt formatting to fix CI
...
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-05 21:28:51 +01:00
Dionisio
4d81bcbd7b
fix(security): V-01,V-02,V-04,V-05,V-06 - multiple vulnerability fixes
...
- V-01: CalDAV unbounded body limit → MAX_CALDAV_BODY = 1MB
- V-02: CardDAV unbounded body limit → MAX_CARDDAV_BODY = 1MB
- V-04: Batch operations without max size → MAX_BATCH_SIZE = 1000
- V-05: WOPI get_editor_url IDOR → authorize_wopi_access with ownership check
- V-06: JWT secret without entropy validation → panic <16, warn 16-31, accept >=32
2026-03-05 16:57:44 +01:00
Dionisio
b503e08384
security: fix vulnerabilities 1-7 from security audit
...
- Fix #1 : Share handler IDOR - enforce owner check on share operations
- Fix #2 : list_files_query IDOR - bind folder queries to authenticated user
- Fix #3 : Dedup handler IDOR - restrict dedup operations to file owner
- Fix #4 : Trash handler OptionalAuthUser - require full AuthUser
- Fix #5 : Error info leakage - sanitize 500 error responses
- Fix #6 : Chunked upload IDOR - bind upload sessions to user_id,
add verify_session_owner() check on all session operations
- Fix #7 : CSP unsafe-inline removal - migrate all inline scripts,
styles and event handlers to external files, tighten CSP to
script-src 'self'; style-src 'self'
New files:
- static/js/core/theme-init.js (render-blocking theme init)
- static/js/core/sw-register.js (service worker registration)
- static/css/views/device-verify.css (extracted inline styles)
- static/js/views/device-verify/device-verify.js (extracted inline script)
2026-03-05 13:15:34 +01:00
Dionisio
fdbb2bf60a
fix(security): patch critical IDOR & auth vulnerabilities
...
- Fix logout no-op: extract refresh token from cookie/body (auth_handler)
- Secure all 12 WebDAV handlers with AuthUser + resolve_path_for_user
- Secure all 7 batch handlers with caller_id ownership checks
- Add _owned variants: copy_file_owned, delete_file_owned, get_file_stream_owned, get_folder_owned
- Secure list_files_query: add AuthUser, SQL-level user_id filter, tenant-isolated ETag
- Remove deprecated unscoped resolve_path() and exists() from PathResolverService
- Remove dead list_files handler (unmounted, no auth)
- Add list_files_for_owner (SQL) and list_files_owned across trait chain
2026-03-05 10:30:39 +01:00
Dionisio
6df68d3716
style: cargo fmt --all
2026-02-26 00:47:32 +01:00
Dionisio
5f883aa0f8
perf: rewrite batch download_zip to stream via temp file instead of RAM
...
- Replace in-memory Cursor<Vec<u8>> with async_zip + NamedTempFile (O(256KB) RAM)
- Stream ZIP to client via ReaderStream instead of materializing entire archive
- Replace N+1 BFS folder traversal with 2 bulk ltree queries
- Remove dead zip_service field and with_zip_service() from BatchOperationService
- Remove synchronous zip crate dependency (only async_zip remains)
- Eliminates ~2.5GB RAM spike per 2GB batch download
2026-02-25 23:12:19 +01:00
Dionisio
5a679dfc90
fix(security): patch 3 vulnerabilities — IDOR, ownership bypass, XSS
...
V1: Add owner-scoped folder pagination (list_folders_by_owner_paginated)
- New method in FolderRepository trait, PG implementation, service & handler
- Prevents IDOR by filtering folder listings to authenticated user
V2: Enforce ownership checks on folder mutations
- rename_folder, move_folder, delete_folder now require caller_id
- Service verifies folder.owner_id == caller_id (returns 404 on mismatch)
- Propagated to folder_handler, batch_handler, batch_operations, webdav_handler
- delete_folder_with_trash upgraded from OptionalAuthUser to AuthUser
- download_folder_zip now checks ownership before streaming
V3: Fix XSS in frontend via DOM APIs
- sharedView.js: innerHTML → createElement + textContent
- contextMenus.js: innerHTML → DOM construction for share dialog
Cleanup: removed unused OptionalAuthUser import, updated all stubs/mocks
2026-02-16 00:22:42 +01:00
Dionisio
7737ed90c7
feat: folder ownership scoping, batch operations integration, frontend audit fixes
...
Backend:
- Add owner_id to Folder entity + FolderDto (DB user_id column)
- Add list_folders_by_owner to FolderRepository trait + PG impl
- Add list_folders_for_owner to FolderUseCase + FolderService
- Rewrite FolderHandler: all endpoints now scope by AuthUser
- Remove dead handler methods (list_folders_inner, list_folders_for_user, is_user_home_folder, folder_belongs_to_user)
- Add ownership check in get_folder (returns 404 on mismatch)
Batch operations:
- Add trash_service + zip_service to BatchOperationService
- New methods: trash_files, trash_folders, move_folders, download_zip
- New handlers: trash_batch, move_folders_batch, download_batch
- New routes: POST /api/batch/trash, /api/batch/folders/move, /api/batch/download
Frontend:
- Replace findUserHomeFolder (~130 lines) with resolveHomeFolder (~35 lines)
- Remove client-side folder filtering in loadFiles (backend now scopes)
- Rewrite batchDelete: N requests -> 1 POST /api/batch/trash
- Rewrite batchMove: N requests -> 2 POST max (files + folders)
- Rewrite batchDownload: N requests -> 1 POST /api/batch/download (ZIP)
- Search moved to backend, share system uses backend API
- Dark mode fixes, frontend audit improvements
2026-02-15 23:45:11 +01:00
Dionisio
4c98c5a657
style: apply cargo fmt to entire codebase
...
Standardize code formatting across all 173 Rust source files
using rustfmt. No functional changes - purely cosmetic.
This establishes a consistent code style baseline for the
project going forward.
2026-02-14 01:29:34 +01:00
Dionisio
d31a413e57
chore: translate all Spanish comments and log messages to English
2026-02-12 09:41:25 +01:00
Dionisio
52840e57df
refactor: remove serde from domain entities for Clean Architecture compliance
...
- Remove Serialize/Deserialize from File, Folder, Session, User, Contact entities
- Create contact_persistence_dto.rs for JSONB persistence in infrastructure layer
- Update contact_pg_repository to use persistence DTOs
- Fix dependency on zip crate (downgrade from 7.2.0 to 2.1.0)
- Fix unused variable warnings in main.rs
- Move PathService import from domain to infrastructure
- Add missing fields to CoreServices and RepositoryServices
- Create proper service initialization in main.rs
Clean Architecture improvements:
- Domain layer no longer depends on serde framework
- Persistence concerns isolated to infrastructure layer
- TokenClaims in auth_service.rs is only exception (required for JWT)
2026-02-02 23:56:40 +01:00
DioCrafts
d9bbd575d2
adding several features
2025-03-19 00:44:27 +01:00