webauthn: persist credentials to JSON file instead of in-memory map

- New credentialStore type in credentials.go loads/saves
  map[id]localCred to a JSON file. Thread-safe with sync.RWMutex,
  writes to disk on every mutation.
- PasskeyHandle replaces sync.RWMutex+map with *credentialStore.
  Inline save/lookip/update closures delegate to store methods.
- newPasskeyHandle now takes a storePath parameter and returns an
  error; callers updated.
- New -passkey-file flag (default ./passkeys.json) configures the
  credential store path in main.go.
- Tests use os.CreateTemp in t.TempDir() so each test gets an
  isolated, auto-cleaned store file.
This commit is contained in:
kami
2026-07-05 02:09:56 +04:00
parent b9248ef2e6
commit 44807b612c
4 changed files with 111 additions and 37 deletions
+6 -2
View File
@@ -83,6 +83,7 @@ func main() {
coreSock := flag.String("core", "", "mavend IPC socket path for presence-signal ingest (empty = disabled)")
pkOrigin := flag.String("webauthn-origin", "", "WebAuthn origin URL (e.g. https://maven.kvmx.ru)")
pkRPID := flag.String("webauthn-rpid", "", "WebAuthn RP ID (e.g. maven.kvmx.ru)")
pkFile := flag.String("passkey-file", "./passkeys.json", "path to WebAuthn credential store (JSON)")
flag.Parse()
var core ipc.CoreAPI
@@ -133,11 +134,14 @@ func main() {
// AuthStepUp actions (tool enable). Without -webauthn-origin, these
// endpoints return 503 and step-up is unavailable (FloorSession).
if *pkOrigin != "" && *pkRPID != "" && core != nil {
pk := newPasskeyHandle(webauthn.Config{
pk, err := newPasskeyHandle(webauthn.Config{
Origin: *pkOrigin,
RPID: *pkRPID,
RPName: "maven",
}, core)
}, core, *pkFile)
if err != nil {
log.Fatalf("passkey store: %v", err)
}
mux.HandleFunc("/auth/passkey", pk.Page)
mux.HandleFunc("/auth/webauthn/register/begin", pk.RegisterBegin)
mux.HandleFunc("/auth/webauthn/register/finish", pk.RegisterFinish)