A terminal-based (TUI) management tool for the Doorlock access control system. Built with Ink (React for the terminal), it provides an interactive interface to manage persons and their RFID/NFC tokens directly on the device.
- Person Management — Add, edit, delete, and disable/enable persons
- Token Management — Assign, reassign, and remove RFID/NFC tokens with PIN hashing
- Filterable Lists — Press
/to search persons or tokens by name in the list view; type-to-filter when selecting a person in forms - Scrollable Views — Handles large lists with windowed rendering and scroll indicators
- Direct Database Access — Reads and writes the doorlock SQLite database in-place
- Node.js ≥ 18
- The doorlock backend database at
../doorlock/backend/doorlock.db(relative to this folder)
npm installnpm startOr use the included helper script (designed for a Raspberry Pi deployment):
./start.shWe use this script as a default shell on a user that is specifically made for this tool.
You can see just about all of the navigation options that you have on the bottom of the screen. Here is a list anyways ;)
| Key | Action |
|---|---|
↑ / ↓ |
Move cursor |
Enter |
Select / confirm |
/ |
Start searching (list views) |
Esc |
Cancel / stop search / go back |
q |
Quit / go back |
- Persons — Manage people who have access
- Tokens — Manage RFID/NFC tokens assigned to persons
| Key | Action |
|---|---|
a |
Add a new person |
e |
Edit selected person |
t |
Toggle disabled |
d |
Delete person (and their tokens) |
| Key | Action |
|---|---|
a |
Add a new token |
e |
Edit selected token |
d |
Delete token |
When adding or editing a token, the person selector supports type-to-filter: start typing a name to narrow down the list, use arrow keys to navigate, and press Enter to select.
src/
├── index.tsx # Entry point — renders the Ink app
├── App.tsx # Main menu and screen routing
├── db.ts # SQLite database access layer (better-sqlite3)
├── components/
│ ├── UI.tsx # Shared UI components (Header, StatusBar, HelpBar)
│ └── Form.tsx # Form components (Form, FormWithSelect, FilterableSelect, Confirm)
└── screens/
├── PersonsScreen.tsx # Person list & CRUD views
└── TokensScreen.tsx # Token list & CRUD views
The tool operates on the following tables in the doorlock SQLite database:
dl_persons—id,name,group_id,disableddl_tokens—id,person_id,token,pindl_groups—id,name
PIN values are stored as SHA-256 hashes of TOKEN:PIN.
# Type-check without emitting
npm run typecheck
# Build and run in one step
npm run devThe project uses:
- TypeScript with strict mode
- esbuild for fast bundling
- Ink 7 + React 19 for the terminal UI
- better-sqlite3 for synchronous database access