diff --git a/openapi/user/config.go b/openapi/user/config.go index 05c502d3..00a5e72b 100644 --- a/openapi/user/config.go +++ b/openapi/user/config.go @@ -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) } } diff --git a/openapi/user/register.go b/openapi/user/register.go new file mode 100644 index 00000000..285aab91 --- /dev/null +++ b/openapi/user/register.go @@ -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 +} diff --git a/openapi/user/types.go b/openapi/user/types.go index 7fada0b3..ac17784f 100644 --- a/openapi/user/types.go +++ b/openapi/user/types.go @@ -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 diff --git a/openapi/user/user.go b/openapi/user/user.go index 4394423f..914bd9e9 100644 --- a/openapi/user/user.go +++ b/openapi/user/user.go @@ -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