feat(gdpr): 필수 저장 항목 허용목록을 운영자 설정으로 이관

허용목록이 플러그인 코드 상수라, 새 확장이 저장 키를 도입할 때마다 이 플러그인을
고쳐야 했다. 고치지 않으면 그 키는 방문마다 파기되는데 예외도 로그도 남지 않아
운영자에게는 "설정이 저장되지 않는다" 는 증상만 보인다.

허용목록을 운영자 설정(necessary_storage_allowlist)으로 옮기고, 관리자 환경설정에
브라우저 저장소·세션 저장소·쿠키 세 카드를 두어 직접 편집하게 했다. 확장은 GDPR 을
알 필요가 없고 GDPR 도 확장을 알 필요가 없다 — 연결은 운영자가 화면에서 한다.
저장 키를 플러그인이 관측·수집하지 않는 것도 같은 이유다: 관측 자체가 추적이다.

판정은 서버(미들웨어)와 클라이언트 셋(인터셉터 둘 + 정리기)이 같은 설정을 같은 매칭
규칙으로 읽는다. 잠금 항목(로그인 토큰·CSRF·세션 쿠키·동의 기록)만 설정 밖에 두고
판정 시점에 합집합으로 얹는다 — 설정에 담기면 저장 요청 한 번으로 지워져 잠금이
아니게 된다. 기설치본은 업그레이드 스텝이 현재 카탈로그를 설정 파일에 못박되,
운영자가 이미 편집했으면 그대로 둔다.

함께 고친 선재 결함 셋:
- 차단 도메인 추천 목록이 응답에 실리지 않아 자동완성이 동작하지 않던 문제
- 세션 쿠키 이름을 기본값에서 바꾼 사이트에서 브라우저 측 목록의 그 항목이 죽던 문제
- 쿠키 목록에만 앞부분 매칭(`이름_*`)이 적용되지 않던 문제
This commit is contained in:
HeuJung
2026-09-03 22:18:18 +09:00
parent 8cf829f953
commit 1124fad027
39 changed files with 3282 additions and 352 deletions
@@ -9,6 +9,8 @@
### Added
- 동의 이력의 출처 "会員退会"(회원탈퇴) 일본어 라벨 추가
- 「必須の保存項目」(필수 저장 항목) 설정 화면의 일본어 문구 추가 — 카드 제목·설명, 저장소 구분 3종(ブラウザストレージ / セッションストレージ / クッキー) 라벨과 설명, 안내 4항목(목적·와일드카드 표기·항목 이름 찾는 법·필수 항목만 등록), 잠금 항목 라벨·안내, 입력 placeholder
- 필수 저장 항목 허용목록의 검증 메시지 일본어 추가 — 저장소 구분별 형식 위반·길이 초과 메시지, 배열 형식 오류, 알 수 없는 저장소 구분
### Changed
@@ -43,6 +43,7 @@ return [
'cookie_policy_version' => 'クッキーポリシーバージョン',
'auto_blocking' => '自動ブロックポリシー',
'auto_blocking_desc' => 'クッキーバナー表示が ON の場合、下記カテゴリー別ブロックドメイン一覧の外部トラッキングリソースがユーザー同意前まで自動ブロックされます。(個別トグルなし — バナー表示と共に自動で動作)',
'necessary_storage' => '必須の保存項目',
],
'nav' => [
'operator' => '運営情報',
@@ -109,6 +110,9 @@ return [
'category_required_badge' => '必須',
'category_optional_badge' => '選択',
],
'necessary_storage_allowlist' => [
'label' => '必須の保存項目許可リスト',
],
],
'save_success' => '設定が保存されました。',
'save_error' => '設定保存中にエラーが発生しました。',
@@ -287,4 +291,14 @@ return [
'category_required_badge' => '必須',
'view_policy_label' => '変更されたポリシー本文を表示',
],
'necessary_storage_allowlist' => [
'invalid_format_local_storage' => 'ブラウザストレージ — 項目の形式が正しくありません。(英字·数字と _ . : @ + - を使用し、末尾には * 1つのみ可能)',
'invalid_format_session_storage' => 'セッションストレージ — 項目の形式が正しくありません。(英字·数字と _ . : @ + - を使用し、末尾には * 1つのみ可能)',
'invalid_format_cookie' => 'Cookie — 項目の形式が正しくありません。(英字·数字と _ . : @ + - を使用し、末尾には * 1つのみ可能)',
'too_long_local_storage' => 'ブラウザストレージ — 項目は128文字を超えることはできません。',
'too_long_session_storage' => 'セッションストレージ — 項目は128文字を超えることはできません。',
'too_long_cookie' => 'Cookie — 項目は128文字を超えることはできません。',
'must_be_array' => 'ストレージ別の項目リストは配列である必要があります。',
'invalid_scope' => '不明なストレージの区分です: :scope (ブラウザストレージ·セッションストレージ·Cookie のみ使用できます)',
],
];
@@ -53,12 +53,15 @@
"cookie_categories": "クッキーカテゴリ",
"cookie_policy_version": "クッキーポリシーバージョン",
"auto_blocking": "自動ブロックポリシー",
"auto_blocking_desc": "クッキーバナーが表示されると、カテゴリ別ドメインリストの外部追跡リソースはユーザーの同意前まで自動ブロックされます。"
"auto_blocking_desc": "クッキーバナーが表示されると、カテゴリ別ドメインリストの外部追跡リソースはユーザーの同意前まで自動ブロックされます。",
"necessary_storage": "必須保存項目",
"necessary_storage_desc": "機能クッキーに同意していない訪問者にも保存が許可される項目を管理します。リストにない項目は訪問するたびに削除されます。"
},
"nav": {
"operator": "運営情報",
"cookie_banner": "クッキーバナー",
"auto_blocking_policy": "自動ブロックポリシー"
"auto_blocking_policy": "自動ブロックポリシー",
"necessary_storage": "必須保存項目"
},
"status": {
"enabled": "有効化",
@@ -140,6 +143,27 @@
"tools": "Meta Pixel(Facebook)、Google 広告リマーケティング、カカオピクセル、YouTube動画埋め込みなど"
}
}
},
"necessary_storage_allowlist": {
"warnings_title": "案内",
"warning_purpose": "ここに登録した項目のみ機能クッキー未同意状態で保存が維持されます。リストにない項目は訪問するたびに削除され、エラーや警告なく「設定が保存されない」という症状のみが現れます。",
"warning_wildcard": "末尾に * を付けると前部分が同じ項目をすべて含みます。例: g7_filters_* は g7_filters_orders_1 を含みます。* は末尾にのみ使用できます。",
"warning_discovery": "新しくインストールした拡張が保存する項目名はその拡張のドキュメントまたはブラウザ開発者ツール(Application → Storage)で確認できます。",
"warning_necessary_only": "サイト運営に必ず必要な項目のみ登録してください。追跡・分析目的の項目を入れると同意前ブロック原則が崩れます。",
"locked_label": "ロック項目(削除不可)",
"locked_hint": "なければサイトが動作しない項目です。リストから外すことはできません。",
"tag_input_placeholder": "項目名を入力してEnter(例: g7_locale, myplugin_*)",
"tag_no_options": "推奨項目がありません。直接入力してください。",
"scope": {
"local_storage": "ブラウザストレージ(localStorage)",
"session_storage": "セッションストレージ(sessionStorage)",
"cookie": "クッキー"
},
"scope_desc": {
"local_storage": "ブラウザを閉じても残る保存領域。言語·テーマのようなユーザー選択と管理者画面表示設定がここに保存されます。",
"session_storage": "タブを閉じると消える保存領域。決済画面·本人認証画面から戻るときに元の画面を復元するのに使われます。",
"cookie": "ブラウザがサーバーに一緒に送る値。サーバーが仕込むクッキーと画面が使うクッキーの両方がこのリストで判定されます。"
}
}
},
"save_success": "設定が保存されました。",
@@ -324,5 +348,15 @@
"operator_and_storage_line": "本サイトは{entity}が運営しており、データは{location}に保存されます",
"operator_only_line": "本サイトは{entity}が運営しています",
"storage_only_line": "ユーザーデータは{location}に保存されます"
},
"necessary_storage_allowlist": {
"invalid_format_local_storage": "ブラウザストレージ — 項目形式が正しくありません。(英数字と _ . : @ + - を使用し、末尾に * は1つだけ可能)",
"invalid_format_session_storage": "セッションストレージ — 項目形式が正しくありません。(英数字と _ . : @ + - を使用し、末尾に * は1つだけ可能)",
"invalid_format_cookie": "クッキー — 項目形式が正しくありません。(英数字と _ . : @ + - を使用し、末尾に * は1つだけ可能)",
"too_long_local_storage": "ブラウザストレージ — 項目は128文字を超えることはできません。",
"too_long_session_storage": "セッションストレージ — 項目は128文字を超えることはできません。",
"too_long_cookie": "クッキー — 項目は128文字を超えることはできません。",
"must_be_array": "ストレージごとの項目リストは配列である必要があります。",
"invalid_scope": "不明なストレージ区分です: :scope (ブラウザストレージ·セッションストレージ·クッキーのみ使用できます)"
}
}