Commit Graph

94 Commits

Author SHA1 Message Date
Diocrafts a1a3bd1b2b fix: folder trash/delete operations & frontend refactoring
- Fix recursive CTE: add missing RECURSIVE keyword in move_to_trash and restore_from_trash SQL queries (relation 'descendants' does not exist)
- Fix folder deletion: delete descendant files before folder to avoid 'duplicate key violates unique constraint idx_files_unique_name_at_root'
- Simplify trash model: only mark the folder as trashed, not child files (implicit trash via parent)
- Update trash_items view: filter to show only top-level trashed items
- Update schema.sql: change files.folder_id FK from ON DELETE SET NULL to ON DELETE CASCADE
- Fix trash view icons: folders and files now show correct visual icons (folder-icon, pdf-icon, etc.) in trash view
- Frontend refactoring: extract inline CSS/JS from admin.html and profile.html into dedicated external files
- Frontend cleanup: replace all inline style attributes with CSS classes
- Frontend cleanup: replace style.display JS
- Fix recursive CTE: add missing RECURSIVE keyword in move_to_trash and restore_from_trash SQL queries (relation 'descendants' d
2026-02-20 12:27:52 +01:00
Dionisio Pozo 27eb7b16e0 Merge pull request #128 from gbw/fix/oidc-env-vars-in-admin-panel 2026-02-20 09:21:18 +01:00
George Wu 5738ddbb54 fix(admin): populate OIDC settings in admin panel from environment variables
- Use load_effective_oidc_config() to get OIDC settings, which applies env var overrides
- Use effective.redirect_uri for callback_url instead of calculated value from server_base_url
- This ensures the admin panel shows the correct OXICLOUD_OIDC_REDIRECT_URI value
2026-02-18 19:41:43 -08:00
George Wu e2a2026c3d fix(admin): populate OIDC settings in admin panel from environment variables
The get_oidc_settings() method was reading directly from the database only,
without applying environment variable overrides. Now it uses load_effective_oidc_config()
which properly applies env var overrides (OXICLOUD_OIDC_*), ensuring the admin
panel accurately reflects the runtime configuration.
2026-02-18 19:25:53 -08:00
George Wu d782d8469c fix: always apply database schema on startup
Previously, the application only applied the schema if auth.users table
didn't exist. This caused issues when upgrading - new schema elements
(like storage.trash_items view) weren't created on existing databases.

Now the schema is applied on every startup. Since schema.sql uses
'IF NOT EXISTS' and 'CREATE OR REPLACE', it's safe to run repeatedly.
2026-02-18 17:56:06 -08:00
Dionisio Pozo 4168e259a5 Merge pull request #125 from gbw/brotli-compression
Enable brotli compression for API and static files
2026-02-18 22:53:18 +01:00
Diocrafts 0d7c8bc019 perf: optimize UI rendering and event lifecycle 2026-02-18 10:53:43 +01:00
George Wu b28aa341b3 Enable brotli compression for API and static files
- Add compression-br feature to tower-http
- Apply CompressionLayer to API routes (JSON responses)
- Apply CompressionLayer to static files (CSS, JS, locales)
- File downloads remain uncompressed (avoid double compression)
2026-02-17 23:00:45 -08:00
Diocrafts f661282962 perf(web): add gzip compression + cache-control headers for static assets
- Add CompressionLayer to web router for gzip compression of JS/CSS/JSON/SVG
- Add Cache-Control header (7 days + stale-while-revalidate) via SetResponseHeaderLayer
- Add 'set-header' feature to tower-http dependency
- Result: 67-85% reduction in transfer size for all static assets
2026-02-17 19:29:42 +01:00
Dionisio 1ceae0ce94 Frontend optimizations: SVG icons, remove updateFileIcons, unify rendering, scope translatePage
- Replace Font Awesome CDN with inline SVG system (icons.js + MutationObserver)
- Remove updateFileIcons() (~140 lines) - redundant with backend icon_class + MutationObserver
- Migrate favorites.js and recent.js to use shared ui.renderFolders/renderFiles (eliminate ~260 lines of duplicate rendering + per-item event listeners)
- Add view-mode aware click delegation for favorites/recent views
- Fix _createFileCard to apply icon_special_class
- Add translateElement(root) for scoped i18n translation
- Replace full-page translatePage() calls with scoped translateElement() or inline t()
- Remove redundant translatePage() calls in shared.js and auth.js
- Remove Alpine.js from Service Worker cache
2026-02-16 21:51:53 +01:00
Dionisio a4709426d9 fix(upload): sanitize multipart filename for folder uploads (#121)
Browsers send the full relative path (e.g. 'Screenshots/file.png') as
the multipart filename when uploading folders via webkitRelativePath.
The File entity rejects names containing '/' or '\', causing all files
in a folder upload to fail with 'Invalid file name'.

Three fixes:
- Backend: strip path components from multipart filename in file_handler,
  keeping only the basename. Also prevents path-traversal attacks.
- Frontend (fileOperations.js): explicitly pass file.name as the third
  argument to FormData.append() in uploadFolderFiles() to override the
  browser's relative path.
- Frontend (ui.js): detect folder drops in drag-and-drop handlers by
  checking webkitRelativePath, and route them to uploadFolderFiles()
  instead of uploadFiles() so subfolders are created first.

Closes #121
2026-02-16 17:58:50 +01:00
Dionisio f70890e884 fix: upload failure, share dialog, shared view styling, dark mode fixes
- Fix 'folder_id is required' upload error by adding create_home_folder
  through the full hexagonal architecture (trait, service, repository, auth)
- Fix double upload issue with _isUploading concurrency guard
- Fix Share context menu doing nothing (ID collision between sharedView
  and main share dialog resolved with sv- prefix)
- Fix Compartidos tab duplicate headers and broken layout
- Add missing .shared-dialog CSS with dark mode support
- Fix dark mode white backgrounds on empty-state, shared-filters,
  trash-actions, action-btn, and header
- Fix i18n key mismatches in sharedView
- Bump version to 0.4.1

Closes #120
2026-02-16 16:18:39 +01:00
Dionisio b7bd656a43 perf: fix issues #1,#2,#3,#13 from performance audit
- #1  image_transcode: dedicated rayon pool + moka cache (no tokio blocking)
- #2  ltree materialized paths: eliminate N+1 folder/file queries
- #3  compute_content_hash: read blob_hash column instead of loading file into RAM
- #13 event delegation + DocumentFragment: ~15 delegated listeners replace ~19k per-item listeners

Backend: 82/82 tests pass, cargo check clean.
Frontend: ui.js and app.js syntax-validated via Node.js.
2026-02-16 13:10:44 +01:00
Dionisio d6c4eb884d feat: batch favorites endpoint + frontend dedup fixes
Backend:
- Add POST /api/favorites/batch endpoint (single multi-row INSERT)
- Add BatchFavoritesResult/BatchFavoritesStats DTOs
- Add batch methods to ports, service, PG repository
- Transaction-based insert with ON CONFLICT DO NOTHING, chunking at 5000

Frontend:
- Rewrite batchFavorites() to single API call (40 requests → 1)
- Add _replaceCacheFromResponse() to avoid extra GET round-trip
- Centralize formatFileSize, isTextViewable, formatDateTime, formatDateShort
- Remove duplicate icon mapping from app.js
- Fix inconsistent quota defaults (10GB everywhere)
2026-02-16 09:17:54 +01:00
Dionisio fb652c07e3 feat(P1+P2): server-authoritative favorites/recent + pre-computed display fields
P1-A: Enrich FavoriteItemDto & RecentItemDto with item_name, item_size,
      item_mime_type, parent_id, modified_at via SQL LEFT JOINs — eliminates
      N+1 per-item fetches.

P1-B: Rewrite favorites.js as server-authoritative (724→380 lines).
      In-memory cache backed by GET /api/favorites; no localStorage.

P1-C: Rewrite recent.js as server-authoritative (341→249 lines).
      GET /api/recent + POST /api/recent/{type}/{id}; no localStorage.

P1 cleanup: Remove dead localStorage cleanup from auth.js logout,
            fix async clearRecentFiles in app.js.

P2: Add icon_class, icon_special_class, category, size_formatted to
    FileDto, FolderDto, FavoriteItemDto, RecentItemDto. New shared
    display_helpers.rs module centralises mime→icon/category/size logic.
    Frontend (ui.js, fileRenderer.js, favorites.js, recent.js) now reads
    pre-computed fields from the API with fallback defaults — eliminates
    5 duplicated mime→icon mapping blocks (~89 lines removed).

Also fixes: synthetic FolderDto in webdav_handler.rs, pre-existing
            missing item_name field in share_service.rs test.

Net: -307 lines across 15 files. cargo check: 0 errors, 0 warnings.
     cargo test display_helpers: 3/3 pass.
2026-02-16 01:09:28 +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 6e1b77f244 chore: remove orphan test_cache.rs and unused memmap2 dependency 2026-02-15 21:20:20 +01:00
Dionisio 1527223d62 refactor: use typed Vec<Jwk> in JWKS parsing, remove double deserialize 2026-02-15 18:19:11 +01:00
Dionisio Pozo b59ff75489 Merge pull request #115 from gbw/feature/es256-jwks-support
Merged: ES256 JWKS support for OIDC
2026-02-15 18:09:36 +01:00
Dionisio 0be7ef8c0b style: fix clippy collapsible_if + cargo fmt 2026-02-15 18:04:32 +01:00
Dionisio 1ed20f425f perf: Phase 4+5 optimizations — uploads 10x, downloads 2x, concurrent 2x. moka cache, 512KB buffers, remove sync_all, hash-on-write, preloaded queries, bench.sh v3, gitignore storage/. 500MB upload 12.6s->1.3s (392MB/s). RSS 69-113MB, 0 swap. 2026-02-15 17:56:47 +01:00
George Wu 77c0dd5907 Add ES256 JWKS support for OIDC
- Simplified oidc_service.rs to use jsonwebtoken's DecodingKey::from_jwk()
- Automatically handles key type detection (RSA/EC) and algorithm detection
- Supports RS256, RS384, RS512, ES256, and ES384 algorithms
- Much cleaner code by leveraging library's built-in JWK parsing
2026-02-14 13:24:25 -08:00
Dionisio fac0b5e77b fix: critical bugs from deep audit
- Fix copy_files() data loss: implement real copy_file across full stack
  (FileWritePort, FileManagementUseCase, stubs, service, repository with
  atomic CTE + dedup ref_count increment, batch_operations caller)
- Fix plaintext password in replace_default_admin: hash password via
  PasswordHasherPort before User::new()
- Fix CalendarService hardcoded user_id: unify CalendarUseCase trait with
  explicit user_id parameter on all methods, remove zombie _for_user
  duplicates and hardcoded 'current_user_id', update 20 CalDAV handler
  call sites
- Previous session: migrate DedupService to PostgreSQL (storage.blobs),
  atomic CTEs with compensation for file/folder repository operations
2026-02-14 20:22:19 +01:00
Dionisio 3179e1dd91 quick fix 2026-02-14 19:30:49 +01:00
Dionisio bc01840fa4 chore: remove dead code from blob storage migration
Remove legacy abstractions that are no longer used after the
100% blob storage model migration (#113):

- IdMappingPort trait from application/ports/outbound.rs
- storage_mediator.rs module (StorageMediator trait + impls)
- StorageMediator impl from PathService
- write_behind_cache.rs (FS-based, incompatible with blob model)

The WriteBehindCachePort trait and Optional fields in services
are preserved for potential future blob-compatible caching.

-968 lines of dead code removed. Build clean, RC=0.
2026-02-14 18:10:37 +01:00
Dionisio 3c7c16f07e feat(#113): 100% blob storage model — PostgreSQL metadata + DedupService blobs
BREAKING CHANGE: Storage model completely rewritten. All file/folder
metadata now lives in PostgreSQL (storage schema). File content stored
as content-addressable blobs via DedupService. Filesystem directories
are no longer used for user storage.

New components:
- storage.folders / storage.files / storage.trash_items (PG schema)
- FolderDbRepository: virtual folders backed by PG
- FileBlobReadRepository: file reads via PG metadata + dedup blobs
- FileBlobWriteRepository: file writes via PG metadata + dedup blobs
- TrashDbRepository: soft-delete trash using is_trashed flags

Removed legacy FS components (~5500 lines deleted):
- FolderFsRepository, FileFsReadRepository, FileFsWriteRepository
- CompositeFileRepository, ParallelFileProcessor
- IdMappingService, IdMappingOptimizer, FileMetadataCache
- BufferPool, FileSystemUtils, RepositoryErrors
- TrashFsRepository, FolderFsRepositoryTrash

DI rewired: build_app_state() now requires PgPool (no FS fallback).
FileUploadService.new_with_read() and FileRetrievalService.new_with_cache()
constructors added for blob model (no write-behind needed).

Closes #113
2026-02-14 17:54:25 +01:00
Dionisio ebb0aee84e fix(#105): ensure folders are nested inside user home folder
Root cause: when window.app.currentPath was empty/falsy (due to timing,
page state reset, or initialization), the frontend sent parent_id: null.
The backend then created folders at the storage root instead of inside
the user's home folder.

Backend fix (folder_handler.rs):
- Added AuthUser extractor to create_folder handler
- When parent_id is None, auto-resolves the user's home folder
  ('My Folder - {username}') as the parent folder
- Folders are now always created inside the user's directory tree

Frontend fix (fileOperations.js):
- Changed parent_id fallback from null to window.app.userHomeFolderId
- Prevents sending null parent_id even if currentPath is reset

Search in subfolders: no fix needed — search_recursive() already
traverses the filesystem correctly; it was only failing because folders
were physically flat instead of nested.

Bumps service worker cache to v12.
2026-02-14 12:45:46 +01:00
Dionisio 3f60765d9a fix(#104): enforce storage quota on uploads & fix usage tracking
Backend:
- Add QuotaExceeded error kind mapped to HTTP 507 Insufficient Storage
- Add check_storage_quota() and get_user_storage_info() to StorageUsagePort
- Enforce quota in upload_file_with_cache, upload_file_with_thumbnails (AuthUser extractor)
- Enforce quota in chunked upload create_upload handler
- Add update_user_storage_usage_by_username() for username-based lookup
- Fix extract_username_from_path() to handle subfolders (take first segment only)
- Fix maybe_update_storage_usage() to use username-based lookup instead of passing
  username to get_user_by_id (which always failed silently)

Frontend:
- Parse and display quota error messages on upload failure (507 / QuotaExceeded)
- Stop remaining uploads when quota is exceeded
- Call refreshUserData() after uploads to update storage usage display
- Bump service worker cache to v9
2026-02-14 10:34:07 +01:00
Dionisio 1c5cf97cc5 security: fix audit vulnerabilities (RUSTSEC-2026-0007, RUSTSEC-2021-0141)
- Update bytes 1.11.0 -> 1.11.1 (fixes integer overflow in BytesMut::reserve, CVE-2026-25541)
- Replace unmaintained dotenv 0.15.0 with dotenvy 0.15.7 (RUSTSEC-2021-0141)
- Note: rsa 0.9.10 (RUSTSEC-2023-0071) has no patch yet, pulled transitively via jsonwebtoken
2026-02-14 01:37:03 +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 67137a3ef2 refactor: apply clippy auto-fixes (162 warnings resolved)
- Fix needless borrows and references
- Collapse nested if statements
- Replace manual strip_prefix with str::strip_prefix()
- Remove redundant closures in map/unwrap_or_else
- Use Iterator::next_back() instead of rev().next()
- Simplify map_or patterns
- Use std::io::Error::other() instead of new(ErrorKind::Other, ..)
- Use div_ceil() instead of manual ceiling division
- Consolidate format! string arguments
- Various other idiomatic Rust improvements

39 files changed, 220 insertions(+), 320 deletions(-)
2026-02-14 01:26:02 +01:00
Dionisio 099d1d1c55 fix: share URL respects scheme in OXICLOUD_SERVER_HOST (#103)
When OXICLOUD_SERVER_HOST contains a full URL with scheme (e.g.
https://oxi.example.com), the share link no longer prepends
http:// or appends :port, avoiding malformed URLs like
http://https://host:8085/s/token.

- Add AppConfig::base_url() helper with smart URL construction
- Replace all 6 inline format!() calls in share_service.rs
- Replace inline construction in di.rs (admin settings base URL)
- Priority: OXICLOUD_BASE_URL > full-URL host > http://host:port
2026-02-14 00:18:59 +01:00
Dionisio 5bf1e4b607 chore: migrate to Rust Edition 2024
- Update edition from 2021 to 2024 in Cargo.toml
- Remove explicit `ref` bindings in pattern matches (di.rs, carddav_adapter.rs)
  Edition 2024 uses implicit ref binding modes
- Refactor folder_handler.rs: change `impl IntoResponse` return types to
  concrete `axum::response::Response` to avoid lifetime capture issues
  (Edition 2024 captures all in-scope lifetimes in `impl Trait`)
- All 101 tests pass, zero warnings
2026-02-13 23:00:16 +01:00
Dionisio 4560a8042c fix(routes): serve pages with clean URLs (no .html extension)
Add server-side routes for /profile, /admin, and /shared that
serve their respective HTML pages directly (same pattern already
used for /login). Updated all frontend references to use clean
URLs instead of .html extensions.

Fixes #99
2026-02-13 22:44:20 +01:00
Dionisio 5771d82b21 refactor: remove Spanish folder naming convention, keep English only
Remove all 'Mi Carpeta - ' references from backend and frontend.
Only 'My Folder - {username}' is now recognized as the home folder
naming convention.
2026-02-13 22:33:27 +01:00
Dionisio 05135529ce fix(security): scope root folder listing to authenticated user
Non-admin users were seeing all users' root folders, including the
admin's. Three root causes fixed:

1. Backend: list_root_folders now extracts AuthUser and filters
   results so each user only sees their own home folder at the
   root level (folders matching 'My Folder - {username}' or
   'Mi Carpeta - {username}').

2. Frontend: findUserHomeFolder() searched only for the Spanish
   pattern 'Mi Carpeta - {username}' but the backend creates
   folders with the English pattern 'My Folder - {username}'.
   Now checks both naming conventions.

3. Frontend: when the home folder was not found, the code fell
   back to folderList[0] — which was usually the admin's folder.
   Removed that dangerous fallback; now shows empty root instead.

Fixes #94
2026-02-13 22:31:05 +01:00
Dionisio d889e325ac fix: increase body limit to 10 GB to prevent upload truncation (#95)
Axum's default body limit for Multipart extraction is 2 MB.
OxiCloud never overrode this default, so any file upload larger
than ~2 MB was silently truncated.

Added DefaultBodyLimit::max(10 GB) both globally on the app
router and specifically on the file upload routes, matching the
chunked upload capability already in place for large files.
2026-02-13 22:13:24 +01:00
Dionisio 40bf43b292 fix: cap default storage quota to available disk space (#92)
Previously the admin quota was hardcoded to 100 GB and the regular
user quota to 1 GB, regardless of actual disk capacity. On systems
with less than 100 GB free this produced misleading quota values.

Added the fs2 crate to query available disk space on the storage
filesystem. A new capped_quota() helper now returns
min(default_quota, available_disk_space) when assigning quotas
during user registration, admin setup, and OIDC provisioning.
2026-02-13 21:58:54 +01:00
Dionisio c384a08763 fix: fetch OIDC discovery before building authorization URL (#91)
get_authorize_url() was synchronous and fell back to constructing
{issuer}/authorize when the discovery cache was empty. This produced
incorrect URLs for providers like Keycloak whose authorization
endpoint is {issuer}/protocol/openid-connect/auth.

Made get_authorize_url() async so it can call get_discovery() to
fetch the real authorization_endpoint from .well-known/openid-configuration
before the first redirect. The discovery document is cached after the
initial fetch.
2026-02-13 21:42:41 +01:00
Dionisio c2c9bb700d Fix: Hide system directories (.blobs, .trash, .dedup_temp) from all users
- Added directory name filtering in folder_fs_repository.rs
- Filters out directories starting with '.' in list_folders, list_folders_paginated, and count_directory_items
- Matches existing file listing behavior
- Also added Italian language to popular languages list

Fixes #87
2026-02-13 19:46:38 +01:00
Dionisio 1be3e4230a feat: admin can create users manually + disable registration (#85)
Backend:
- POST /api/admin/users — admin-only user creation endpoint
  - username & password required, email optional (auto-generated placeholder)
  - role, quota_bytes, active all configurable
  - creates personal folder automatically
- PUT /api/admin/users/{id}/password — admin password reset
- GET/PUT /api/admin/settings/registration — toggle public registration
  - Supports env var OXICLOUD_DISABLE_REGISTRATION override
  - Blocks POST /api/auth/register when disabled
- AdminCreateUserDto, AdminResetPasswordDto added to settings DTOs
- registration_enabled field added to DashboardStatsDto

Frontend (admin.html):
- 'Create User' button in Users tab with full modal form
  (username, password, email, role, quota)
- 'Reset Password' button per user in actions column
- 'Allow public self-registration' toggle in Dashboard > System
  with warning banner when disabled

Closes #85
2026-02-13 16:46:59 +01:00
Dionisio ea234bc6a1 fix: share dialog not opening + connect to backend API
- Fix showShareDialog: add try-catch, null checks, prevent textContent
  from destroying header icon (use span child instead)
- Capture file/folder target before closeContextMenu to prevent race
- createSharedLink now calls real backend POST /api/shares instead of
  localStorage-only mock (still caches locally for offline compat)
- Fix share_handler.rs: use OptionalAuthUser instead of AuthUser to
  prevent 401 when auth is disabled (same pattern as delete/trash)
- Add null-safety to closeShareDialog
- Reset new-share-section on dialog open
2026-02-13 12:29:21 +01:00
Dionisio 5c53d94c0c feat: fix favorites display and add star indicator on favorited items
- Add ?metadata=true support to GET /api/files/{id} to return JSON metadata
  instead of binary content (was the root cause of favorites not loading)
- Fix favorites loadFileDetails to use metadata endpoint with auth headers
- Add star icon on favorited files/folders in grid view (top-left corner)
- Add star icon on favorited files/folders in list view (next to name)
- Refresh file view when toggling favorites so star appears/disappears
- Add CSS styles for .favorite-star and .favorite-star-inline
2026-02-13 09:32:16 +01:00
Dionisio fb65d1976b fix: resolve file management operations not working (#83)
- Fix rename: context menu was nullifying target reference before rename dialog could use it
- Fix delete files/folders: auth extractors were mandatory, causing 401 when auth not configured
- Fix view-file: async fetch race condition with context menu cleanup
- Fix orphaned ID mappings on file deletion
- Fix Authorization: Bearer null headers sent without token
- Add OptionalUserId and OptionalAuthUser infallible extractors
2026-02-13 08:54:51 +01:00
Dionisio e2297d276a fix: resolve admin registration failure on fresh Docker installs (#81)
Three bugs caused 403 errors when creating the first admin on fresh
Docker deployments (Unraid, Komodo):

1. db.rs: Schema application failures were silently swallowed. The app
   started with no tables, causing all auth queries to fail. Now the
   startup aborts if schema cannot be applied, with a fallback
   statement-by-statement executor that handles dollar-quoted blocks.
   Retries increased to 5 with 2s intervals.

2. auth_application_service.rs: count_admin_users() used fragile string
   matching (contains "does not exist")) on multi-layer wrapped errors.
   count_all_users() rejected admin creation on any DB error. Both now
   allow admin creation on any error for bootstrap scenarios.

3. auth_handler.rs: Redundant 60-line handler-level admin detection
   duplicated service-layer logic and generated noisy ERROR logs on
   fresh installs. Removed entirely - service layer handles it all.

Closes #81
2026-02-12 23:20:46 +01:00
Dionisio ab8f3191cb refactor: remove legacy 'Mi Carpeta' references, use 'My Folder' only 2026-02-12 15:31:39 +01:00
Dionisio ad07a5abda fix: auto-apply DB schema on fresh install and fix admin registration (#81)
- Auto-apply schema.sql when database tables don't exist (embedded in binary)
- Handle missing tables gracefully during admin registration (treat as fresh install)
- Fix docker-compose depends_on to wait for postgres healthcheck
- Rename personal folder from 'Mi Carpeta' to 'My Folder' with backward compat
- Translate remaining Spanish messages to English
2026-02-12 14:45:52 +01:00
Dionisio 76d9038e5b fix: resolve compiler warnings and downgrade JWT secret log to warn
- Downgrade OXICLOUD_JWT_SECRET missing log from error to warn level,
  since generating a random secret per session is valid behavior
- Remove unused import super::* in calendar_storage_adapter tests
- Remove unused import tokio_stream::StreamExt in compression_service tests
- Prefix unused validate_user_ownership with _ in trash_service
- Add nohup.out to .gitignore
2026-02-12 12:29:12 +01:00
Dionisio 59af22390d fix: restore missing match arms in trash_service restore_item
The translation commit accidentally removed the match statement and
opening arms (match item_result, Ok(Some(item)), match item.item_type)
while keeping the body, causing a brace mismatch compilation error.
2026-02-12 11:26:23 +01:00