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:
@@ -118,6 +118,16 @@ class SalesReport extends BaseController
|
||||
$hasBsFee
|
||||
);
|
||||
|
||||
// 대표자명 PII: 암호화 대비 복호화 + 권한 없으면 마스킹 (표시 계층)
|
||||
helper('pii_encryption');
|
||||
$canViewPii = can_view_shop_pii((int) $lgIdx);
|
||||
foreach ($detailRows as $row) {
|
||||
if (isset($row->ds_rep_name) && $row->ds_rep_name !== '') {
|
||||
$rep = pii_decrypt((string) $row->ds_rep_name);
|
||||
$row->ds_rep_name = $canViewPii ? $rep : mask_shop_field('ds_rep_name', $rep);
|
||||
}
|
||||
}
|
||||
|
||||
$filtered = [];
|
||||
foreach ($detailRows as $row) {
|
||||
if ($this->ledgerRowMatchesCategories($row, $cats)) {
|
||||
|
||||
Reference in New Issue
Block a user