Merge pull request #1200 from trheyi/main

Enhance user registration and configuration handling
This commit is contained in:
Max 2025-10-14 19:13:17 +08:00 committed by GitHub
commit 4bf2c6b998
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 114 additions and 28 deletions

View file

@ -396,6 +396,14 @@ func loadRegisterConfigs(_ string) error {
return fmt.Errorf("failed to parse register config %s: %v", filename, err)
}
// Process ENV variables in the configuration
processRegisterConfigENVVariables(&config)
// Copy third_party from signin config if available
if signinConfig, exists := fullConfigs[locale]; exists && signinConfig.ThirdParty != nil {
config.ThirdParty = signinConfig.ThirdParty
}
// Store register configuration
registerConfigs[locale] = &config
@ -614,6 +622,33 @@ func normalizeDuration(expiresIn string) (string, error) {
return normalized, nil
}
// processFormConfigENVVariables processes environment variables in the form configuration
func processFormConfigENVVariables(form *FormConfig) []string {
var missingEnvVars []string
if form == nil {
return missingEnvVars
}
// Process form captcha options
if form.Captcha != nil && form.Captcha.Options != nil {
for key, value := range form.Captcha.Options {
if strValue, ok := value.(string); ok {
// Check if ENV variable exists before replacement
if strings.HasPrefix(strValue, "$ENV.") {
envVar := strings.TrimPrefix(strValue, "$ENV.")
if _, exists := os.LookupEnv(envVar); !exists {
missingEnvVars = append(missingEnvVars, envVar)
}
}
form.Captcha.Options[key] = replaceENVVar(strValue)
}
}
}
return missingEnvVars
}
// processConfigENVVariables processes environment variables in the signin configuration
func processConfigENVVariables(config *Config) {
var missingEnvVars []string
@ -635,24 +670,23 @@ func processConfigENVVariables(config *Config) {
}
config.ClientSecret = replaceENVVar(config.ClientSecret)
// Process form captcha options
if config.Form != nil && config.Form.Captcha != nil && config.Form.Captcha.Options != nil {
for key, value := range config.Form.Captcha.Options {
if strValue, ok := value.(string); ok {
// Check if ENV variable exists before replacement
if strings.HasPrefix(strValue, "$ENV.") {
envVar := strings.TrimPrefix(strValue, "$ENV.")
if _, exists := os.LookupEnv(envVar); !exists {
missingEnvVars = append(missingEnvVars, envVar)
}
}
config.Form.Captcha.Options[key] = replaceENVVar(strValue)
}
}
}
// Process form configuration
formMissingVars := processFormConfigENVVariables(config.Form)
missingEnvVars = append(missingEnvVars, formMissingVars...)
// Log warning for missing environment variables (optional, can be removed if log package not available)
// Log warning for missing environment variables
if len(missingEnvVars) > 0 {
fmt.Printf("Warning: The following environment variables are not set in user configuration: %v\n", missingEnvVars)
fmt.Printf("Warning: The following environment variables are not set in signin configuration: %v\n", missingEnvVars)
}
}
// processRegisterConfigENVVariables processes environment variables in the register configuration
func processRegisterConfigENVVariables(config *RegisterConfig) {
// Process form configuration
missingEnvVars := processFormConfigENVVariables(config.Form)
// Log warning for missing environment variables
if len(missingEnvVars) > 0 {
fmt.Printf("Warning: The following environment variables are not set in register configuration: %v\n", missingEnvVars)
}
}

41
openapi/user/register.go Normal file
View file

@ -0,0 +1,41 @@
package user
import (
"github.com/gin-gonic/gin"
"github.com/yaoapp/yao/openapi/response"
"github.com/yaoapp/yao/openapi/utils"
)
// getRegisterConfig is the handler for get register configuration
func getRegisterConfig(c *gin.Context) {
// Get locale from query parameter (optional)
locale := c.Query("locale")
// Get register configuration for the specified locale (already includes third_party from signin config)
config := GetRegisterConfig(locale)
// Set session id if not exists
sid := utils.GetSessionID(c)
if sid == "" {
sid = generateSessionID()
response.SendSessionCookie(c, sid)
}
// If no configuration found, return error
if config == nil {
errorResp := &response.ErrorResponse{
Code: response.ErrInvalidRequest.Code,
ErrorDescription: "No register configuration found for the requested locale",
}
response.RespondWithError(c, response.StatusNotFound, errorResp)
return
}
// Return the register configuration
response.RespondWithSuccess(c, response.StatusOK, config)
}
// register is the handler for user registration
func register(c *gin.Context) {
// This is a placeholder - you may need to implement the actual registration logic here
}

View file

@ -41,10 +41,12 @@ type Config struct {
type FormConfig struct {
Username *UsernameConfig `json:"username,omitempty"`
Password *PasswordConfig `json:"password,omitempty"`
ConfirmPassword *PasswordConfig `json:"confirm_password,omitempty"`
Captcha *CaptchaConfig `json:"captcha,omitempty"`
ForgotPasswordLink bool `json:"forgot_password_link,omitempty"`
RememberMe bool `json:"remember_me,omitempty"`
RegisterLink string `json:"register_link,omitempty"`
LoginLink string `json:"login_link,omitempty"`
TermsOfServiceLink string `json:"terms_of_service_link,omitempty"`
PrivacyPolicyLink string `json:"privacy_policy_link,omitempty"`
}
@ -84,16 +86,24 @@ type ProviderRegisterConfig struct {
// RegisterConfig represents the register configuration
type RegisterConfig struct {
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Default bool `json:"default,omitempty"`
SuccessURL string `json:"success_url,omitempty"`
FailureURL string `json:"failure_url,omitempty"`
AutoLogin bool `json:"auto_login,omitempty"`
Role string `json:"role,omitempty"`
Type string `json:"type,omitempty"` // User type id
Form *FormConfig `json:"form,omitempty"`
ConfirmPassword *PasswordConfig `json:"confirm_password,omitempty"`
Title string `json:"title,omitempty"`
Description string `json:"description,omitempty"`
Default bool `json:"default,omitempty"`
SuccessURL string `json:"success_url,omitempty"`
FailureURL string `json:"failure_url,omitempty"`
AutoLogin bool `json:"auto_login,omitempty"`
Role string `json:"role,omitempty"`
Type string `json:"type,omitempty"` // User type id
Form *FormConfig `json:"form,omitempty"`
Messenger *MessengerConfig `json:"messenger,omitempty"`
InviteRequired bool `json:"invite_required,omitempty"`
ThirdParty *ThirdParty `json:"third_party,omitempty"` // Third party login configuration (copied from signin config)
}
// MessengerConfig represents the messenger configuration for user registration
type MessengerConfig struct {
Channel string `json:"channel,omitempty"`
Templates map[string]string `json:"templates,omitempty"` // mail, sms templates
}
// YaoClientConfig represents the Yao OpenAPI Client config

View file

@ -31,7 +31,8 @@ func Attach(group *gin.RouterGroup, oauth types.OAuth) {
group.GET("/login", getLoginConfig) // Get login page config (public) - migrated from /signin
group.POST("/login", login) // User login (public) - migrated from /signin
group.GET("/login/captcha", getCaptcha) // Get captcha for login (public)
group.POST("/register", placeholder) // User register (public)
group.GET("/register", getRegisterConfig) // Get register page config (public)
group.POST("/register", register) // User register (public)
group.POST("/logout", oauth.Guard, placeholder) // User logout
// Logined User Settings