PasswordResetController.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. <?php
  2. namespace App\Http\Controllers\V3;
  3. use App\Http\Controllers\Controller;
  4. use App\Http\Requests\V3\StorePasswordResetRequest;
  5. use App\Http\Requests\V3\UpdatePasswordResetRequest;
  6. use App\Http\Resources\V3\PasswordResetResource;
  7. use App\Services\V3\PasswordResetService;
  8. /**
  9. * 找回密码。
  10. *
  11. * 取代 `POST /v2/auth/forgot-password`、`GET /v2/auth/reset-password/{token}`、
  12. * `POST /v2/auth/reset-password`(`ForgotPasswordController` / `ResetPasswordController`)。
  13. * v2 那几条在 dashboard-v4 下线前原样保留,不要改动。
  14. *
  15. * 一次「密码重置」是一个以 token 为标识的资源:store 发起(发邮件),
  16. * show 查看(给哪个账号、何时过期),update 完成(设新密码,token 作废)。
  17. */
  18. class PasswordResetController extends Controller
  19. {
  20. public function __construct(private readonly PasswordResetService $resets) {}
  21. /**
  22. * 申请重置密码(发邮件)
  23. *
  24. * 无论邮箱是否注册都返回 204,不泄露账号是否存在。邮件是同步发出的,
  25. * 返回时已经发完,所以是 204 而不是 202。邮件里的链接指向
  26. * dashboard-v6 的 `/anonymous/reset-password/{token}`,60 分钟内有效。
  27. *
  28. * 按 IP 与邮箱限流,超出返回 429。
  29. *
  30. * @unauthenticated
  31. *
  32. * @bodyParam email string required 账号邮箱。Example: someone@example.com
  33. * @bodyParam lang string 邮件语言,没有对应模板的回落 en。Enum: en,en-US,zh-Hans,zh-Hant
  34. *
  35. * @responseStatus 204 已发送(或邮箱未注册),无响应体
  36. * @responseStatus 429 请求过于频繁
  37. * @responseStatus 503 邮件发送失败
  38. */
  39. public function store(StorePasswordResetRequest $request)
  40. {
  41. $this->resets->request($request->validated('email'), $request->validated('lang'));
  42. return response()->noContent();
  43. }
  44. /**
  45. * 查看一次待完成的重置
  46. *
  47. * 重置页用它显示「正在为哪个账号设置新密码」。token 不存在或已过期一律 404。
  48. *
  49. * @unauthenticated
  50. *
  51. * @urlParam token string required 邮件链接里的 token
  52. *
  53. * @responseStatus 404 token 无效或已过期
  54. */
  55. public function show(string $token): PasswordResetResource
  56. {
  57. return PasswordResetResource::make($this->resets->find($token));
  58. }
  59. /**
  60. * 设置新密码
  61. *
  62. * 成功后 token 作废,返回 204 空体;之后用新密码走登录。
  63. *
  64. * @unauthenticated
  65. *
  66. * @urlParam token string required 邮件链接里的 token
  67. *
  68. * @bodyParam password string required 新密码,6–32 位
  69. * @bodyParam password_confirmation string required 再输一次新密码
  70. *
  71. * @responseStatus 204 已重置,无响应体
  72. * @responseStatus 404 token 无效或已过期
  73. */
  74. public function update(UpdatePasswordResetRequest $request, string $token)
  75. {
  76. $this->resets->reset($token, $request->validated('password'));
  77. return response()->noContent();
  78. }
  79. }