- Add SetSubscriptionUpdatedAt to Store interface, remove DB() accessor - Rename store files to store_sqlite.go and store_postgres.go - Use camelCase for test function names - Add tests for upsert field updates and multi-user removal - Use transaction in setupNewPostgresDB - Use lowercase "excluded." in PostgreSQL upsert query
53 lines
1.5 KiB
Go
53 lines
1.5 KiB
Go
package webpush
|
|
|
|
import (
|
|
"errors"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"heckel.io/ntfy/v2/log"
|
|
)
|
|
|
|
const (
|
|
SubscriptionIDPrefix = "wps_"
|
|
SubscriptionIDLength = 10
|
|
SubscriptionEndpointLimitPerSubscriberIP = 10
|
|
)
|
|
|
|
var (
|
|
ErrWebPushNoRows = errors.New("no rows found")
|
|
ErrWebPushTooManySubscriptions = errors.New("too many subscriptions")
|
|
ErrWebPushUserIDCannotBeEmpty = errors.New("user ID cannot be empty")
|
|
)
|
|
|
|
// Store is the interface for a web push subscription store.
|
|
type Store interface {
|
|
UpsertSubscription(endpoint, auth, p256dh, userID string, subscriberIP netip.Addr, topics []string) error
|
|
SubscriptionsForTopic(topic string) ([]*Subscription, error)
|
|
SubscriptionsExpiring(warnAfter time.Duration) ([]*Subscription, error)
|
|
MarkExpiryWarningSent(subscriptions []*Subscription) error
|
|
RemoveSubscriptionsByEndpoint(endpoint string) error
|
|
RemoveSubscriptionsByUserID(userID string) error
|
|
RemoveExpiredSubscriptions(expireAfter time.Duration) error
|
|
SetSubscriptionUpdatedAt(endpoint string, updatedAt int64) error
|
|
Close() error
|
|
}
|
|
|
|
// Subscription represents a web push subscription.
|
|
type Subscription struct {
|
|
ID string
|
|
Endpoint string
|
|
Auth string
|
|
P256dh string
|
|
UserID string
|
|
}
|
|
|
|
// Context returns the logging context for the subscription.
|
|
func (w *Subscription) Context() log.Context {
|
|
return map[string]any{
|
|
"web_push_subscription_id": w.ID,
|
|
"web_push_subscription_user_id": w.UserID,
|
|
"web_push_subscription_endpoint": w.Endpoint,
|
|
}
|
|
}
|