Who holds
the keys.

Create the people, issue their codes, publish the roster. Managers and callers sign in with the codes you set here.

Root access · issues and revokes every other login.
Five wrong attempts locks the form for 60 seconds.
Keep this page off shared machines.

The key ring.

Root · ADMIN ·

The roster.

Everyone who can sign in anywhere
PersonRoleContactStatus CodeCode ageAdded

Changes here only reach the login page once you Publish roster and upload the file.

Codes needing attention.

Missing, or older than the rotation window

Handover card.

What to send the person — never the code by the same channel
Pick a person above.

Send the card by one channel and the code by another — card on email, code on a call.

Code policy.

Applies to every code you issue from here

Codes are never stored. Each person gets a random salt, and the code is stretched through PBKDF2-SHA256 before only the result is saved. Raising the rounds makes a stolen roster file far more expensive to attack — and login a fraction slower.

Device unlock.

Fingerprint or face, on this device
Checking…

Uses the fingerprint reader or face unlock already built into this device — nothing is sent anywhere and no biometric data reaches this page or your server. It replaces typing the code on this device only. Keep the code safe: you still need it on a new phone or laptop, and after clearing browser data.

Revoke everything.

When a device or a file goes missing

Clears every code on the roster. Nobody can sign in until you issue new ones and publish again. People and their details are kept.

Publish the roster.

Two steps — download, then upload
  1. Download the roster file. It contains names, roles and stretched code fingerprints — never the codes themselves.
  2. Upload it to your web root, next to login.html, keeping the exact filename below. On most hosts that is the public_html folder.
  3. Test one login. Open login.html, sign in as one of the people. If the roster loaded, the page says so under the form.
  4. Republish every time you change a person or a code. Nothing reaches the login page until you do.
The roster file is publicly readable. Anyone who knows the filename can download it. That is why codes are stretched rather than stored — but it is also why you should use a hard-to-guess filename, keep codes long, and never reuse a personal password here. Serve the site over HTTPS: this page needs it, and so does login.html.

Offline fallback.

If you would rather not upload a file

You can paste the roster directly into login.html instead. Copy the block below and replace the line that starts with const EMBEDDED_ROSTER near the bottom of login.html. Simpler, but you must edit the file by hand every time someone joins or a code changes.

Sign-in log.

Recorded on this device only
WhenNameDoorResultDevice

A browser cannot see sign-ins that happened on someone else's phone or laptop. This shows what happened here. For a real audit trail across everyone, you need a server.

Adding someone.

Start to finish
  1. People → Add person. Name, role, phone. The name is what they type at the login screen, so keep it simple and tell them exactly how it is spelled.
  2. Set their code. Generate one, or type your own. It is shown once, right then. Copy it before closing — it cannot be recovered, only replaced.
  3. Publish roster and upload the file to your web root.
  4. Send the handover card by email, and the code by a separate channel.

When someone leaves.

Same day, not next week
  1. Suspend them in People. Their code stops working the moment you publish.
  2. Publish and upload. Until you upload, the old file is still live and their code still works.
  3. Rotate the codes of anyone who shared a device with them.
  4. Remove their broker access separately. This page controls the consoles, nothing else.

The three doors.

Who sees what
  • Admin — this page. People and codes. Cannot see the client book unless also given Manager.
  • Manager — the client book. Funds, feedback, leads, growth, settings.
  • Team — the calling desk. Queue, call sheets, referrals. No fund values by default.

Honest limits.

Read this once
  • Verification happens in the visitor's browser. A determined person can bypass the screen and read what the page loads.
  • Client records live in each browser separately. This page issues logins; it does not sync the book.
  • Good enough to keep a working area private. Not good enough to be the only thing standing between the public and real client money data.
  • When you are ready, the fix is a small server login — PHP sessions on your existing hosting, or Cloudflare Access in front of these pages.