EmailController.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <?php
  2. namespace App\Http\Controllers\Account;
  3. use Illuminate\Http\Request;
  4. use Illuminate\Support\Facades\Mail;
  5. use App\Http\Controllers\Controller;
  6. use App\Models\User;
  7. use App\Models\UserEmailLog;
  8. use App\Models\DTO\ResponseData;
  9. use App\Mail\VerifyCode;
  10. use Exception;
  11. class EmailController extends Controller
  12. {
  13. private User $userModel;
  14. private UserEmailLog $userEmailLogModel;
  15. public function __construct(User $user, UserEmailLog $userEmailLogModel)
  16. {
  17. $this->middleware('auth');
  18. $this->middleware('throttle:verify')->only('index');
  19. $this->userModel = $user;
  20. $this->userEmailLogModel = $userEmailLogModel;
  21. }
  22. /**
  23. * 회원 이메일 수정
  24. * @method GET
  25. * @see /account/email
  26. */
  27. public function index(Request $request, ResponseData $response): ResponseData
  28. {
  29. try{
  30. $rules = [
  31. 'email' => 'required|email|unique:users,email'
  32. ];
  33. $attributes = [
  34. 'email' => '이메일'
  35. ];
  36. $messages = [
  37. 'email.required' => '이메일을 입력해 주세요.',
  38. 'email.email' => '이메일 형식이 옳지 않습니다.',
  39. 'email.unique' => '이미 사용 중인 이메일 입니다.'
  40. ];
  41. $posts = $this->validate($request, $rules, $messages, $attributes);
  42. if(!$this->userEmailLogModel->isUpdateAble(UID)) {
  43. throw new Exception(
  44. sprintf('이메일 변경은 %d일 지난 후 가능합니다.', $this->userEmailLogModel->getDayLeft(UID))
  45. );
  46. }
  47. // 이메일 인증번호/남은시간 생성
  48. $verifyCode = rand(100000, 999999);
  49. $verifyExpiresAt = now()->addMinutes(VERIFY_EXPIRES_AT)->diffInSeconds(now());
  50. // 이메일 인증번호 발송
  51. [$name] = explode('@', $posts['email']);
  52. $sender = (object)[
  53. 'name' => $name,
  54. 'email' => $posts['email'],
  55. ];
  56. Mail::to($sender)->send(new VerifyCode($verifyCode, $verifyExpiresAt, UID));
  57. // 쿠키 생성
  58. $sender->verifyCode = $verifyCode;
  59. $sender = serialize($sender);
  60. $cookie = cookie('tmpVerifyData', $sender, VERIFY_EXPIRES_AT);
  61. $response->cookie($cookie);
  62. // 이메일 인증 화면
  63. $response->view = view(layout('account.email'), [
  64. 'user' => $request->user(),
  65. 'menuID' => 'MODIFY',
  66. 'verifyExpiresAt' => $verifyExpiresAt,
  67. ])->render();
  68. }catch(Exception $e) {
  69. $response = $response::fromException($e);
  70. }
  71. return $response;
  72. }
  73. /**
  74. * 회원 정보 수정 처리
  75. * @method POST
  76. * @see /account/email/update
  77. */
  78. public function update(Request $request, ResponseData $response): ResponseData
  79. {
  80. try{
  81. $rules = [
  82. 'code' => 'required|integer'
  83. ];
  84. $attributes = [
  85. 'code' => '인증번호'
  86. ];
  87. $messages = [
  88. 'code.required' => '인증번호를 입력해 주세요.',
  89. 'code.integer' => '인증번호 형식이 옳지 않습니다.'
  90. ];
  91. $posts = $this->validate($request, $rules, $messages, $attributes);
  92. $user = $request->user();
  93. $tmpVerifyData = unserialize($request->cookie('tmpVerifyData'));
  94. if($posts['code'] != $tmpVerifyData->verifyCode) {
  95. throw new Exception('인증번호가 일치하지 않습니다.');
  96. }
  97. $this->userModel->info()->generateEmailVerified(
  98. $tmpVerifyData->email
  99. );
  100. // 이메일 변경 확인
  101. if($user->email != $tmpVerifyData->email) {
  102. $this->userEmailLogModel->setLog($user, $tmpVerifyData->email);
  103. }
  104. }catch(Exception $e) {
  105. $response = $response::fromException($e);
  106. }
  107. return $response;
  108. }
  109. }