feat(nextcloud-files): Teilen in Modul-Changelog, Anleitungen und Changelog
- Modul-Changelog: unveroeffentlichter Eintrag 1.0.0 um drei Teilen-Punkte erweitert (Version bleibt 1.0.0) - CHANGELOG.md: Dateien, Teilen und Dateien, Uebersicht der Freigaben - Anleitungen Anwender, Administration, Betrieb, Entwicklung beschreiben das Teilen - Live-Test e2e-shares.sh: Abschnitt version - Teilen-Dialog: Linkformular scrollt beim Oeffnen in den sichtbaren Bereich - Mit mir geteilt: offene Freigaben zeigen kein irrefuehrendes Eigene Berechtigung Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -796,3 +796,58 @@ Hintergrund- und Textfarbe über die CSS-Variablen laufen, nicht über `dark:`-U
|
||||
Oberfläche wird also grundsätzlich dunkel, nur Feinheiten (Status-, Warn- und Fehlerfarben,
|
||||
Hinweisboxen, Badges, wie im Projekt bereits an über 100 Stellen betroffen) bleiben falsch. Jede neue
|
||||
`dark:`-Utility-Klasse im Projekt setzt voraus, dass diese Zeile in `globals.css` unverändert bleibt.
|
||||
|
||||
**Dateien (Nextcloud), Teilen (quick-261009-dkv):** Das Teilen läuft über eine eigene
|
||||
OCS-Schicht, `apps/api/src/nextcloud-files/nextcloud-shares.ts`, und nicht über den Anmelde-Helfer
|
||||
`ocsRequest` aus `nextcloud-auth-client.ts`. Der Anmeldecode wertet einen 403 als „App-Passwort
|
||||
vorhanden“ und wirft den Text jeder Fehlerantwort weg; beim Teilen steht genau dort die Begründung
|
||||
der Nextcloud (`ocs.meta.message`), und ein 403 heißt „nicht erlaubt“. Die Schicht liest den
|
||||
Antwortkörper deshalb bei jedem Status (Erfolg bis 8 MiB, Fehler bis 64 KiB, Fähigkeiten bis
|
||||
1 MiB), bleibt sonst aber bei den Regeln der Etappe 1: fester Pfadanfang `/ocs/v2.php/`, jedes
|
||||
Segment einzeln codiert, keine Weiterleitungen, keine Cookies, und es wird nie eine Adresse aus
|
||||
einer Nextcloud-Antwort aufgerufen (weder die `url` einer Freigabe noch `api.generate`). Die
|
||||
Parser bauen kleine eigene Ansichten; Passwort (`hasPassword` statt Wert), Kennung und Adressen
|
||||
fremder Links verlassen sie nie.
|
||||
|
||||
Der Browser schickt nie Bitmasken. Die Routen (`shares/policy`, `shares/by-path`, `sharees`,
|
||||
`shares/mine`, `shares/received`, `POST shares`, `PUT/DELETE shares/:id`, `POST shares/:id/accept`)
|
||||
nehmen nur die Aufzählungen `kind` (`user`, `group`, `link`) und `access` (`view`, `edit`,
|
||||
`upload`); `permissionsFor` rechnet sie selbst in Bits um, Eintragsart und Schreibrecht kommen aus
|
||||
einer eigenen PROPFIND- bzw. GET-Abfrage, das Teilen-Bit 16 wird nie gesendet. Die statischen
|
||||
Routen stehen vor den `:id`-Routen (das Controller-Spec prüft die Reihenfolge). Die Freigaberegeln
|
||||
(Links erlaubt, Passwortpflicht, Ablaufdatum mit Tagen, öffentliches Hochladen, Gruppen,
|
||||
Mindestlänge) liest der Dienst bei **jedem** Schreibzugriff frisch aus `cloud/capabilities` des
|
||||
jeweiligen Benutzers und prüft vorab; es gibt keinen Zwischenspeicher. Nextcloud selbst
|
||||
beantwortet die Fähigkeiten nach einer `occ`-Änderung noch einige Sekunden aus dem Zwischenspeicher
|
||||
(der Live-Test wartet darauf mit `policy_wait`).
|
||||
|
||||
Fehlerabbildung (`mapShareFailure`, immer nach Aufruf, Status und gesendeten Feldern, **nie nach
|
||||
dem Text** der Nextcloud, der übersetzt sein kann): Nextcloud verschweigt bei `PUT` die Gründe, und
|
||||
Ablauffehler kommen als **404**, nicht als 400 (gemessen: `PUT` mit Ablauf jenseits des Höchstwerts
|
||||
ergibt 404, ein schwaches Passwort 400). Daraus folgt: 400 mit gesendetem Passwort ist
|
||||
`sharePasswordRejected`, 404 oder (beim Ändern) 400 mit gesendetem Ablaufdatum ist
|
||||
`shareExpiryInvalid`, 404 ohne beides ist beim Anlegen `shareRecipientInvalid` (Link: `notFound`),
|
||||
beim Ändern `shareNotFound`; 401 setzt die Verbindung auf „abgelaufen“, 429 und ab 500 laufen
|
||||
unverändert durch `mapNcFailure`, und ein 403 der Nextcloud kommt als `shareRejected` (422) beim
|
||||
Browser an. 401 und 403 verlassen die API nie. Die Datums-Eingabe prüft der DTO streng
|
||||
(`YYYY-MM-DD` plus echte Datumsprüfung `isRealDate`), weil Nextcloud Daten großzügig parst
|
||||
(`31.12.2026x` würde angenommen).
|
||||
|
||||
Zwei Fallen beim Anlegen: Ein `POST` für einen Empfänger, der die Freigabe schon hat, liefert die
|
||||
alte Freigabe zurück und **verschickt die Benachrichtigung erneut**. Der Dienst prüft deshalb vorab
|
||||
über `shares/by-path`, ob es sie schon gibt (`shareAlreadyExists`, 409), und ändert Berechtigungen
|
||||
immer per `PUT`. Außerdem begrenzt Tessera selbst auf 15 neue Freigaben je Benutzer in 10 Minuten
|
||||
(`checkShareCreate`, im Arbeitsspeicher, zählt auch Versuche, die die Nextcloud ablehnt;
|
||||
unmittelbar vor dem `POST`, nach allen Vorprüfungen). Das liegt absichtlich unter dem Limit der
|
||||
Nextcloud (20 in 600 s): Deren 429 würde die Aufrufsperre des Ursprungs auslösen, und die hielte
|
||||
die Anfragen aller Benutzer 15 Minuten an. Die Oberfläche legt immer nur eine Freigabe zugleich an.
|
||||
|
||||
Live-Test: `.planning/quick/261009-dkv-modul-dateien-etappe-2a-teilen-von-datei/e2e/e2e-shares.sh
|
||||
[people|links|received|version|all]` gegen die Test-Nextcloud (`nc-test-setup.sh` der Etappe 1
|
||||
vorher). Er legt Benutzer `ben` und Gruppe `tessera-team` an, schaltet die Ratenbegrenzung der
|
||||
Nextcloud (`ratelimit.protection.enabled`) nur für den Lauf aus und stellt die Regeln über
|
||||
`occ config:app:set core …` um (`shareapi_enforce_links_password`, `shareapi_default_expire_date`,
|
||||
`shareapi_enforce_expire_date`, `shareapi_expire_after_n_days`; für die offenen Freigaben
|
||||
`user:setting anna files_sharing default_accept`). Alles setzt der `trap` zurück. Der Zähler von
|
||||
Tessera liegt im Prozess: `all` verbraucht 7 der 15 Plätze, nach höchstens zwei `all`-Läufen
|
||||
`docker compose restart api`.
|
||||
|
||||
Reference in New Issue
Block a user