feat(captcha): 打通人机验证 11 个场景的前后端完整链路
- 统一验证入口 aksrt_require_captcha(),返回 true|WP_Error,启用场景配置缺失时 fail-closed 拒绝 - 前端公共 API 重构为 window.AKSRTCaptcha(verify/collect/reset/run),单飞锁防并发重复验证,一次性 proof 绑定浏览器 cookie+场景+服务商+主机名 - challenge/exchange REST 端点:challenge 原子占用防票据放大厂商调用,增加频率限制 - 新增 OAuth bind pass:服务端签发 5 分钟一次性令牌,绑定用户+服务商+浏览器,微信扫码延迟消费 - 覆盖场景:评论、登录、注册、绑定第三方、绑定手机、找回密码、修改密码、更改邮箱、资料下载、签到、前台投稿 - 移除 Service 层重复验证与 _auth_code_verified/_defer_login 等客户端可伪造标志,删除下载共享 pass 死代码 - 修复腾讯 TC3 签名 scope、Cloudflare action/cdata/hostname 严格校验、阿里云验签错误码映射 - 后台 Schema 保存对 secret 字段做掩码/保留合并;导入导出过滤 aksrt_captcha_config - 重建 public bundle 与 admin SPA;新增 captcha 运行时/安全/业务契约测试与 harness
This commit is contained in:
@@ -115,16 +115,20 @@ test('legacy authentication templates and scripts are removed', () => {
|
||||
test('unified handlers enforce nonce, captcha, rate limits, configured channels, and generic errors', () => {
|
||||
const handlers = read('src/Admin/UserControllerAuthPhoneOperations.php');
|
||||
const service = read('src/Auth/Service.php');
|
||||
const serviceA = read('src/Auth/ServicePart1a.php');
|
||||
const serviceB = read('src/Auth/ServicePart1b.php');
|
||||
|
||||
assert.match(handlers, /auth_verify_rest_nonce/);
|
||||
assert.match(handlers, /aksrt_require_captcha/);
|
||||
assert.match(handlers, /private function auth_require_captcha/);
|
||||
assert.match(handlers, /get_error_code\(\)/);
|
||||
assert.match(handlers, /get_error_message\(\)/);
|
||||
assert.match(handlers, /auth_rate_limited/);
|
||||
assert.match(handlers, /auth_channel_allowed/);
|
||||
['auth_code', 'auth_login', 'auth_register', 'auth_reset_password'].forEach((method) => {
|
||||
const start = handlers.indexOf(`public function ${method}(`);
|
||||
const end = handlers.indexOf('\n\tpublic function ', start + 1);
|
||||
const body = handlers.slice(start, end === -1 ? handlers.length : end);
|
||||
assert.match(body, /aksrt_require_captcha/, method);
|
||||
assert.match(body, /auth_require_captcha/, method);
|
||||
});
|
||||
assert.match(handlers, /passwordless_login_type/);
|
||||
assert.match(handlers, /signup_verification_type/);
|
||||
@@ -132,6 +136,10 @@ test('unified handlers enforce nonce, captcha, rate limits, configured channels,
|
||||
assert.match(handlers, /账号或密码错误/);
|
||||
assert.match(handlers, /账号或验证码错误/);
|
||||
assert.match(service, /signin_phone_enabled/);
|
||||
assert.doesNotMatch(service + serviceA + serviceB, /aksrt_require_captcha/);
|
||||
assert.doesNotMatch(service + serviceA + serviceB, /_auth_code_verified|_defer_login/);
|
||||
assert.doesNotMatch(service, /captcha_scene/);
|
||||
assert.match(handlers, /public function user_bind_phone[\s\S]*?auth_require_captcha\('bind_phone'/);
|
||||
assert.doesNotMatch(service, /login_by_phone_password|login_by_phone_code/);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user