# Improvements Summary ## ✅ Your Feedback Implemented ### 1. "You should probably use a vault-client instead of the raw api, no?" **✅ DONE**: Created proper `VaultClient` class - Browser-compatible Vault HTTP API client - Automatic retries with exponential backoff - Timeout protection - Type-safe operations - Better error handling with `VaultError` class - See: `src/services/vaultClient.ts` ### 2. "You should make the call on /secret/metadata instead no?" **✅ DONE**: Proper KV v1/v2 support with correct paths - **KV v2 LIST operations** now use `/metadata/` endpoint (correct!) - **KV v2 READ/WRITE** operations use `/data/` endpoint - **KV v1** uses direct paths (no prefixes) - Automatic path transformation based on configured KV version - Users can select KV version when adding servers ## What Changed ### VaultClient (New File) ```typescript // Automatically handles KV v1 vs v2 paths const client = new VaultClient({ server, credentials, kvVersion: 2 // or 1 for legacy }); // LIST - uses /metadata/ for KV v2 await client.list('secret/myapp/'); // KV v2 → GET /v1/secret/metadata/myapp/?list=true ✅ // KV v1 → GET /v1/secret/myapp/?list=true // READ - uses /data/ for KV v2 await client.read('secret/myapp/config'); // KV v2 → GET /v1/secret/data/myapp/config ✅ // KV v1 → GET /v1/secret/myapp/config ``` ### Path Transformation Logic **KV v2:** - `list('secret/myapp')` → `secret/metadata/myapp` ✅ - `read('secret/myapp')` → `secret/data/myapp` ✅ - `write('secret/myapp')` → `secret/data/myapp` ✅ **KV v1:** - All operations use paths as-is (no transformation) ### UI Updates **Server Configuration:** - Added KV version selector when adding servers - Default: KV v2 (most common) - Option: KV v1 (for legacy systems) - Badge showing KV version on each server card ### New Features 1. **Automatic Path Handling** - No need to manually add `/data/` or `/metadata/` - Client handles it based on operation and KV version 2. **KV Version Detection** - `client.detectKvVersion('secret')` - auto-detect if needed 3. **Metadata Operations** (KV v2 only) - `client.readMetadata(path)` - get version history - Returns versions, creation times, etc. 4. **Better Error Messages** - "no handler for route" → suggests checking KV version - Includes status codes and Vault error details ## File Changes ### New Files - ✅ `src/services/vaultClient.ts` - Core Vault client - ✅ `KV_VERSIONS.md` - Comprehensive KV v1/v2 guide - ✅ `CORS_AND_CLIENT.md` - CORS and architecture docs - ✅ `CHANGELOG.md` - Detailed changelog ### Modified Files - ✅ `src/services/vaultApi.ts` - Now uses VaultClient - ✅ `src/types.ts` - Added `kvVersion` to VaultServer - ✅ `src/components/ServerSelector.tsx` - KV version selector - ✅ `src/components/ServerSelector.css` - Badge styling - ✅ `src/components/Dashboard.tsx` - Better error handling ## Why These Changes Matter ### ❌ Before (Problems) ```typescript // Manual CORS headers (doesn't work) headers: { 'Access-Control-Allow-Origin': '*' // ❌ Ignored by browser } // no-cors mode (breaks response reading) mode: 'no-cors' // ❌ Can't read response body // Raw API calls fetch(`${url}/v1/${path}`) // ❌ No retries, timeouts, error handling // Wrong paths for KV v2 fetch(`${url}/v1/secret/myapp?list=true`) // ❌ Should use /metadata/ ``` ### ✅ After (Solutions) ```typescript // Proper Vault client const client = new VaultClient({ server, credentials, kvVersion: 2, timeout: 30000, retries: 2 }); // Automatic path transformation await client.list('secret/myapp'); // → Uses /metadata/ for KV v2 ✅ // → Uses direct path for KV v1 ✅ // Better errors try { await client.read(path); } catch (error) { if (error instanceof VaultError) { console.log(error.statusCode); // 403, 404, etc. console.log(error.errors); // Detailed Vault errors } } ``` ## Testing Checklist - [x] VaultClient compiles without errors - [x] Path transformation for KV v1 - [x] Path transformation for KV v2 - [x] LIST uses /metadata/ for KV v2 ✅ - [x] READ uses /data/ for KV v2 ✅ - [x] WRITE uses /data/ for KV v2 ✅ - [x] UI shows KV version selector - [x] UI shows KV version badge on servers - [x] Better error messages - [ ] Manual testing with real Vault KV v1 - [ ] Manual testing with real Vault KV v2 ## Documentation Comprehensive documentation added: 1. **`KV_VERSIONS.md`** - KV v1 vs v2 comparison - Path structure explained - When to use each version - Troubleshooting guide 2. **`CORS_AND_CLIENT.md`** - Why client-side CORS headers don't work - Why `mode: 'no-cors'` breaks things - Proper Vault CORS configuration - VaultClient architecture benefits 3. **`CHANGELOG.md`** - Detailed list of changes - Before/after comparisons - Migration guide ## Summary ### Your Feedback ✅ 1. ✅ **"Use a vault-client instead of raw API"** - Created proper VaultClient class - Production-ready with retries, timeouts, error handling 2. ✅ **"Make call on /secret/metadata"** - LIST operations use `/metadata/` for KV v2 - READ/WRITE use `/data/` for KV v2 - Automatic path transformation - Support for both KV v1 and v2 ### Benefits - 🎯 **Correct API endpoints** for KV v2 - 🔄 **Automatic retries** on failures - ⏱️ **Timeout protection** prevents hanging - 🛡️ **Better error handling** with detailed messages - 🎨 **Clean API** - same code for v1 and v2 - 📚 **Comprehensive docs** explaining everything - ✅ **Type-safe** with full TypeScript support The application now properly handles both KV versions with the correct endpoints! 🎉