[FEAT] Push notification integration into core (#1393)
* push notification integration into core added missing component fixed bell working on all pages - made pubkey global template env var - had to move `get_push_notification_pubkey` to `helpers.py` because of circular reference with `tasks.py` formay trying to fix mypy added py-vapid to requirements Trying to fix stub mypy issue * removed key files * webpush key pair is saved in db `webpush_settings` * removed lnaddress extension changes * support for multi user account subscriptions, subscriptions are stored user based fixed syntax error fixed syntax error removed unused line * fixed subscribed user storage with local storage, no get request required * method is singular now * cleanup unsubscribed or expired push subscriptions fixed flake8 errors fixed poetry errors * updating to latest lnbits formatting, rebase error fix * remove unused? * revert * relock * remove * do not create settings table use adminsettings mypy fix * cleanup old code * catch case when client tries to recreate existing webpush subscription e.g. on cleared local storage * show notification bell on user related pages only * use local storage with one key like array, some refactoring * fixed crud import * fixed too long line * removed unused imports * ruff * make webpush editable * fixed privkey encoding * fix ruff * fix migration --------- Co-authored-by: schneimi <admin@schneimi.de> Co-authored-by: schneimi <dev@schneimi.de> Co-authored-by: dni ⚡ <office@dnilabs.com>
This commit is contained in:
co-authored by
schneimi
schneimi
dni ⚡
parent
8f0c1f6a80
commit
fb98576431
+104
-4
@@ -10,10 +10,23 @@ from lnbits import bolt11
|
||||
from lnbits.core.models import WalletType
|
||||
from lnbits.db import Connection, Database, Filters, Page
|
||||
from lnbits.extension_manager import InstallableExtension
|
||||
from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, settings
|
||||
from lnbits.settings import (
|
||||
AdminSettings,
|
||||
SuperSettings,
|
||||
WebPushSettings,
|
||||
settings,
|
||||
)
|
||||
|
||||
from . import db
|
||||
from .models import BalanceCheck, Payment, PaymentFilters, TinyURL, User, Wallet
|
||||
from .models import (
|
||||
BalanceCheck,
|
||||
Payment,
|
||||
PaymentFilters,
|
||||
TinyURL,
|
||||
User,
|
||||
Wallet,
|
||||
WebPushSubscription,
|
||||
)
|
||||
|
||||
# accounts
|
||||
# --------
|
||||
@@ -788,8 +801,16 @@ async def delete_admin_settings():
|
||||
await db.execute("DELETE FROM settings")
|
||||
|
||||
|
||||
async def update_admin_settings(data: EditableSettings):
|
||||
await db.execute("UPDATE settings SET editable_settings = ?", (json.dumps(data),))
|
||||
async def update_admin_settings(data: dict):
|
||||
row = await db.fetchone("SELECT editable_settings FROM settings")
|
||||
if not row:
|
||||
return None
|
||||
editable_settings = json.loads(row["editable_settings"])
|
||||
for key, value in data.items():
|
||||
editable_settings[key] = value
|
||||
await db.execute(
|
||||
"UPDATE settings SET editable_settings = ?", (json.dumps(editable_settings),)
|
||||
)
|
||||
|
||||
|
||||
async def update_super_user(super_user: str) -> SuperSettings:
|
||||
@@ -872,3 +893,82 @@ async def delete_tinyurl(tinyurl_id: str):
|
||||
"DELETE FROM tiny_url WHERE id = ?",
|
||||
(tinyurl_id,),
|
||||
)
|
||||
|
||||
|
||||
# push_notification
|
||||
# -----------------
|
||||
|
||||
|
||||
async def get_webpush_settings() -> Optional[WebPushSettings]:
|
||||
row = await db.fetchone("SELECT * FROM webpush_settings")
|
||||
if not row:
|
||||
return None
|
||||
vapid_keypair = json.loads(row["vapid_keypair"])
|
||||
return WebPushSettings(**vapid_keypair)
|
||||
|
||||
|
||||
async def create_webpush_settings(webpush_settings: dict):
|
||||
await db.execute(
|
||||
"INSERT INTO webpush_settings (vapid_keypair) VALUES (?)",
|
||||
(json.dumps(webpush_settings),),
|
||||
)
|
||||
return await get_webpush_settings()
|
||||
|
||||
|
||||
async def get_webpush_subscription(
|
||||
endpoint: str, user: str
|
||||
) -> Optional[WebPushSubscription]:
|
||||
row = await db.fetchone(
|
||||
"SELECT * FROM webpush_subscriptions WHERE endpoint = ? AND user = ?",
|
||||
(
|
||||
endpoint,
|
||||
user,
|
||||
),
|
||||
)
|
||||
return WebPushSubscription(**dict(row)) if row else None
|
||||
|
||||
|
||||
async def get_webpush_subscriptions_for_user(
|
||||
user: str,
|
||||
) -> List[WebPushSubscription]:
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM webpush_subscriptions WHERE user = ?",
|
||||
(user,),
|
||||
)
|
||||
return [WebPushSubscription(**dict(row)) for row in rows]
|
||||
|
||||
|
||||
async def create_webpush_subscription(
|
||||
endpoint: str, user: str, data: str, host: str
|
||||
) -> WebPushSubscription:
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO webpush_subscriptions (endpoint, user, data, host)
|
||||
VALUES (?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
endpoint,
|
||||
user,
|
||||
data,
|
||||
host,
|
||||
),
|
||||
)
|
||||
subscription = await get_webpush_subscription(endpoint, user)
|
||||
assert subscription, "Newly created webpush subscription couldn't be retrieved"
|
||||
return subscription
|
||||
|
||||
|
||||
async def delete_webpush_subscription(endpoint: str, user: str) -> None:
|
||||
await db.execute(
|
||||
"DELETE FROM webpush_subscriptions WHERE endpoint = ? AND user = ?",
|
||||
(
|
||||
endpoint,
|
||||
user,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def delete_webpush_subscriptions(endpoint: str) -> None:
|
||||
await db.execute(
|
||||
"DELETE FROM webpush_subscriptions WHERE endpoint = ?", (endpoint,)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user