feat: YOUreka Tools express app — landing page + fpagent enrollment wizard
- tools/: express host (hardcoded config, YOUreka Auth cookie session, OpenFGA domain filtering with 5-min cache, a2loft proxies) - /fingerprint wizard: domain picker, two-finger capture via fpagent Socket.IO, OTP-validated lookup/save, domain refresh control - node --test suite (27 tests, fake portal/PocketBase/a2loft upstreams) - Dockerfile (node:22-alpine, non-root, healthcheck) - README rewritten; node_modules gitignored Field-verified end to end: portal login, permitted-domain filtering, real U.are.U 4500 captures, cancel-preserves-capture, a2loft save.
This commit is contained in:
@@ -1,18 +1,93 @@
|
||||
# YOUreka IDID Fingerprint Service
|
||||
# YOUreka Tools — Fingerprint Service
|
||||
|
||||
This service uses the libfprint library (version 2 and newwer) to capture fingerprints for profiles in YOUreka ID Domains.
|
||||
A small Express app that hosts the YOUreka tools landing page and the
|
||||
**Fingerprint Agent** enrollment wizard. Fingerprint capture is performed by
|
||||
the local [`fpagent`](../fingerprint-agent) binary (Socket.IO on
|
||||
`127.0.0.1:9000`); this app provides the login (YOUreka Auth), the permitted
|
||||
domain selection, and the a2loft integration that stores the enrolled
|
||||
fingerprints.
|
||||
|
||||
## Dependencies
|
||||
## Layout
|
||||
|
||||
## Debian Packages:
|
||||
1. sudo apt install libfprint-2-dev
|
||||
2. sudo apt install python3-pip
|
||||
```
|
||||
tools/
|
||||
├── server.js # Express app: routes, session middleware, proxies
|
||||
├── yrka-auth.js # YOUreka Auth cookie session → PocketBase (authRefresh)
|
||||
├── permit.js # OpenFGA domain permission checks + 5-minute cache
|
||||
├── public/
|
||||
│ ├── index.html # landing page (Image Cropper + Fingerprint Agent)
|
||||
│ └── assets/
|
||||
│ ├── style.css
|
||||
│ └── fp/ # /fingerprint enrollment wizard (Vue 2 via CDN)
|
||||
└── test/ # node --test suite (fake portal / PocketBase / a2loft)
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
Prerequisites: Node.js 22+, `fpagent` installed and running on this laptop
|
||||
(see the fingerprint-agent repository for installation), the U.are.U 4500
|
||||
scanner attached.
|
||||
|
||||
```sh
|
||||
cd tools
|
||||
npm install
|
||||
npm start # → http://localhost:4173
|
||||
```
|
||||
|
||||
Open http://localhost:4173 and sign in with your YOUreka account.
|
||||
|
||||
> fpagent must allow the tools origin. On a dev machine run it with:
|
||||
> `fpagent -allowed-origins http://localhost:4173`
|
||||
|
||||
## How enrollment works
|
||||
|
||||
1. **Sign in** — YOUreka Auth (portal web-auth redirect). The PocketBase
|
||||
session is kept in an httpOnly cookie and refreshed server-side.
|
||||
2. **Pick a domain** — the hardcoded catalog (UNICAL, Metropolitan Hotel, UCTH,
|
||||
UNICAL Radio International, YOUreka) is filtered against the same portal
|
||||
OpenFGA endpoint fpagent uses (`capture_biometric` per domain). Results are
|
||||
cached for 5 minutes; the **Refresh domains** control unlocks once the
|
||||
cache expires. fpagent re-authorizes every capture regardless.
|
||||
3. **Locate the staff profile** — reference + OTP, validated by
|
||||
`apis.a2loft.net` through a same-origin proxy (the operator's phone comes
|
||||
from the session).
|
||||
4. **Capture** — right thumb and right index finger, one capture at a time,
|
||||
with per-scan progress and cancel; the PocketBase token, domain and
|
||||
reference travel with every `fprint-enroll` to fpagent.
|
||||
5. **Save** — both templates are posted to a2loft (with a fresh OTP).
|
||||
|
||||
## Configuration
|
||||
|
||||
Everything is hardcoded in `tools/server.js` by design — port `4173`, portal
|
||||
`https://portal.yrka.app`, PocketBase `https://pb.itcass.net`, a2loft
|
||||
`https://apis.a2loft.net`, agent `http://127.0.0.1:9000`, and the domain
|
||||
catalog. Change them there; there are no environment variables or config
|
||||
files.
|
||||
|
||||
## Tests
|
||||
|
||||
```sh
|
||||
cd tools
|
||||
npm test # node --test — 27 tests, no network or hardware required
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
The app is stateless, so the container only serves the web front-end; fpagent
|
||||
keeps running on the operator's laptop (the wizard connects to
|
||||
`http://127.0.0.1:9000` from the browser, wherever this container lives).
|
||||
|
||||
```sh
|
||||
docker build -t yreka-tools .
|
||||
docker run -d -p 4173:4173 --name yreka-tools yreka-tools
|
||||
```
|
||||
|
||||
Behind a TLS-terminating proxy the app honours `X-Forwarded-Proto`
|
||||
(`trust proxy` is enabled), so session cookies get the `Secure` flag
|
||||
automatically.
|
||||
|
||||
Field walkthrough (real portal, PocketBase, a2loft, and U.are.U 4500): login →
|
||||
permitted-domain filtering → staff lookup → two scanner captures with cancel
|
||||
path → save → reset, all verified end to end via Playwright.
|
||||
|
||||
## PIP Packages
|
||||
1. pip3 install python-socketio
|
||||
2. pip3 install simple-websocket
|
||||
3. pip3 install flask
|
||||
4. pip3 install requests
|
||||
|
||||
# How to run
|
||||
```python3 app.py```
|
||||
Reference in New Issue
Block a user