You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`src/server/validateUrl.ts` — HTTPS + gov.uk domain validation for URL overrides
35
+
-`src/insights/sanitiseHtml.ts` — sanitise-html wrapper for LLM output
33
36
34
37
## Running locally
35
38
@@ -62,6 +65,8 @@ APP_URL=http://localhost:3000
62
65
63
66
OAuth2 authorization code flow via Internal Access (`sso.service.security.gov.uk`). Sessions stored in Postgres via `connect-pg-simple` (auto-creates `session` table). 2-hour session expiry matching token lifetime. No refresh tokens.
64
67
68
+
Session is regenerated on login (`session.regenerate()`) to prevent session fixation. The OIDC `sub` claim is stored as the stable user identifier (email may change).
69
+
65
70
Public routes: `/`, `/health`, `/auth/*`, `/public/*`, `/assets/*`
-**Migrations** in `src/db/migrations/` — numbered SQL files, applied by `src/db/migrate.ts`
76
81
-**Sessions** — `session` table auto-created by `connect-pg-simple`
77
82
83
+
## Security
84
+
85
+
-**CSRF** — synchroniser token pattern via `csrf-sync`. Tokens delivered in a `<meta>` tag and submitted as `_csrf` body field or `x-csrf-token` header. All POST endpoints are protected.
86
+
-**SQL validation** — LLM-generated SQL is parsed with `pgsql-ast-parser` (AST-based). Only single SELECT/WITH statements allowed; function calls checked against an allowlist; LIMIT capped at 100. The read-only pool also enforces `default_transaction_read_only` and `statement_timeout` at DB level.
-**Prompt injection** — scraper extracts `innerText` (not `innerHTML`) before sending to Bedrock, so hidden elements, scripts, and HTML comments never reach the LLM.
89
+
-**HTML sanitisation** — LLM prose responses are sanitised server-side with `sanitize-html` (strict tag allowlist) before rendering.
90
+
-**TLS** — database connections use `ssl: { rejectUnauthorized: true }` in production.
Copy file name to clipboardExpand all lines: README.md
+2-12Lines changed: 2 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,23 +55,13 @@ npm run db:seed
55
55
56
56
## Running locally
57
57
58
-
### UI only (no worker)
59
-
60
58
```bash
61
59
npm run dev
62
-
```
63
-
64
-
Opens at [http://localhost:3000](http://localhost:3000). This starts only the Express server — no scraping will happen.
65
-
66
-
### Full app (server + worker)
67
-
68
-
```bash
60
+
npm run dev:watch
69
61
npm run build && npm start
70
62
```
71
63
72
-
Starts the Express server and the pg-boss job worker in the same process. The worker runs 3 concurrent scrape loops and a daily cron at 2am London time.
73
-
74
-
Trigger checks from the Workers page (all services) or from individual service pages (single service).
64
+
Opens at [http://localhost:3000](http://localhost:3000)
0 commit comments