From b9039dbf194f66738766cb4296ba6d141d6d433e Mon Sep 17 00:00:00 2001 From: Claudomator Agent Date: Tue, 17 Mar 2026 08:04:04 +0000 Subject: fix: validate VAPID public key on load, regenerate if swapped The DB may contain keys generated before the swap fix, with the private key stored as the public key. Add ValidateVAPIDPublicKey() and use it in serve.go to detect and regenerate invalid stored keys on startup. Co-Authored-By: Claude Sonnet 4.6 --- internal/notify/vapid_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'internal/notify/vapid_test.go') diff --git a/internal/notify/vapid_test.go b/internal/notify/vapid_test.go index 6157854..a45047d 100644 --- a/internal/notify/vapid_test.go +++ b/internal/notify/vapid_test.go @@ -5,6 +5,27 @@ import ( "testing" ) +// TestValidateVAPIDPublicKey verifies that ValidateVAPIDPublicKey accepts valid +// public keys and rejects private keys, empty strings, and invalid base64. +func TestValidateVAPIDPublicKey(t *testing.T) { + pub, priv, err := GenerateVAPIDKeys() + if err != nil { + t.Fatalf("GenerateVAPIDKeys: %v", err) + } + if !ValidateVAPIDPublicKey(pub) { + t.Error("valid public key should pass validation") + } + if ValidateVAPIDPublicKey(priv) { + t.Error("private key (32 bytes) should fail public key validation") + } + if ValidateVAPIDPublicKey("") { + t.Error("empty string should fail validation") + } + if ValidateVAPIDPublicKey("notbase64!!!") { + t.Error("invalid base64 should fail validation") + } +} + // TestGenerateVAPIDKeys_PublicKeyIs65Bytes verifies that the public key returned // by GenerateVAPIDKeys is a 65-byte uncompressed P256 EC point (base64url, no padding = 87 chars) // and the private key is 32 bytes (43 chars). Previously the return values were swapped. -- cgit v1.2.3