feat: 지정판매소 개인정보(PII) 보호 — 마스킹·암호화·열람 게이트 (기본 OFF)

종량제3 세션 작업. 마스터 플래그(Config\Pii.designatedShopProtection)가 OFF면
현재 동작(원문 그대로) 유지, ON일 때만 마스킹·게이트 적용.

- 표시 계층 단일 지점 마스킹: 대표자명/전화/이메일/계좌/가상계좌 (목록·상세·엑셀·판매대장·전화주문)
- 원문 열람 게이트: 지자체 허용 IP 자동열람 or 2단계 인증(TOTP) step-up + 감사기록(revealPii)
- 정확일치 검색: 블라인드 인덱스(HMAC) 컬럼 있으면 사용, 없으면 평문 폴백
- 저장계층 암호화(encryptAtRest, 기본 OFF): 모델 콜백 + spark 명령 pii:protect-designated-shops
- SQL(추가·멱등): designated_shop_add_pii_bidx / local_government_add_allow_ips
- Auth: TOTP 실제 통과 시에만 세션 auth_2fa_verified=true

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
taekyoungc
2026-07-16 15:45:28 +09:00
parent c5df784f91
commit 5e8e81f404
12 changed files with 726 additions and 19 deletions

View File

@@ -233,7 +233,7 @@ class Auth extends BaseController
return $this->handleTotpFailure($member, $this->buildLogData($member->mb_id, (int) $member->mb_idx));
}
return $this->completeLogin($member, $this->buildLogData($member->mb_id, (int) $member->mb_idx));
return $this->completeLogin($member, $this->buildLogData($member->mb_id, (int) $member->mb_idx), true);
}
public function showTotpSetup()
@@ -329,7 +329,7 @@ class Auth extends BaseController
return redirect()->to(site_url('login'))->with('error', '회원 정보를 다시 확인할 수 없습니다.');
}
return $this->completeLogin($fresh, $this->buildLogData($fresh->mb_id, (int) $fresh->mb_idx));
return $this->completeLogin($fresh, $this->buildLogData($fresh->mb_id, (int) $fresh->mb_idx), true);
}
public function logout()
@@ -573,7 +573,7 @@ class Auth extends BaseController
/**
* @param array<string, mixed> $logData
*/
private function completeLogin(object $member, array $logData): RedirectResponse
private function completeLogin(object $member, array $logData, bool $twofaVerified = false): RedirectResponse
{
$this->clearPending2faSession();
// 중복 로그인 방지(나중 로그인 우선): 새 세션 토큰 발급 → 기존 다른 세션은 다음 요청 때 무효화됨
@@ -586,6 +586,8 @@ class Auth extends BaseController
'mb_lg_idx' => $member->mb_lg_idx ?? null,
'logged_in' => true,
'session_token' => $sessionToken,
// 지정판매소 PII 자동 원문 열람 조건에 사용(TOTP 실제 통과 시에만 true)
'auth_2fa_verified' => $twofaVerified,
];
session()->set($sessionData);