feat(aether): initial commit – self-hosted Cloud, Phasen 1–7

Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 5 committed 2026-08-24 09:25:36 +02:00
commit 31a027c93a
225 files changed
+38042

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
package files
import "testing"
// Das Alpine-Image bringt keine /etc/mime.types mit, und Gos eingebaute
// Ersatztabelle kennt nur Web-Typen. Ohne die eigene Tabelle landete eine MP3
// als application/octet-stream in der Datenbank – nicht abspielbar, falsches
// Symbol.
func TestDetectMIMEKennteMedienTypen(t *testing.T) {
cases := map[string]string{
"lied.mp3": "audio/mpeg",
"clip.mp4": "video/mp4",
"paket.zip": "application/zip",
"paket.tar.gz": "application/gzip",
"tabelle.csv": "text/csv",
"BILD.PNG": "image/png", // Endung ohne Rücksicht auf Groß/Klein
"folien.pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
"brief.docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"budget.xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}
for name, want := range cases {
if got := detectMIME(name, ""); got != want {
t.Errorf("detectMIME(%q) = %q, want %q", name, got, want)
}
}
}
// Behauptet der Client etwas Sinnvolles und die Endung sagt nichts, gilt der
// Client. Behauptet er octet-stream, ist das keine Aussage.
func TestDetectMIMEFallback(t *testing.T) {
if got := detectMIME("datei.unbekannt", "image/png"); got != "image/png" {
t.Errorf("got %q, want the client type", got)
}
if got := detectMIME("datei.unbekannt", "application/octet-stream"); got != "application/octet-stream" {
t.Errorf("got %q", got)
}
}