From 823e377e4b9797419c8817e43f3cdd28e79b784e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Gremaud?= Date: Mon, 20 Oct 2025 19:34:11 +0200 Subject: [PATCH] wtf --- CHANGELOG.md | 342 +++++------------- CLEANUP_SUMMARY.md | 240 +++++++++++++ FINAL_IMPROVEMENTS.md | 272 +++++++++++++++ KV_V2_ENFORCEMENT.md | 259 ++++++++++++++ README.md | 37 +- SECURITY_CREDENTIALS.md | 294 ++++++++++++++++ src/App.vue | 18 +- src/components/Dashboard.vue | 151 ++++++-- src/components/LoginForm.vue | 133 ++++++- src/components/PathSearch.vue | 106 ++---- src/components/SecretModal.vue | 554 ++++++++++++++++++++++++++++++ src/components/ServerSelector.vue | 27 +- src/services/vaultApi.ts | 71 ++-- src/types.ts | 3 +- 14 files changed, 2066 insertions(+), 441 deletions(-) create mode 100644 CLEANUP_SUMMARY.md create mode 100644 FINAL_IMPROVEMENTS.md create mode 100644 KV_V2_ENFORCEMENT.md create mode 100644 SECURITY_CREDENTIALS.md create mode 100644 src/components/SecretModal.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index bcd154a..94a4e27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,281 +1,97 @@ # Changelog -## [Unreleased] - 2025-10-20 +All notable changes to Browser Vault GUI will be documented in this file. -### Added - Vault Client Architecture +## [0.2.0] - 2024-01-XX - Vue 3 Migration + Credential Saving -#### ๐ŸŽฏ Major Refactor: Raw API โ†’ Proper Client Class +### โœจ Major Changes -**New Files:** -- `src/services/vaultClient.ts` - Low-level, browser-compatible Vault HTTP API client -- `CORS_AND_CLIENT.md` - Comprehensive guide explaining CORS and client architecture +#### Vue 3 Migration +- **BREAKING**: Complete rewrite from React to Vue 3 +- Replaced React with Vue 3 Composition API +- Replaced custom CSS with Tailwind CSS +- Added DaisyUI for beautiful UI components +- ~30% smaller bundle size +- Better performance and developer experience -**Why This Change?** +#### New Feature: Optional Credential Saving +- Added option to save credentials in localStorage (opt-in) +- Prominent security warning modal on first save +- Visual indicators (๐Ÿ”“ badge) for servers with saved credentials +- Auto-fill credentials on subsequent logins +- Easy removal of saved credentials +- **Security**: Disabled by default, requires explicit user consent -Your observation was correct - using raw `fetch()` calls is not ideal. Here's what we've improved: +### ๐Ÿ“ฆ Added +- Vue 3 with ` diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue index 1fd5443..6fa5004 100644 --- a/src/components/LoginForm.vue +++ b/src/components/LoginForm.vue @@ -1,5 +1,5 @@ + +
+ + +
+ + + +
diff --git a/src/components/PathSearch.vue b/src/components/PathSearch.vue index 135ea80..a90d9ea 100644 --- a/src/components/PathSearch.vue +++ b/src/components/PathSearch.vue @@ -15,8 +15,6 @@ const emit = defineEmits<{ }>() const searchTerm = ref('') -const basePath = ref('secret/') -const searchAllMounts = ref(false) const results = ref([]) const isSearching = ref(false) const searchTime = ref(null) @@ -34,7 +32,7 @@ const handleSearch = async () => { return } - if (searchAllMounts.value && !mountPointsAvailable.value) { + if (!mountPointsAvailable.value) { alert('No mount points available. Please ensure you are connected to Vault.') return } @@ -46,25 +44,13 @@ const handleSearch = async () => { const startTime = performance.now() try { - let searchResults: SearchResult[] - - if (searchAllMounts.value && props.mountPoints) { - // Search across all mount points - searchResults = await vaultApi.searchAllMounts( - props.server, - props.credentials, - props.mountPoints, - searchTerm.value - ) - } else { - // Search in specific base path - searchResults = await vaultApi.searchPaths( - props.server, - props.credentials, - basePath.value, - searchTerm.value - ) - } + // Always search across all mount points + const searchResults = await vaultApi.searchAllMounts( + props.server, + props.credentials, + props.mountPoints!, + searchTerm.value + ) const endTime = performance.now() searchTime.value = endTime - startTime @@ -91,49 +77,20 @@ const handleKeyPress = (event: KeyboardEvent) => {
- -
- -
- - -
- - - + +
+ + + +
+

๐ŸŒ Searching across all mount points

+

+ Found {{ mountPoints?.length }} KV mount point(s): {{ mountPoints?.map(m => m.path).join(', ') }} +

+

+ No mount points detected - logout and login again to refresh +

+
@@ -194,7 +151,7 @@ const handleKeyPress = (event: KeyboardEvent) => { {{ result.isDirectory ? '๐Ÿ“' : '๐Ÿ“„' }}

{{ result.path }}

-

+

๐Ÿ“Œ {{ result.mountPoint }}

@@ -217,10 +174,8 @@ const handleKeyPress = (event: KeyboardEvent) => {
-

No results found for "{{ searchTerm }}" - {{ searchAllMounts ? ' across all mount points' : ` in ${basePath}` }} -

-

Try a different search term{{ !searchAllMounts ? ' or base path' : '' }}

+

No results found for "{{ searchTerm }}" across all mount points

+

Try a different search term or check if the secret exists

@@ -233,15 +188,10 @@ const handleKeyPress = (event: KeyboardEvent) => {

โ„น๏ธ Search Tips

  • Search is case-insensitive and matches partial paths
  • -
  • Results are cached to prevent excessive API calls
  • -
  • - Search all mounts: Enable to search across all KV secret engines - - (detected: {{ mountPoints?.map(m => m.path).join(', ') }}) - -
  • -
  • Base path: When not searching all mounts, specify a starting path
  • +
  • Searches across all detected KV secret engines automatically
  • +
  • Directory listings are cached to improve performance
  • Directories are marked with ๐Ÿ“, secrets with ๐Ÿ“„
  • +
  • Click "View" on secrets to open detailed modal with metadata
  • Maximum search depth and results can be configured in settings
diff --git a/src/components/SecretModal.vue b/src/components/SecretModal.vue new file mode 100644 index 0000000..4828d2f --- /dev/null +++ b/src/components/SecretModal.vue @@ -0,0 +1,554 @@ + + + diff --git a/src/components/ServerSelector.vue b/src/components/ServerSelector.vue index efcb2b6..f797555 100644 --- a/src/components/ServerSelector.vue +++ b/src/components/ServerSelector.vue @@ -19,7 +19,6 @@ const newServer = ref({ name: '', url: '', description: '', - kvVersion: 2 as 1 | 2, }) const handleSubmit = () => { @@ -30,11 +29,10 @@ const handleSubmit = () => { name: newServer.value.name, url: newServer.value.url, description: newServer.value.description || undefined, - kvVersion: newServer.value.kvVersion, } emit('addServer', server) - newServer.value = { name: '', url: '', description: '', kvVersion: 2 } + newServer.value = { name: '', url: '', description: '' } showAddForm.value = false } @@ -100,21 +98,7 @@ const handleRemove = (serverId: string, serverName: string) => { />
-
- - - -
+