# Standalone `worker_security` bundle

Single Python entrypoint [`worker_security.py`](worker_security.py): polls Supabase `scan_details`, runs Docker-based scans (nuclei, nmap, ZAP, httpx, subfinder), renders Jinja reports, generates PDF with Playwright, sends SMTP email—same behavior as the repo’s split [`scripts/scan_queue_worker.py`](../scripts/scan_queue_worker.py) + [`scan.py`](../scan.py) + [`generate_reports_from_update.py`](../generate_reports_from_update.py).

## Layout

- `worker_security.py` — all logic (deploy this file).
- `Reports/` — required templates (`email_html.jinja2`, `full_vulnerable_reports.jinja2`, `email_body.jinja2`, `Detailed Report.html`).
- `.env` — copy from [`.env.example`](.env.example); include `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, and SMTP settings (see [`docs/SCAN_QUEUE_WORKER.md`](../docs/SCAN_QUEUE_WORKER.md)).

**Env loading:** [`load_env.py`](../load_env.py) loads repo-root `.env` first, then `worker_security/.env` when present. Values from `.env` **override** stale `SMTP_*` / `SCAN_REPORT_*` already in the shell. On startup the worker prints `[env] SMTP host=…` so you can confirm the active mail server. Set `SCAN_SHIELD_ENV_FILE=/path/to/.env` to force a specific file. When deployed standalone (only this folder), put SMTP vars in `worker_security/.env` or copy `load_env.py` from the repo root beside the bundle.

## Prerequisites

- **Docker** with images pulled: `projectdiscovery/nuclei`, `instrumentisto/nmap`, `zaproxy/zap-stable`, `projectdiscovery/httpx`, `projectdiscovery/subfinder`.
- **Python 3.10+**

## Install

```bash
cd /path/to/worker_security
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -r requirements.txt
playwright install chromium
```

Copy `.env.example` to `.env` and fill secrets. The shared loader also reads repo-root `.env` when this bundle lives inside the full repo. Restart the worker after changing SMTP settings.

## Run

```bash
cd /path/to/worker_security
python worker_security.py
```

Poll interval: `SCAN_QUEUE_POLL_SEC` (default 30). Tune threads/timeouts with `SCAN_QUEUE_THREADS`, `SCAN_QUEUE_SCAN_TIMEOUT`, etc.

## systemd (auto-start on boot)

1. Deploy this folder to e.g. `/opt/worker_security` (keep `Reports/` beside `worker_security.py`).
2. Edit [`systemd/worker-security.service`](systemd/worker-security.service): set `User=`, `WorkingDirectory=`, and `ExecStart=` to your venv Python and script paths.
3. `sudo cp systemd/worker-security.service /etc/systemd/system/`
4. `sudo systemctl daemon-reload && sudo systemctl enable --now worker-security`
5. `journalctl -u worker-security -f`

Ensure Docker is enabled for your user (`docker` group) or run Docker via root as appropriate.

## Windows

Use Task Scheduler to run `python.exe` with “Start in” set to this folder, or a tool like NSSM to run the same command at startup.

## Email delivery and `error_message`

The worker sends **two** messages: (1) summary + PDF to `requester_email` on the `scan_details` row, (2) full HTML report to the internal address in code (`REPORT_EMAIL_JACO` in `worker_security.py`). If the SMTP server accepts a message, the console prints `[smtp] … accepted by server`. If anything fails (missing env, connection, login, or **refused recipients**), the exception is stored in Supabase on **`scan_details.error_message`** and the row is set to `pending` (scan already saved) or `failed` (before scan). There is no separate error log table; use that column in the dashboard or SQL.

**Ops alerts:** failures, timeouts, and per-tool warnings also trigger a plain-text alert email to **`jaco@overdrive.co.za`** (`SCAN_OPS_ALERT_EMAIL` to override) naming the script/stage and scan row.

## Regenerating `worker_security.py`

The merge builder lives at [`work_scripts/worker_security_merge/build_merged_worker.py`](../../work_scripts/worker_security_merge/build_merged_worker.py) (repo root `www`). After editing `scan.py` or `generate_reports_from_update.py`, re-run that script and re-test.
