Skip to content

fix(admin-pin): changing or removing the PIN takes the current one - #350

Merged
jherforth merged 1 commit into
mainfrom
fix/admin-pin-needs-current
Oct 28, 2026
Merged

jherforth merged 1 commit into
mainfrom
fix/admin-pin-needs-current

Conversation

@jherforth

Copy link
Copy Markdown
Owner

Why

POST /api/admin-pin/set and DELETE /api/admin-pin didn't check anything. Anyone on the home network could remove or replace the admin PIN, for example:

curl -X DELETE http://homeglow:3000/api/admin-pin

The PIN guards backup export (which includes the encryption key), restores and rollbacks, and Home Assistant unlock, disarm and garage-door actions. All of that went with it.

What changes

  • Server
    • Replacing an existing PIN takes { pin, currentPin }.
    • Removing one takes { pin }.
    • Both count toward the existing wrong-guess limit: 403 for a missing or wrong PIN, 429 when locked out.
    • Setting the first PIN still needs nothing.
  • Admin Panel
    • Update Admin PIN and Remove PIN ask for the current PIN first, even on a display that remembers it.
    • A wrong PIN is caught before the new one is typed.
  • Forgotten PIN: resetting it now takes access to the server itself.
    • New server/reset-admin-pin.js (npm run reset-pin). It is in the backend image; server/scripts/ is excluded from Docker builds, so it lives next to index.js.
    • It is safe to run while HomeGlow is running.
    • Setting a new PIN clears any leftover lockout.
    • Commands for each install type:
      docker exec homeglow-backend node reset-admin-pin.js
      pct exec <CTID> -- docker exec homeglow-backend node reset-admin-pin.js
      cd server && npm run reset-pin
      
    • The PIN prompt and Admin → Security point to the new "Resetting a forgotten admin PIN" section in docs/guides/deployment.md.
  • Refactor: server/utils/dbPath.js is shared by the server and the script, so both open the same database file.

Testing

  • Server npm test: 667/667. adminPinRoutes.test.js now covers:
    • change and remove without the PIN or with a wrong one (403);
    • both while locked out (429);
    • running the reset script against the live server's database, then setting a new PIN straight past the earlier lockout.
  • Client: vitest 832/832; check:i18n and build are clean.
  • Edge (Playwright, real server and database):
    • the PIN prompt shows the reset hint;
    • Update with a wrong current PIN is refused, and with the right one sets the new PIN;
    • Remove with the old PIN is refused, and with the current one removes it;
    • no page errors.
  • Not tested: running the script inside the Docker image. It isn't excluded by .dockerignore, and /app is the image's working directory.

🤖 Generated with Claude Code

Until now POST /api/admin-pin/set and DELETE /api/admin-pin asked for
nothing, so anyone on the home network could remove or replace the PIN,
and with it the guard on backups, restores and Home Assistant unlocks.

- set takes { currentPin } when a PIN exists; DELETE takes { pin }.
  Both share the wrong-guess limit (403, then 429).
- The Admin Panel asks for the current PIN before Update or Remove,
  even on a display that remembers it.
- A forgotten PIN is reset on the server itself: reset-admin-pin.js
  (npm run reset-pin), shipped in the backend image. The PIN prompt
  and Admin -> Security point to the deployment guide's new section.
- utils/dbPath.js: the server and the script open the same file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jherforth
jherforth merged commit f8070db into main Oct 28, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in HomeGlow Kanban Oct 28, 2026
@jherforth jherforth self-assigned this Oct 28, 2026
@jherforth jherforth added the bug Something isn't working label Oct 28, 2026
@jherforth jherforth added this to the 1.11 milestone Oct 28, 2026
@jherforth
jherforth deleted the fix/admin-pin-needs-current branch October 30, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant