feat: GetSecret returns full item (all fields: username/uri/notes/fields)
This commit is contained in:
1 parent
4fdc94ba44
commit
0ad0415dba
2 files changed
+36
-11
No files matched your search
@@ -108,10 +108,7 @@ func (h *Handler) GetSecret(c *fiber.Ctx) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(fiber.Map{
|
return c.JSON(value.ToMap())
|
||||||
"name": secretName,
|
|
||||||
"value": value,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseUUIDQuery(field, raw string) (string, error) {
|
func parseUUIDQuery(field, raw string) (string, error) {
|
||||||
|
|||||||
@@ -126,11 +126,22 @@ func matchesSecretFilter(item DecryptedItem, f SecretFilter) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSecret retrieves a decrypted secret by name.
|
// GetSecret retrieves a decrypted secret by name and returns the full item
|
||||||
// It searches by exact name (case-insensitive), then falls back to partial match.
|
// (all fields) so the caller can see username/uri/notes/custom fields, not
|
||||||
func (c *Client) GetSecret(name string, filter SecretFilter) (string, error) {
|
// just the primary value. Searches by exact name (case-insensitive), then
|
||||||
|
// falls back to partial match.
|
||||||
|
func (c *Client) GetSecret(name string, filter SecretFilter) (DecryptedItem, error) {
|
||||||
|
item, err := c.getSecretItem(name, filter)
|
||||||
|
if err != nil {
|
||||||
|
return DecryptedItem{}, err
|
||||||
|
}
|
||||||
|
return item, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSecretItem finds the matching decrypted item without extracting a single value.
|
||||||
|
func (c *Client) getSecretItem(name string, filter SecretFilter) (DecryptedItem, error) {
|
||||||
if name == "" {
|
if name == "" {
|
||||||
return "", fmt.Errorf("secret name cannot be empty")
|
return DecryptedItem{}, fmt.Errorf("secret name cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.mu.RLock()
|
c.mu.RLock()
|
||||||
@@ -148,18 +159,35 @@ func (c *Client) GetSecret(name string, filter SecretFilter) (string, error) {
|
|||||||
// Case 1: Exact match.
|
// Case 1: Exact match.
|
||||||
for _, item := range candidates {
|
for _, item := range candidates {
|
||||||
if strings.EqualFold(item.Name, name) {
|
if strings.EqualFold(item.Name, name) {
|
||||||
return extractSecret(item), nil
|
return item, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Case 2: Partial match
|
// Case 2: Partial match
|
||||||
for _, item := range candidates {
|
for _, item := range candidates {
|
||||||
if strings.Contains(strings.ToLower(item.Name), key) {
|
if strings.Contains(strings.ToLower(item.Name), key) {
|
||||||
logger.Debug.Printf("Partial match found for secret lookup")
|
logger.Debug.Printf("Partial match found for secret lookup")
|
||||||
return extractSecret(item), nil
|
return item, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("secret not found")
|
return DecryptedItem{}, fmt.Errorf("secret not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToMap renders the decrypted item as a flat map for JSON output.
|
||||||
|
// The "value" key holds the same primary value extractSecret() would return,
|
||||||
|
// while the other keys expose every decrypted field.
|
||||||
|
func (item DecryptedItem) ToMap() map[string]interface{} {
|
||||||
|
out := map[string]interface{}{
|
||||||
|
"name": item.Name,
|
||||||
|
"type": item.Type,
|
||||||
|
"username": item.Username,
|
||||||
|
"password": item.Password,
|
||||||
|
"uri": item.URI,
|
||||||
|
"notes": item.Notes,
|
||||||
|
"fields": item.Fields,
|
||||||
|
}
|
||||||
|
out["value"] = extractSecret(item)
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearCache triggers a fresh vault sync.
|
// ClearCache triggers a fresh vault sync.
|
||||||
|
|||||||
Reference in new issue
Block a user