✨ feat(admin): GET /api/v1/admin/jwt/secrets — metadata-only introspection (#51)
Co-authored-by: Gabriel Radureau <arcodange@gmail.com> Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
This commit was merged in pull request #51.
This commit is contained in:
@@ -25,11 +25,32 @@ func NewAdminHandler(authService user.AuthService) *AdminHandler {
|
||||
// RegisterRoutes registers admin routes
|
||||
func (h *AdminHandler) RegisterRoutes(router chi.Router) {
|
||||
router.Route("/jwt", func(r chi.Router) {
|
||||
r.Get("/secrets", h.handleListJWTSecrets)
|
||||
r.Post("/secrets", h.handleAddJWTSecret)
|
||||
r.Post("/secrets/rotate", h.handleRotateJWTSecret)
|
||||
})
|
||||
}
|
||||
|
||||
// handleListJWTSecrets godoc
|
||||
//
|
||||
// @Summary List JWT secrets metadata
|
||||
// @Description Returns metadata for every tracked JWT secret. The actual secret values are NOT included — exposing them via an admin endpoint would defeat the retention/rotation infrastructure. Each entry has is_primary, created_at_unix, expires_at_unix (optional), age_seconds, is_expired, and a SHA-256 fingerprint (first 16 hex chars) for ops correlation.
|
||||
// @Tags API/v1/Admin
|
||||
// @Produce json
|
||||
// @Success 200 {object} map[string]interface{} "List of secret metadata"
|
||||
// @Failure 401 {object} map[string]string "Unauthorized"
|
||||
// @Router /v1/admin/jwt/secrets [get]
|
||||
func (h *AdminHandler) handleListJWTSecrets(w http.ResponseWriter, r *http.Request) {
|
||||
infos := h.authService.ListJWTSecretsInfo()
|
||||
resp := map[string]interface{}{
|
||||
"count": len(infos),
|
||||
"secrets": infos,
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_ = json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
// AddJWTSecretRequest represents a request to add a new JWT secret
|
||||
type AddJWTSecretRequest struct {
|
||||
Secret string `json:"secret" validate:"required,min=16"`
|
||||
|
||||
Reference in New Issue
Block a user