Einladungscodes: registration_mode open|invite|closed, Admin-API /api/invites, App mit Code-Feld und Code-Verwaltung; v0.3.2

This commit is contained in:
OpenClaw Dev 2026-11-01 05:53:32 +01:00
parent d2658de099
commit cf5e0b1ca7
38 changed files with 665 additions and 25 deletions

View file

@ -80,6 +80,8 @@ type Config struct {
AuthToken string `yaml:"auth_token" json:"auth_token"`
// AllowRegistration enables self-service sign-up (default true).
AllowRegistration *bool `yaml:"allow_registration" json:"allow_registration"`
// RegistrationMode: open | invite | closed. Empty = derived from allow_registration.
RegistrationMode string `yaml:"registration_mode" json:"registration_mode"`
// TokenTTLHours is the lifetime of login tokens (default 720 = 30 days).
TokenTTLHours int `yaml:"token_ttl_hours" json:"token_ttl_hours"`
// AllowedOrigins for browser WebSocket/CORS. Empty = same host only. "*" must be set explicitly.
@ -164,6 +166,7 @@ func applyEnv(c *Config, get func(string) string) {
b := v == "1" || strings.EqualFold(v, "true") || strings.EqualFold(v, "yes")
c.AllowRegistration = &b
}
set("BYTECLAW_REGISTRATION_MODE", &c.RegistrationMode)
if v := get("BYTECLAW_ALLOWED_ORIGINS"); v != "" {
c.AllowedOrigins = nil
for _, o := range strings.Split(v, ",") {
@ -177,12 +180,29 @@ func applyEnv(c *Config, get func(string) string) {
// RegistrationAllowed reports allow_registration (default true).
func (c Config) RegistrationAllowed() bool { return c.AllowRegistration == nil || *c.AllowRegistration }
// Registration returns the effective registration mode (open, invite or closed).
func (c Config) Registration() string {
if m := strings.ToLower(strings.TrimSpace(c.RegistrationMode)); m != "" {
return m
}
if c.RegistrationAllowed() {
return "open"
}
return "closed"
}
// Validate enforces required fields and secure settings.
func (c Config) Validate() error {
var errs []error
if c.AuthToken != "" && len(c.AuthToken) < 16 {
errs = append(errs, errors.New("auth_token must be at least 16 characters when set (BYTECLAW_AUTH_TOKEN)"))
}
if m := c.Registration(); m != "open" && m != "invite" && m != "closed" {
errs = append(errs, errors.New("registration_mode must be open, invite or closed"))
}
if c.Registration() == "invite" && c.AuthToken == "" {
errs = append(errs, errors.New("registration_mode invite needs auth_token (only the admin can create invite codes)"))
}
if c.LLM.BaseURL == "" || c.LLM.Model == "" {
errs = append(errs, errors.New("llm.base_url and llm.model are required"))
}