Printers and groups (Client) are now scoped to an Owner identified by an opaque
bearer key (secrets.token_urlsafe(32)) stored in an httponly cookie, defaulting
to temporary. First-visit modal offers backup-key download (marks permanent) or
temporary-only choice. /session/restore re-attaches a fresh browser to a saved
key. Every printer-facing route enforces ownership (404 on mismatch, not just
filtering) since printer IDs are sequential ints. Drivers stay global/shared.
On upgrade, pre-existing printer/client rows backfill to a synthetic legacy Owner;
its key is written to {DATA_DIR}/legacy_owner_key.txt for manual restore.
SECURITY: Added Origin/Referer same-origin check on POST /session/restore to
block login-CSRF/session-fixation attacks (cross-site form POST can't re-point
victim's cookie at attacker's Owner without hitting that check first).
Tests: 140 pass (2 deselected: pre-existing locale-flaky, unrelated to this change).
Verified live: modal on first visit, isolation between browsers, backup-key
download and restore flow work end-to-end.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
ImpTune
Build printer deploy packages (.intunewin for Intune, .zip for NinjaRMM) from Windows driver ZIPs via a web UI.
Run
Local development
docker compose up
docker-compose.override.yml is merged automatically: it mounts your working
copy into the container and runs uvicorn with --reload, so code edits are
picked up live. The override is gitignored (personal / per-machine).
Run the published image
To run the image from the registry instead of building locally, skip the override:
docker compose -f docker-compose.yml pull
docker compose -f docker-compose.yml up
Then open http://localhost:8000
Publishing
scripts/publish.ps1 builds the image and pushes it to the Gitea container
registry at git.azuze.fr/kawa/imptune.
# build + push :<short-git-sha> and :latest (prompts for a Gitea token)
./scripts/publish.ps1
# tag an explicit version
./scripts/publish.ps1 -Tag v1.2.0
Use a Gitea access token (Settings → Applications, with package read/write
scope) as the password. For non-interactive runs set GITEA_USER /
GITEA_TOKEN env vars. Run Get-Help ./scripts/publish.ps1 -Detailed for all
parameters (-Registry, -Owner, -Image, -NoBuild, -SkipLogin, …).
Environment variables
Set these under environment: in docker-compose.yml.
| Variable | Default | Purpose |
|---|---|---|
DATA_DIR |
/data |
Storage root for the SQLite DB, drivers and icons. Should map to the imptune_data volume. |
PORT |
8000 |
Port the server listens on inside the container. |