feat(menu): #55 System › Fingerprint enroll/list/PAM
Self-gated System › Fingerprint when fprintd is on PATH: enroll, list, verify, delete-all (terminal), and Use for login writing settings.fingerprint.pam (hardware.nix default from theme-state). Close #55. Verified: V1 (HM menu rebuild). V3 pending: real-reader enroll (HARDWARE-QUEUE).
This commit is contained in:
@@ -8,6 +8,11 @@ the failure as a NOW bug in BACKLOG.md. Machines: the **AMD dev box**
|
|||||||
QA machine), the **T14s** (webcam case).
|
QA machine), the **T14s** (webcam case).
|
||||||
|
|
||||||
## Any machine (dev box is fine)
|
## Any machine (dev box is fine)
|
||||||
|
- [ ] **#55 fingerprint enroll on real reader** — with
|
||||||
|
`nomarchy.hardware.fingerprint.enable` and a physical reader: System ›
|
||||||
|
Fingerprint › Enroll a finger; List shows it; Verify succeeds; optional
|
||||||
|
Use for login (on) → `sys-rebuild` → login/sudo accept fingerprint.
|
||||||
|
Menu surface is V1/V2 without a reader (self-gate + dry paths).
|
||||||
- [ ] **#60 non-BAT* battery name (if available)** — on a machine whose
|
- [ ] **#60 non-BAT* battery name (if available)** — on a machine whose
|
||||||
system battery is **not** named `BAT*` (e.g. `CMB0`): confirm
|
system battery is **not** named `BAT*` (e.g. `CMB0`): confirm
|
||||||
charge-limit oneshot writes the threshold, System › Battery limit
|
charge-limit oneshot writes the threshold, System › Battery limit
|
||||||
|
|||||||
@@ -163,27 +163,26 @@ nomarchy.hardware.fingerprint.enable = true; # services.fprintd
|
|||||||
# nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in)
|
# nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Enroll (CLI today)
|
### Enroll (menu or CLI)
|
||||||
|
|
||||||
|
**Shipped #55:** System › Fingerprint (self-gated when `fprintd-list` is
|
||||||
|
on PATH) — Enroll / List / Verify / Delete all, plus **Use for login**
|
||||||
|
which writes `settings.fingerprint.pam` and applies on the next
|
||||||
|
`sys-rebuild` (option default follows theme-state.json).
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
fprintd-enroll # as your user
|
# CLI still works:
|
||||||
|
fprintd-enroll
|
||||||
fprintd-list "$USER"
|
fprintd-list "$USER"
|
||||||
# then, if you want login/sudo:
|
# or: System › Fingerprint › Use for login (on) → sys-rebuild
|
||||||
# uncomment fingerprint.pam in system.nix → sys-rebuild
|
|
||||||
```
|
```
|
||||||
|
|
||||||
PAM stays opt-in on purpose: password-only remains the cautious default
|
PAM stays opt-in on purpose: password-only remains the cautious default
|
||||||
until a finger is enrolled.
|
until a finger is enrolled. Full enroll on a real reader is V3/hardware.
|
||||||
|
|
||||||
### Gaps
|
### Doctor
|
||||||
|
|
||||||
- No System menu “Fingerprint” row (enroll / list / delete).
|
`nomarchy-doctor` reports fprintd unit + enroll status when present.
|
||||||
- No “use for login” toggle that writes state + rebuild note.
|
|
||||||
- Doctor does not check reader presence or enroll status.
|
|
||||||
|
|
||||||
**Product direction (queued):** when `fprintd` is active, a self-gated
|
|
||||||
menu module for enroll/list; optional PAM toggle via state + rebuild
|
|
||||||
hint (same pattern as Bluetooth in Control Center).
|
|
||||||
|
|
||||||
## 6. NVIDIA (deep dive)
|
## 6. NVIDIA (deep dive)
|
||||||
|
|
||||||
|
|||||||
@@ -702,6 +702,62 @@ ${themeRows}
|
|||||||
fi
|
fi
|
||||||
printf "\nEnter to close."; read -r _' ;;
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
|
|
||||||
|
fingerprint)
|
||||||
|
# System ▸ Fingerprint — enroll/list/delete + optional PAM for
|
||||||
|
# login/sudo (HARDWARE.md §5, BACKLOG #55). Self-gated on fprintd
|
||||||
|
# CLI (services.fprintd). Enroll is interactive → terminal.
|
||||||
|
command -v fprintd-list >/dev/null 2>&1 \
|
||||||
|
|| { notify-send "Fingerprint" "fprintd not available (nomarchy.hardware.fingerprint.enable?)."; exit 0; }
|
||||||
|
pam=$(nomarchy-theme-sync get settings.fingerprint.pam 2>/dev/null || echo false)
|
||||||
|
case "$pam" in true|True) pam_label="Use for login (on)" ;; *) pam_label="Use for login (off)" ;; esac
|
||||||
|
choice=$( {
|
||||||
|
row "Enroll finger" preferences-desktop-user-password
|
||||||
|
row "List enrolled" view-list
|
||||||
|
row "Verify" dialog-password
|
||||||
|
row "Delete all" edit-delete
|
||||||
|
row "$pam_label" system-lock-screen
|
||||||
|
back
|
||||||
|
} | rofi -dmenu -show-icons -p Fingerprint) || exit 0
|
||||||
|
case "$choice" in
|
||||||
|
"$BACK") exec "$0" system ;;
|
||||||
|
*Enroll*)
|
||||||
|
exec ${cfg.terminal} -e sh -c '
|
||||||
|
echo "== Enroll fingerprint for $USER =="
|
||||||
|
fprintd-enroll || true
|
||||||
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
|
*List*)
|
||||||
|
exec ${cfg.terminal} -e sh -c '
|
||||||
|
echo "== Enrolled fingers for $USER =="
|
||||||
|
fprintd-list "$USER" || true
|
||||||
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
|
*Verify*)
|
||||||
|
exec ${cfg.terminal} -e sh -c '
|
||||||
|
echo "== Verify fingerprint for $USER =="
|
||||||
|
fprintd-verify || true
|
||||||
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
|
*"Delete all"*)
|
||||||
|
exec ${cfg.terminal} -e sh -c '
|
||||||
|
echo "== Delete all fingerprints for $USER =="
|
||||||
|
printf "Type yes to delete every enrolled finger: "
|
||||||
|
read -r ans
|
||||||
|
case "$ans" in
|
||||||
|
yes) fprintd-delete "$USER" || true ;;
|
||||||
|
*) echo "Cancelled." ;;
|
||||||
|
esac
|
||||||
|
printf "\nEnter to close."; read -r _' ;;
|
||||||
|
*"Use for login"*)
|
||||||
|
case "$pam" in true|True) new=false ;; *) new=true ;; esac
|
||||||
|
if [ "$new" = true ]; then
|
||||||
|
if fprintd-list "$USER" 2>/dev/null | grep -qiE 'no fingers enrolled|No devices available'; then
|
||||||
|
notify-send "Fingerprint" "Enroll a finger first, then enable login."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
nomarchy-theme-sync --quiet set settings.fingerprint.pam "$new" --no-switch
|
||||||
|
notify-send "Fingerprint" "Use for login: $new — applies on next sys-rebuild."
|
||||||
|
;;
|
||||||
|
esac ;;
|
||||||
|
|
||||||
controlcenter)
|
controlcenter)
|
||||||
# Nomarchy TUI Control Center.
|
# Nomarchy TUI Control Center.
|
||||||
exec ${cfg.terminal} -e nomarchy-control-center ;;
|
exec ${cfg.terminal} -e nomarchy-control-center ;;
|
||||||
@@ -811,6 +867,8 @@ ${themeRows}
|
|||||||
# Firmware/LVFS updates — self-gated on fwupd (default-on, but off
|
# Firmware/LVFS updates — self-gated on fwupd (default-on, but off
|
||||||
# on VMs/headless via services.fwupd.enable=false), like Printers.
|
# on VMs/headless via services.fwupd.enable=false), like Printers.
|
||||||
command -v fwupdmgr >/dev/null 2>&1 && row "Firmware" firmware-manager
|
command -v fwupdmgr >/dev/null 2>&1 && row "Firmware" firmware-manager
|
||||||
|
# Fingerprint — self-gated on fprintd CLI (services.fprintd; BACKLOG #55).
|
||||||
|
command -v fprintd-list >/dev/null 2>&1 && row "Fingerprint" preferences-desktop-user-password
|
||||||
command -v nomarchy-control-center >/dev/null 2>&1 && row "Control Center" preferences-desktop
|
command -v nomarchy-control-center >/dev/null 2>&1 && row "Control Center" preferences-desktop
|
||||||
if has_system_battery && command -v powerprofilesctl >/dev/null 2>&1; then
|
if has_system_battery && command -v powerprofilesctl >/dev/null 2>&1; then
|
||||||
row "Power profile" preferences-system-power
|
row "Power profile" preferences-system-power
|
||||||
@@ -835,6 +893,7 @@ ${themeRows}
|
|||||||
*Rollback*) exec "$0" rollback ;;
|
*Rollback*) exec "$0" rollback ;;
|
||||||
*Doctor*) exec "$0" doctor ;;
|
*Doctor*) exec "$0" doctor ;;
|
||||||
*Firmware*) exec "$0" firmware ;;
|
*Firmware*) exec "$0" firmware ;;
|
||||||
|
*Fingerprint*) exec "$0" fingerprint ;;
|
||||||
*"Control Center"*) exec "$0" controlcenter ;;
|
*"Control Center"*) exec "$0" controlcenter ;;
|
||||||
*"Power profile"*) exec "$0" power-profile ;;
|
*"Power profile"*) exec "$0" power-profile ;;
|
||||||
*"Battery limit"*) exec "$0" batterylimit ;;
|
*"Battery limit"*) exec "$0" batterylimit ;;
|
||||||
@@ -904,7 +963,7 @@ ${themeRows}
|
|||||||
esac ;;
|
esac ;;
|
||||||
|
|
||||||
*)
|
*)
|
||||||
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autocommit|vpn|snapshot|doctor|firmware|controlcenter|rollback]" >&2
|
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autocommit|vpn|snapshot|doctor|firmware|fingerprint|controlcenter|rollback]" >&2
|
||||||
exit 64 ;;
|
exit 64 ;;
|
||||||
esac
|
esac
|
||||||
'';
|
'';
|
||||||
|
|||||||
@@ -15,6 +15,13 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.nomarchy.hardware;
|
cfg = config.nomarchy.hardware;
|
||||||
|
# Fingerprint PAM can follow theme-state.json (menu toggle → next
|
||||||
|
# sys-rebuild), same bridge as autoTimezone (BACKLOG #55).
|
||||||
|
hwState =
|
||||||
|
if config.nomarchy.system.stateFile != null
|
||||||
|
then builtins.fromJSON (builtins.readFile config.nomarchy.system.stateFile)
|
||||||
|
else { };
|
||||||
|
pamFromState = (hwState.settings or { }).fingerprint.pam or false;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.nomarchy.hardware = {
|
options.nomarchy.hardware = {
|
||||||
@@ -92,9 +99,18 @@ in
|
|||||||
a fingerprint reader via fprintd (the installer turns this on when it
|
a fingerprint reader via fprintd (the installer turns this on when it
|
||||||
detects a known reader). Enroll with `fprintd-enroll`'';
|
detects a known reader). Enroll with `fprintd-enroll`'';
|
||||||
|
|
||||||
pam = lib.mkEnableOption ''
|
pam = lib.mkOption {
|
||||||
using the fingerprint for login and sudo (PAM). Opt-in — password-only
|
type = lib.types.bool;
|
||||||
stays the default for the cautious; enroll a finger first'';
|
default = pamFromState;
|
||||||
|
defaultText = lib.literalExpression
|
||||||
|
"(settings.fingerprint.pam from theme-state.json) or false";
|
||||||
|
description = ''
|
||||||
|
Use the fingerprint for login and sudo (PAM). Opt-in — password-only
|
||||||
|
stays the default for the cautious; enroll a finger first. Defaults
|
||||||
|
from theme-state.json `settings.fingerprint.pam` (System › Fingerprint
|
||||||
|
menu) when set; otherwise false.
|
||||||
|
'';
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
npu.enable = lib.mkEnableOption ''
|
npu.enable = lib.mkEnableOption ''
|
||||||
|
|||||||
Reference in New Issue
Block a user