Expose image studio flow and related admin controls

Bundle the current backend and web changes into one publishable snapshot
from the server worktree so the remote mirror reflects the deployed source.

Constraint: Push the existing mixed worktree from /docker/new-api/src without reshaping files
Rejected: Split into feature-specific commits | current worktree is already a single undifferentiated snapshot
Confidence: medium
Scope-risk: moderate
Directive: Split future feature work before deployment to preserve clearer history
Tested: git status inspection; git diff --stat review
Not-tested: build, lint, unit tests, integration tests
This commit is contained in:
OpenClaw Task Bot
2026-05-05 12:16:54 +08:00
parent 58c0258362
commit 92ee465a41
23 changed files with 2694 additions and 202 deletions

1087
controller/image_studio.go Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,10 @@ const (
SecureVerificationSessionKey = "secure_verified_at"
// PasskeyReadySessionKey means WebAuthn finished and /api/verify can finalize step-up verification.
PasskeyReadySessionKey = "secure_passkey_ready_at"
// secureVerificationMethodSessionKey stores the method that completed step-up verification.
secureVerificationMethodSessionKey = "secure_verification_method"
secureVerificationMethod2FA = "2fa"
secureVerificationMethodPasskey = "passkey"
// SecureVerificationTimeout 验证有效期(秒)
SecureVerificationTimeout = 300 // 5分钟
// PasskeyReadyTimeout passkey ready 标记有效期(秒)
@@ -77,6 +81,7 @@ func UniversalVerify(c *gin.Context) {
// 根据验证方式进行验证
var verified bool
var verifyMethod string
var sessionMethod string
var err error
switch req.Method {
@@ -91,6 +96,7 @@ func UniversalVerify(c *gin.Context) {
}
verified = validateTwoFactorAuth(twoFA, req.Code)
verifyMethod = "2FA"
sessionMethod = secureVerificationMethod2FA
case "passkey":
if !hasPasskey {
@@ -108,6 +114,7 @@ func UniversalVerify(c *gin.Context) {
return
}
verifyMethod = "Passkey"
sessionMethod = secureVerificationMethodPasskey
default:
common.ApiError(c, fmt.Errorf("不支持的验证方式: %s", req.Method))
@@ -120,7 +127,7 @@ func UniversalVerify(c *gin.Context) {
}
// 验证成功,在 session 中记录时间戳
now, err := setSecureVerificationSession(c)
now, err := setSecureVerificationSession(c, sessionMethod)
if err != nil {
common.ApiError(c, fmt.Errorf("保存验证状态失败: %v", err))
return
@@ -139,11 +146,16 @@ func UniversalVerify(c *gin.Context) {
})
}
func setSecureVerificationSession(c *gin.Context) (int64, error) {
func setSecureVerificationSession(c *gin.Context, method string) (int64, error) {
session := sessions.Default(c)
session.Delete(PasskeyReadySessionKey)
now := time.Now().Unix()
session.Set(SecureVerificationSessionKey, now)
if method != "" {
session.Set(secureVerificationMethodSessionKey, method)
} else {
session.Delete(secureVerificationMethodSessionKey)
}
if err := session.Save(); err != nil {
return 0, err
}

View File

@@ -475,6 +475,12 @@ func generateDefaultSidebarConfig(userRole int) string {
"personal": true,
}
// 其他功能区域 - 所有用户都可以访问
defaultConfig["other"] = map[string]interface{}{
"enabled": true,
"image_studio": true,
}
// 管理员区域 - 根据角色决定
if userRole == common.RoleAdminUser {
// 管理员可以访问管理员区域,但不能访问系统设置