forked from baron/baron-sso
구조 통합
This commit is contained in:
@@ -484,6 +484,7 @@ func main() {
|
||||
user := api.Group("/user")
|
||||
user.Get("/me", authHandler.GetMe)
|
||||
user.Put("/me", authHandler.UpdateMe)
|
||||
user.Post("/me/password", authHandler.ChangeMyPassword)
|
||||
user.Post("/me/send-code", authHandler.SendUpdateCode)
|
||||
user.Post("/me/verify-code", authHandler.VerifyUpdateCode)
|
||||
user.Get("/rp/linked", authHandler.ListLinkedRps)
|
||||
|
||||
@@ -452,6 +452,24 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/MessageResponse"
|
||||
|
||||
/api/v1/user/me/password:
|
||||
post:
|
||||
tags: [User]
|
||||
summary: 비밀번호 변경
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/UserPasswordChangeRequest"
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/MessageResponse"
|
||||
|
||||
/api/v1/user/me/verify-code:
|
||||
post:
|
||||
tags: [User]
|
||||
@@ -1127,6 +1145,14 @@ components:
|
||||
companyCode:
|
||||
type: string
|
||||
|
||||
UserPasswordChangeRequest:
|
||||
type: object
|
||||
properties:
|
||||
currentPassword:
|
||||
type: string
|
||||
newPassword:
|
||||
type: string
|
||||
|
||||
UserProfileSendCodeRequest:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
@@ -96,3 +96,9 @@ type PasswordResetCompleteRequest struct {
|
||||
LoginID string `json:"loginId"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
|
||||
// PasswordChangeRequest는 로그인 상태에서 비밀번호 변경 요청을 표현합니다.
|
||||
type PasswordChangeRequest struct {
|
||||
CurrentPassword string `json:"currentPassword"`
|
||||
NewPassword string `json:"newPassword"`
|
||||
}
|
||||
|
||||
@@ -3970,6 +3970,72 @@ func (h *AuthHandler) UpdateMe(c *fiber.Ctx) error {
|
||||
})
|
||||
}
|
||||
|
||||
// ChangeMyPassword - 로그인 상태에서 현재 비밀번호를 확인한 뒤 변경합니다.
|
||||
func (h *AuthHandler) ChangeMyPassword(c *fiber.Ctx) error {
|
||||
var req domain.PasswordChangeRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid request body"})
|
||||
}
|
||||
|
||||
currentPassword := strings.TrimSpace(req.CurrentPassword)
|
||||
newPassword := strings.TrimSpace(req.NewPassword)
|
||||
if currentPassword == "" || newPassword == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Current password and new password are required"})
|
||||
}
|
||||
|
||||
policy := h.resolvePasswordPolicy()
|
||||
if err := validatePasswordWithPolicy(policy, newPassword); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
loginID := ""
|
||||
token := h.getBearerToken(c)
|
||||
if token != "" && looksLikeJWT(token) && h.DescopeClient != nil {
|
||||
authorized, userToken, err := h.DescopeClient.Auth.ValidateSessionWithToken(c.Context(), token)
|
||||
if err == nil && authorized {
|
||||
resolved, err := h.resolveDescopeLoginID(c.Context(), userToken)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Failed to resolve login ID"})
|
||||
}
|
||||
loginID = resolved
|
||||
}
|
||||
}
|
||||
|
||||
if loginID == "" && token != "" {
|
||||
if resolved, err := h.resolveKratosLoginID(token); err == nil {
|
||||
loginID = resolved
|
||||
}
|
||||
}
|
||||
|
||||
if loginID == "" {
|
||||
cookie := c.Get("Cookie")
|
||||
if cookie == "" {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Missing authorization token"})
|
||||
}
|
||||
_, traits, err := h.getKratosIdentityWithCookie(cookie)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Invalid session"})
|
||||
}
|
||||
loginID = pickLoginIDFromTraits(traits)
|
||||
if loginID == "" {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Login ID not found"})
|
||||
}
|
||||
if !strings.Contains(loginID, "@") {
|
||||
loginID = normalizePhoneForLoginID(loginID)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := h.IdpProvider.SignIn(loginID, currentPassword); err != nil {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "Current password is invalid"})
|
||||
}
|
||||
|
||||
if err := h.IdpProvider.UpdateUserPassword(loginID, newPassword, nil); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "Failed to update password"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"message": "Password updated"})
|
||||
}
|
||||
|
||||
// SendUpdateCode - Sends OTP for phone number change
|
||||
func (h *AuthHandler) SendUpdateCode(c *fiber.Ctx) error {
|
||||
token := h.getBearerToken(c)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
var sensitiveKeys = map[string]struct{}{
|
||||
"password": {},
|
||||
"currentpassword": {},
|
||||
"newpassword": {},
|
||||
"oldpassword": {},
|
||||
"token": {},
|
||||
|
||||
Reference in New Issue
Block a user