Lightbox: fix proxy 404, cap modal size, allow multi-Civi embed

Three quick fixes off first-deploy testing:

1. /api/staff/file 404'd for valid files. Refactor fileBelongsToOrg
   to SELECT the org's and activities' file columns and JS-compare
   instead of WHERE ... OR with custom field refs (APIv4 fragility
   around nested OR + dotted custom fields). Same ownership probe,
   same shape /api/staff/report itself uses to read file values.

2. Lightbox ballooned to full report height because the staff iframe
   auto-grows to fit content (often 3000+ px). Cap to a fixed
   640px x min(92vw, 900px) box so it stays a reasonable preview
   regardless of iframe document size.

3. Production frame-ancestors blocked crm.fci.coop from iframing
   survey.fci.coop -- the CSP only included the dev Civi origin
   derived from CIVI_BASE_URL. Add CIVI_FRAME_ALLOWED_ORIGINS
   (comma-separated) so one app deploy can be embedded by both
   dev and prod Civi. Falls back to CIVI_BASE_URL for single-Civi
   compatibility.

PRODUCTION_CUTOVER.md updated inline and in the change log.
This commit is contained in:
Joel Brock
2026-06-16 16:15:28 -07:00
parent 0019996b15
commit 5124010b8a
4 changed files with 124 additions and 64 deletions
+25 -8
View File
@@ -197,13 +197,20 @@ Full extension docs:
## 6. CSP / `frame-ancestors` — app side
The Next.js app's `/staff/report` route must allow the CiviCRM origin
in its `frame-ancestors` CSP, or the iframe will refuse to render.
The Next.js app's `/staff/report` and `/api/staff/file` routes must
allow every CiviCRM origin that will iframe them, or the browser will
refuse to render.
The build reads `CIVI_BASE_URL` and adds its origin to the CSP
automatically — so make sure `CIVI_BASE_URL` on the app deploy points
at the **production** CRM origin (`https://crm.fci.coop`), not
`client.crm.fci.coop`.
Set **`CIVI_FRAME_ALLOWED_ORIGINS`** (comma-separated) in the app
deploy env. Each origin needs the scheme:
```
CIVI_FRAME_ALLOWED_ORIGINS=https://crm.fci.coop,https://client.crm.fci.coop
```
Include both prod and any staging Civi origins you want to keep
embedding. If unset, the build falls back to the origin of
`CIVI_BASE_URL` (single-Civi compatibility).
Confirm after deploy:
@@ -211,8 +218,11 @@ Confirm after deploy:
curl -sI https://survey.fci.coop/staff/report | grep -i content-security-policy
```
Should include `frame-ancestors 'self' https://crm.fci.coop` (or
whatever your production CRM origin is).
Should include
`frame-ancestors 'self' https://crm.fci.coop https://client.crm.fci.coop`
(or whatever list you configured). If you see only one origin and the
other Civi is failing to embed, the env var is missing or stale —
trigger a new build, not just a restart.
---
@@ -276,3 +286,10 @@ so the rationale survives.
- **2026-06-08** — Documented the field-242 "Unknown" default issue
after a production submission was stamped `Stage = "Unknown"`.
Cleared via `CustomField.update`; see step 2.
- **2026-06-16** — Step 6 split off `CIVI_FRAME_ALLOWED_ORIGINS` as a
separate env from `CIVI_BASE_URL`. Surfaced after the production
cutover hit a `frame-ancestors` block: the app's CSP only listed the
staging Civi origin (derived from `CIVI_BASE_URL`), so prod
(`crm.fci.coop`) couldn't iframe `survey.fci.coop`. The new var
takes a comma-separated list so one app deploy can be embedded by
both dev and prod Civi.