diff --git a/lnbits/extensions/admin/crud.py b/lnbits/extensions/admin/crud.py index 0d7019cc..e4cb5d77 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.tasks import internal_invoice_queue from . import db -from .models import Admin, Funding +from .models import Funding async def update_wallet_balance(wallet_id: str, amount: int) -> str: @@ -23,26 +24,26 @@ async def update_wallet_balance(wallet_id: str, amount: int) -> str: ) # manually send this for now await internal_invoice_queue.put(internal_id) - return payment -async def update_admin(user: str, **kwargs) -> Admin: +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.admin SET {q} WHERE "user" = ?', (*kwargs.values(), user) + f'UPDATE admin.settings SET {q} WHERE "user" = ?', (*kwargs.values(), user) ) - row = await db.fetchone('SELECT * FROM admin.admin WHERE "user" = ?', (user,)) + row = await db.fetchone('SELECT * FROM admin.settings WHERE "user" = ?', (user,)) assert row, "Newly updated settings couldn't be retrieved" - return Admin(**row) if row else None - - -async def get_admin() -> Admin: - row = await db.fetchone("SELECT * FROM admin.admin") - return Admin(**row) if row else None + return Settings(**row) if row else None async def update_funding(data: Funding) -> Funding: + await db.execute( + """ + UPDATE admin.settings SET funding_source = ? WHERE user = ? + """, + (data.backend_wallet, data.user), + ) await db.execute( """ UPDATE admin.funding @@ -69,5 +70,4 @@ async def update_funding(data: Funding) -> Funding: async def get_funding() -> List[Funding]: rows = await db.fetchall("SELECT * FROM admin.funding") - return [Funding(**row) for row in rows] diff --git a/lnbits/extensions/admin/migrations.py b/lnbits/extensions/admin/migrations.py index 2d48a8e4..8f6c76a0 100644 --- a/lnbits/extensions/admin/migrations.py +++ b/lnbits/extensions/admin/migrations.py @@ -1,292 +1,57 @@ -from os import getenv - -from sqlalchemy.exc import OperationalError # type: ignore - -from lnbits.config import conf -from lnbits.helpers import urlsafe_short_hash - - -async def get_admin_user(): - if len(conf.admin_users) > 0: - return conf.admin_users[0] - from lnbits.core.crud import create_account, get_user - - print("Seems like there's no admin users yet. Let's create an account for you!") - account = await create_account() - user = account.id - assert user, "Newly created user couldn't be retrieved" - print( - f"Your newly created account/user id is: {user}. This will be the Super Admin user." - ) - conf.admin_users.insert(0, user) - return user - - -async def m001_create_admin_table(db): - - - # users/server - user = await get_admin_user() - admin_users = ",".join(conf.admin_users) - allowed_users = ",".join(conf.allowed_users) - admin_ext = ",".join(conf.admin_ext) - disabled_ext = ",".join(conf.disabled_ext) - funding_source = conf.funding_source - # operational - data_folder = conf.data_folder - database_url = conf.database_url - force_https = conf.force_https - reserve_fee_min = conf.reserve_fee_min - reserve_fee_pct = conf.reserve_fee_pct - service_fee = conf.service_fee - hide_api = conf.hide_api - denomination = conf.denomination - # Theme'ing - site_title = conf.site_title - site_tagline = conf.site_tagline - site_description = conf.site_description - default_wallet_name = conf.default_wallet_name - theme = ",".join(conf.theme) - custom_logo = conf.custom_logo - ad_space = ",".join(conf.ad_space) - +async def m001_create_admin_settings_table(db): await db.execute( """ - CREATE TABLE IF NOT EXISTS admin.admin ( - "user" TEXT PRIMARY KEY, - admin_users TEXT, - allowed_users TEXT, - admin_ext TEXT, - disabled_ext TEXT, - funding_source TEXT, - data_folder TEXT, - database_url TEXT, - force_https BOOLEAN, - reserve_fee_min INT, - reserve_fee_pct REAL, - service_fee REAL, - hide_api BOOLEAN, - denomination TEXT, - site_title TEXT, - site_tagline TEXT, - site_description TEXT, - default_wallet_name TEXT, - theme TEXT, - custom_logo TEXT, - ad_space TEXT - ); - """ - ) - await db.execute( - """ - INSERT INTO admin.admin ( - "user", - admin_users, - allowed_users, - admin_ext, - disabled_ext, - funding_source, - data_folder, - database_url, - force_https, - reserve_fee_min, - reserve_fee_pct, - service_fee, - hide_api, - denomination, - site_title, - site_tagline, - site_description, - default_wallet_name, - theme, - custom_logo, - ad_space) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - """, - ( - user, - admin_users, - allowed_users, - admin_ext, - disabled_ext, - funding_source, - data_folder, - database_url, - force_https, - reserve_fee_min, - reserve_fee_pct, - service_fee, - hide_api, - denomination, - site_title, - site_tagline, - site_description, - default_wallet_name, - theme, - custom_logo, - ad_space, - ), - ) - - funding_wallet = getenv("LNBITS_BACKEND_WALLET_CLASS") - - # Make the funding table, if it does not already exist - await db.execute( - """ - CREATE TABLE IF NOT EXISTS admin.funding ( - id TEXT PRIMARY KEY, - backend_wallet TEXT, - endpoint TEXT, + CREATE TABLE IF NOT EXISTS admin.settings ( + lnbits_admin_ui TEXT, + debug TEXT, + host TEXT, port INT, - read_key TEXT, - invoice_key TEXT, - admin_key TEXT, - cert TEXT, - balance INT, - selected INT + lnbits_path TEXT, + lnbits_commit TEXT, + lnbits_admin_users TEXT, + lnbits_allowed_users TEXT, + lnbits_allowed_funding_sources TEXT, + lnbits_admin_extensions TEXT, + lnbits_disabled_extensions TEXT, + lnbits_site_title TEXT, + lnbits_site_tagline TEXT, + lnbits_site_description TEXT, + lnbits_default_wallet_name TEXT, + lnbits_theme_options TEXT, + lnbits_custom_logo TEXT, + lnbits_ad_space TEXT, + lnbits_data_folder TEXT, + lnbits_database_url TEXT, + lnbits_force_https TEXT, + lnbits_reserve_fee_min TEXT, + lnbits_reserve_fee_percent TEXT, + lnbits_service_fee TEXT, + lnbits_hide_api TEXT, + lnbits_denomination TEXT, + lnbits_backend_wallet_class TEXT, + fake_wallet_secret TEXT, + lnbits_endpoint TEXT, + lnbits_key TEXT, + cliche_endpoint TEXT, + corelightning_rpc TEXT, + eclair_url TEXT, + eclair_pass TEXT, + lnd_rest_endpoint TEXT, + lnd_rest_cert TEXT, + lnd_rest_macaroon TEXT, + lnpay_api_endpoint TEXT, + lnpay_api_key TEXT, + lnpay_wallet_key TEXT, + lntxbot_api_endpoint TEXT, + lntxbot_key TEXT, + opennode_api_endpoint TEXT, + opennode_key TEXT, + spark_url TEXT, + spark_token TEXT, + boltz_network TEXT, + boltz_url TEXT, + boltz_mempool_space_url TEXT, + boltz_mempool_space_url_ws TEXT ); """ ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, selected) - VALUES (?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "CLightningWallet", - getenv("CLIGHTNING_RPC"), - 1 if funding_wallet == "CLightningWallet" else 0, - ), - ) - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - VALUES (?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "SparkWallet", - getenv("SPARK_URL"), - getenv("SPARK_TOKEN"), - 1 if funding_wallet == "SparkWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - VALUES (?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "LnbitsWallet", - getenv("LNBITS_ENDPOINT"), - getenv("LNBITS_KEY"), - 1 if funding_wallet == "LnbitsWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, port, admin_key, cert, selected) - VALUES (?, ?, ?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "LndWallet", - getenv("LND_GRPC_ENDPOINT"), - getenv("LND_GRPC_PORT"), - getenv("LND_GRPC_MACAROON"), - getenv("LND_GRPC_CERT"), - 1 if funding_wallet == "LndWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, cert, selected) - VALUES (?, ?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "LndRestWallet", - getenv("LND_REST_ENDPOINT"), - getenv("LND_REST_MACAROON"), - getenv("LND_REST_CERT"), - 1 if funding_wallet == "LndWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, cert, selected) - VALUES (?, ?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "LNPayWallet", - getenv("LNPAY_API_ENDPOINT"), - getenv("LNPAY_WALLET_KEY"), - getenv("LNPAY_API_KEY"), # this is going in as the cert - 1 if funding_wallet == "LNPayWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - VALUES (?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "LntxbotWallet", - getenv("LNTXBOT_API_ENDPOINT"), - getenv("LNTXBOT_KEY"), - 1 if funding_wallet == "LntxbotWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - VALUES (?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "OpenNodeWallet", - getenv("OPENNODE_API_ENDPOINT"), - getenv("OPENNODE_KEY"), - 1 if funding_wallet == "OpenNodeWallet" else 0, - ), - ) - - await db.execute( - """ - INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - VALUES (?, ?, ?, ?, ?) - """, - ( - urlsafe_short_hash(), - "SparkWallet", - getenv("SPARK_URL"), - getenv("SPARK_TOKEN"), - 1 if funding_wallet == "SparkWallet" else 0, - ), - ) - - ## PLACEHOLDER FOR ECLAIR WALLET - # await db.execute( - # """ - # INSERT INTO admin.funding (id, backend_wallet, endpoint, admin_key, selected) - # VALUES (?, ?, ?, ?, ?) - # """, - # ( - # urlsafe_short_hash(), - # "EclairWallet", - # getenv("ECLAIR_URL"), - # getenv("ECLAIR_PASS"), - # 1 if funding_wallet == "EclairWallet" else 0, - # ), - # ) diff --git a/lnbits/extensions/admin/models.py b/lnbits/extensions/admin/models.py index 6e95d68f..ef57cadd 100644 --- a/lnbits/extensions/admin/models.py +++ b/lnbits/extensions/admin/models.py @@ -29,36 +29,36 @@ class UpdateAdminSettings(BaseModel): ad_space: str = Query(None) -class Admin(BaseModel): - # users - user: str - admin_users: Optional[str] - allowed_users: Optional[str] - admin_ext: Optional[str] - disabled_ext: Optional[str] - funding_source: Optional[str] - # ops - data_folder: Optional[str] - database_url: Optional[str] - force_https: bool = Field(default=True) - reserve_fee_min: Optional[int] - reserve_fee_pct: Optional[float] - service_fee: float = Optional[float] - hide_api: bool = Field(default=False) - # Change theme - site_title: Optional[str] - site_tagline: Optional[str] - site_description: Optional[str] - default_wallet_name: Optional[str] - denomination: str = Field(default="sats") - theme: Optional[str] - custom_logo: Optional[str] - ad_space: Optional[str] +# class Admin(BaseModel): +# # users +# user: str +# admin_users: Optional[str] +# allowed_users: Optional[str] +# admin_ext: Optional[str] +# disabled_ext: Optional[str] +# funding_source: Optional[str] +# # ops +# data_folder: Optional[str] +# database_url: Optional[str] +# force_https: bool = Field(default=True) +# reserve_fee_min: Optional[int] +# reserve_fee_pct: Optional[float] +# service_fee: float = Optional[float] +# hide_api: bool = Field(default=False) +# # Change theme +# site_title: Optional[str] +# site_tagline: Optional[str] +# site_description: Optional[str] +# default_wallet_name: Optional[str] +# denomination: str = Field(default="sats") +# theme: Optional[str] +# custom_logo: Optional[str] +# ad_space: Optional[str] - @classmethod - def from_row(cls, row: Row) -> "Admin": - data = dict(row) - return cls(**data) +# @classmethod +# def from_row(cls, row: Row) -> "Admin": +# data = dict(row) +# return cls(**data) class Funding(BaseModel): diff --git a/lnbits/extensions/admin/templates/admin/_tab_funding.html b/lnbits/extensions/admin/templates/admin/_tab_funding.html new file mode 100644 index 00000000..2ed0aae2 --- /dev/null +++ b/lnbits/extensions/admin/templates/admin/_tab_funding.html @@ -0,0 +1,158 @@ + + +
Wallets Management
+
+
+
+
+

Funding Source Info

+
    + {%raw%} +
  • + Funding Source: {{data.settings.lnbits_backend_wallet_class}} +
  • +
  • Balance: {{data.balance / 1000}} sats
  • + {%endraw%} +
+
+
+
+
+
+
+
+

Active Funding (Requires server restart)

+ +
+
+ +
+
+
+

Fee reserve

+
+
+ +
+
+ +
+
+
+
+
+
+

TopUp a wallet

+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+

Funding Sources

+ {% raw %} + + + + + + + + + + + + + + {% endraw %} +
+
+
diff --git a/lnbits/extensions/admin/templates/admin/_tab_server.html b/lnbits/extensions/admin/templates/admin/_tab_server.html new file mode 100644 index 00000000..2924e6a4 --- /dev/null +++ b/lnbits/extensions/admin/templates/admin/_tab_server.html @@ -0,0 +1,78 @@ + + +
Server Management
+
+
+
+
+

Server Info

+
    + {%raw%} +
  • + SQlite: {{data.settings.lnbits_data_folder}} +
  • +
  • + Postgres: {{data.settings.lnbits_database_url}} +
  • + {%endraw%} +
+
+
+
+
+
+

Service Fee

+ +
+
+
+

Miscelaneous

+ + + Force HTTPS + Prefer secure URLs + + + + + + + + Hide API + Hides wallet api, extensions can choose to honor + + + + + +
+
+
+
+ +
+ Save +
+
+
diff --git a/lnbits/extensions/admin/templates/admin/_tab_theme.html b/lnbits/extensions/admin/templates/admin/_tab_theme.html new file mode 100644 index 00000000..41dc0447 --- /dev/null +++ b/lnbits/extensions/admin/templates/admin/_tab_theme.html @@ -0,0 +1,122 @@ + + +
UI Management
+
+
+
+
+

Site Title

+ +
+
+
+

Site Tagline

+ +
+
+
+
+

Site Description

+ +
+
+
+
+

Default Wallet Name

+ +
+
+
+

Denomination

+ +
+
+
+
+
+

Themes

+ +
+
+
+

Advertisement Slots

+ + + +
+ {% raw %} + + {{ space.slice(0, 8) + " ... " + space.slice(-8) }} + + {% endraw %} +
+
+
+
+
+
+

Custom Logo

+ +
+
+
+
+ +
+ Save +
+
+
diff --git a/lnbits/extensions/admin/templates/admin/_tab_users.html b/lnbits/extensions/admin/templates/admin/_tab_users.html new file mode 100644 index 00000000..3eb53ac4 --- /dev/null +++ b/lnbits/extensions/admin/templates/admin/_tab_users.html @@ -0,0 +1,96 @@ + + +
User Management
+
+

+ Super Admin: {% raw %}{{this.data.settings.lnbits_admin_users[0]}}{% + endraw %} +

+
+
+

Admin Users

+ + + +
+ {% raw %} + + {{ user }} + + {% endraw %} +
+
+
+
+

Allowed Users

+ + + +
+ {% raw %} + + {{ user }} + + {% endraw %} +
+
+
+
+
+

Admin Extensions

+ +
+
+
+

Disabled Extensions

+ +
+
+
+
+ Save +
+
+
diff --git a/lnbits/extensions/admin/templates/admin/index.html b/lnbits/extensions/admin/templates/admin/index.html index 319ca3f0..87e89321 100644 --- a/lnbits/extensions/admin/templates/admin/index.html +++ b/lnbits/extensions/admin/templates/admin/index.html @@ -29,1118 +29,16 @@ - - - -
Wallets Management
-
-
-
-
-

Funding Source Info

-
    - {%raw%} -
  • Funding Source: {{data.admin.funding_source}}
  • -
  • Balance: {{data.admin.balance / 1000}} sats
  • - {%endraw%} -
-
-
-
-
-
-
-
-

- Active Funding - (Requires server restart) -

- -
-
- -
-
-
-

Fee reserve

-
-
- -
-
- -
-
- -
-
-
-
- -

TopUp a wallet

-
-
- -
-
-
- -
-
-
- -
- -
-
-
-

Funding Sources

- {% raw %} - - - - - - - - - - - - - - {% endraw %} - -
-
-
- - -
User Management
-
-

- Super Admin: {% raw %}{{this.data.admin.user}}{% endraw %} -

-
-
-

Admin Users

- - - -
- {% raw %} - - {{ user }} - - {% endraw %} -
-
-
-
-

Allowed Users

- - - -
- {% raw %} - - {{ user }} - - {% endraw %} -
-
-
-
-
-

Admin Extensions

- -
-
-
-

Disabled Extensions

- -
-
-
-
- Save -
-
-
- - -
Server Management
-
-
-
-
-

Server Info

-
    - {%raw%} -
  • - SQlite: {{data.admin.data_folder}} -
  • -
  • - Postgres: {{data.admin.database_url}} -
  • - {%endraw%} -
-
-
-
-
-
-

Service Fee

- -
-
-
-

Miscelaneous

- - - Force HTTPS - Prefer secure URLs - - - - - - - - Hide API - Hides wallet api, extensions can choose to - honor - - - - - -
-
-
-
- -
- Save -
-
-
- - -
UI Management
-
-
-
-
-

Site Title

- -
-
-
-

Site Tagline

- -
-
-
-
-

Site Description

- -
-
-
-
-

Default Wallet Name

- -
-
-
-

Denomination

- -
-
-
-
-
-

Themes

- -
-
-
-

Advertisement Slots

- - - -
- {% raw %} - - {{ space.slice(0, 8) + " ... " + space.slice(-8) }} - - {% endraw %} -
-
-
-
-
-
-

Custom Logo

- -
-
-
-
- -
- Save -
-
-
+ {% include "admin/_tab_funding.html" %} {% include + "admin/_tab_users.html" %} {% include "admin/_tab_server.html" %} {% + include "admin/_tab_theme.html" %}
- - -
- -
{% endblock %} {% block scripts %} {{ window_vars(user) }}