Documentation
¶
Index ¶
Constants ¶
const ( // KVNamespace is the kv.namespace value used for every notify // domain row. KVNamespace = "notify" // KVKeyVAPIDPublic holds the VAPID public key as plaintext. KVKeyVAPIDPublic = "vapid_public" // KVKeyVAPIDPrivate holds the VAPID private key, envelope-sealed // with the host-bound KEK at <v1>/auth/kek.bin (see design doc // §3.4). AAD is derived from the (namespace, key) pair below — // see VAPIDPrivateAAD. KVKeyVAPIDPrivate = "vapid_private" )
kv table layout for the notify domain. Single source of truth shared by cmd/kojo (runtime VAPID load/save) and internal/migrate/importers (v0→v1 migration). Keeping the constants in one place lets the compiler catch drift — diverging namespace / key / AAD between the importer and the runtime would orphan every secret row, since the AAD is part of the GCM authentication tag.
const VAPIDPrivateAADString = KVNamespace + "/" + KVKeyVAPIDPrivate
VAPIDPrivateAADString binds the encrypted private-key bytes to their (namespace, key) slot. Must round-trip between Seal (importer or SaveVAPID) and Open (LoadVAPID) — bumping it would orphan every existing secret row, so treat it as a wire constant. Exposed as `const string` rather than `var []byte` so a consumer can't accidentally mutate the shared backing array; call sites convert via []byte(notify.VAPIDPrivateAADString) at use.
Variables ¶
This section is empty.
Functions ¶
func VAPIDPrivateAAD ¶ added in v0.101.0
func VAPIDPrivateAAD() []byte
VAPIDPrivateAAD returns a fresh []byte for the AAD on each call. Helper for call sites that don't want to repeat the cast; the underlying bytes are independent per call so mutation by one consumer cannot leak into another.
Types ¶
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
func NewManagerWithVAPIDStore ¶ added in v0.101.0
func NewManagerWithVAPIDStore(logger *slog.Logger, store VAPIDStore) (*Manager, error)
NewManagerWithVAPIDStore is the Phase-5 constructor that takes a kv-backed VAPID store. The legacy NewManager keeps the file-only path for tests.
func (*Manager) Subscribe ¶
func (m *Manager) Subscribe(sub *webpush.Subscription)
func (*Manager) Unsubscribe ¶
func (*Manager) VAPIDPublicKey ¶
type VAPIDStore ¶ added in v0.101.0
type VAPIDStore interface {
// LoadVAPID returns the persisted keys, or ("","",nil) if no
// keys are stored. Errors other than "absent" are surfaced so a
// boot doesn't silently regenerate keys (which would invalidate
// every existing browser subscription).
LoadVAPID() (priv, pub string, err error)
// SaveVAPID writes the keys atomically. Idempotent overwrite.
SaveVAPID(priv, pub string) error
}
VAPIDStore is the persistence interface for the VAPID key pair. Implementations in cmd/kojo/ wrap the kv table + envelope crypto so the private key never lives on disk in plaintext on a v1 install.