Skip to content

[2.x] feat(gdpr): PII field declarations and anonymized context support#4396

Merged
imorland merged 4 commits into2.xfrom
im/gdpr-pii-field-declarations
Mar 3, 2026
Merged

[2.x] feat(gdpr): PII field declarations and anonymized context support#4396
imorland merged 4 commits into2.xfrom
im/gdpr-pii-field-declarations

Conversation

@imorland
Copy link
Copy Markdown
Member

@imorland imorland commented Mar 2, 2026

Summary

Port of flarum/gdpr#65, #67, #68, and #69 from the standalone 1.x repo to the 2.x monorepo.

Backend

  • Add piiFields(): array to the DataType interface and Type base class (default returns []); implement on User (5+3 fields), Posts (ip_address), Tokens (last_ip_address)
  • DataProcessor::getPiiKeysForSerialization() aggregates PII fields from all registered types plus extras
  • DataProcessor::getPiiKeysWithExtensions() builds a unified key→extensionId map (type-declared wins over extras, replaces getExtraPiiKeysWithExtensions())
  • DataProcessor::$removeUserColumns refactored from string[] to array<string, string|null> (column→extensionId map); new removableUserColumnsWithExtensions() and resetRemovableUserColumns() methods
  • UserData extender gains addPiiKeysForSerialization() and now passes extensionId to removeUserColumns()
  • DataTypeResource user-columns endpoint updated to return piiKeys, piiKeyExtensions, removableColumns (as object/map), allColumns
  • Exporter guards against null return from DataType::export()

Frontend

  • Admin GDPR page "User Table Data" section fully implemented — replaces "Not yet implemented" stub with a 6-column grid: Column, Type, Nullable, PII (badge + tooltip), Redacted on export (tooltip), Extension
  • ExportAvailableNotification opens download in new tab via markAsRead() to prevent XHR abort on navigation (uses Icon component, 2.x pattern)

Locale

  • Added flarum-gdpr.lib.data.default_user_action key
  • Added 10 user_table_data.* keys for the new column grid UI

README

  • Fixed lingering Blomstra\ namespace references
  • Added developer docs section: PII fields, anonymized contexts, and how to consume the PII list from an extension

Test plan

  • All 30 unit tests pass (phpunit.unit.xml)
  • All 70 integration tests pass (phpunit.integration.xml) — including 6 new tests in ListUserColumnsDataControllerTest
  • yarn build compiles without errors
  • yarn format reports all files unchanged
  • Admin → GDPR page → "User Table Data" shows 6-column grid with PII badges on email, username, etc.
  • GET /api/gdpr-datatypes/user-columns returns piiKeys, piiKeyExtensions, removableColumns (object), allColumns
  • Exporting data for a user with a type that returns null from export() does not throw

🤖 Generated with Claude Code

imorland and others added 2 commits March 2, 2026 23:07
… and user column overview (#65, #67, #68, #69)

Port flarum/gdpr#65, #67, #68, #69 from the standalone 1.x repo to the 2.x monorepo.

- Add `piiFields(): array` to `DataType` interface and `Type` base class; implement on `User`, `Posts`, `Tokens`
- `DataProcessor::getPiiKeysForSerialization()` aggregates PII fields from all registered types plus extras
- `DataProcessor::getPiiKeysWithExtensions()` builds a unified key→extensionId map (type-declared wins over extras)
- `DataProcessor::$removeUserColumns` refactored from `string[]` to `array<string, string|null>` (column→extensionId map); add `removableUserColumnsWithExtensions()` and `resetRemovableUserColumns()`
- `UserData` extender gains `addPiiKeysForSerialization()` and passes extensionId to `removeUserColumns()`
- `DataTypeResource` `user-columns` endpoint now returns `piiKeys`, `piiKeyExtensions`, `removableColumns` (as map), `allColumns`
- Admin `GdprPage` user table section fully implemented with 6-column grid (Column, Type, Nullable, PII, Redacted on export, Extension); uses `Icon` component (2.x)
- `Exporter` guards against `null` return from `DataType::export()`
- `ExportAvailableNotification` opens download in new tab via `markAsRead()` to prevent XHR abort
- `User::piiFields()` expanded to include `nickname`, `suspend_reason`, `suspend_message`
- Add `flarum-gdpr.lib.data.default_user_action` locale key; add 10 user table column UI keys
- README: fix `Blomstra\` → `Flarum\` namespace references; add PII fields and anonymized contexts developer docs
- Tests: 6 new integration tests (`ListUserColumnsDataControllerTest`), 7 new unit tests (`DataProcessorTest`), 4 new unit tests (`TypeTest`), 4 new integration tests (`ExtenderTest`)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
imorland and others added 2 commits March 2, 2026 23:09
…ate type

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…or admin settings page

- Restore Form/Form-group/label structure in GdprPage (accidentally replaced with h3/hr layout following 1.x diff too closely)
- Keep grid() as separate method, add userColumnTable() alongside it
- Use customSetting() for the GDPR page link (JSX cannot be passed to setting())
- Fix default-anonymous-username type: 'string' → 'text' (unknown type rendered a bare input with no label)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@imorland imorland merged commit 1c5d596 into 2.x Mar 3, 2026
34 checks passed
@imorland imorland deleted the im/gdpr-pii-field-declarations branch March 3, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants