Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/extension-pii-config-wiring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kiji-privacy-proxy": minor
---

Chrome extension: configure PII entity types and custom regex patterns from the options page, wired to the `/api/pii/entities` and `/api/pii/regexes` endpoints.
137 changes: 136 additions & 1 deletion chrome-extension/options.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ body {
min-height: 100vh;
padding: 48px 24px;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
gap: 24px;
}

.card {
Expand Down Expand Up @@ -307,3 +309,136 @@ input[type="url"]:focus,
.save-error {
color: var(--err);
}

/* ---------- Label grid (PII types) ---------- */

.label-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 8px;
margin-bottom: 20px;
}

.label-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
font-family: var(--mono);
color: var(--text);
cursor: pointer;
padding: 6px 8px;
border-radius: var(--radius-sm);
background: var(--bg-subtle);
user-select: none;
}

.label-item input[type="checkbox"] {
accent-color: var(--brand);
width: 14px;
height: 14px;
flex-shrink: 0;
cursor: pointer;
}

.label-loading {
font-size: 12px;
color: var(--text-muted);
}

/* ---------- Custom patterns ---------- */

.pattern-form {
margin-bottom: 16px;
}

.pattern-form-row {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
margin-bottom: 8px;
}

.pattern-form-row .input-mono {
flex: 1;
min-width: 120px;
}

.pattern-preview-row {
display: flex;
gap: 8px;
align-items: center;
}

.pattern-preview-row .input-mono {
flex: 1;
}

.pattern-preview-result {
font-size: 12px;
font-family: var(--mono);
color: var(--text-muted);
white-space: nowrap;
}

.pattern-error {
color: var(--err);
min-height: 1.2em;
}

.pattern-list {
display: flex;
flex-direction: column;
gap: 6px;
border-top: 0.5px solid var(--border);
padding-top: 16px;
}

.pattern-row {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
background: var(--bg-subtle);
border-radius: var(--radius-sm);
font-size: 12px;
flex-wrap: wrap;
}

.pattern-name {
font-family: var(--mono);
font-weight: 600;
color: var(--brand);
flex-shrink: 0;
}

.pattern-regex-val {
font-family: var(--mono);
color: var(--code-text);
flex: 1;
word-break: break-all;
}

.btn-danger {
padding: 5px 10px;
background: transparent;
color: var(--err);
border: 0.5px solid var(--err);
border-radius: var(--radius-sm);
font-size: 12px;
cursor: pointer;
flex-shrink: 0;
transition: background 0.15s ease;
}

.btn-danger:hover {
background: rgba(226, 75, 74, 0.1);
}

.pattern-row .input-mono {
padding: 5px 8px;
font-size: 12px;
flex: 1;
min-width: 80px;
}
67 changes: 67 additions & 0 deletions chrome-extension/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,73 @@
</div>
</div>
</div>

<div class="card" id="pii-types-card">
<header class="card-header">
<div class="card-title">
<span class="card-name">PII entity types</span>
<span class="card-sub">Uncheck types you want to leave unmasked</span>
</div>
<a href="#" id="toggle-all" class="link">Disable all</a>
</header>
<div class="card-body">
<div id="label-grid" class="label-grid">
<span class="label-loading">Loading entity types…</span>
</div>
<div class="form-actions">
<button id="save-labels-btn" type="button" class="btn-primary">
Save
</button>
<span id="labels-status" class="save-status" role="status"></span>
</div>
</div>
</div>

<div class="card" id="patterns-card">
<header class="card-header">
<div class="card-title">
<span class="card-name">Custom patterns</span>
<span class="card-sub">Domain-specific regex rules applied on top of the model</span>
</div>
</header>
<div class="card-body">
<form id="pattern-form" class="pattern-form" autocomplete="off">
<div class="pattern-form-row">
<input
type="text"
id="pattern-name"
class="input-mono"
placeholder="NAME"
title="Name for this entity type (e.g. EMPLOYEE_ID)"
required
/>
<input
type="text"
id="pattern-regex"
class="input-mono"
placeholder="Regex"
title="Regular expression pattern (e.g. EMP-\d{6})"
required
/>
<button type="submit" class="btn-primary">Add</button>
</div>
<div class="pattern-preview-row">
<input
type="text"
id="pattern-sample"
class="input-mono"
placeholder="Sample text to test against"
/>
<span id="pattern-preview-result" class="pattern-preview-result"></span>
</div>
<p id="pattern-regex-error" class="form-help pattern-error"></p>
</form>

<div id="pattern-list" class="pattern-list">
<span class="label-loading">Loading patterns…</span>
</div>
</div>
</div>
</div>
<script src="config.js"></script>
<script src="options.js"></script>
Expand Down
Loading
Loading