Admin sits behind a 6-digit PIN
The passcode machinery existed but could only be set by hand in a config file, so in practice every install left admin open to anyone on the network. It is now a PIN you set from the admin page itself. - Six digits, stored as a scrypt hash in this machine's proddash.json — never in the clear, since that file gets copied between machines. - The unlock card takes the PIN and submits itself on the sixth digit. Five wrong tries from one address locks it out for 30 seconds, and the right PIN is refused during the lockout. - Changing or turning off the PIN asks for the current one, so a browser left open on the admin page cannot be used to take the machine over. Whoever sets it keeps their session rather than being bounced to the card they just built. - This is the shell's own PIN and guards /admin and the admin API only. Dashboards stay open, and it is unrelated to a module's PIN — Slack's 4-8 digit send PIN still guards sending, separately and independently. - Ways back in if it is forgotten: PRODDASH_PASSCODE in the environment (which overrides the PIN), or delete adminPin from proddash.json and restart. Both are in the README and on the page itself. - The older free-text adminPasscode still works, so an existing install keeps running. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
095fe66118
commit
6dabd9d8a1
+36
-2
@@ -18,10 +18,11 @@
|
||||
|
||||
<main id="admin-main">
|
||||
<section class="admin-card" id="login-card" hidden>
|
||||
<h2>Admin passcode</h2>
|
||||
<h2>Admin PIN</h2>
|
||||
<p class="admin-copy">This page changes the server-wide configuration for every dashboard in the building.</p>
|
||||
<div class="login-row">
|
||||
<input type="password" id="passcode" placeholder="Passcode" autocomplete="current-password">
|
||||
<input type="password" id="passcode" class="pin-input" inputmode="numeric" autocomplete="off"
|
||||
maxlength="6" placeholder="••••••" aria-label="Admin PIN">
|
||||
<button class="btn primary" id="login-btn">Unlock</button>
|
||||
</div>
|
||||
<div class="admin-status" id="login-status"></div>
|
||||
@@ -65,6 +66,39 @@
|
||||
<h1 class="admin-h1">Saved layouts</h1>
|
||||
<div id="layouts-list"></div>
|
||||
</section>
|
||||
|
||||
<section id="security-section" hidden>
|
||||
<h1 class="admin-h1">Admin PIN</h1>
|
||||
<p class="admin-copy" id="pin-state"></p>
|
||||
<div class="admin-card">
|
||||
<div class="pin-form">
|
||||
<label class="pin-field" id="pin-current-field" hidden>
|
||||
<span>Current PIN</span>
|
||||
<input type="password" id="pin-current" class="pin-input" inputmode="numeric"
|
||||
autocomplete="off" maxlength="6" placeholder="••••••">
|
||||
</label>
|
||||
<label class="pin-field">
|
||||
<span id="pin-new-label">New PIN</span>
|
||||
<input type="password" id="pin-new" class="pin-input" inputmode="numeric"
|
||||
autocomplete="off" maxlength="6" placeholder="6 digits">
|
||||
</label>
|
||||
<label class="pin-field">
|
||||
<span>Repeat</span>
|
||||
<input type="password" id="pin-repeat" class="pin-input" inputmode="numeric"
|
||||
autocomplete="off" maxlength="6" placeholder="6 digits">
|
||||
</label>
|
||||
<div class="pin-actions">
|
||||
<button class="btn primary" id="pin-save">Set PIN</button>
|
||||
<button class="btn" id="pin-clear" hidden>Turn off</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="admin-copy pin-note">Only this page and the admin API ask for it — dashboards stay
|
||||
open, and it is nothing to do with a module's own PIN, such as Slack's send PIN. Forgotten?
|
||||
Remove <code>adminPin</code> from <code id="pin-file">proddash.json</code> in the settings
|
||||
folder and restart.</p>
|
||||
<div class="admin-status" id="pin-status"></div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div id="toast" hidden></div>
|
||||
|
||||
Reference in New Issue
Block a user