feat: replace Bitwarden CLI with native Go API client (#2)
BREAKING: Removes Node.js/Bitwarden CLI dependency entirely. ## What changed - New native HTTP client talks directly to Vaultwarden API - Bitwarden-compatible crypto in pure Go: - AES-256-CBC + HMAC-SHA256 decryption - PBKDF2-SHA256 and Argon2id key derivation - HKDF key stretching (with legacy fallback) - Auto token refresh (never expires) - Background vault sync (configurable interval, default 5min) - Docker image: ~233MB → ~15MB (pure Alpine, no Node.js) ## New env vars - VAULTWARDEN_EMAIL (replaces CLIENT_ID/CLIENT_SECRET) - SYNC_INTERVAL (default: 5m) ## Removed - internal/vaultwarden/client_cli.go (CLI interaction) - Bitwarden CLI dependency (Node.js + npm package) - VAULTWARDEN_CLIENT_ID, VAULTWARDEN_CLIENT_SECRET env vars ## Added - internal/vaultwarden/crypto.go (encryption/decryption) - internal/vaultwarden/crypto_test.go (11 unit tests) - internal/vaultwarden/api_client.go (HTTP client) ## Unchanged - External API surface (GET /secret/:name, POST /refresh, GET /health) - All security middleware (auth, IP whitelist, rate limiting)
This commit is contained in:
1 parent
e320f95d9f
commit
9f8ebf2408
14 files changed
+1527
-964
No files matched your search
@@ -1,4 +1,4 @@
|
||||
// Package handlers provides HTTP request handlers for the API
|
||||
// Package handlers provides HTTP request handlers for the API.
|
||||
package handlers
|
||||
|
||||
import (
|
||||
@@ -8,27 +8,27 @@ import (
|
||||
"github.com/thijsherman/vaultwarden-api/pkg/logger"
|
||||
)
|
||||
|
||||
// Handler contains all HTTP handlers
|
||||
// Handler contains all HTTP handlers.
|
||||
type Handler struct {
|
||||
vaultClient *vaultwarden.Client
|
||||
}
|
||||
|
||||
// NewHandler creates a new handler instance
|
||||
// NewHandler creates a new handler instance.
|
||||
func NewHandler(vaultClient *vaultwarden.Client) *Handler {
|
||||
return &Handler{
|
||||
vaultClient: vaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
// HealthCheck handles GET /health
|
||||
// HealthCheck handles GET /health.
|
||||
func (h *Handler) HealthCheck(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{
|
||||
"status": "ok",
|
||||
"status": "ok",
|
||||
"service": "vaultwarden-api",
|
||||
})
|
||||
}
|
||||
|
||||
// GetSecret handles GET /secret/:name
|
||||
// GetSecret handles GET /secret/:name.
|
||||
func (h *Handler) GetSecret(c *fiber.Ctx) error {
|
||||
secretName := c.Params("name")
|
||||
|
||||
@@ -48,20 +48,19 @@ func (h *Handler) GetSecret(c *fiber.Ctx) error {
|
||||
|
||||
value, err := h.vaultClient.GetSecret(secretName)
|
||||
if err != nil {
|
||||
logger.Error.Printf("Failed to fetch secret (requested by IP: %s): %v", c.IP(), err)
|
||||
logger.Error.Printf("Failed to fetch secret (requested by IP: %s)", c.IP())
|
||||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
|
||||
"error": "secret not found",
|
||||
})
|
||||
}
|
||||
|
||||
// Return the secret value
|
||||
return c.JSON(fiber.Map{
|
||||
"name": secretName,
|
||||
"value": value,
|
||||
})
|
||||
}
|
||||
|
||||
// RefreshCache handles POST /refresh
|
||||
// RefreshCache handles POST /refresh.
|
||||
func (h *Handler) RefreshCache(c *fiber.Ctx) error {
|
||||
h.vaultClient.ClearCache()
|
||||
|
||||
|
||||
Reference in new issue
Block a user