postJson(route('password.check_account'), [ 'username' => 'non_existing_user_abc', ]); $response->assertStatus(200); $response->assertJson([ 'status' => 'not_found', 'message' => '抱歉,没有找到该昵称对应的账号。请确认后再试。', ]); } /** * 测试账号检测分流状态与脱敏邮箱输出 */ public function test_check_account_shows_correct_channels(): void { // 1. 双绑定用户 $bothBoundUser = User::factory()->create([ 'username' => 'both_user', 'email' => 'both.test@example.com', 'wxid' => 'wxid_both', ]); $response1 = $this->postJson(route('password.check_account'), [ 'username' => 'both_user', ]); $response1->assertJson([ 'status' => 'success', 'has_email' => true, 'has_wechat' => true, 'masked_email' => 'b*******t@example.com', ]); // 2. 仅绑定微信用户 $wechatUser = User::factory()->create([ 'username' => 'wx_user', 'email' => null, 'wxid' => 'wxid_single', ]); $response2 = $this->postJson(route('password.check_account'), [ 'username' => 'wx_user', ]); $response2->assertJson([ 'status' => 'success', 'has_email' => false, 'has_wechat' => true, ]); // 3. 均未绑定用户 $noneUser = User::factory()->create([ 'username' => 'none_user', 'email' => null, 'wxid' => null, ]); $response3 = $this->postJson(route('password.check_account'), [ 'username' => 'none_user', ]); $response3->assertJson([ 'status' => 'success', 'has_email' => false, 'has_wechat' => false, ]); } /** * 测试 IP 防扫描限流限制 (每个 IP 1分钟限制 5 次检测) */ public function test_check_account_rate_limiting(): void { $ip = '127.0.0.1'; // 连续请求 5 次都应该正常响应 for ($i = 0; $i < 5; $i++) { $response = $this->postJson(route('password.check_account'), [ 'username' => 'non_existing_user', ]); $response->assertStatus(200); } // 第 6 次应该被 RateLimiter 节流拦截返回 429 $response = $this->postJson(route('password.check_account'), [ 'username' => 'non_existing_user', ]); $response->assertStatus(429); $response->assertJson([ 'status' => 'error', ]); $this->assertStringContainsString('请求过于频繁', $response->json('message')); } /** * 测试发送链接的双层安全控频防御 (防止疯狂邮件轰炸他人) */ public function test_store_link_prevents_email_bombing(): void { Sysparam::updateOrCreate(['alias' => 'smtp_enabled'], ['body' => '1']); $user = User::factory()->create([ 'username' => 'bomb_user', 'email' => 'bomb.target@example.com', ]); $email = $user->email; $targetKey = 'pw-email:target:'.md5($email); RateLimiter::clear($targetKey); // 模拟第一次发送成功 $response1 = $this->postJson(route('password.email'), [ 'username' => 'bomb_user', ]); // 第二次在 3 分钟内再次连续发送同一个账号邮件,应该直接拦截返回 429,防止邮箱轰炸 $response2 = $this->postJson(route('password.email'), [ 'username' => 'bomb_user', ]); $response2->assertStatus(429); $response2->assertJson([ 'status' => 'error', ]); $this->assertStringContainsString('重置链接过于频繁', $response2->json('message')); } }