1
0
forked from baron/baron-sso

Merge remote-tracking branch 'origin/main' into dev/mypage

This commit is contained in:
2026-01-27 13:46:04 +09:00
21 changed files with 1902 additions and 101 deletions

View File

@@ -3,6 +3,7 @@ package main
import (
"baron-sso-backend/internal/domain"
"baron-sso-backend/internal/handler"
"baron-sso-backend/internal/idp"
"baron-sso-backend/internal/logger"
"baron-sso-backend/internal/repository"
"baron-sso-backend/internal/service"
@@ -73,14 +74,12 @@ func main() {
)
// --- Fail-Fast Schema Validation ---
// Initialize the IDP Provider (Descope)
descopeProjectID := getEnv("DESCOPE_PROJECT_ID", "")
descopeManagementKey := getEnv("DESCOPE_MANAGEMENT_KEY", "")
// We create a provider instance to check schema compatibility.
// This ensures that our BrokerUser model requirements (e.g. custom attributes)
// are supported by the configured IDP.
idpProvider := service.NewDescopeProvider(descopeProjectID, descopeManagementKey)
// 팩토리를 사용하여 IDP 공급자를 초기화합니다.
idpProvider, err := idp.InitializeProvider()
if err != nil {
slog.Error("❌ [CRITICAL] Failed to initialize IDP Provider", "error", err)
os.Exit(1)
}
if err := validator.ValidateIDPCompatibility(domain.BrokerUser{}, idpProvider); err != nil {
slog.Error("❌ [CRITICAL] Broker Schema Mismatch",
@@ -167,8 +166,21 @@ func main() {
AllowHeaders: "Origin, Content-Type, Accept, Authorization",
AllowMethods: "GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS",
}))
// Ensure COOKIE_SECRET is exactly 32 bytes for AES-256
cookieSecret := getEnv("COOKIE_SECRET", "secret-key-must-be-32-bytes-long!")
if len(cookieSecret) != 32 {
slog.Warn("COOKIE_SECRET length is not 32 bytes. Adjusting...", "original_length", len(cookieSecret))
if len(cookieSecret) > 32 {
cookieSecret = cookieSecret[:32]
} else {
// Pad with '0' if too short
cookieSecret = fmt.Sprintf("%-32s", cookieSecret)
}
}
app.Use(encryptcookie.New(encryptcookie.Config{
Key: getEnv("COOKIE_SECRET", "secret-key-must-be-32-bytes-long!"),
Key: cookieSecret,
}))
// Routes
@@ -228,6 +240,14 @@ func main() {
auth.Post("/enchanted-link/init", authHandler.InitEnchantedLink)
auth.Post("/enchanted-link/poll", authHandler.PollEnchantedLink)
auth.Post("/magic-link/verify", authHandler.VerifyMagicLink)
auth.Post("/password/login", authHandler.PasswordLogin)
auth.Post("/password/reset/initiate", authHandler.InitiatePasswordReset)
// [Changed] Use Interstitial Page for GET to prevent Scanner consumption
auth.Get("/password/reset/verify", authHandler.VerifyPasswordResetPage)
// [Added] Use POST for actual verification triggered by the user
auth.Post("/password/reset/verify", authHandler.ProcessPasswordResetToken)
auth.Post("/password/reset/complete", authHandler.CompletePasswordReset)
auth.Get("/password/policy", authHandler.GetPasswordPolicy)
auth.Post("/sms", authHandler.SendSms)
auth.Post("/verify-sms", authHandler.VerifySms)
auth.Post("/qr/init", authHandler.InitQRLogin)