Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
1ec831a
frontend: improve rule options UX and visual styling
theodubus Feb 15, 2026
20b0fa6
Merge pull request #47 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
74881f6
Update RulesList.tsx
theodubus Feb 15, 2026
21b5822
frontend: adjust rule list height and accent/subword option UX
theodubus Feb 15, 2026
fa24e84
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
5b9c3a0
Merge pull request #48 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
286c4d9
frontend: make accent option default state visually unambiguous
theodubus Feb 15, 2026
25c2a26
Merge pull request #49 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
3aeff59
frontend: clarify inactive accent pill and restore global pill weight
theodubus Feb 15, 2026
1a86b3c
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
e0928f5
Merge pull request #50 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
b3ecbcc
frontend: reset options defaults on open and restore regex pill styling
theodubus Feb 15, 2026
400b24e
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
9680bdd
Merge pull request #51 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
ac66b38
frontend: restore visible active state for non-regex option pills
theodubus Feb 15, 2026
3fa0ab4
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
c5b9d50
Merge pull request #52 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
cc92f28
frontend: restore bold-on-active behavior for option pills
theodubus Feb 15, 2026
8a4aa44
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
e33cd6f
Merge pull request #53 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
b6f1af4
Update RulesSection.tsx
theodubus Feb 15, 2026
e4b1cf2
Merge branch 'feat/graphic_selection_dev2' of https://github.com/theo…
theodubus Feb 15, 2026
ed0b754
frontend: make base pills non-bold so active state weight change is v…
theodubus Feb 15, 2026
f299466
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
7a65584
Merge pull request #54 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
9a89b46
Update RulesSection.tsx
theodubus Feb 15, 2026
35df215
Merge branch 'feat/graphic_selection_dev2' of https://github.com/theo…
theodubus Feb 15, 2026
f4740fc
frontend: localize option badge tooltips in rules list
theodubus Feb 15, 2026
d8baed0
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
8a6c2fb
Merge pull request #55 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
b6e215a
frontend: unify options and preset pills to shared styling
theodubus Feb 15, 2026
7539153
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
a249bab
Merge pull request #56 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
d21a3e6
frontend: strengthen shared active pill contrast for all pill types
theodubus Feb 15, 2026
9e73bbe
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
e70dc6d
Merge pull request #57 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
7899d5e
frontend: restore original light active pill appearance
theodubus Feb 15, 2026
3a77958
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
c66df6e
Merge pull request #58 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
5c0d7da
frontend: increase inactive/active pill contrast while keeping light …
theodubus Feb 15, 2026
e939cc5
Merge branch 'feat/graphic_selection_dev2' into codex/inspect-code-an…
theodubus Feb 15, 2026
65a6c8b
Merge pull request #59 from theodubus/codex/inspect-code-and-make-ui-…
theodubus Feb 15, 2026
ce4d7f1
Update RuleOptionsRow.tsx
theodubus Feb 15, 2026
3cd99e0
feat(frontend): add redact current page rule with preview
theodubus Feb 15, 2026
ea42af3
Merge pull request #60 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
5254661
fix(page-redaction): align page rule labels and ensure full-page apply
theodubus Feb 15, 2026
054b100
Merge branch 'feat/graphic_selection_dev2' into codex/add-page-censor…
theodubus Feb 15, 2026
1c31315
Merge pull request #61 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
85935e7
fix(frontend): force image/graphics redaction for full-page rules
theodubus Feb 15, 2026
df57e68
Merge pull request #62 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
8a61158
fix(frontend): use real page dimensions for full-page redaction rects
theodubus Feb 15, 2026
359c070
Merge branch 'feat/graphic_selection_dev2' into codex/add-page-censor…
theodubus Feb 15, 2026
d3086c8
Merge pull request #63 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
52924a6
fix(frontend): stabilize text selection by memoizing page size callback
theodubus Feb 15, 2026
89a100b
Merge branch 'feat/graphic_selection_dev2' into codex/add-page-censor…
theodubus Feb 15, 2026
ac1706e
Merge pull request #64 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
4f36039
feat(frontend): add draw-rectangle redaction workflow
theodubus Feb 15, 2026
286bf11
Merge branch 'feat/graphic_selection_dev2' into codex/add-page-censor…
theodubus Feb 15, 2026
2238c88
Merge pull request #65 from theodubus/codex/add-page-censoring-feature
theodubus Feb 15, 2026
9fc664b
feat(frontend): enable strict redaction options for rectangle draws
theodubus Feb 23, 2026
378a58f
Merge branch 'feat/graphic_selection_dev2' into codex/add-page-censor…
theodubus Feb 23, 2026
be0bb32
Merge pull request #66 from theodubus/codex/add-page-censoring-feature
theodubus Feb 23, 2026
698b61c
docs: expand product, security, contribution, and deployment guides
theodubus Feb 23, 2026
313bc69
Merge pull request #67 from theodubus/codex/add-page-censoring-feature
theodubus Feb 23, 2026
1705231
stabilize
theodubus May 4, 2026
9095e1c
add partial image redaction
theodubus May 4, 2026
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
159 changes: 145 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,166 @@
# RedactPDF
Local, verifiable PDF redaction (removes content instead of masking).

## Backend
Local web app for redacting sensitive content from PDF files. Targets manual
rectangles, text search, regex (single- or multi-line), and presets (email,
phone, credit card). Every export passes a post-redaction audit before being
returned, if any targeted content remains in the output, the export is
blocked with a structured failure report.

For the security model and limitations, see [docs/SECURITY.md](docs/SECURITY.md).

---

## Requirements

- **Python 3.10 or newer** (CI runs 3.11)
- **Node.js 20 or newer** (for the frontend dev server / build)
- A POSIX-like shell (Linux, macOS, WSL). Windows native is not officially
tested.

---

## Install

Clone the repo and set up the two halves:

Install dev dependencies:
```bash
pip install -e "backend[dev]"
git clone https://github.com/theodubus/RedactPDF.git
cd RedactPDF
```

Run tests:
### Backend (FastAPI + PyMuPDF)

```bash
cd backend
pytest
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
```

`.[dev]` pulls runtime deps (FastAPI, PyMuPDF, `phonenumbers`, …) plus dev
tooling (pytest, ruff, reportlab, httpx, pypdf).

### Frontend (React + Vite)

```bash
cd ../frontend
npm ci
```

---

## Run locally

You need two terminals.

**Terminal 1 - backend:**

```bash
cd backend
source .venv/bin/activate
uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
```

Run the API locally:
**Terminal 2 - frontend:**

```bash
cd frontend
npm run dev
```

Open the URL Vite prints (default: `http://localhost:5173`). The Vite dev
server proxies `/api/*` to the backend on `127.0.0.1:8000` (configured in
[frontend/vite.config.ts](frontend/vite.config.ts)), so you do not need to
worry about CORS in development.

---

## Use it

1. Drop a PDF into the upload area.
2. Add redaction rules in the right pane:
- **Selection** : select text in the viewer and click "Add as rule".
- **Manual rectangle** : toggle the draw tool and trace rectangles.
- **Whole page** : censor the current page.
- **Exact / regex** : typed rules with options (case sensitivity,
whole-word, ignore accents, multiline).
- **Presets** : email, phone (libphonenumber-validated, default region
`FR`), credit card (Luhn-filtered).
3. Pick an **image redaction mode** in the right pane (segmented control):
- **Aucune** (None) : images and vector graphics are not modified, even
if a redaction rectangle overlaps them. Only the text under the
redaction is removed; visually a black overlay is drawn on top, but
the underlying images/graphics still exist in the PDF and are
recoverable by anyone who removes the overlay.
- **Totale** (Full) : any image touched by a rectangle is removed
entirely; any vector path touched is removed.
- **Précise** (Precise) *(default)* : only the pixels inside the
redaction rectangle are blackened in the underlying bitmap; the rest
of the image stays visible. Vector paths touched by the rectangle are
removed (per-path, not pixel-level, vector partial redaction is not
supported). **This is the mode that makes flattened / scanned PDFs
redactable**, without it, the only options on a scan would be "lose
the whole page" or draw a fake black overlay. Re-encoding may be
lossy on JPEG-backed images.

The mode applies globally to the redaction request. **Exception**: any
"Censurer la page" rule (full-page redaction) always uses strict mode
for the page it covers, regardless of the chosen image mode, so a
full-page rule cannot accidentally leave images or graphics under a
black overlay. See [docs/SECURITY.md](docs/SECURITY.md) for details.
4. Click the submit button. The redacted PDF downloads automatically.
5. If the post-redaction audit finds any targeted content remaining, you
get a 400 with a JSON report instead, fix the rule and retry.

### Phone preset region

The `phone` preset uses `phonenumbers` to validate candidates. Numbers
without a leading `+` are parsed against a default region. To change it:

```bash
export REDACT_DEFAULT_REGION=US
uvicorn app.main:app ...
```

---

## Run the tests

```bash
cd backend
uvicorn app.main:app --reload
source .venv/bin/activate
ruff check .
pytest
```

## Security
The test suite uses **versioned PDF fixtures** : see
[backend/tests/fixtures/README.md](backend/tests/fixtures/README.md). Do not
edit the generated PDFs by hand. If you change the fixture generator,
regenerate all of them in one go:

```bash
python -m backend.tests.fixtures.generate_fixtures
```

---

## Production deployment

See [docs/SECURITY.md](docs/SECURITY.md).
This project is built for local single-user usage. **Exposing the API to
untrusted networks or multiple users is unsafe out of the box**, there is
no auth, no rate limiting, no upload size cap, no regex timeout. If you
plan to host it for others, read
[docs/SECURITY.md → Production / Multi-user Deployment](docs/SECURITY.md)
first and put the recommended protections in your reverse proxy /
container.

## Fixtures
A typical setup is: build the frontend (`npm run build` produces a static
bundle in `frontend/dist`), serve it from a reverse proxy that also
proxies `/api/*` to the backend (Uvicorn or Gunicorn-with-Uvicorn-workers
behind nginx/Caddy). With same-origin serving, you do not need CORS.

See [backend/tests/fixtures/README.md](backend/tests/fixtures/README.md).
---

## Testing
## License

See [docs/TESTING.md](docs/TESTING.md).
See repository root.
Loading
Loading