From c5cec11c03f5e7f2f70301c9809c3d34ff5ca2cf Mon Sep 17 00:00:00 2001 From: kyy Date: Tue, 3 Feb 2026 17:58:58 +0900 Subject: [PATCH] =?UTF-8?q?=EC=97=B0=EB=8F=99=20=ED=95=B4=EC=A7=80=20api?= =?UTF-8?q?=20=EC=95=A4=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/cmd/server/main.go | 1 + backend/internal/handler/auth_handler.go | 29 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 35215a82..a51bea25 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -535,6 +535,7 @@ func main() { user.Post("/me/send-code", authHandler.SendUpdateCode) user.Post("/me/verify-code", authHandler.VerifyUpdateCode) user.Get("/rp/linked", authHandler.ListLinkedRps) + user.Delete("/rp/linked/:id", authHandler.RevokeLinkedRp) // Admin Routes admin := api.Group("/admin") diff --git a/backend/internal/handler/auth_handler.go b/backend/internal/handler/auth_handler.go index b9dda06d..b69353ff 100644 --- a/backend/internal/handler/auth_handler.go +++ b/backend/internal/handler/auth_handler.go @@ -3306,6 +3306,35 @@ func (h *AuthHandler) ListLinkedRps(c *fiber.Ctx) error { return c.JSON(linkedRpListResponse{Items: items}) } +func (h *AuthHandler) RevokeLinkedRp(c *fiber.Ctx) error { + clientID := c.Params("id") + if clientID == "" { + return fiber.NewError(fiber.StatusBadRequest, "client_id is required") + } + + subject, err := h.resolveConsentSubject(c) + if err != nil || subject == "" { + return fiber.NewError(fiber.StatusUnauthorized, "Authentication required") + } + + slog.Info("RevokeLinkedRp called", "subject", subject, "client_id", clientID) + + if h.Hydra == nil { + return fiber.NewError(fiber.StatusServiceUnavailable, "hydra admin unavailable") + } + + // Hydra에서 해당 사용자와 클라이언트의 모든 동의 세션을 삭제 + if err := h.Hydra.RevokeConsentSessions(c.Context(), subject, clientID); err != nil { + slog.Error("failed to revoke hydra consent sessions", "error", err) + return fiber.NewError(fiber.StatusInternalServerError, "Failed to revoke link") + } + + return c.Status(fiber.StatusOK).JSON(fiber.Map{ + "status": "success", + "message": "Link revoked successfully", + }) +} + func (h *AuthHandler) GetConsentRequest(c *fiber.Ctx) error { challenge := c.Query("consent_challenge") if challenge == "" {