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,17 +1,17 @@
# Internxt Auth-Analyse: Web vs CLI vs Rclone
# Internxt Auth Analysis: Web vs CLI vs Rclone
## Kernbefund: Client-Identifikation bestimmt Zugang
## Core Finding: Client Identification Determines Access
Der Backend-Server blockiert bestimmte Account-Tiers basierend auf der **Client-Identifikation**:
The backend server blocks certain account tiers based on **client identification**:
| Client | clientName | Login-Methode | Endpoint | Status für eingeschränkte Tiers |
|--------|-----------|---------------|----------|--------------------------------|
| **drive-web** | `drive-web` | `login()` | `/auth/login` | ✅ Erlaubt |
| **drive-desktop** | `drive-desktop` | `login()` | `/auth/login` | ✅ Erlaubt |
| **internxt-cli** | `internxt-cli` | `loginAccess()` | `/auth/login/access` | ❌ Blockiert |
| **rclone** | (rclone-adapter) | loginAccess-ähnlich | `/auth/login/access` | ❌ Blockiert |
| Client | clientName | Login Method | Endpoint | Status for restricted tiers |
|--------|------------|--------------|----------|-----------------------------|
| **drive-web** | `drive-web` | `login()` | `/auth/login` | ✅ Allowed |
| **drive-desktop** | `drive-desktop` | `login()` | `/auth/login` | ✅ Allowed |
| **internxt-cli** | `internxt-cli` | `loginAccess()` | `/auth/login/access` | ❌ Blocked |
| **rclone** | (rclone-adapter) | loginAccess-like | `/auth/login/access` | ❌ Blocked |
## Quellen
## Sources
### drive-web ([auth.service.ts](drive-web/src/services/auth.service.ts))
@@ -24,13 +24,13 @@ const getAuthClient = (authType: 'web' | 'desktop') => {
return AUTH_CLIENT[authType];
};
// Login mit authClient.login() - NICHT loginAccess()
// Login with authClient.login() - NOT loginAccess()
return authClient.login(loginDetails, cryptoProvider)
```
- **createAuthClient()**: `clientName: packageJson.name` = `"drive-web"`
- **createDesktopAuthClient()**: `clientName: "drive-desktop"`
- **Methode**: `login()` (nicht `loginAccess`)
- **Method**: `login()` (not `loginAccess`)
### CLI ([auth.service.ts](https://github.com/internxt/cli/blob/main/src/services/auth.service.ts))
@@ -39,8 +39,8 @@ const authClient = SdkManager.instance.getAuth();
const data = await authClient.loginAccess(loginDetails, CryptoService.cryptoProvider);
```
- **getAppDetails()**: `clientName: packageJson.clientName` = `"internxt-cli"` (aus [package.json](https://github.com/internxt/cli/blob/main/package.json))
- **Methode**: `loginAccess()` (nicht `login`)
- **getAppDetails()**: `clientName: packageJson.clientName` = `"internxt-cli"` (from [package.json](https://github.com/internxt/cli/blob/main/package.json))
- **Method**: `loginAccess()` (not `login`)
### SDK Factory ([drive-web](drive-web/src/app/core/factory/sdk/index.ts))
@@ -61,38 +61,38 @@ private static getDesktopAppDetails(): AppDetails {
}
```
## Lösung für WebDAV-Wrapper
## Solution for WebDAV Wrapper
**Strategie:** Den Auth-Client so konfigurieren, dass er sich als `drive-web` ausgibt und `login()` statt `loginAccess()` verwendet.
**Strategy:** Configure the auth client to identify as `drive-web` and use `login()` instead of `loginAccess()`.
1. **@internxt/sdk** mit `Auth.client(apiUrl, appDetails, apiSecurity)` verwenden
2. **appDetails** setzen: `{ clientName: "drive-web", clientVersion: "1.0" }`
3. **login()** aufrufen (nicht `loginAccess()`)
4. CryptoProvider wie in drive-web implementieren (passToHash, decryptText, getKeys, parseAndDecryptUserKeys)
1. Use **@internxt/sdk** with `Auth.client(apiUrl, appDetails, apiSecurity)`
2. Set **appDetails**: `{ clientName: "drive-web", clientVersion: "1.0" }`
3. Call **login()** (not `loginAccess()`)
4. Implement CryptoProvider like in drive-web (passToHash, decryptText, getKeys, parseAndDecryptUserKeys)
## Abhängigkeiten für WebDAV-Wrapper
## Dependencies for WebDAV Wrapper
- `@internxt/sdk` (Version 1.13.x oder kompatibel drive-web nutzt 1.13.2)
- `@internxt/lib` (für aes, Crypto)
- Crypto-Logik aus drive-web: `app/crypto/services/keys.service`, `app/crypto/services/utils`
- Keys-Format: ECC + Kyber (post-quantum)
- `@internxt/sdk` (version 1.13.x or compatible drive-web uses 1.13.2)
- `@internxt/lib` (for aes, Crypto)
- Crypto logic from drive-web: `app/crypto/services/keys.service`, `app/crypto/services/utils`
- Keys format: ECC + Kyber (post-quantum)
## Aktueller Status (Stand: Analyse)
## Current Status (as of analysis)
- **CRYPTO_SECRET**: Korrekt (Salt-Decryption OK mit `6KYQBP847D4ATSFA`)
- **loginWithoutKeys**: Liefert weiterhin "Wrong login credentials" möglicherweise lehnt das Backend diesen Flow für bestimmte Account-Typen (z.B. mailbox.org-Partner) ab
- **login() mit Keys**: Kyber-WASM schlägt unter Windows fehl (`@dashlane/pqc-kem-kyber512-node`)
- **CRYPTO_SECRET**: Correct (salt decryption OK with `6KYQBP847D4ATSFA`)
- **loginWithoutKeys**: Still returns "Wrong login credentials" backend may reject this flow for certain account types (e.g. mailbox.org partner)
- **login() with keys**: Kyber-WASM fails under Windows (`@dashlane/pqc-kem-kyber512-node`)
## Nächste Schritte
## Next Steps
1. **Ansatz B testen**: Browser-basierter Token-Extrakt im Web einloggen, Session-Token aus localStorage/DevTools lesen, im Wrapper verwenden
2. **login() unter Linux**: Kyber-Paket könnte unter Linux funktionieren
3. **Internxt-Support**: Nachfragen, ob Partner-Accounts (mailbox.org) andere Auth-Flows nutzen
1. **Test approach B**: Browser-based token extraction log in via web, read session token from localStorage/DevTools, use in wrapper
2. **login() under Linux**: Kyber package may work under Linux
3. **Internxt support**: Ask whether partner accounts (mailbox.org) use different auth flows
## CRYPTO_SECRET und API-URL
## CRYPTO_SECRET and API URL
Aus [internxt/cli .env.template](https://github.com/internxt/cli/blob/main/.env.template):
From [internxt/cli .env.template](https://github.com/internxt/cli/blob/main/.env.template):
- **DRIVE_API_URL**: `https://gateway.internxt.com/drive`
- **APP_CRYPTO_SECRET**: `6KYQBP847D4ATSFA`
Der PoC nutzt diese Werte als Fallback.
The PoC uses these values as fallback.

View File

@@ -1,44 +1,44 @@
# Browser-Token-Authentifizierung (Ansatz B)
# Browser Token Authentication (Approach B)
Da der API-Login für Ihren Account-Typ blockiert ist, können Sie sich im Browser einloggen und die Session-Daten für den WebDAV-Wrapper verwenden.
Since API login is blocked for your account type, you can log in via the browser and use the session data for the WebDAV wrapper.
## Ablauf
## Flow
1. Auf https://drive.internxt.com einloggen
2. Token und Mnemonic aus dem Browser extrahieren
3. In `.env` eintragen
4. WebDAV-Server starten
1. Log in at https://drive.internxt.com
2. Extract token and mnemonic from the browser
3. Add to `.env`
4. Start WebDAV server
## Token extrahieren
## Extracting Tokens
### Schritt 1: Alle gespeicherten Keys anzeigen
### Step 1: Show all stored keys
Auf **https://drive.internxt.com** eingeloggt sein. DevTools (F12) → **Console**:
Be logged in at **https://drive.internxt.com**. DevTools (F12) → **Console**:
```javascript
// Alle localStorage-Keys anzeigen
// Show all localStorage keys
Object.keys(localStorage).filter(k => k.includes('x') || k.includes('token') || k.includes('Token')).forEach(k => console.log(k));
```
Damit sehen Sie, welche Keys es gibt (z.B. `xNewToken`, `xMnemonic`, `xUser`).
This shows which keys exist (e.g. `xNewToken`, `xMnemonic`, `xUser`).
### Schritt 2: Token und Mnemonic auslesen
### Step 2: Read token and mnemonic
```javascript
// Token und Mnemonic anzeigen
console.log('Token:', localStorage.getItem('xNewToken') || localStorage.getItem('xToken') || '(nicht gefunden)');
console.log('Mnemonic:', localStorage.getItem('xMnemonic') || '(nicht gefunden)');
// Display token and mnemonic
console.log('Token:', localStorage.getItem('xNewToken') || localStorage.getItem('xToken') || '(not found)');
console.log('Mnemonic:', localStorage.getItem('xMnemonic') || '(not found)');
```
### Schritt 3: Falls nichts gefunden wird
### Step 3: If nothing is found
- **Application-Tab prüfen:** DevTools → **Application** (oder **Anwendung**) → links **Local Storage****https://drive.internxt.com** auswählen. Dort alle Einträge durchsehen.
- **Richtige URL:** Sie müssen auf `https://drive.internxt.com` sein (nicht internxt.com) und **eingeloggt** sein nach dem Login auf `/drive` oder `/app`.
- **Session vs. Local:** Manche Werte liegen in `sessionStorage`. Testen mit:
- **Check Application tab:** DevTools → **Application** (or **Storage**) → **Local Storage** select **https://drive.internxt.com**. Inspect all entries.
- **Correct URL:** You must be on `https://drive.internxt.com` (not internxt.com) and **logged in** after login, on `/drive` or `/app`.
- **Session vs Local:** Some values may be in `sessionStorage`. Test with:
```javascript
console.log('sessionStorage:', Object.keys(sessionStorage));
```
- **Alle Keys anzeigen:** Zum Debuggen alle Keys mit Werten:
- **Show all keys:** For debugging, list all keys with values:
```javascript
for (let i = 0; i < localStorage.length; i++) {
const k = localStorage.key(i);
@@ -46,40 +46,40 @@ console.log('Mnemonic:', localStorage.getItem('xMnemonic') || '(nicht gefunden)'
}
```
## .env eintragen
## Add to .env
```
INXT_TOKEN=eyJhbGciOiJIUzI1NiIs...
INXT_MNEMONIC=word1 word2 word3 ...
# Namensentschlüsselung: CRYPTO_SECRET oder CRYPTO_SECRET2 (CLI-Default: 6KYQBP847D4ATSFA)
# Name decryption: CRYPTO_SECRET or CRYPTO_SECRET2 (CLI default: 6KYQBP847D4ATSFA)
CRYPTO_SECRET=6KYQBP847D4ATSFA
# Optional: WebDAV-Credentials erzwingen (sonst beliebige Credentials akzeptiert)
# Optional: Enforce WebDAV credentials (otherwise any credentials accepted)
# WEBDAV_USER=backup
# WEBDAV_PASS=geheim
# WEBDAV_PASS=secret
```
## Duplicati Pre-/Post-Scripts (optional)
## Duplicati Pre/Post Scripts (optional)
Falls der WebDAV-Server nicht dauerhaft läuft, kann Duplicati ihn vor dem Backup starten und danach beenden:
If the WebDAV server does not run permanently, Duplicati can start it before backup and stop it after:
| Script | Duplicati-Einstellung | Pfad |
|--------|------------------------|------|
| Start | Vor dem Backup ausführen | `scripts\start-webdav.cmd` |
| Stop | Nach dem Backup ausführen | `scripts\stop-webdav.cmd` |
| Script | Duplicati setting | Path |
|--------|-------------------|------|
| Start | Run before backup | `scripts\start-webdav.cmd` |
| Stop | Run after backup | `scripts\stop-webdav.cmd` |
**Einstellungen → Erweitert → Scripts** jeweils den vollen Pfad eintragen, z.B.:
**Settings → Advanced → Scripts** enter full path, e.g.:
```
C:\Pfad\zu\internxt-webdav\scripts\start-webdav.cmd
C:\Pfad\zu\internxt-webdav\scripts\stop-webdav.cmd
C:\Path\to\internxt-webdav\scripts\start-webdav.cmd
C:\Path\to\internxt-webdav\scripts\stop-webdav.cmd
```
Optional Port als Argument (Standard: 3005):
Optional port as argument (default: 3005):
```
C:\Pfad\zu\internxt-webdav\scripts\start-webdav.cmd 8080
C:\Pfad\zu\internxt-webdav\scripts\stop-webdav.cmd 8080
C:\Path\to\internxt-webdav\scripts\start-webdav.cmd 8080
C:\Path\to\internxt-webdav\scripts\stop-webdav.cmd 8080
```
Der Server startet im Hintergrund und ist nach ~5 Sekunden bereit.
The server starts in the background and is ready after ~5 seconds.
## Restic + rclone
@@ -87,65 +87,65 @@ Der Server startet im Hintergrund und ist nach ~5 Sekunden bereit.
restic -r rclone:internxt-webdav:repo-name init
```
Der Server erstellt fehlende Ordner rekursiv (MKCOL). Bei 500-Fehlern: Server-Log prüfen (`PUT Fehler:`), Token mit `npm run token-refresh` erneuern.
The server creates missing folders recursively (MKCOL). On 500 errors: check server log (`PUT Fehler:`), renew token with `npm run token-refresh`.
### Restic object not found / 500
### Restic "object not found" / 500
1. **Port prüfen:** rclone-URL muss exakt dem Server-Port entsprechen. Steht in der Konsole z.B. `http://127.0.0.1:3010`, dann in rclone `url = http://127.0.0.1:3010` eintragen.
2. **Nur einen Server:** `npm start` beenden (Ctrl+C), dann nur `scripts\start-webdav.cmd` nutzen sonst antwortet evtl. ein alter Prozess.
3. **rclone config:** `rclone config` → Remote `internxt-webdav` → `url` = `http://127.0.0.1:PORT` (PORT aus Server-Start).
4. **Logs:** `WEBDAV_LOG=debug` in `.env` setzen, Server neu starten, dann `logs\webdav-errors.log` und `logs\webdav-debug.log` prüfen.
1. **Check port:** rclone URL must match server port exactly. If console shows e.g. `http://127.0.0.1:3010`, set `url = http://127.0.0.1:3010` in rclone.
2. **Single server only:** Stop `npm start` (Ctrl+C), then use only `scripts\start-webdav.cmd` otherwise an old process may respond.
3. **rclone config:** `rclone config` → Remote `internxt-webdav` → `url` = `http://127.0.0.1:PORT` (PORT from server startup).
4. **Logs:** Set `WEBDAV_LOG=debug` in `.env`, restart server, then check `logs\webdav-errors.log` and `logs\webdav-debug.log`.
## WebDAV-Credentials (für Duplicati, Explorer)
## WebDAV Credentials (for Duplicati, Explorer)
Der Server erwartet **Basic Auth**. Ohne `WEBDAV_USER`/`WEBDAV_PASS` in `.env` akzeptiert er **beliebige** Credentials Sie können in Duplicati z.B. Benutzername `backup` und Passwort `geheim` eintragen. Mit `WEBDAV_USER` und `WEBDAV_PASS` werden nur diese Credentials akzeptiert.
The server expects **Basic Auth**. Without `WEBDAV_USER`/`WEBDAV_PASS` in `.env`, it accepts **any** credentials you can use e.g. username `backup` and password `secret` in Duplicati. With `WEBDAV_USER` and `WEBDAV_PASS` set, only those credentials are accepted.
## WebDAV-Server starten
## Start WebDAV Server
```bash
npm start
```
Server läuft auf `http://127.0.0.1:3005`. Phase 14 aktiv: PROPFIND, MKCOL, DELETE, MOVE, GET, PUT. Für GET und PUT wird INXT_MNEMONIC benötigt.
Server runs at `http://127.0.0.1:3005`. Phase 14 active: PROPFIND, MKCOL, DELETE, MOVE, GET, PUT. INXT_MNEMONIC required for GET and PUT.
### PowerShell Copy-Item: Null character in path
### PowerShell Copy-Item: "Null character in path"
Windows/.NET fügt bei WebDAV-Pfaden manchmal Null-Bytes ein. **Workaround:**
Windows/.NET sometimes adds null bytes to WebDAV paths. **Workaround:**
```powershell
# Variante 1: Direkt per HTTP (umgeht WebDAV-Bugs, UUID aus dir i: übernehmen)
# Option 1: Direct HTTP (bypasses WebDAV bugs, use UUID from dir i:)
Invoke-WebRequest -Uri "http://127.0.0.1:3005/_.69942103-e16f-4714-89bb-9f9f7d3b1bd5" -OutFile test.md
# Upload per PUT (PowerShell)
Invoke-WebRequest -Uri "http://127.0.0.1:3005/meine-datei.txt" -Method PUT -Body "Inhalt" -ContentType "application/octet-stream"
# Upload via PUT (PowerShell)
Invoke-WebRequest -Uri "http://127.0.0.1:3005/my-file.txt" -Method PUT -Body "Content" -ContentType "application/octet-stream"
# Variante 2: Robocopy (kopiert alle Dateien aus Root)
# Option 2: Robocopy (copy all files from root)
robocopy "i:\" "." /NFL /NDL
# Variante 3: Explorer Datei per Drag & Drop kopieren
``` Windows Explorer: Netzlaufwerk verbinden`http://127.0.0.1:3005`.
# Option 3: Explorer drag & drop file
# Windows Explorer: Map network drive → http://127.0.0.1:3005
## Token erneuern (bei 401 / abgelaufen)
## Renew Token (on 401 / expired)
Tokens laufen nach einiger Zeit ab (typisch Stunden). Bei 401-Fehlern oder „Nicht autorisiert“:
Tokens expire after some time (typically hours). On 401 errors or "Unauthorized":
### Option A: Automatisch (Chromium)
### Option A: Automatic (Chromium)
```bash
npm run token-refresh
```
Öffnet einen Browser mit drive.internxt.com. Einloggen die Tokens werden extrahiert und `.env` automatisch aktualisiert. Server neu starten.
Opens a browser with drive.internxt.com. Log in tokens are extracted and `.env` updated automatically. Restart server.
### Option B: Manuell
### Option B: Manual
1. **[https://drive.internxt.com](https://drive.internxt.com)** öffnen und erneut einloggen
2. Token und Mnemonic wie oben (Schritt 2) aus der Console auslesen
3. `.env` mit den neuen Werten aktualisieren
4. WebDAV-Server neu starten
1. Open **[https://drive.internxt.com](https://drive.internxt.com)** and log in again
2. Read token and mnemonic from Console as in Step 2 above
3. Update `.env` with new values
4. Restart WebDAV server
## Hinweise
## Notes
- **Bridge-API**: Der Download nutzt die Internxt Bridge mit `x-api-version: 2` und den Headern `internxt-version`/`internxt-client`. Ohne diese liefert die Bridge 400.
- **Sicherheit**: Mnemonic und Token sind hochsensibel. Nicht in Git committen, `.env` in `.gitignore` belassen.
- **Nur für Sie**: Die Tokens sind an Ihre Session gebunden. Für andere Nutzer funktioniert dieser Ansatz nicht.
- **Bridge API:** Download uses Internxt Bridge with `x-api-version: 2` and headers `internxt-version`/`internxt-client`. Without these, Bridge returns 400.
- **Security:** Mnemonic and token are highly sensitive. Do not commit to Git, keep `.env` in `.gitignore`.
- **Personal only:** Tokens are bound to your session. This approach does not work for other users.

View File

@@ -1,35 +1,35 @@
# CRYPTO_SECRET aus drive.internxt.com ermitteln
# Extract CRYPTO_SECRET from drive.internxt.com
Falls der Login mit "Wrong login credentials" fehlschlägt, ist vermutlich der `CRYPTO_SECRET` falsch. drive-web nutzt `REACT_APP_CRYPTO_SECRET`, der CLI-Wert (`6KYQBP847D4ATSFA`) kann abweichen.
If login fails with "Wrong login credentials", `CRYPTO_SECRET` is likely incorrect. drive-web uses `REACT_APP_CRYPTO_SECRET`, which may differ from the CLI value (`6KYQBP847D4ATSFA`).
## Methode 1: DEBUG-Modus (Salt-Decryption prüfen)
## Method 1: DEBUG mode (verify salt decryption)
```bash
DEBUG=1 npm run auth-test
```
- **"Salt-Decryption OK"** → CRYPTO_SECRET stimmt, Problem liegt woanders (Passwort, API)
- **"Salt-Decryption fehlgeschlagen"** → CRYPTO_SECRET ist falsch
- **"Salt decryption OK"** → CRYPTO_SECRET is correct, problem is elsewhere (password, API)
- **"Salt decryption failed"** → CRYPTO_SECRET is wrong
## Methode 2: Secret im Browser suchen
## Method 2: Search for secret in browser
1. https://drive.internxt.com öffnen
1. Open https://drive.internxt.com
2. DevTools (F12) → **Sources**
3. **Strg+Shift+F** (Suche in allen Dateien)
4. Suchen nach:
- `6KYQBP847D4ATSFA` falls gefunden, wird derselbe Wert wie beim CLI genutzt
- `REACT_APP_CRYPTO_SECRET` oder `CRYPTO_SECRET`
- Hex-Strings (z.B. 16 Zeichen wie `a1b2c3d4e5f6...`)
3. **Ctrl+Shift+F** (search in all files)
4. Search for:
- `6KYQBP847D4ATSFA` if found, same value as CLI is used
- `REACT_APP_CRYPTO_SECRET` or `CRYPTO_SECRET`
- Hex strings (e.g. 16 chars like `a1b2c3d4e5f6...`)
5. Gefundenen Wert in `.env` eintragen:
5. Add found value to `.env`:
```
CRYPTO_SECRET=gefundener_wert
CRYPTO_SECRET=found_value
```
## Methode 3: drive-web lokal bauen (mit bekanntem Secret)
## Method 3: Build drive-web locally (with known secret)
Falls Sie Zugriff auf drive-web haben und den korrekten Secret kennen:
If you have access to drive-web and know the correct secret:
1. In `drive-web` eine `.env` mit `REACT_APP_CRYPTO_SECRET=...` anlegen
2. `yarn build` ausführen
3. In den Build-Artefakten nach dem eingebetteten Wert suchen
1. Create `.env` in `drive-web` with `REACT_APP_CRYPTO_SECRET=...`
2. Run `yarn build`
3. Search build artifacts for the embedded value

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.

View File

@@ -1,36 +1,36 @@
# Entwicklung unter WSL (login() mit Keys)
# Development under WSL (login() with Keys)
Unter Windows schlägt das Kyber-WASM-Modul fehl. Unter WSL (Ubuntu/Debian) funktioniert es in der Regel.
Under Windows, the Kyber WASM module fails. Under WSL (Ubuntu/Debian) it usually works.
## Voraussetzungen
## Prerequisites
- WSL2 mit Ubuntu oder Debian
- WSL2 with Ubuntu or Debian
- Node.js 20+ (`node -v`)
## Setup
```bash
# Im WSL-Terminal
# In WSL terminal
cd /mnt/c/Users/mbusc/source/repos/internxt-webdav
# Abhängigkeiten installieren (inkl. Kyber für login mit Keys)
# Install dependencies (including Kyber for login with keys)
npm install
# .env mit Credentials (INXT_EMAIL, INXT_PASSWORD)
# Optional: DEBUG=1 für Salt-Check
# .env with credentials (INXT_EMAIL, INXT_PASSWORD)
# Optional: DEBUG=1 for salt check
```
## Auth-PoC mit login() testen
## Test Auth PoC with login()
Zuerst den Auth-PoC auf `login()` umstellen (mit Keys):
First switch the Auth PoC to `login()` (with keys):
```bash
npm run auth-test
```
Falls der Fehler "Wrong login credentials" weiterhin auftritt, liegt das Problem nicht am Kyber-WASM, sondern am Backend/Account-Typ.
If the "Wrong login credentials" error persists, the issue is not Kyber-WASM but the backend/account type.
## Projektpfad
## Project Path
Windows-Pfad: `c:\Users\mbusc\source\repos\internxt-webdav`
WSL-Pfad: `/mnt/c/Users/mbusc/source/repos/internxt-webdav`
Windows path: `c:\Users\mbusc\source\repos\internxt-webdav`
WSL path: `/mnt/c/Users/mbusc/source/repos/internxt-webdav`