feat: establish NekoNest Cloud control and relay
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package tenantstore
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
corestore "github.com/klarkxy/nekonest/relaycore/store"
|
||||
)
|
||||
|
||||
const maxPushSubscriptionsPerDevice = 32
|
||||
|
||||
// PushSubscription represents a Web Push subscription.
|
||||
type PushSubscription = corestore.PushSubscription
|
||||
|
||||
// SavePushSubscription stores one endpoint mapping per device. A browser reuses
|
||||
// the same endpoint while the user subscribes to multiple devices.
|
||||
func (db *DB) SavePushSubscription(sub *PushSubscription) error {
|
||||
now := time.Now().Unix()
|
||||
tx, err := db.conn.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
if _, err = tx.Exec(`
|
||||
INSERT INTO push_subscriptions (device_id, phone_id, endpoint, p256dh, auth, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(endpoint, device_id) DO UPDATE SET
|
||||
phone_id = excluded.phone_id,
|
||||
p256dh = excluded.p256dh,
|
||||
auth = excluded.auth,
|
||||
created_at = excluded.created_at`,
|
||||
sub.DeviceID, sub.PhoneID, sub.Endpoint, sub.P256DH, sub.Auth, now,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = tx.Exec(`
|
||||
DELETE FROM push_subscriptions
|
||||
WHERE id IN (
|
||||
SELECT id FROM push_subscriptions
|
||||
WHERE device_id = ?
|
||||
ORDER BY created_at DESC, id DESC
|
||||
LIMIT -1 OFFSET ?
|
||||
)`,
|
||||
sub.DeviceID, maxPushSubscriptionsPerDevice,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// GetPushSubscriptions returns all subscriptions for a device.
|
||||
func (db *DB) GetPushSubscriptions(deviceID string) ([]*PushSubscription, error) {
|
||||
rows, err := db.conn.Query(
|
||||
`SELECT id, device_id, phone_id, endpoint, p256dh, auth FROM push_subscriptions WHERE device_id = ?`,
|
||||
deviceID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var subs []*PushSubscription
|
||||
for rows.Next() {
|
||||
sub := &PushSubscription{}
|
||||
if err := rows.Scan(&sub.ID, &sub.DeviceID, &sub.PhoneID, &sub.Endpoint, &sub.P256DH, &sub.Auth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
subs = append(subs, sub)
|
||||
}
|
||||
return subs, nil
|
||||
}
|
||||
|
||||
// DeletePushSubscription removes a subscription by endpoint.
|
||||
func (db *DB) DeletePushSubscription(endpoint string) error {
|
||||
_, err := db.conn.Exec(`DELETE FROM push_subscriptions WHERE endpoint = ?`, endpoint)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user