# UniFi Protect webhook capture POC

This plain PHP application records raw webhook requests for schema inspection. It does not interpret UniFi fields or calculate line-crossing totals.

Configure the web server's document root as this project's `public/` directory and serve it over HTTPS. Set these PHP environment variables in the server configuration (never in a web-accessible file):

- `LINECROSSING_DB_PATH`: absolute path to a SQLite file in an existing, PHP-writable directory **outside this project and every web document root**. For example, a suitably permissioned `/var/lib/linecrossing/captures.sqlite` could be used. The file is created there on the first successful request.
- `LINECROSSING_WEBHOOK_SECRET`: a separate random secret of at least 32 characters.
- `LINECROSSING_INSPECTION_SECRET`: another random secret of at least 32 characters.

Generate each secret with `php -r 'echo bin2hex(random_bytes(32)), PHP_EOL;'`. Keep both values out of version control. The application fails closed when configuration is missing or the database path is inside the project.

Configure UniFi Protect's custom webhook URL as:

`https://linecrossing.246techsolutions.com/webhook.php?token=YOUR_WEBHOOK_SECRET`

The URL receives POST requests and returns `204` after a successful insert. Invalid JSON is still captured. Configure web-server access logs to omit or redact the webhook query string so the URL secret is not written to logs. The application does not record the URL or token.

Visit `https://linecrossing.246techsolutions.com/` to inspect captures. The browser will request HTTP Basic credentials: username `inspector`, password equal to `LINECROSSING_INSPECTION_SECRET`. The recent list shows 50 requests, newest first; open a capture to see its metadata, untouched raw payload, and pretty JSON when valid. Use HTTPS because Basic credentials and captured payloads are sensitive.

Timestamps are stored as UTC ISO 8601 strings and shown in `America/Barbados` on the inspection pages. Neither the SQLite file nor secrets should be placed in `public/`; verify the deployed document root before enabling the webhook.
