feat(nextcloud): add Nextcloud-compatible API layer

Implement a complete Nextcloud client compatibility layer so that
Nextcloud desktop/mobile sync clients can connect to OxiCloud.

Key additions:
- Login Flow v2 (device auth) with OIDC bridge support
- WebDAV handler compatible with Nextcloud clients (PROPFIND, GET,
  PUT, DELETE, MKCOL, MOVE, COPY, HEAD, PROPPATCH)
- OCS API endpoints (user info, capabilities, notifications stubs,
  sharees, unified search)
- Basic Auth middleware with app password verification, account
  lockout integration, and blake3-keyed auth cache
- App password management: create, list, revoke via both native
  API (JWT-authenticated profile page) and Nextcloud OCS endpoints
- Nextcloud file ID mapping (oc:fileid) with persistent DB storage
- Chunked upload support (Nextcloud v2 chunking protocol)
- Trashbin WebDAV interface
- Avatar (SVG placeholder) and preview (redirect) handlers
- User profile page with app password management UI
- URL user validation on all DAV routes (403 on mismatch)
- Database schema for app_passwords and nextcloud_object_ids tables

All services are behind a `nextcloud.enabled` config flag and
cleanly separated under src/interfaces/nextcloud/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
zjean
2026-03-04 14:02:15 +01:00
parent ecd1a8148a
commit 54eedf5483
64 changed files with 6761 additions and 126 deletions
+18
View File
@@ -1,3 +1,5 @@
use std::collections::HashSet;
use crate::application::dtos::favorites_dto::{BatchFavoritesResult, FavoriteItemDto};
use crate::common::errors::Result;
@@ -27,6 +29,14 @@ pub trait FavoritesUseCase: Send + Sync {
user_id: &str,
items: &[(String, String)],
) -> Result<BatchFavoritesResult>;
/// Check which of the given item IDs are favorites for this user.
/// Returns the set of item_ids that are favorites.
async fn batch_check_favorites(
&self,
user_id: &str,
item_ids: &[(&str, &str)], // (item_id, item_type) pairs
) -> Result<HashSet<String>>;
}
// ─────────────────────────────────────────────────────
@@ -54,4 +64,12 @@ pub trait FavoritesRepositoryPort: Send + Sync + 'static {
/// Insert multiple items in a single transaction.
/// Returns the number of rows actually inserted (ignoring duplicates).
async fn add_favorites_batch(&self, user_id: &str, items: &[(String, String)]) -> Result<u64>;
/// Check which of the given item IDs are favorites for this user.
/// Returns the set of item_ids that are favorites.
async fn batch_check_favorites(
&self,
user_id: &str,
item_ids: &[(&str, &str)], // (item_id, item_type) pairs
) -> Result<HashSet<String>>;
}