diff --git a/backend/internal/handler/dev_handler.go b/backend/internal/handler/dev_handler.go index 732e4e2f..33a9b3f5 100644 --- a/backend/internal/handler/dev_handler.go +++ b/backend/internal/handler/dev_handler.go @@ -13,16 +13,18 @@ import ( ) type DevHandler struct { - Hydra *service.HydraAdminService - Redis *service.RedisService - SecretRepo domain.ClientSecretRepository + Hydra *service.HydraAdminService + Redis *service.RedisService + SecretRepo domain.ClientSecretRepository + KratosAdmin *service.KratosAdminService } func NewDevHandler(redis *service.RedisService, secretRepo domain.ClientSecretRepository) *DevHandler { return &DevHandler{ - Hydra: service.NewHydraAdminService(), - Redis: redis, - SecretRepo: secretRepo, + Hydra: service.NewHydraAdminService(), + Redis: redis, + SecretRepo: secretRepo, + KratosAdmin: service.NewKratosAdminService(), } } @@ -59,6 +61,7 @@ type clientEndpoints struct { type consentSummary struct { Subject string `json:"subject"` + UserName string `json:"userName,omitempty"` ClientID string `json:"clientId"` ClientName string `json:"clientName,omitempty"` GrantedScopes []string `json:"grantedScopes"` @@ -395,6 +398,15 @@ func (h *DevHandler) ListConsents(c *fiber.Ctx) error { if subject == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "subject is required"}) } + + // If subject is not a UUID, try to resolve it as an identifier (email/username) + if _, err := uuid.Parse(subject); err != nil { + resolved, err := h.KratosAdmin.FindIdentityIDByIdentifier(c.Context(), subject) + if err == nil && resolved != "" { + subject = resolved + } + } + clientID := strings.TrimSpace(c.Query("client_id")) sessions, err := h.Hydra.ListConsentSessions(c.Context(), subject, clientID) @@ -412,6 +424,21 @@ func (h *DevHandler) ListConsents(c *fiber.Ctx) error { if subject == "" && session.ConsentRequest != nil { subject = session.ConsentRequest.Subject } + + userName := "" + if subject != "" { + identity, err := h.KratosAdmin.GetIdentity(c.Context(), subject) + if err == nil && identity != nil { + if name, ok := identity.Traits["name"].(string); ok { + userName = name + } else if displayName, ok := identity.Traits["displayname"].(string); ok { + userName = displayName + } else if email, ok := identity.Traits["email"].(string); ok { + userName = email + } + } + } + authAt := "" if session.AuthenticatedAt != nil { authAt = session.AuthenticatedAt.Format(time.RFC3339) @@ -422,6 +449,7 @@ func (h *DevHandler) ListConsents(c *fiber.Ctx) error { } items = append(items, consentSummary{ Subject: subject, + UserName: userName, ClientID: client.ClientID, ClientName: client.ClientName, GrantedScopes: session.GrantedScope, @@ -437,6 +465,15 @@ func (h *DevHandler) RevokeConsents(c *fiber.Ctx) error { if subject == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "subject is required"}) } + + // If subject is not a UUID, try to resolve it as an identifier (email/username) + if _, err := uuid.Parse(subject); err != nil { + resolved, err := h.KratosAdmin.FindIdentityIDByIdentifier(c.Context(), subject) + if err == nil && resolved != "" { + subject = resolved + } + } + clientID := strings.TrimSpace(c.Query("client_id")) if err := h.Hydra.RevokeConsentSessions(c.Context(), subject, clientID); err != nil {