diff --git a/lnbits/app.py b/lnbits/app.py index 50f218b7..49ad8d77 100644 --- a/lnbits/app.py +++ b/lnbits/app.py @@ -64,7 +64,7 @@ def create_app() -> FastAPI: # TODO: why those 2? g().config = settings - # g().base_url = f"http://{settings.host}:{settings.port}" + g().base_url = f"http://{settings.host}:{settings.port}" app.add_middleware(GZipMiddleware, minimum_size=1000) diff --git a/lnbits/extensions/admin/migrations.py b/lnbits/extensions/admin/migrations.py index c4bc98d8..ea698c27 100644 --- a/lnbits/extensions/admin/migrations.py +++ b/lnbits/extensions/admin/migrations.py @@ -6,6 +6,9 @@ async def m001_create_admin_settings_table(db): debug TEXT, host TEXT, port INTEGER, + lnbits_saas_instance_id TEXT, + lnbits_saas_callback TEXT, + lnbits_saas_secret TEXT, lnbits_path TEXT, lnbits_commit TEXT, lnbits_admin_users TEXT, diff --git a/lnbits/extensions/admin/templates/admin/index.html b/lnbits/extensions/admin/templates/admin/index.html index ccaddda4..575b377f 100644 --- a/lnbits/extensions/admin/templates/admin/index.html +++ b/lnbits/extensions/admin/templates/admin/index.html @@ -369,10 +369,10 @@ topupWallet() { LNbits.api .request( - 'POST', + 'PUT', '/admin/api/v1/topup/?usr=' + this.g.user.id, - this.wallet.id, - this.wallet.amount + this.g.user.wallets[0].adminkey, + this.wallet ) .then(response => { this.$q.notify({ diff --git a/lnbits/extensions/admin/views_api.py b/lnbits/extensions/admin/views_api.py index 19b52e35..63ed5b3c 100644 --- a/lnbits/extensions/admin/views_api.py +++ b/lnbits/extensions/admin/views_api.py @@ -1,7 +1,6 @@ from http import HTTPStatus -from fastapi import Body, Depends, Request -from loguru import logger +from fastapi import Body, Depends, Query from starlette.exceptions import HTTPException from lnbits.core.crud import get_wallet @@ -9,52 +8,50 @@ from lnbits.core.models import User from lnbits.decorators import check_admin from lnbits.extensions.admin import admin_ext from lnbits.extensions.admin.models import UpdateSettings -from lnbits.requestvars import g from lnbits.server import server_restart -from lnbits.settings import settings from .crud import delete_settings, update_settings, update_wallet_balance -@admin_ext.get("/api/v1/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, dependencies=[Depends(check_admin)] +) +async def api_restart_server() -> dict[str, str]: server_restart.set() return {"status": "Success"} -@admin_ext.put("/api/v1/topup/", status_code=HTTPStatus.OK) +@admin_ext.put( + "/api/v1/topup/", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] +) async def api_update_balance( - wallet_id, topup_amount: int, user: User = Depends(check_admin) -): + id: str = Body(...), amount: int = Body(...) +) -> dict[str, str]: try: - wallet = await get_wallet(wallet_id) + await get_wallet(id) except: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="wallet does not exist." ) - await update_wallet_balance(wallet_id=wallet_id, amount=int(topup_amount)) + await update_wallet_balance(wallet_id=id, amount=int(amount)) return {"status": "Success"} -@admin_ext.put("/api/v1/settings/", status_code=HTTPStatus.OK) +@admin_ext.put( + "/api/v1/settings/", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] +) async def api_update_settings( - user: User = Depends(check_admin), data: UpdateSettings = Body(...), ): settings = await update_settings(data) return {"status": "Success", "settings": settings.dict()} -@admin_ext.delete("/api/v1/settings/", status_code=HTTPStatus.OK) -async def api_delete_settings( - user: User = Depends(check_admin), -): +@admin_ext.delete( + "/api/v1/settings/", status_code=HTTPStatus.OK, dependencies=[Depends(check_admin)] +) +async def api_delete_settings() -> dict[str, str]: 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"} diff --git a/lnbits/server.py b/lnbits/server.py index 79af8112..6d4cd2e7 100644 --- a/lnbits/server.py +++ b/lnbits/server.py @@ -52,6 +52,7 @@ def main(ctx, port: int, host: str, ssl_keyfile: str, ssl_certfile: str, reload: port=port, host=host, reload=reload, + forwarded_allow_ips="*", ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile, **d diff --git a/lnbits/settings.py b/lnbits/settings.py index ffcdcc0a..61dbd6f2 100644 --- a/lnbits/settings.py +++ b/lnbits/settings.py @@ -5,6 +5,7 @@ from os import path from sqlite3 import Row from typing import List, Optional +import httpx from loguru import logger from pydantic import BaseSettings, Field, validator @@ -12,7 +13,7 @@ from pydantic import BaseSettings, Field, validator def list_parse_fallback(v): try: return json.loads(v) - except Exception as e: + except Exception: replaced = v.replace(" ", "") if replaced: return replaced.split(",") @@ -34,6 +35,11 @@ class Settings(BaseSettings): lnbits_path: str = Field(default=".") lnbits_commit: str = Field(default="unknown") + # saas + lnbits_saas_callback: Optional[str] = Field(default=None) + lnbits_saas_secret: Optional[str] = Field(default=None) + lnbits_saas_instance_id: Optional[str] = Field(default=None) + # users lnbits_admin_users: List[str] = Field(default=[]) lnbits_allowed_users: List[str] = Field(default=[]) @@ -230,11 +236,40 @@ async def check_admin_settings(): http = "https" if settings.lnbits_force_https else "http" user = settings.lnbits_admin_users[0] - logger.warning( - f" ✔️ Access admin user account at: {http}://{settings.host}:{settings.port}/wallet?usr={user}" + + admin_url = ( + f"{http}://{settings.host}:{settings.port}/wallet?usr={user}" ) + logger.warning(f"✔️ Access admin user account at: {admin_url}") + + if ( + settings.lnbits_saas_callback + and settings.lnbits_saas_secret + and settings.lnbits_saas_instance_id + ): + with httpx.Client() as client: + headers = { + "Content-Type": "application/json; charset=utf-8", + "X-API-KEY": settings.lnbits_saas_secret, + } + payload = { + "instance_id": settings.lnbits_saas_instance_id, + "adminuser": user, + } + try: + client.post( + settings.lnbits_saas_callback, + headers=headers, + json=payload, + ) + logger.warning("sent admin user to saas application") + except: + logger.error( + f"error sending admin user to saas: {settings.lnbits_saas_callback}" + ) + except: - logger.warning("admin.settings tables does not exist.") + logger.error("admin.settings tables does not exist.") raise diff --git a/lnbits/wallets/fake.py b/lnbits/wallets/fake.py index 73458e8c..94ff5f48 100644 --- a/lnbits/wallets/fake.py +++ b/lnbits/wallets/fake.py @@ -19,7 +19,6 @@ from .base import ( class FakeWallet(Wallet): - queue: asyncio.Queue = asyncio.Queue(0) secret: str = settings.fake_wallet_secret privkey: str = hashlib.pbkdf2_hmac( "sha256", @@ -98,6 +97,7 @@ class FakeWallet(Wallet): return PaymentStatus(None) async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: + self.queue: asyncio.Queue = asyncio.Queue(0) while True: value: Invoice = await self.queue.get() yield value.payment_hash