From 4e8374ed6d04d8c7d003c574c48bd01f79ed41bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Wed, 5 Oct 2022 09:19:07 +0200 Subject: [PATCH] fixup frontend and routes --- lnbits/extensions/admin/crud.py | 31 ++++++++-- lnbits/extensions/admin/models.py | 15 +++-- .../admin/templates/admin/_tab_funding.html | 3 + .../admin/templates/admin/index.html | 61 ++++++++++++++++--- lnbits/extensions/admin/views_api.py | 36 ++++++----- 5 files changed, 109 insertions(+), 37 deletions(-) diff --git a/lnbits/extensions/admin/crud.py b/lnbits/extensions/admin/crud.py index 2dc144f8..cc937b5e 100644 --- a/lnbits/extensions/admin/crud.py +++ b/lnbits/extensions/admin/crud.py @@ -2,10 +2,11 @@ from typing import List from lnbits.core.crud import create_payment from lnbits.helpers import urlsafe_short_hash -from lnbits.settings import Settings +from lnbits.settings import Settings, read_only_variables from lnbits.tasks import internal_invoice_queue from . import db +from .models import UpdateSettings async def update_wallet_balance(wallet_id: str, amount: int) -> str: @@ -25,10 +26,28 @@ async def update_wallet_balance(wallet_id: str, amount: int) -> str: await internal_invoice_queue.put(internal_id) -async def update_settings(user: str, **kwargs) -> Settings: - q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) - # print("UPDATE", q) - await db.execute(f'UPDATE admin.settings SET {q}') - row = await db.fetchone('SELECT * FROM admin.settings') +async def update_settings(data: UpdateSettings) -> Settings: + fields = [] + for key, value in data.dict(exclude_none=True).items(): + if not key in read_only_variables: + if type(value) == list: + joined = ",".join(value) + fields.append(f"{key} = '{joined}'") + if type(value) == int or type(value) == float: + fields.append(f"{key} = {value}") + if type(value) == bool: + fields.append(f"{key} = {'true' if value else 'false'}") + if type(value) == str: + value = value.replace("'", "") + fields.append(f"{key} = '{value}'") + + q = ", ".join(fields) + print("UPDATE", q) + await db.execute(f"UPDATE admin.settings SET {q}") + row = await db.fetchone("SELECT * FROM admin.settings") assert row, "Newly updated settings couldn't be retrieved" return Settings(**row) if row else None + + +async def delete_settings(): + await db.execute("DELETE FROM admin.settings") diff --git a/lnbits/extensions/admin/models.py b/lnbits/extensions/admin/models.py index 2110f7f2..13a6cd23 100644 --- a/lnbits/extensions/admin/models.py +++ b/lnbits/extensions/admin/models.py @@ -1,10 +1,9 @@ -from sqlite3 import Row -from typing import List, Optional - from fastapi import Query -from pydantic import BaseModel, Field +from pydantic import BaseModel + class UpdateSettings(BaseModel): + lnbits_backend_wallet_class: str = Query(None) lnbits_admin_users: str = Query(None) lnbits_allowed_users: str = Query(None) lnbits_admin_ext: str = Query(None) @@ -15,11 +14,11 @@ class UpdateSettings(BaseModel): lnbits_reserve_fee_percent: float = Query(None, ge=0) lnbits_service_fee: float = Query(None, ge=0) lnbits_hide_api: bool = Query(None) - lnbits_site_title: str = Query("LNbits") - lnbits_site_tagline: str = Query("free and open-source lightning wallet") + lnbits_site_title: str = Query(None) + lnbits_site_tagline: str = Query(None) lnbits_site_description: str = Query(None) - lnbits_default_wallet_name: str = Query("LNbits wallet") - lnbits_denomination: str = Query("sats") + lnbits_default_wallet_name: str = Query(None) + lnbits_denomination: str = Query(None) lnbits_theme: str = Query(None) lnbits_custom_logo: str = Query(None) lnbits_ad_space: str = Query(None) diff --git a/lnbits/extensions/admin/templates/admin/_tab_funding.html b/lnbits/extensions/admin/templates/admin/_tab_funding.html index 715f0e09..503f2adc 100644 --- a/lnbits/extensions/admin/templates/admin/_tab_funding.html +++ b/lnbits/extensions/admin/templates/admin/_tab_funding.html @@ -24,6 +24,7 @@

Active Funding (Requires server restart)

@@ -46,6 +48,7 @@ dense type="number" filled + name="lnbits_reserve_fee_percent" v-model="data.settings.lnbits_reserve_fee_percent" label="Reserve fee in percent" step="0.1" diff --git a/lnbits/extensions/admin/templates/admin/index.html b/lnbits/extensions/admin/templates/admin/index.html index 50e05413..f1ead27b 100644 --- a/lnbits/extensions/admin/templates/admin/index.html +++ b/lnbits/extensions/admin/templates/admin/index.html @@ -4,8 +4,12 @@
- - + +
@@ -37,7 +41,7 @@
- + {% include "admin/_tab_funding.html" %} {% include "admin/_tab_users.html" %} {% include "admin/_tab_server.html" %} {% @@ -111,8 +115,7 @@ LNbits.api .request( 'GET', - '/admin/api/v1/admin/restart/', - this.g.user.wallets[0].adminkey + '/admin/api/v1/restart/?usr=' + this.g.user.id, ) .then(response => { this.$q.notify({ @@ -129,8 +132,7 @@ LNbits.api .request( 'POST', - '/admin/api/v1/admin/topup/', - this.g.user.wallets[0].adminkey, + '/admin/api/v1/topup/?usr=' + this.g.user.id, this.wallet.id, this.wallet.amount, ) @@ -151,11 +153,18 @@ }) }, updateSettings() { - let data = {} + const formElement = document.getElementById('settings_form'); + const formData = new FormData(formElement); + const data = {}; + formData.forEach((value, key) => (data[key] = value)); + // only for debugging + for (const [key, value] of formData) { + console.log(`${key}: ${value}\n`); + } LNbits.api .request( 'PUT', - '/admin/api/v1/admin/', + '/admin/api/v1/settings/?usr=' + this.g.user.id, this.g.user.wallets[0].adminkey, data ) @@ -169,6 +178,40 @@ .catch(function (error) { LNbits.utils.notifyApiError(error) }); + }, + deleteSettings() { + LNbits.api + .request( + 'DELETE', + '/admin/api/v1/settings/?usr=' + this.g.user.id + ) + .then(response => { + this.$q.notify({ + type: 'positive', + message: 'Success! Restored settings to defaults, restart required!', + icon: null + }) + }) + .catch(function (error) { + LNbits.utils.notifyApiError(error) + }); + }, + downloadBackup() { + LNbits.api + .request( + 'GET', + '/admin/api/v1/backup/?usr=' + this.g.user.id + ) + .then(response => { + this.$q.notify({ + type: 'positive', + message: 'Success! Database backup request, download starts soon!', + icon: null + }) + }) + .catch(function (error) { + LNbits.utils.notifyApiError(error) + }); } } }) diff --git a/lnbits/extensions/admin/views_api.py b/lnbits/extensions/admin/views_api.py index ceb40312..c8120564 100644 --- a/lnbits/extensions/admin/views_api.py +++ b/lnbits/extensions/admin/views_api.py @@ -1,7 +1,7 @@ from http import HTTPStatus -from loguru import logger from fastapi import Body, Depends, Request +from loguru import logger from starlette.exceptions import HTTPException from lnbits.core.crud import get_wallet @@ -13,18 +13,16 @@ from lnbits.requestvars import g from lnbits.server import server_restart from lnbits.settings import settings -from .crud import update_settings, update_wallet_balance +from .crud import delete_settings, update_settings, update_wallet_balance -@admin_ext.get("/api/v1/admin/restart/", status_code=HTTPStatus.OK) -async def api_restart_server( - user: User = Depends(check_admin) -): +@admin_ext.get("/api/v1/restart/", status_code=HTTPStatus.OK) +async def api_restart_server(user: User = Depends(check_admin)): server_restart.set() return {"status": "Success"} -@admin_ext.put("/api/v1/admin/topup/", status_code=HTTPStatus.OK) +@admin_ext.put("/api/v1/topup/", status_code=HTTPStatus.OK) async def api_update_balance( wallet_id, topup_amount: int, user: User = Depends(check_admin) ): @@ -32,7 +30,7 @@ async def api_update_balance( wallet = await get_wallet(wallet_id) except: raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="wallet: {wallet_id} does not exist." + status_code=HTTPStatus.FORBIDDEN, detail="wallet does not exist." ) await update_wallet_balance(wallet_id=wallet_id, amount=int(topup_amount)) @@ -40,13 +38,23 @@ async def api_update_balance( return {"status": "Success"} -@admin_ext.put("/api/v1/admin/", status_code=HTTPStatus.OK) -async def api_update_admin( - request: Request, +@admin_ext.put("/api/v1/settings/", status_code=HTTPStatus.OK) +async def api_update_settings( user: User = Depends(check_admin), data: UpdateSettings = Body(...), ): - updated = await update_settings(data) - g().settings = g().settings.copy(update=updated.dict()) - + await update_settings(data) return {"status": "Success"} + + +@admin_ext.delete("/api/v1/settings/", status_code=HTTPStatus.OK) +async def api_delete_settings( + user: User = Depends(check_admin), +): + await delete_settings() + return {"status": "Success"} + + +@admin_ext.get("/api/v1/backup/", status_code=HTTPStatus.OK) +async def api_backup(user: User = Depends(check_admin)): + return {"status": "not implemented"}