- 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
3.8 KiB
3.8 KiB
Internxt Auth Analysis: Web vs CLI vs Rclone
Core Finding: Client Identification Determines Access
The backend server blocks certain account tiers based on client identification:
| 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 |
Sources
drive-web (auth.service.ts)
const getAuthClient = (authType: 'web' | 'desktop') => {
const AUTH_CLIENT = {
web: SdkFactory.getNewApiInstance().createAuthClient(), // clientName: "drive-web"
desktop: SdkFactory.getNewApiInstance().createDesktopAuthClient(), // clientName: "drive-desktop"
};
return AUTH_CLIENT[authType];
};
// Login with authClient.login() - NOT loginAccess()
return authClient.login(loginDetails, cryptoProvider)
- createAuthClient():
clientName: packageJson.name="drive-web" - createDesktopAuthClient():
clientName: "drive-desktop" - Method:
login()(notloginAccess)
CLI (auth.service.ts)
const authClient = SdkManager.instance.getAuth();
const data = await authClient.loginAccess(loginDetails, CryptoService.cryptoProvider);
- getAppDetails():
clientName: packageJson.clientName="internxt-cli"(from package.json) - Method:
loginAccess()(notlogin)
SDK Factory (drive-web)
private static getAppDetails(): AppDetails {
return {
clientName: packageJson.name, // "drive-web"
clientVersion: packageJson.version,
customHeaders,
};
}
private static getDesktopAppDetails(): AppDetails {
return {
clientName: 'drive-desktop',
clientVersion: packageJson.version,
};
}
Solution for WebDAV Wrapper
Strategy: Configure the auth client to identify as drive-web and use login() instead of loginAccess().
- Use @internxt/sdk with
Auth.client(apiUrl, appDetails, apiSecurity) - Set appDetails:
{ clientName: "drive-web", clientVersion: "1.0" } - Call login() (not
loginAccess()) - Implement CryptoProvider like in drive-web (passToHash, decryptText, getKeys, parseAndDecryptUserKeys)
Dependencies for WebDAV Wrapper
@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)
Current Status (as of analysis)
- 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)
Next Steps
- Test approach B: Browser-based token extraction – log in via web, read session token from localStorage/DevTools, use in wrapper
- login() under Linux: Kyber package may work under Linux
- Internxt support: Ask whether partner accounts (mailbox.org) use different auth flows
CRYPTO_SECRET and API URL
From internxt/cli .env.template:
- DRIVE_API_URL:
https://gateway.internxt.com/drive - APP_CRYPTO_SECRET:
6KYQBP847D4ATSFA
The PoC uses these values as fallback.