giftcon_dev/app/Http/Controllers/Web/Mypage/InfoGateController.php

336 lines
12 KiB
PHP

<?php
namespace App\Http\Controllers\Web\Mypage;
use App\Http\Controllers\Controller;
use App\Services\MemInfoService;
use App\Services\Danal\DanalAuthtelService;
use App\Repositories\Member\MemberAuthRepository;
use App\Support\LegacyCrypto\CiSeedCrypto;
use App\Support\LegacyCrypto\CiPassword;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Arr;
final class InfoGateController extends Controller
{
public function __construct(
private readonly CiSeedCrypto $seed,
) {}
/**
* 비밀번호 재인증 화면
*/
public function show(Request $request)
{
$gate = (array) $request->session()->get('mypage_gate', []);
$ok = (bool) ($gate['ok'] ?? false);
$at = (int) ($gate['at'] ?? 0);
$ttlSeconds = 5 * 60;
$isValid = $ok && $at > 0 && (time() - $at) <= $ttlSeconds;
if ($isValid) {
return redirect()->to('/mypage/info_renew');
}
return view('web.mypage.info.gate');
}
public function info_renew(Request $request)
{
// ✅ gate (기존 그대로)
$gate = (array) $request->session()->get('mypage_gate', []);
$gateOk = (bool) Arr::get($gate, 'ok', false);
$gateAt = (int) Arr::get($gate, 'at', 0);
$ttlSec = 5 * 60;
$nowTs = now()->timestamp;
$expireTs = ($gateOk && $gateAt > 0) ? ($gateAt + $ttlSec) : 0;
$remainSec = ($expireTs > 0) ? max(0, $expireTs - $nowTs) : 0;
$isGateValid = ($remainSec > 0);
// ✅ 회원정보: _sess 기반
$sess = (array) $request->session()->get('_sess', []);
$memberName = (string) Arr::get($sess, '_mname', '');
$memberEmail = (string) Arr::get($sess, '_mid', '');
$dtReg = (string) Arr::get($sess, '_dt_reg', '');
// ✅ 전화번호 복호 (인증 완료 상태라 마스킹 제외)
$rawPhone = (string) Arr::get($sess, '_mcell', '');
$memberPhone = (string) $this->seed->decrypt($rawPhone);
$user = $request->user();
$withdrawBankName = (string)($user->withdraw_bank_name ?? $user->bank_name ?? '');
$withdrawAccount = (string)($user->withdraw_account ?? $user->bank_account ?? '');
$hasWithdrawAccount = ($withdrawBankName !== '' && $withdrawAccount !== '');
$agreeEmail = (string)($user->agree_marketing_email ?? $user->agree_email ?? 'n');
$agreeSms = (string)($user->agree_marketing_sms ?? $user->agree_sms ?? 'n');
return view('web.mypage.info.renew', [
// gate
'ttlSec' => $ttlSec,
'expireTs' => (int) $expireTs,
'remainSec' => (int) $remainSec,
'isGateValid' => (bool) $isGateValid,
// member (sess)
'memberName' => $memberName,
'memberEmail' => $memberEmail,
'memberPhone' => $memberPhone,
'memberDtReg' => $dtReg,
// etc
'hasWithdrawAccount' => (bool) $hasWithdrawAccount,
'agreeEmail' => $agreeEmail,
'agreeSms' => $agreeSms,
]);
}
/**
* 재인증을 위한 세셔초기화
*/
public function gateReset(Request $request)
{
// 게이트 인증 세션만 초기화
$request->session()->forget('mypage_gate');
// (선택) reauth도 같이 초기화하고 싶으면
$request->session()->forget('mypage.reauth.at');
$request->session()->forget('mypage.reauth.until');
$request->session()->save();
// 게이트 페이지로 이동
return redirect()->route('web.mypage.info.index');
}
/**
* 비밀번호 재인증 처리
*/
public function verify(Request $request, MemInfoService $memInfoService)
{
$request->validate([
'password' => ['required', 'string'],
], [
'password.required' => '비밀번호를 입력해 주세요.',
]);
$sess = (array) $request->session()->get('_sess', []);
$isLogin = (bool) ($sess['_login_'] ?? false);
$email = (string) ($sess['_mid'] ?? '');
if (!$isLogin || $email === '') {
return redirect()->route('web.auth.login', ['return_url' => url('/mypage/info')]);
}
$pw = (string) $request->input('password');
$res = $memInfoService->attemptLegacyLogin([
'email' => $email,
'password' => $pw,
'ip' => $request->ip(),
'ua' => substr((string) $request->userAgent(), 0, 500),
'return_url' => url('/mypage/info'),
]);
$ok = (bool)($res['ok'] ?? $res['success'] ?? false);
if (!$ok) {
$msg = (string)($res['message'] ?? '비밀번호가 일치하지 않습니다.');
return back()
->withErrors(['password' => $msg]) // 레이어 알림 스크립트가 이걸 잡음
->withInput($request->except('password'));
}
// 게이트 통과 세션 (예: 30분)
$request->session()->put('mypage_gate', [
'ok' => true,
'email' => $email,
'at' => time(),
]);
return redirect()->route('web.mypage.info.renew');
}
public function passReady(Request $request)
{
// 목적 저장 (result에서 분기용)
$purpose = (string) $request->input('purpose', 'mypage_phone_change');
$request->session()->put('mypage.pass_purpose', $purpose);
$request->session()->save();
$danal = app(\App\Services\Danal\DanalAuthtelService::class)->prepare([
'targetUrl' => route('web.mypage.info.danal.result'),
'backUrl' => route('web.mypage.info.renew'), // 취소/뒤로가기
'cpTitle' => request()->getHost(),
]);
if (!($danal['ok'] ?? false)) {
return response()->json([
'ok' => false,
'message' => $danal['message'] ?? '본인인증 준비에 실패했습니다. 잠시 후 다시 시도해 주세요.',
], 500);
}
// 필요하면 txid 저장 (회원가입과 동일)
$request->session()->put('mypage.danal', [
'txid' => $danal['txid'] ?? null,
'created_at' => now()->toDateTimeString(),
'purpose' => $purpose,
]);
$request->session()->save();
return response()->json([
'ok' => true,
'reason' => 'danal_ready',
'popup' => [
'url' => route('web.mypage.info.danal.start'),
'fields' => $danal['fields'],
],
]);
}
public function danalStart(Request $request)
{
$fieldsJson = (string) $request->input('fields', '');
$fields = json_decode($fieldsJson, true);
if (!is_array($fields) || empty($fields)) {
abort(400, 'Invalid Danal fields');
}
$platform = strtolower((string) $request->input('platform', ($fields['platform'] ?? '')));
$isMobile = false;
if ($platform === 'mobile') {
$isMobile = true;
} elseif ($platform === 'web') {
$isMobile = false;
} else {
$ua = (string) $request->header('User-Agent', '');
$isMobile = (bool) preg_match('/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i', $ua);
}
$action = $isMobile
? 'https://wauth.teledit.com/Danal/WebAuth/Mobile/Start.php'
: 'https://wauth.teledit.com/Danal/WebAuth/Web/Start.php';
unset($fields['platform']);
// 기존 autosubmit 뷰 재사용 OK
return view('web.auth.danal_autosubmit', [
'action' => $action,
'fields' => $fields,
'isMobile' => $isMobile,
]);
}
public function danalResult(
Request $request,
DanalAuthtelService $danal,
MemberAuthRepository $repo
) {
$payload = $request->all();
if (config('app.debug')) {
Log::info('[MYPAGE][DANAL][RESULT] keys', [
'method' => $request->method(),
'url' => $request->fullUrl(),
'keys' => array_keys($payload),
]);
}
$tid = (string)($payload['TID'] ?? '');
if ($tid === '') {
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => 'TID가 없습니다.',
'redirect' => route('web.mypage.info.index'),
]);
}
// CI와 동일: TID로 CONFIRM
$res = $danal->confirm($tid, 0, 1);
// 로그 저장 (성공/실패 무조건)
$logSeq = $repo->insertDanalAuthLog('M', (array) $res);
if ($logSeq > 0) {
$request->session()->put('mypage.pass.danal_log_seq', $logSeq);
}
$ok = (($res['RETURNCODE'] ?? '') === '0000');
if (!$ok) {
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => ($res['RETURNMSG'] ?? '본인인증에 실패했습니다.') . ' (' . ($res['RETURNCODE'] ?? 'NO_CODE') . ')',
'redirect' => route('web.mypage.info.index'),
]);
}
// ✅ 목적이 마이페이지 연락처 변경일 때만 추가 검증
$purpose = (string) $request->session()->get('mypage.pass_purpose', '');
if ($purpose === 'mypage_phone_change') {
$sess = (array) $request->session()->get('_sess', []);
$memNo = (int) ($sess['_mno'] ?? 0);
if ($memNo <= 0) {
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => '로그인 정보가 확인되지 않습니다. 다시 로그인 후 시도해 주세요.',
'redirect' => route('web.auth.login'),
]);
}
$svc = app(\App\Services\MypageInfoService::class);
//연락처 검증
$check = $svc->validatePassPhoneChange($sess, (array) $res);
if (!($check['ok'] ?? false)) {
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => $check['message'] ?? '연락처 변경 검증에 실패했습니다.',
'redirect' => route('web.mypage.info.index'),
]);
}
//전화번호 저장
$check = $svc->commitPhoneChange($memNo, (array) $res);
if (!($check['ok'] ?? false)) {
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => $check['message'] ?? '연락처 저장에 실패했습니다.',
'redirect' => route('web.mypage.info.index'),
]);
}
$request->session()->put('_sess._mcell', $check['_cell'] ?? ''); //전화번호 변경
}else{
return response()->view('web.auth.danal_finish_top', [
'ok' => false,
'message' => $check['message'] ?? '연락처 변경에 실패했습니다.\n\n관리자에게 문의하세요!',
'redirect' => route('web.mypage.info.index'),
]);
}
// 성공: 마이페이지 인증 플래그 세션 저장
$request->session()->forget('mypage.pass');
$request->session()->forget('mypage.danal ');
$request->session()->save();
return response()->view('web.auth.danal_finish_top', [
'ok' => true,
'message' => '본인인증이 완료되었습니다.',
'redirect' => url('/mypage/info_renew'),
]);
}
}