优化了一些问题
This commit is contained in:
@@ -279,132 +279,104 @@ class SchemaUsers {
|
||||
]],
|
||||
],
|
||||
],
|
||||
'oauth' => [
|
||||
'key' => 'oauth',
|
||||
'title' => '第三方登录',
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'basic', 'title' => '基础设置', 'fields' => [
|
||||
['key' => 'oauth_s', 'label' => '启用第三方登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_proxy_mode', 'label' => '代理登录模式', 'type' => 'radio', 'default' => 'close', 'options' => [
|
||||
['label' => '关闭', 'value' => 'close'],
|
||||
['label' => '服务端', 'value' => 'server'],
|
||||
['label' => '客户端', 'value' => 'client'],
|
||||
]],
|
||||
['key' => 'oauth_proxy_secret', 'label' => '代理 HMAC 密钥', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'oauth_proxy_mode', 'not' => 'close']],
|
||||
['key' => 'oauth_proxy_server_url', 'label' => '服务端地址', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'client']],
|
||||
['key' => 'oauth_proxy_server_providers', 'label' => '服务端允许平台', 'type' => 'checkbox', 'default' => ['github', 'gitee', 'qq', 'google'], 'options' => [
|
||||
['label' => 'GitHub', 'value' => 'github'],
|
||||
['label' => 'Gitee', 'value' => 'gitee'],
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => 'Google', 'value' => 'google'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
['label' => '百度', 'value' => 'baidu'],
|
||||
['label' => '支付宝', 'value' => 'alipay'],
|
||||
], 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'server']],
|
||||
['key' => 'oauth_proxy_client_providers', 'label' => '客户端启用平台', 'type' => 'checkbox', 'default' => ['github', 'gitee', 'qq', 'google'], 'options' => [
|
||||
['label' => 'GitHub', 'value' => 'github'],
|
||||
['label' => 'Gitee', 'value' => 'gitee'],
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => 'Google', 'value' => 'google'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
['label' => '百度', 'value' => 'baidu'],
|
||||
['label' => '支付宝', 'value' => 'alipay'],
|
||||
], 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'client']],
|
||||
['key' => 'oauth_proxy_gzh_type', 'label' => '代理公众号类型', 'type' => 'radio', 'default' => 'service', 'options' => [
|
||||
['label' => '服务号', 'value' => 'service'],
|
||||
['label' => '订阅号', 'value' => 'subscribe'],
|
||||
], 'dependsOn' => ['key' => 'oauth_proxy_mode', 'not' => 'close']],
|
||||
['key' => 'oauth_bind_type', 'label' => '绑定方式', 'type' => 'radio', 'default' => 'auto', 'options' => [
|
||||
['label' => '自动绑定', 'value' => 'auto'],
|
||||
['label' => '手动绑定', 'value' => 'manual'],
|
||||
]],
|
||||
['key' => 'oauth_button_lg', 'label' => '大按钮样式', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'weixingzh_priority', 'label' => 'PC端优先微信扫码', 'type' => 'switch', 'default' => false, 'help' => '开启后 PC 端登录框优先显示微信公众号扫码'],
|
||||
['key' => 'weixingzh_auto', 'label' => '微信APP内自动登录', 'type' => 'switch', 'default' => false, 'help' => '在微信内置浏览器中自动使用公众号授权登录'],
|
||||
['key' => 'weixingzh_auto_expires', 'label' => '自动登录频率限制 (秒)', 'type' => 'number', 'default' => 3600, 'min' => 0, 'max' => 86400, 'dependsOn' => ['key' => 'weixingzh_auto', 'value' => true]],
|
||||
]],
|
||||
['key' => 'providers', 'title' => '登录提供商', 'fields' => [
|
||||
['key' => 'oauth_github_s', 'label' => 'GitHub登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_gitee_s', 'label' => 'Gitee登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_qq_s', 'label' => 'QQ登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weixingzh_s', 'label' => '微信公众号登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weixin_s', 'label' => '微信开放平台登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weibo_s', 'label' => '微博登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_baidu_s', 'label' => '百度登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_alipay_s', 'label' => '支付宝登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'clogin_s', 'label' => '彩虹聚合登录', 'type' => 'switch', 'default' => false],
|
||||
]],
|
||||
['key' => 'github', 'title' => 'GitHub配置', 'fields' => [
|
||||
['key' => 'github_appid', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'github_appkey', 'label' => 'Client Secret', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'gitee', 'title' => 'Gitee配置', 'fields' => [
|
||||
['key' => 'gitee_appid', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'gitee_appkey', 'label' => 'Client Secret', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'qq', 'title' => 'QQ配置', 'fields' => [
|
||||
['key' => 'qq_appid', 'label' => 'App ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'qq_appkey', 'label' => 'App Key', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'weixin', 'title' => '微信开放平台配置', 'fields' => [
|
||||
['key' => 'weixin_appid', 'label' => 'AppID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixin_appsecret', 'label' => 'AppSecret', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'weixingzh', 'title' => '微信公众号配置', 'fields' => [
|
||||
['key' => 'weixingzh_gzh_type', 'label' => '公众号类型', 'type' => 'radio', 'default' => 'service', 'options' => [
|
||||
['label' => '服务号', 'value' => 'service'],
|
||||
['label' => '订阅号', 'value' => 'subscribe'],
|
||||
]],
|
||||
['key' => 'weixingzh_token', 'label' => 'Token', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixingzh_token_nocheck', 'label' => '不验证Token', 'type' => 'switch', 'default' => false, 'help' => '开发调试时可跳过 Token 验证'],
|
||||
['key' => 'weixingzh_encoding_aes_key', 'label' => 'EncodingAESKey', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixingzh_appid', 'label' => 'AppID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixingzh_appsecret', 'label' => 'AppSecret', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixingzh_code_qrcode', 'label' => '公众号二维码', 'type' => 'media', 'default' => '', 'help' => '引导用户扫码关注登录的二维码图片'],
|
||||
['key' => 'weixingzh_code_keyword', 'label' => '登录回复关键词', 'type' => 'input', 'default' => '登录', 'help' => '用户在公众号内回复此关键词触发登录验证码'],
|
||||
['key' => 'weixingzh_code_reply', 'label' => '验证码回复模板', 'type' => 'textarea', 'default' => '您的验证码是:%s,有效期 %d 分钟。', 'help' => '%s=验证码,%d=有效分钟数'],
|
||||
['key' => 'weixingzh_code_subscribe_reply', 'label' => '新关注回复模板', 'type' => 'textarea', 'default' => '欢迎关注!回复「%s」获取登录验证码。', 'help' => '%s=登录关键词'],
|
||||
['key' => 'weixingzh_subscribe_msg', 'label' => '关注后回复', 'type' => 'textarea', 'default' => '', 'help' => '用户关注公众号后的自动回复文案'],
|
||||
['key' => 'weixingzh_new_subscribe_msg', 'label' => '新用户关注回复', 'type' => 'textarea', 'default' => '', 'help' => '首次关注用户的专属回复文案,留空使用通用回复'],
|
||||
['key' => 'weixingzh_scan_msg', 'label' => '扫码回复', 'type' => 'textarea', 'default' => '', 'help' => '用户扫码关注公众号后的回复文案'],
|
||||
['key' => 'weixingzh_auto_reply_text', 'label' => '文本自动回复', 'type' => 'textarea', 'default' => '', 'help' => '收到文本消息的自动回复'],
|
||||
['key' => 'weixingzh_auto_reply_search', 'label' => '搜索回复', 'type' => 'textarea', 'default' => '', 'help' => '未匹配关键词时的搜索提示回复'],
|
||||
['key' => 'weixingzh_auto_reply_image', 'label' => '图片回复', 'type' => 'textarea', 'default' => '', 'help' => '收到图片消息的自动回复'],
|
||||
['key' => 'weixingzh_auto_reply_voice', 'label' => '语音回复', 'type' => 'textarea', 'default' => '', 'help' => '收到语音消息的自动回复'],
|
||||
['key' => 'weixingzh_auto_reply_default', 'label' => '默认回复', 'type' => 'textarea', 'default' => '暂不支持此类型的消息', 'help' => '其他未匹配消息类型的兜底回复'],
|
||||
['key' => 'weixingzh_gzh_menu', 'label' => '自定义菜单 JSON', 'type' => 'textarea', 'default' => '', 'help' => '微信公众号自定义菜单 JSON 配置,留空不创建菜单'],
|
||||
]],
|
||||
['key' => 'weibo', 'title' => '微博配置', 'fields' => [
|
||||
['key' => 'weibo_appid', 'label' => 'App Key', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weibo_appkey', 'label' => 'App Secret', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'baidu', 'title' => '百度配置', 'fields' => [
|
||||
['key' => 'baidu_appid', 'label' => 'API Key', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'baidu_appkey', 'label' => 'Secret Key', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
['key' => 'clogin', 'title' => '彩虹聚合登录', 'fields' => [
|
||||
['key' => 'clogin_url', 'label' => '接口地址', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true], 'help' => '如 https://xxx.com'],
|
||||
['key' => 'clogin_id', 'label' => 'AppID', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
['key' => 'clogin_key', 'label' => 'AppKey', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
['key' => 'clogin_oauth_s', 'label' => '启用平台', 'type' => 'checkbox', 'default' => ['qq', 'weixin', 'weibo', 'alipay'], 'options' => [
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
['label' => '支付宝', 'value' => 'alipay'],
|
||||
['label' => '百度', 'value' => 'baidu'],
|
||||
], 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
]],
|
||||
['key' => 'alipay', 'title' => '支付宝配置', 'fields' => [
|
||||
['key' => 'alipay_appid', 'label' => 'AppID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'alipay_privatekey', 'label' => '应用私钥', 'type' => 'textarea', 'sanitize_type' => 'code', 'default' => ''],
|
||||
['key' => 'alipay_publickey', 'label' => '支付宝公钥', 'type' => 'input', 'default' => ''],
|
||||
]],
|
||||
],
|
||||
],
|
||||
'oauth' => [
|
||||
'key' => 'oauth',
|
||||
'title' => '第三方登录',
|
||||
'version' => '1.0.0',
|
||||
'option_key' => 'aksrt_settings',
|
||||
'groups' => [
|
||||
['key' => 'basic', 'title' => '基础设置', 'fields' => [
|
||||
['key' => 'oauth_s', 'label' => '启用第三方登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_proxy_mode', 'label' => '代理登录模式', 'type' => 'radio', 'default' => 'close', 'options' => [
|
||||
['label' => '关闭', 'value' => 'close'],
|
||||
['label' => '服务端', 'value' => 'server'],
|
||||
['label' => '客户端', 'value' => 'client'],
|
||||
]],
|
||||
['key' => 'oauth_proxy_secret', 'label' => '代理 HMAC 密钥', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => '', 'dependsOn' => ['key' => 'oauth_proxy_mode', 'not' => 'close']],
|
||||
['key' => 'oauth_proxy_server_url', 'label' => '服务端地址', 'type' => 'input', 'sanitize_type' => 'url', 'default' => '', 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'client']],
|
||||
['key' => 'oauth_proxy_server_providers', 'label' => '服务端允许平台', 'type' => 'checkbox', 'default' => ['github', 'gitee', 'qq', 'google'], 'options' => [
|
||||
['label' => 'GitHub', 'value' => 'github'],
|
||||
['label' => 'Gitee', 'value' => 'gitee'],
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => 'Google', 'value' => 'google'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
], 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'server']],
|
||||
['key' => 'oauth_proxy_client_providers', 'label' => '客户端启用平台', 'type' => 'checkbox', 'default' => ['github', 'gitee', 'qq', 'google'], 'options' => [
|
||||
['label' => 'GitHub', 'value' => 'github'],
|
||||
['label' => 'Gitee', 'value' => 'gitee'],
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => 'Google', 'value' => 'google'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
], 'dependsOn' => ['key' => 'oauth_proxy_mode', 'value' => 'client']],
|
||||
['key' => 'oauth_bind_type', 'label' => '绑定方式', 'type' => 'radio', 'default' => 'auto', 'options' => [
|
||||
['label' => '自动绑定', 'value' => 'auto'],
|
||||
['label' => '手动绑定', 'value' => 'manual'],
|
||||
]],
|
||||
['key' => 'oauth_button_lg', 'label' => '大按钮样式', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'weixingzh_priority', 'label' => 'PC端优先微信扫码', 'type' => 'switch', 'default' => false, 'help' => '开启后 PC 端登录框优先显示微信公众号扫码'],
|
||||
]],
|
||||
['key' => 'providers', 'title' => '登录提供商', 'fields' => [
|
||||
['key' => 'oauth_github_s', 'label' => 'GitHub登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_gitee_s', 'label' => 'Gitee登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_qq_s', 'label' => 'QQ登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_google_s', 'label' => 'Google登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weibo_s', 'label' => '微博登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weixin_s', 'label' => '微信开放平台登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'oauth_weixingzh_s', 'label' => '微信公众号登录', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'clogin_s', 'label' => '彩虹聚合登录', 'type' => 'switch', 'default' => false],
|
||||
]],
|
||||
['key' => 'github', 'title' => 'GitHub配置', 'fields' => [
|
||||
['key' => 'github_appid', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'github_appkey', 'label' => 'Client Secret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'gitee', 'title' => 'Gitee配置', 'fields' => [
|
||||
['key' => 'gitee_appid', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'gitee_appkey', 'label' => 'Client Secret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'qq', 'title' => 'QQ配置', 'fields' => [
|
||||
['key' => 'qq_appid', 'label' => 'App ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'qq_appkey', 'label' => 'App Key', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'google', 'title' => 'Google配置', 'fields' => [
|
||||
['key' => 'google_client_id', 'label' => 'Client ID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'google_client_secret', 'label' => 'Client Secret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'weibo', 'title' => '微博配置', 'fields' => [
|
||||
['key' => 'weibo_appid', 'label' => 'App Key', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weibo_appkey', 'label' => 'App Secret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'weixin', 'title' => '微信开放平台配置', 'fields' => [
|
||||
['key' => 'weixin_appid', 'label' => 'AppID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixin_appsecret', 'label' => 'AppSecret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
]],
|
||||
['key' => 'weixingzh', 'title' => '微信公众号配置', 'fields' => [
|
||||
['key' => 'weixingzh_gzh_type', 'label' => '公众号类型', 'type' => 'radio', 'default' => 'service', 'options' => [
|
||||
['label' => '服务号', 'value' => 'service'],
|
||||
['label' => '订阅号', 'value' => 'subscribe'],
|
||||
]],
|
||||
['key' => 'weixingzh_token', 'label' => 'Token', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
['key' => 'weixingzh_appid', 'label' => 'AppID', 'type' => 'input', 'default' => ''],
|
||||
['key' => 'weixingzh_appsecret', 'label' => 'AppSecret', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => ''],
|
||||
['key' => 'weixingzh_code_qrcode', 'label' => '公众号二维码', 'type' => 'media', 'default' => '', 'help' => '引导用户扫码关注登录的二维码图片'],
|
||||
['key' => 'weixingzh_code_keyword', 'label' => '登录回复关键词', 'type' => 'input', 'default' => '登录', 'help' => '用户在公众号内回复此关键词触发登录验证码'],
|
||||
['key' => 'weixingzh_code_reply', 'label' => '验证码回复模板', 'type' => 'textarea', 'default' => '您的验证码是:%s,有效期 %d 分钟。', 'help' => '%s=验证码,%d=有效分钟数'],
|
||||
['key' => 'weixingzh_subscribe_msg', 'label' => '关注后回复', 'type' => 'textarea', 'default' => '', 'help' => '用户关注公众号后的自动回复文案'],
|
||||
['key' => 'weixingzh_scan_msg', 'label' => '扫码回复', 'type' => 'textarea', 'default' => '', 'help' => '用户扫码关注公众号后的回复文案'],
|
||||
]],
|
||||
['key' => 'clogin', 'title' => '彩虹聚合登录', 'fields' => [
|
||||
['key' => 'clogin_url', 'label' => '接口地址', 'type' => 'input', 'sanitize_type' => 'url', 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true], 'help' => '如 https://xxx.com,不要带 connect.php'],
|
||||
['key' => 'clogin_id', 'label' => 'AppID', 'type' => 'input', 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
['key' => 'clogin_key', 'label' => 'AppKey', 'type' => 'input', 'inputType' => 'password', 'secret' => true, 'default' => '', 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
['key' => 'clogin_oauth_s', 'label' => '启用平台', 'type' => 'checkbox', 'default' => ['qq', 'weixin', 'weibo'], 'options' => [
|
||||
['label' => 'QQ', 'value' => 'qq'],
|
||||
['label' => '微信', 'value' => 'weixin'],
|
||||
['label' => '微博', 'value' => 'weibo'],
|
||||
], 'dependsOn' => ['key' => 'clogin_s', 'value' => true]],
|
||||
]],
|
||||
],
|
||||
],
|
||||
'sms' => [
|
||||
'key' => 'sms',
|
||||
'title' => '短信接口',
|
||||
|
||||
+188
-10
@@ -139,6 +139,12 @@ class SchemaProvider {
|
||||
$clean[$key] = $this->sanitize_field_value($data[$key], $field);
|
||||
}
|
||||
}
|
||||
if (!empty($data['__clear_secrets']) && is_array($data['__clear_secrets'])) {
|
||||
$clean['__clear_secrets'] = array_values(array_intersect(
|
||||
array_map('sanitize_key', $data['__clear_secrets']),
|
||||
$this->secret_field_keys($schema)
|
||||
));
|
||||
}
|
||||
|
||||
return $clean;
|
||||
}
|
||||
@@ -266,6 +272,15 @@ class SchemaProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if ($domain === 'users' && ($section === 'oauth' || $section === '')) {
|
||||
$stored = get_option('aksrt_settings', []);
|
||||
$merged = is_array($stored) ? array_merge($stored, $data) : $data;
|
||||
foreach ((array) ($data['__clear_secrets'] ?? []) as $secret_key) {
|
||||
$merged[sanitize_key((string) $secret_key)] = '';
|
||||
}
|
||||
$errors = array_merge($errors, $this->validate_oauth_settings($merged, is_array($stored) ? $stored : []));
|
||||
}
|
||||
|
||||
if ($domain === 'payment' && $section === 'withdrawal') {
|
||||
$stored = get_option('aksrt_settings', []);
|
||||
$merged = is_array($stored) ? array_merge($stored, $data) : $data;
|
||||
@@ -307,6 +322,132 @@ class SchemaProvider {
|
||||
return ['valid' => empty($errors), 'errors' => $errors];
|
||||
}
|
||||
|
||||
private function validate_oauth_settings(array $settings, array $stored = []): array {
|
||||
if (empty($settings['oauth_s'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
$mode = sanitize_key((string) ($settings['oauth_proxy_mode'] ?? 'close'));
|
||||
$secret_configured = $this->oauth_secret_is_configured($settings['oauth_proxy_secret'] ?? '', $stored['oauth_proxy_secret'] ?? '');
|
||||
|
||||
if ($mode === 'client') {
|
||||
$url = trim((string) ($settings['oauth_proxy_server_url'] ?? ''));
|
||||
if (!$this->is_secure_oauth_url($url)) {
|
||||
$errors[] = __('客户端代理模式需要有效的 HTTPS 服务端地址', 'aksrt');
|
||||
}
|
||||
if (!$secret_configured) {
|
||||
$errors[] = __('客户端代理模式需要代理 HMAC 密钥', 'aksrt');
|
||||
}
|
||||
if (empty($settings['oauth_proxy_client_providers']) || !is_array($settings['oauth_proxy_client_providers'])) {
|
||||
$errors[] = __('客户端代理模式至少需要启用一个登录平台', 'aksrt');
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
if ($mode === 'server') {
|
||||
if (!$secret_configured) {
|
||||
$errors[] = __('服务端代理模式需要代理 HMAC 密钥', 'aksrt');
|
||||
}
|
||||
$selected = is_array($settings['oauth_proxy_server_providers'] ?? null) ? $settings['oauth_proxy_server_providers'] : [];
|
||||
if ($selected === []) {
|
||||
$errors[] = __('服务端代理模式至少需要允许一个登录平台', 'aksrt');
|
||||
}
|
||||
$provider_fields = [
|
||||
'github' => ['GitHub', 'github_appid', 'github_appkey'],
|
||||
'gitee' => ['Gitee', 'gitee_appid', 'gitee_appkey'],
|
||||
'qq' => ['QQ', 'qq_appid', 'qq_appkey'],
|
||||
'google' => ['Google', 'google_client_id', 'google_client_secret'],
|
||||
'weibo' => ['微博', 'weibo_appid', 'weibo_appkey'],
|
||||
'weixin' => ['微信开放平台', 'weixin_appid', 'weixin_appsecret'],
|
||||
];
|
||||
foreach ($selected as $provider) {
|
||||
if (!isset($provider_fields[$provider])) {
|
||||
continue;
|
||||
}
|
||||
[$label, $id_key, $secret_key] = $provider_fields[$provider];
|
||||
if (trim((string) ($settings[$id_key] ?? '')) === '' || !$this->oauth_secret_is_configured($settings[$secret_key] ?? '', $stored[$secret_key] ?? '')) {
|
||||
$errors[] = sprintf(__('代理服务端的 %s 平台缺少完整凭据', 'aksrt'), $label);
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
$providers = [
|
||||
'github' => ['GitHub', 'github_appid', 'github_appkey'],
|
||||
'gitee' => ['Gitee', 'gitee_appid', 'gitee_appkey'],
|
||||
'qq' => ['QQ', 'qq_appid', 'qq_appkey'],
|
||||
'google' => ['Google', 'google_client_id', 'google_client_secret'],
|
||||
'weibo' => ['微博', 'weibo_appid', 'weibo_appkey'],
|
||||
'weixin' => ['微信开放平台', 'weixin_appid', 'weixin_appsecret'],
|
||||
];
|
||||
$enabled = 0;
|
||||
foreach ($providers as $provider => [$label, $id_key, $secret_key]) {
|
||||
if (empty($settings['oauth_' . $provider . '_s'])) {
|
||||
continue;
|
||||
}
|
||||
$enabled++;
|
||||
if (trim((string) ($settings[$id_key] ?? '')) === '' || !$this->oauth_secret_is_configured($settings[$secret_key] ?? '', $stored[$secret_key] ?? '')) {
|
||||
$errors[] = sprintf(__('%s 登录已启用,请填写完整凭据', 'aksrt'), $label);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($settings['oauth_weixingzh_s'])) {
|
||||
$enabled++;
|
||||
$gzh_type = sanitize_key((string) ($settings['weixingzh_gzh_type'] ?? 'service'));
|
||||
$base_ready = $this->oauth_secret_is_configured($settings['weixingzh_token'] ?? '', $stored['weixingzh_token'] ?? '')
|
||||
&& trim((string) ($settings['weixingzh_appid'] ?? '')) !== '';
|
||||
$mode_ready = $gzh_type === 'subscribe'
|
||||
? trim((string) ($settings['weixingzh_code_qrcode'] ?? '')) !== ''
|
||||
&& trim((string) ($settings['weixingzh_code_keyword'] ?? '')) !== ''
|
||||
: $this->oauth_secret_is_configured($settings['weixingzh_appsecret'] ?? '', $stored['weixingzh_appsecret'] ?? '');
|
||||
if (!$base_ready || !$mode_ready) {
|
||||
$errors[] = $gzh_type === 'subscribe'
|
||||
? __('微信公众号订阅号登录已启用,请填写 Token、AppID、二维码和回复关键词', 'aksrt')
|
||||
: __('微信公众号服务号登录已启用,请填写 Token、AppID 和 AppSecret', 'aksrt');
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($settings['clogin_s'])) {
|
||||
$enabled++;
|
||||
if (!$this->is_secure_oauth_url((string) ($settings['clogin_url'] ?? ''))
|
||||
|| trim((string) ($settings['clogin_id'] ?? '')) === ''
|
||||
|| !$this->oauth_secret_is_configured($settings['clogin_key'] ?? '', $stored['clogin_key'] ?? '')
|
||||
|| empty($settings['clogin_oauth_s'])
|
||||
) {
|
||||
$errors[] = __('彩虹聚合登录已启用,请填写 HTTPS 接口地址、AppID、AppKey 并选择平台', 'aksrt');
|
||||
}
|
||||
}
|
||||
|
||||
if ($enabled === 0) {
|
||||
$errors[] = __('启用第三方登录后,至少需要启用一个本地登录提供商', 'aksrt');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
private function oauth_secret_is_configured($value, $stored_value = ''): bool {
|
||||
$value = trim((string) $value);
|
||||
if ($value === '***') {
|
||||
return trim((string) $stored_value) !== '';
|
||||
}
|
||||
return $value !== '';
|
||||
}
|
||||
|
||||
private function is_secure_oauth_url(string $url): bool {
|
||||
$url = trim($url);
|
||||
if ($url === '' || filter_var($url, FILTER_VALIDATE_URL) === false) {
|
||||
return false;
|
||||
}
|
||||
$parts = wp_parse_url($url);
|
||||
return is_array($parts)
|
||||
&& strtolower((string) ($parts['scheme'] ?? '')) === 'https'
|
||||
&& !empty($parts['host'])
|
||||
&& empty($parts['user'])
|
||||
&& empty($parts['pass'])
|
||||
&& empty($parts['fragment']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level slugs that must never be shadowed by the download route.
|
||||
*/
|
||||
@@ -360,13 +501,22 @@ class SchemaProvider {
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function reset_to_defaults(string $domain, string $section = ''): bool {
|
||||
if ($section !== '') {
|
||||
return $this->write_settings($domain, $this->get_defaults($domain, $section), $section);
|
||||
}
|
||||
public function reset_to_defaults(string $domain, string $section = ''): bool {
|
||||
if ($section !== '') {
|
||||
$defaults = $this->get_defaults($domain, $section);
|
||||
$schema = $this->get_section_schema($domain, $section);
|
||||
$defaults['__clear_secrets'] = $schema ? $this->secret_field_keys($schema) : [];
|
||||
return $this->write_settings($domain, $defaults, $section);
|
||||
}
|
||||
|
||||
return $this->write_settings($domain, $this->get_defaults($domain));
|
||||
}
|
||||
$result = true;
|
||||
foreach ($this->get_sections($domain) as $section_schema) {
|
||||
$defaults = $this->collect_defaults($section_schema);
|
||||
$defaults['__clear_secrets'] = $this->secret_field_keys($section_schema);
|
||||
$result = $this->write_section_settings($section_schema, $defaults) && $result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function get_schema_builder_map(): array {
|
||||
// Builders live under AKSRT\Admin\Schema (Composer PSR-4). Relative
|
||||
@@ -395,6 +545,10 @@ class SchemaProvider {
|
||||
if (array_key_exists($field['key'], $stored)) {
|
||||
$data[$field['key']] = $stored[$field['key']];
|
||||
}
|
||||
$stored_value = array_key_exists($field['key'], $stored) ? $stored[$field['key']] : ($data[$field['key']] ?? '');
|
||||
if (!empty($field['secret'])) {
|
||||
$data[$field['key']] = trim((string) $stored_value) !== '' ? '***' : '';
|
||||
}
|
||||
}
|
||||
|
||||
// Captcha: always surface the normalized positive scene list.
|
||||
@@ -421,13 +575,27 @@ class SchemaProvider {
|
||||
foreach ($this->get_all_fields($schema) as $field) {
|
||||
$fields[(string) $field['key']] = $field;
|
||||
}
|
||||
$clear_secrets = isset($data['__clear_secrets']) && is_array($data['__clear_secrets'])
|
||||
? array_values(array_map('sanitize_key', $data['__clear_secrets']))
|
||||
: [];
|
||||
foreach ($fields as $key => $field) {
|
||||
if (!array_key_exists($key, $data)) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($field['secret']) && in_array($key, $clear_secrets, true)) {
|
||||
unset($stored[$key]);
|
||||
continue;
|
||||
}
|
||||
if (!array_key_exists($key, $data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!empty($field['secret'])) {
|
||||
$value = is_scalar($data[$key]) ? trim((string) $data[$key]) : '';
|
||||
if ($value === '' || $value === '***') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$stored[$key] = $this->sanitize_field_value($data[$key], $field);
|
||||
}
|
||||
}
|
||||
|
||||
// Captcha stores a single positive scene list.
|
||||
if ($option_key === 'aksrt_captcha_config' && function_exists('aksrt_captcha_scenes')) {
|
||||
@@ -449,6 +617,16 @@ class SchemaProvider {
|
||||
return $updated || true;
|
||||
}
|
||||
|
||||
private function secret_field_keys(array $schema): array {
|
||||
$keys = [];
|
||||
foreach ($this->get_all_fields($schema) as $field) {
|
||||
if (!empty($field['secret']) && !empty($field['key'])) {
|
||||
$keys[] = sanitize_key((string) $field['key']);
|
||||
}
|
||||
}
|
||||
return array_values(array_unique($keys));
|
||||
}
|
||||
|
||||
private function collect_defaults(array $schema): array {
|
||||
$defaults = [];
|
||||
foreach ($this->get_all_fields($schema) as $field) {
|
||||
|
||||
@@ -31,20 +31,6 @@ class UserController extends ControllerBase {
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// OAuth settings
|
||||
register_rest_route(self::API_NAMESPACE, '/settings/oauth', [
|
||||
'methods' => ['GET', 'POST'],
|
||||
'callback' => [$this, 'rest_handle_oauth'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// OAuth proxy settings
|
||||
register_rest_route(self::API_NAMESPACE, '/settings/oauth-proxy', [
|
||||
'methods' => ['GET', 'POST'],
|
||||
'callback' => [$this, 'rest_handle_oauth_proxy'],
|
||||
'permission_callback' => [$this, 'check_permission'],
|
||||
]);
|
||||
|
||||
// User profile media uploads (logged-in users).
|
||||
register_rest_route(self::API_NAMESPACE, '/user/background', [
|
||||
'methods' => 'POST',
|
||||
@@ -531,59 +517,6 @@ class UserController extends ControllerBase {
|
||||
return $this->success(['message' => __('消息清理任务已受理', 'aksrt')]);
|
||||
}
|
||||
|
||||
public function rest_handle_oauth(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$provider = SchemaProvider::get_instance();
|
||||
$allowed = $provider->get_allowed_fields('users', 'oauth');
|
||||
|
||||
if ($request->get_method() === 'GET') {
|
||||
$data = \AKSRT\Settings\Settings::get_all();
|
||||
return $this->success(['data' => array_intersect_key($data, $allowed)]);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
$settings = \AKSRT\Settings\Settings::get_all();
|
||||
$settings = array_merge($settings, $this->sanitize_fields($params, $allowed));
|
||||
update_option('aksrt_settings', $settings);
|
||||
\AKSRT\Settings\Settings::flush_settings_cache();
|
||||
|
||||
return $this->success(['message' => __('第三方登录配置已保存', 'aksrt')]);
|
||||
}
|
||||
|
||||
public function rest_handle_oauth_proxy(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$keys = [
|
||||
'oauth_proxy_mode',
|
||||
'oauth_proxy_secret',
|
||||
'oauth_proxy_server_url',
|
||||
'oauth_proxy_server_providers',
|
||||
'oauth_proxy_client_providers',
|
||||
'oauth_proxy_gzh_type',
|
||||
];
|
||||
|
||||
if ($request->get_method() === 'GET') {
|
||||
$all = \AKSRT\Settings\Settings::get_all();
|
||||
$data = [];
|
||||
foreach ($keys as $key) {
|
||||
$data[$key] = $all[$key] ?? null;
|
||||
}
|
||||
return $this->success(['data' => $data]);
|
||||
}
|
||||
|
||||
$params = $this->get_json_params($request);
|
||||
$settings = \AKSRT\Settings\Settings::get_all();
|
||||
foreach ($keys as $key) {
|
||||
if (!array_key_exists($key, $params)) {
|
||||
continue;
|
||||
}
|
||||
$settings[$key] = is_array($params[$key])
|
||||
? array_values(array_map('sanitize_key', (array) $params[$key]))
|
||||
: sanitize_text_field((string) $params[$key]);
|
||||
}
|
||||
update_option('aksrt_settings', $settings);
|
||||
\AKSRT\Settings\Settings::flush_settings_cache();
|
||||
|
||||
return $this->success(['message' => __('OAuth 代理配置已保存', 'aksrt')]);
|
||||
}
|
||||
|
||||
public function rest_upload_comment_image(\WP_REST_Request $request): \WP_REST_Response {
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
|
||||
@@ -11,6 +11,14 @@ defined('ABSPATH') || exit;
|
||||
|
||||
trait UserControllerAuthPhoneOperations {
|
||||
|
||||
private function delete_oauth_registration_user(int $user_id): void {
|
||||
if ($user_id <= 0) {
|
||||
return;
|
||||
}
|
||||
require_once ABSPATH . 'wp-admin/includes/user.php';
|
||||
wp_delete_user($user_id);
|
||||
}
|
||||
|
||||
private function auth_payload(\WP_REST_Request $request): array {
|
||||
$params = $this->get_json_params($request);
|
||||
return is_array($params) ? $params : [];
|
||||
@@ -220,14 +228,23 @@ trait UserControllerAuthPhoneOperations {
|
||||
if (!$user || !$this->auth_consume_code('login', $target, sanitize_text_field((string) $payload['code']), $channel)) {
|
||||
return $this->error(__('账号或验证码错误', 'aksrt'), 401);
|
||||
}
|
||||
if ($oauth_data) {
|
||||
$oauth_data = \AKSRT\Auth\Service::claim_oauth_bind_context($obk);
|
||||
if (!$oauth_data) {
|
||||
return $this->error(__('绑定会话已被使用,请重新授权', 'aksrt'), 410);
|
||||
}
|
||||
$binding = \AKSRT\Auth\Service::finalize_oauth_binding((int) $user->ID, $oauth_data, $obk);
|
||||
if (is_wp_error($binding)) {
|
||||
return $this->error($binding->get_error_message(), 409);
|
||||
}
|
||||
\AKSRT\Auth\OAuthAccountService::complete_login($user, !empty($payload['rememberme']));
|
||||
$redirect = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : $redirect;
|
||||
return $this->success(['message' => __('账号绑定成功', 'aksrt'), 'redirect' => $redirect]);
|
||||
}
|
||||
wp_set_current_user((int) $user->ID);
|
||||
wp_set_auth_cookie((int) $user->ID, !empty($payload['rememberme']));
|
||||
do_action('wp_login', $user->user_login, $user);
|
||||
if ($oauth_data) {
|
||||
\AKSRT\Auth\Service::finalize_oauth_binding((int) $user->ID, $oauth_data, $obk);
|
||||
$redirect = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : $redirect;
|
||||
}
|
||||
return $this->success(['message' => $oauth_data ? __('账号绑定成功', 'aksrt') : __('登录成功', 'aksrt'), 'redirect' => $redirect]);
|
||||
return $this->success(['message' => __('登录成功', 'aksrt'), 'redirect' => $redirect]);
|
||||
}
|
||||
|
||||
if (!class_exists('\AKSRT\Auth\Service')) {
|
||||
@@ -236,17 +253,27 @@ trait UserControllerAuthPhoneOperations {
|
||||
$payload['log'] = $target;
|
||||
$payload['pwd'] = (string) ($payload['password'] ?? $payload['pwd'] ?? '');
|
||||
$payload['redirect_to'] = $redirect;
|
||||
$result = \AKSRT\Auth\Service::login_user($payload, $oauth_data ? 'bind' : 'login');
|
||||
if (empty($result['success'])) {
|
||||
return $this->error(__('账号或密码错误', 'aksrt'), 401);
|
||||
}
|
||||
if ($oauth_data) {
|
||||
$user_id = get_current_user_id();
|
||||
if ($user_id <= 0) {
|
||||
$resolved_login = \AKSRT\Auth\Service::resolve_email_to_username($target);
|
||||
$user = wp_authenticate($resolved_login, (string) ($payload['password'] ?? $payload['pwd'] ?? ''));
|
||||
if (is_wp_error($user) || !$user instanceof \WP_User) {
|
||||
return $this->error(__('账号或密码错误', 'aksrt'), 401);
|
||||
}
|
||||
\AKSRT\Auth\Service::finalize_oauth_binding($user_id, $oauth_data, $obk);
|
||||
$oauth_data = \AKSRT\Auth\Service::claim_oauth_bind_context($obk);
|
||||
if (!$oauth_data) {
|
||||
return $this->error(__('绑定会话已被使用,请重新授权', 'aksrt'), 410);
|
||||
}
|
||||
$binding = \AKSRT\Auth\Service::finalize_oauth_binding((int) $user->ID, $oauth_data, $obk);
|
||||
if (is_wp_error($binding)) {
|
||||
return $this->error($binding->get_error_message(), 409);
|
||||
}
|
||||
\AKSRT\Auth\OAuthAccountService::complete_login($user, !empty($payload['rememberme']));
|
||||
$redirect = function_exists('aksrt_get_user_center_url') ? aksrt_get_user_center_url() : $redirect;
|
||||
return $this->success(['message' => __('账号绑定成功', 'aksrt'), 'redirect' => $redirect]);
|
||||
}
|
||||
$result = \AKSRT\Auth\Service::login_user($payload, 'login');
|
||||
if (empty($result['success'])) {
|
||||
return $this->error(__('账号或密码错误', 'aksrt'), 401);
|
||||
}
|
||||
return $this->success(['message' => $oauth_data ? __('账号绑定成功', 'aksrt') : __('登录成功', 'aksrt'), 'redirect' => $redirect]);
|
||||
}
|
||||
@@ -263,7 +290,10 @@ trait UserControllerAuthPhoneOperations {
|
||||
if ($obk !== '' && !$oauth_data) {
|
||||
return $this->error(__('绑定会话已过期,请重新使用第三方登录', 'aksrt'), 410);
|
||||
}
|
||||
if (class_exists('\AKSRT\Settings\Settings') && (\AKSRT\Settings\Settings::close_sign() || (!$oauth_data && !\AKSRT\Settings\Settings::registration_enabled()))) {
|
||||
if (class_exists('\AKSRT\Settings\Settings') && (
|
||||
\AKSRT\Settings\Settings::close_sign()
|
||||
|| ($oauth_data ? !\AKSRT\Settings\Settings::oauth_registration_enabled() : !\AKSRT\Settings\Settings::registration_enabled())
|
||||
)) {
|
||||
return $this->error(__('当前已关闭新用户注册', 'aksrt'), 403);
|
||||
}
|
||||
if ($this->auth_rate_limited('register')) {
|
||||
@@ -296,26 +326,47 @@ trait UserControllerAuthPhoneOperations {
|
||||
}
|
||||
if ($channel === 'phone') {
|
||||
$payload['phone'] = $target;
|
||||
$payload['_defer_login'] = !empty($oauth_data);
|
||||
$result = \AKSRT\Auth\Service::register_by_phone($payload);
|
||||
if (empty($result['success'])) {
|
||||
return $this->error($this->auth_registration_error((string) ($result['error'] ?? __('注册失败', 'aksrt'))));
|
||||
}
|
||||
$user_id = (int) ($result['user_id'] ?? 0);
|
||||
if ($oauth_data && $user_id > 0) {
|
||||
\AKSRT\Auth\Service::finalize_oauth_binding($user_id, $oauth_data, $obk);
|
||||
$binding = \AKSRT\Auth\Service::finalize_oauth_binding($user_id, $oauth_data, $obk);
|
||||
if (is_wp_error($binding)) {
|
||||
$this->delete_oauth_registration_user($user_id);
|
||||
return $this->error($binding->get_error_message(), 409);
|
||||
}
|
||||
$user = get_user_by('id', $user_id);
|
||||
if ($user instanceof \WP_User) {
|
||||
\AKSRT\Auth\OAuthAccountService::complete_login($user, true);
|
||||
}
|
||||
}
|
||||
return $this->success(['message' => $oauth_data ? __('注册并绑定成功', 'aksrt') : __('注册成功', 'aksrt'), 'redirect' => $result['redirect'] ?? home_url('/'), 'notice' => (string) ($result['notice'] ?? '')]);
|
||||
}
|
||||
$payload['user_email'] = sanitize_email($target);
|
||||
$payload['user_pass'] = (string) ($payload['password'] ?? '');
|
||||
$payload['user_pass_confirm'] = (string) ($payload['password_confirm'] ?? $payload['password'] ?? '');
|
||||
$payload['_defer_login'] = !empty($oauth_data);
|
||||
$result = \AKSRT\Auth\Service::register_user($payload);
|
||||
if (empty($result['success'])) {
|
||||
return $this->error($this->auth_registration_error((string) ($result['error'] ?? __('注册失败', 'aksrt'))));
|
||||
}
|
||||
$user_id = (int) ($result['user_id'] ?? 0);
|
||||
if ($oauth_data && $user_id > 0) {
|
||||
\AKSRT\Auth\Service::finalize_oauth_binding($user_id, $oauth_data, $obk);
|
||||
$binding = \AKSRT\Auth\Service::finalize_oauth_binding($user_id, $oauth_data, $obk);
|
||||
if (is_wp_error($binding)) {
|
||||
wp_delete_user($user_id);
|
||||
return $this->error($binding->get_error_message(), 409);
|
||||
}
|
||||
$user = get_user_by('id', $user_id);
|
||||
if ($user instanceof \WP_User) {
|
||||
if ($channel === 'email' && !empty($payload['_auth_code_verified'])) {
|
||||
\AKSRT\Auth\Service::mark_verified_email($user_id);
|
||||
}
|
||||
\AKSRT\Auth\OAuthAccountService::complete_login($user, true);
|
||||
}
|
||||
}
|
||||
return $this->success([
|
||||
'message' => $oauth_data ? __('注册并绑定成功', 'aksrt') : __('注册成功', 'aksrt'),
|
||||
|
||||
Reference in New Issue
Block a user