Commit Graph

521 Commits

Author SHA1 Message Date
Edouard Vanbelle 0d5a726ef4 feat(oidc): explicit rejection reason
Show explicitly login rejection (for example when a user does not have a valid
email reported from OIDC but email verification is set)
2026-08-14 13:38:24 +02:00
Edouard Vanbelle e0654cd848 feat(openapi): implement missing routes
Admin:
- /api/admin/drives, /api/admin/drives/{id}, /api/admin/drives/{id}/members, /api/admin/drives/{id}/members/{kind}/{sid}
- /api/admin/jobs/{name}/pause, /api/admin/jobs/{name}/runs/{id}/findings, /api/admin/jobs/runs/purge
- /api/admin/smtp/info, /api/admin/smtp/test
- /api/admin/storage/entries/{name}/rotate
- /api/admin/users/{id}/promote-to-internal

Auth:
- /api/auth/dpop/bind
- /api/auth/magic-link/send
- /api/auth/me/profile
- /api/auth/upgrade-to-internal

Drives / grants / trash / users / dedup:
- /api/drives/{id}, /api/drives/{id}/members (get + delete), /api/drives/{id}/policies, /api/drives/{id}/quota
- /api/grants/{id}/notify
- /api/trash/drive/{drive_id}
- /api/users/{id}
- /api/dedup/check-batch

Faces
- /api/people — cluster list (PersonDto[])
- /api/people/{id}/photos — file ids for one person
- /api/people/{id} — rename (or clear name)
- /api/people/merge — merge two clusters
- /api/people/recluster — re-run clustering
- /api/people/data — nuke all face data
- /api/people/faces/{file_id} — face boxes per photo (FaceBoxDto[])
2026-08-09 17:58:06 +02:00
Edouard Vanbelle d638566d04 feat(openapi): add sessions + opaque 2026-08-09 16:36:42 +02:00
Edouard Vanbelle a7df46f8f8 feat(sessions): show session origin in admin panel + test 2026-08-09 16:36:42 +02:00
Edouard Vanbelle 763ee82028 security(session): do not expose 'sid' from OIDC
prefer exposing origin of the session: passwod, opaque, magic_link, oidc, unknown
2026-08-09 16:36:42 +02:00
Edouard Vanbelle 950c8c0f38 feat(dpop): provide nonce on immediate login
provide the DPoP nonce via cookie on login, this reduce the amount of API call
and prevent having any first call returning in 401
2026-08-09 16:36:42 +02:00
Edouard Vanbelle 69c57e1e24 feat(dpop): client now aware if session if bound
this prevent client to try binding and creating
- unnecessary call
- unnecessary warning in server log
2026-08-09 12:05:56 +02:00
Edouard Vanbelle 6a434aebe6 refactor(dpop): apply clippy 2026-08-09 11:46:51 +02:00
Edouard Vanbelle 10d831b204 feat(session): ensure dpop even with OIDC 2026-08-09 10:41:34 +02:00
Edouard Vanbelle bee856fbd0 feat(session): handle sessions for admin 2026-08-09 10:41:34 +02:00
Edouard Vanbelle 1b9d812175 feat(telemetry): add /metrics prommetheus exporter 2026-08-09 10:41:34 +02:00
Edouard Vanbelle 80f2f67db6 feat(dpop): server request dpop on all /api/* 2026-08-09 10:35:52 +02:00
Edouard Vanbelle d0712817c5 refactor(dpop): apply clippy 2026-08-09 02:18:02 +02:00
Edouard Vanbelle 34d80d70b8 feat(dpop): release route that must not dpop protected (temp version) 2026-08-09 01:56:13 +02:00
Edouard Vanbelle 82bd2e4d22 fix(dpop): do not sign GET /... tumbnail/images/ basic assets
no need sign this simole GET to this simplify
an hijacked session could retreive these assets but cannot get the list of them
2026-08-09 01:56:08 +02:00
Edouard Vanbelle 8d6e03a4bb feat(DPoP): check requests and 401 on failure 2026-08-09 01:56:07 +02:00
Edouard Vanbelle 5c4354bc67 feat(DPoP): add anti replay cache 2026-08-09 01:56:07 +02:00
Edouard Vanbelle 2e6789e506 feat(DPoP): add verification + X-Forwarded-Host X-Forwarded-Proto 2026-08-09 01:56:07 +02:00
Edouard Vanbelle 8b79e26329 feat(DPoP): bing ceremony on login 2026-08-09 01:56:07 +02:00
Edouard Vanbelle 4c34b25a7b feat(oidc): support of +alias email (clean it up to reconciliate) 2026-08-08 22:21:55 +02:00
Edouard Vanbelle 4d6c4bb92e feat(oidc): improve error handling 2026-08-08 20:44:27 +02:00
Edouard Vanbelle fa7b651897 feat(oidc): provide reason of autolink failure 2026-08-08 20:09:02 +02:00
Edouard Vanbelle e9495a63ad feat(oidc): permit auto/manual oidc account link/unlink
link are checking that email matches, +email alias are normalize into email
if email is already used on another account, link is not possible
not usurpation risk as the IDP is choosen by the admin
2026-08-08 19:21:13 +02:00
Edouard Vanbelle d8b3f2e026 refactor(oidc): migrate provider into issuer
this make OIDC compliant with the invariant binding (issuer and subject)
admin can now rename their provider without breaking

clarifing federation_kind: report the kind of federation wired not the allowed login method
hybryd login method are still allowed
2026-08-08 16:37:45 +02:00
Edouard Vanbelle 21607e3e7f feat(opaque): improve password change
- rebuild the opaque envoloppe
- revoke all other useer's sessions
- send a security email to user
2026-08-06 20:52:17 +02:00
Edouard Vanbelle 94e5b9e355 feat(opaque): permits ksf values change
KSF values are stored per user, if admin change value, client will detect it and regenerate the envelop
This pervent users being stuck
2026-08-05 22:52:19 +02:00
Edouard Vanbelle 84a1b0e005 feat(admin/user): show users auth method + add cli to recover broken opaque login 2026-08-05 21:13:21 +02:00
Edouard Vanbelle baac330389 fix(opaque): fix cookie setting 2026-08-04 23:58:23 +02:00
Edouard Vanbelle 906934ba25 fix(opaque): use safe url base64 2026-08-04 23:32:33 +02:00
Edouard Vanbelle 2de476d281 feat(pass reset): request a pass change on 1st login 2026-08-04 23:32:30 +02:00
Edouard Vanbelle 168d94370a feat(opaque): legacy login refuses migrated OPAQUE users 2026-08-04 07:03:08 +02:00
Edouard Vanbelle fac65a7c4d feat(opaque): add lookup identifier (with anti-enum) 2026-08-04 07:03:08 +02:00
Edouard Vanbelle bd8384c9b5 feat(opaque): add change password 2026-08-04 07:03:08 +02:00
Edouard Vanbelle 94c6121f3b feat(opaque): add /api/auth/opaque/params 2026-08-04 07:03:08 +02:00
Edouard Vanbelle 7d7621e387 feat(opaque): wire API
- POST /api/auth/opaque/login/ke1 (public) — takes {userIdentifier, startLoginRequest}, resolves the identifier via the same @-dispatch as legacy login (AuthApplicationService::lookup_user_for_login, factored out), fetches envelope, runs ServerLogin::start (real branch for known users, dummy branch for anti-enum on unknown/unregistered), stashes state under a random exchange_id in the moka cache, returns {exchangeId, loginResponse}.
- POST /api/auth/opaque/login/ke3 (public) — atomic take from the cache FIRST (anti-enum + anti-replay), then decodes the payload, runs ServerLogin::finish, stamps opaque_migrated_at (Phase 3 signal), and mints a session via the new AuthApplicationService::mint_session_for_authenticated_user helper — returns the same AuthResponseDto shape as legacy login so the SPA has one downstream handler.
- Session mint factored: mint_session_for_authenticated_user(User) extracted from login() so both the legacy password path and OPAQUE KE3 converge through one implementation.
- OpaqueRepositoryPort::mark_migrated with COALESCE-preserving idempotent stamp of opaque_migrated_at.
- opaque-setup CLI + Dockerfile wiring already shipped (Step 0 hygiene).
- Routing fix: sub-prefix split (/api/auth/opaque/register vs /api/auth/opaque/login) — axum composes middleware between sibling nests at the same prefix, which was cross-applying auth+CSRF to my public login routes. Distinct prefixes side-step that cleanly. Documented in both main.rs and the router builder doc.
- Rate-limit sharing: login KE1/KE3 layered with the SAME login_limiter instance as legacy POST /api/auth/login, so an attacker can't halve the per-IP budget by spraying both endpoints.

Anti-enum + anti-replay hardening in KE3: take runs BEFORE payload parse so:
- Unknown / expired / already-consumed exchange_id → 401 InvalidCredentials (same shape as wrong-passphrase, no payload-shape leak)
- Consumed handle can't be re-used to spam parse attempts
2026-08-04 07:03:08 +02:00
Edouard Vanbelle 033146a6c9 feat(opaque): add login opaque exchange 2026-08-04 07:03:08 +02:00
Edouard Vanbelle acd4420fe3 feat(oidc): impl back channel logout 2026-08-03 08:00:13 +02:00
Edouard Vanbelle 166b8c4891 feat(oidc): RP initiator logout
request token invalidation to IdP (OIDC) on logout
2026-08-03 07:59:14 +02:00
Edouard Vanbelle 5ebe2d3bae feat(oidc): add auto-redirect for OIDC
add `auto_redirect_if_standalone_oidc` in `OXICLOUD_AUTH_POLICIES`
let admin decide to redirect immediately to IdP if OIDC is the only auth method enabled
2026-08-03 01:01:00 +02:00
Edouard Vanbelle 8b0fb03b5c feat(recoverable jobs): clarify life cycle pause vs cancel
a job can be paused/resumed
    a job as an exclusibity by it's name
    if you want to run another job with same name:
    either cancel the first one, or wait of it's terminaison

    pause does not permit to run the other job, this can create
    race conditions
2026-08-02 17:38:44 +02:00
Edouard Vanbelle 07802e01f8 feat(recoverable job): add pause/resume capability 2026-08-02 16:17:15 +02:00
Edouard Vanbelle 49a4c53eed feat(admin storage): show finger print on key generation 2026-08-02 15:26:41 +02:00
Edouard Vanbelle 015f2da0f7 refactor(backend): normalize naming convention to backend rather storage
no ambiguity with the backend rather storage
2026-08-02 14:56:29 +02:00
Edouard Vanbelle 9902a6f8fe refactor(usage_reconcile): explicit naming to prevent confusion with storage (backend) 2026-08-02 14:56:29 +02:00
Edouard Vanbelle 4297d8139a feat(admin dashboard): clarify quota usage vs backend usage 2026-08-02 14:56:22 +02:00
Edouard Vanbelle a58351b7ad feat(storage key rot): add admin panel 2026-08-02 02:40:33 +02:00
Edouard Vanbelle a9d5aae781 feat(storage key rot): add rotate services 2026-08-02 02:40:33 +02:00
Edouard Vanbelle bbfb106a32 feat(maintenance): add a maintenance notification during backend migration 2026-08-01 18:46:17 +02:00
Edouard Vanbelle f409658c96 feat(storage): hot swap backend on migrate 2026-08-01 17:11:07 +02:00
Edouard Vanbelle d7c19570a5 feat(storage): wire choice of storage 2026-08-01 14:19:14 +02:00