session()->get('find_pw', []); $step = 1; if (!empty($sess['verified'])) $step = 3; else if (!empty($sess['sent'])) $step = 2; return view('web.auth.find_password', [ 'initialStep' => $step, 'email' => $sess['email'] ?? null, 'name' => $sess['name'] ?? null, ]); } public function sendMail(Request $request, FindPasswordService $svc) { $rules = [ 'email' => ['required', 'email', 'max:120'], 'name' => ['required', 'string', 'max:50'], ]; if (app()->environment('production')) { $rules['g-recaptcha-response'] = ['required', new RecaptchaV3Rule('find_pass')]; } $v = Validator::make($request->all(), $rules, [ 'email.required' => '이메일을 입력해 주세요.', 'email.email' => '이메일 형식이 올바르지 않습니다.', 'name.required' => '성명을 입력해 주세요.', 'g-recaptcha-response.required' => '올바른 접근이 아닙니다.', ]); if ($v->fails()) { return response()->json([ 'ok' => false, 'message' => $v->errors()->first(), ], 422); } $email = (string) $request->input('email'); $name = (string) $request->input('name'); $res = $svc->sendResetMail($request, $email, $name, 30); if (!($res['ok'] ?? false)) { return response()->json([ 'ok' => false, 'code' => $res['code'] ?? null, 'message' => $res['message'] ?? '요청 처리 중 오류가 발생했습니다.', 'step' => $res['step'] ?? 1, ], (int)($res['status'] ?? 400)); } if (!empty($res['session'])) { $request->session()->put('find_pw', $res['session']); } return response()->json([ 'ok' => true, 'message' => $res['message'] ?? '인증메일을 발송했습니다.', 'expires_in' => $res['expires_in'] ?? 1800, 'step' => $res['step'] ?? 2, ]); } public function verifyLink(Request $request, FindPasswordService $svc) { $memNo = (int) $request->query('mem_no', 0); $res = $svc->verifyResetLink($request, $memNo); if (!($res['ok'] ?? false)) { return redirect()->route('web.auth.find_password.show') ->with('ui_dialog', [ 'type' => 'alert', 'title' => '안내', 'message' => $res['message'] ?? '잘못된 접근입니다.', ]); } // ✅ 인증완료 세션 세팅 if (!empty($res['session'])) { $request->session()->put('find_pw', $res['session']); } return redirect()->route('web.auth.find_password.show') ->with('ui_dialog', [ 'type' => 'alert', 'title' => '안내', 'message' => $res['message'] ?? '인증이 완료되었습니다.', ]); } public function reset(Request $request, FindPasswordService $svc) { $v = Validator::make($request->all(), [ 'new_password' => [ 'required', 'string', 'min:8', 'max:20', 'regex:/^(?=.*[A-Za-z])(?=.*\d)(?=.*[^A-Za-z0-9\s]).+$/' ], 'new_password_confirmation' => ['required', 'same:new_password'], ], [ 'new_password.required' => '새 비밀번호를 입력해 주세요.', 'new_password.min' => '비밀번호는 8자리 이상이어야 합니다.', 'new_password.max' => '비밀번호는 20자리를 초과할 수 없습니다.', 'new_password.regex' => '비밀번호는 영문+숫자+특수문자를 포함해야 합니다.', 'new_password_confirmation.same' => '비밀번호 확인이 일치하지 않습니다.', ]); if ($v->fails()) { return response()->json(['ok' => false, 'message' => $v->errors()->first()], 422); } $pw = (string) $request->input('new_password'); $res = $svc->resetPasswordFinal($request, $pw); return response()->json([ 'ok' => (bool)($res['ok'] ?? false), 'message' => $res['message'] ?? '', 'redirect_url' => $res['redirect_url'] ?? null, ], (int)($res['status'] ?? 200)); } }