diff --git a/CLAUDE.md b/CLAUDE.md index dee9bd5..addae5a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,7 +93,7 @@ Entry point: `main.go` → opens SQLite DB → runs CLI or starts HTTP server on - `phoenix/` — HTTP client for Phoenix Server API (invoices, payments, balance, channels). Uses basic auth from phoenix config (password cached at startup with `sync.Once`) - `crypto/` — AES-CMAC authentication and AES decryption for Bolt Card NFC protocol - `util/` — Error handling helpers (`CheckAndLog`), random hex generation, QR code encoding -- `build/` — Version string (currently "0.22.2"), date/time injected at build +- `build/` — Version string (currently "0.22.3"), date/time injected at build - `web-content/` — Static assets under `public/`, SPA build output under `admin/spa/` ### Route Groups (`web/app.go`) diff --git a/docker/card/build/build.go b/docker/card/build/build.go index 625d8b1..ece3781 100644 --- a/docker/card/build/build.go +++ b/docker/card/build/build.go @@ -1,5 +1,5 @@ package build -var Version string = "0.22.2" +var Version string = "0.22.3" var Date string var Time string diff --git a/docker/card/web/main_test.go b/docker/card/web/main_test.go new file mode 100644 index 0000000..cf9e8c0 --- /dev/null +++ b/docker/card/web/main_test.go @@ -0,0 +1,19 @@ +package web + +import ( + "os" + "testing" + + "golang.org/x/crypto/bcrypt" +) + +// TestMain lowers the bcrypt work factor for the whole web test package. +// Production keeps bcrypt.DefaultCost (see HashPassword in util.go); the +// admin-login and 2FA recovery-code tests hash dozens of values per run, and +// at DefaultCost that hashing — amplified by the race detector — dominated +// CI's `go test -race` step (~3 min). MinCost keeps the hashing path fully +// exercised while making it roughly 64x cheaper. +func TestMain(m *testing.M) { + bcryptCost = bcrypt.MinCost + os.Exit(m.Run()) +} diff --git a/docker/card/web/util.go b/docker/card/web/util.go index a97ca5e..f659dd6 100644 --- a/docker/card/web/util.go +++ b/docker/card/web/util.go @@ -25,8 +25,14 @@ func GetPwHash(db_conn *sql.DB, passwordStr string) (passwordHashStr string) { return passwordHashStr } +// bcryptCost is the work factor used for all password/recovery-code hashing. +// Production keeps bcrypt.DefaultCost; the test suite lowers it (see TestMain +// in main_test.go) because the admin-login and 2FA tests hash dozens of values +// and at DefaultCost that alone dominated CI's `go test -race` step. +var bcryptCost = bcrypt.DefaultCost + func HashPassword(passwordStr string) (string, error) { - hash, err := bcrypt.GenerateFromPassword([]byte(passwordStr), bcrypt.DefaultCost) + hash, err := bcrypt.GenerateFromPassword([]byte(passwordStr), bcryptCost) return string(hash), err }