Translate all user-facing output to English

- Scripts: start-webdav.cmd, stop-webdav.cmd (echo messages, REM comments)
- Server: server.js (console.log, HTTP error messages)
- Token tools: token-test.js, token-refresh.js
- Other: auth-poc.js, debug-name-decrypt.js, internxt-client.js, upload.js
- Docs: README, .env.example, docs/*.md

Made-with: Cursor
This commit is contained in:
2026-02-28 16:37:28 +01:00
parent 19dd30e0fb
commit 262cffe4a6
16 changed files with 339 additions and 338 deletions

View File

@@ -1,8 +1,8 @@
# WebDAV-Server Architektur
# WebDAV Server Architecture
## Empfohlener Ansatz: Adapter (nicht Proxy)
## Recommended Approach: Adapter (not Proxy)
Der WebDAV-Server ist ein **Adapter**: Er implementiert das WebDAV-Protokoll und übersetzt Anfragen in Internxt Drive API + Network-Aufrufe. Es wird **nicht** zu einem anderen WebDAV-Server weitergeleitet.
The WebDAV server is an **adapter**: it implements the WebDAV protocol and translates requests into Internxt Drive API + Network calls. It does **not** forward to another WebDAV server.
```mermaid
flowchart LR
@@ -13,7 +13,7 @@ flowchart LR
subgraph Adapter [WebDAV Adapter]
WebDAV[WebDAV Server]
Mapping[Path zu UUID]
Mapping[Path to UUID]
Crypto[Encrypt/Decrypt]
end
@@ -29,46 +29,46 @@ flowchart LR
Crypto --> Network
```
## Datenfluss
## Data Flow
| WebDAV-Anfrage | Internxt-Operation |
| WebDAV Request | Internxt Operation |
|----------------|-------------------|
| PROPFIND (Verzeichnisinhalt) | Storage.getFolderContentByUuid |
| GET (Datei lesen) | File-Metadaten → Network.download → Entschlüsseln |
| PUT (Datei schreiben) | Verschlüsseln → Network.upload → createFileEntry |
| MKCOL (Ordner anlegen) | Storage.createFolderByUuid |
| DELETE | Trash oder permanent delete |
| PROPFIND (directory listing) | Storage.getFolderContentByUuid |
| GET (read file) | File metadata → Network.download → Decrypt |
| PUT (write file) | Encrypt → Network.upload → createFileEntry |
| MKCOL (create folder) | Storage.createFolderByUuid |
| DELETE | Trash or permanent delete |
| MOVE | Storage.moveFileByUuid / moveFolderByUuid |
## Komplexität
## Complexity
- **Einfach:** PROPFIND, MKCOL nur Drive API, keine Verschlüsselung
- **Mittel:** DELETE, MOVE Drive API
- **Aufwändig:** GET, PUT Bridge/Network + Mnemonic-Verschlüsselung
- **Simple:** PROPFIND, MKCOL Drive API only, no encryption
- **Medium:** DELETE, MOVE Drive API
- **Complex:** GET, PUT Bridge/Network + mnemonic encryption
Die drive-web nutzt `Network.client` (Bridge) und `NetworkFacade` für Up-/Download. Die Bridge-Credentials kommen aus der User-Session.
drive-web uses `Network.client` (Bridge) and `NetworkFacade` for up/download. Bridge credentials come from the user session.
## Implementierungsreihenfolge
## Implementation Order
1. **Phase 1:** PROPFIND (Verzeichnis auflisten) ✅ implementiert
2. **Phase 2:** MKCOL, DELETE, MOVE ✅ implementiert
3. **Phase 3:** GET (Download) Bridge + Entschlüsselung ✅ implementiert
4. **Phase 4:** PUT (Upload) Verschlüsselung + Bridge ✅ implementiert
1. **Phase 1:** PROPFIND (list directory) ✅ implemented
2. **Phase 2:** MKCOL, DELETE, MOVE ✅ implemented
3. **Phase 3:** GET (download) Bridge + decryption ✅ implemented
4. **Phase 4:** PUT (upload) Encryption + Bridge ✅ implemented
### Namensentschlüsselung
### Name Decryption
Internxt nutzt Zero-Knowledge-Verschlüsselung. Die API liefert verschlüsselte Namen (`name`). Wenn `plain_name` fehlt, kann der Server mit `CRYPTO_SECRET2` (oder `CRYPTO_SECRET`) Namen entschlüsseln analog zur drive-web `aes.decrypt`-Logik mit `secret2-parentId`/`secret2-folderId`. Ohne gesetztes Secret werden die rohen (verschlüsselten) Namen verwendet.
Internxt uses zero-knowledge encryption. The API returns encrypted names (`name`). When `plain_name` is missing, the server can decrypt names with `CRYPTO_SECRET2` (or `CRYPTO_SECRET`) analogous to drive-web `aes.decrypt` logic with `secret2-parentId`/`secret2-folderId`. Without a set secret, raw (encrypted) names are used.
## Token vs. Bridge-Credentials
## Token vs Bridge Credentials
- **Drive API:** Nutzt `xNewToken` (Authorization: Bearer)
- **Network/Bridge:** Braucht `bridgeUser` + `userId` (aus User-Credentials) und Mnemonic für Verschlüsselung
- **Drive API:** Uses `xNewToken` (Authorization: Bearer)
- **Network/Bridge:** Requires `bridgeUser` + `userId` (from user credentials) and mnemonic for encryption
**Bridge-Credentials aus refreshUser:** Der Endpoint `/users/refresh` liefert `user` (UserResponseDto) mit:
- `bridgeUser` E-Mail des Nutzers
- `userId` wird mit SHA256 gehasht und als Bridge-Passwort genutzt
- `bucket` Bucket-ID für Uploads
- `mnemonic` für Dateiverschlüsselung
- `rootFolderId` Root-Ordner-UUID
**Bridge credentials from refreshUser:** The `/users/refresh` endpoint returns `user` (UserResponseDto) with:
- `bridgeUser` User email
- `userId` hashed with SHA256 and used as Bridge password
- `bucket` Bucket ID for uploads
- `mnemonic` for file encryption
- `rootFolderId` Root folder UUID
Damit liefert der Browser-Token (via refreshUser) alle nötigen Daten für Drive API und Bridge.
Thus the browser token (via refreshUser) provides all data needed for Drive API and Bridge.