From 9c518b8e6d0664b4d42ba0d35898eda3ff9faf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Mon, 1 Apr 2024 09:22:40 +0200 Subject: [PATCH] fix: change wallet for paylink closes #26 --- crud.py | 4 ++-- models.py | 1 + static/js/index.js | 3 +-- views_api.py | 39 ++++++++++++++++++++++++++------------- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/crud.py b/crud.py index f30fd1b..837b56a 100644 --- a/crud.py +++ b/crud.py @@ -39,7 +39,7 @@ async def get_pay_link_by_username(username: str) -> Optional[PayLink]: return PayLink.from_row(row) if row else None -async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: +async def create_pay_link(data: CreatePayLinkData) -> PayLink: link_id = urlsafe_short_hash()[:6] @@ -69,7 +69,7 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: """, ( link_id, - wallet_id, + data.wallet, data.description, data.min, data.max, diff --git a/models.py b/models.py index 864900a..070655f 100644 --- a/models.py +++ b/models.py @@ -28,6 +28,7 @@ class LnurlpSettings(BaseModel): class CreatePayLinkData(BaseModel): description: str + wallet: Optional[str] = None min: float = Query(1, ge=0.01) max: float = Query(1, ge=0.01) currency: str = Query(None) diff --git a/static/js/index.js b/static/js/index.js index 5a44726..5feb767 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -123,8 +123,7 @@ new Vue({ const wallet = _.findWhere(this.g.user.wallets, { id: this.formDialog.data.wallet }) - var data = _.omit(this.formDialog.data, 'wallet') - + const data = _.clone(this.formDialog.data) if (this.formDialog.fixedAmount) data.max = data.min if (data.currency === 'satoshis') data.currency = null if (isNaN(parseInt(data.comment_chars))) data.comment_chars = 0 diff --git a/views_api.py b/views_api.py index d4e0dcf..6da2899 100644 --- a/views_api.py +++ b/views_api.py @@ -1,12 +1,13 @@ import json from http import HTTPStatus +from typing import Optional from fastapi import Depends, Query, Request from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl from starlette.exceptions import HTTPException -from lnbits.core.crud import get_user -from lnbits.decorators import WalletTypeInfo, check_admin, get_key_type +from lnbits.core.crud import get_user, get_wallet +from lnbits.decorators import WalletTypeInfo, check_admin, get_key_type, require_admin_key, require_invoice_key from lnbits.utils.exchange_rates import currencies, get_fiat_rate_satoshis from . import lnurlp_ext @@ -68,7 +69,7 @@ async def api_links( @lnurlp_ext.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) async def api_link_retrieve( - r: Request, link_id, wallet: WalletTypeInfo = Depends(get_key_type) + r: Request, link_id: str, key_info: WalletTypeInfo = Depends(require_invoice_key) ): link = await get_pay_link(link_id) @@ -77,7 +78,9 @@ async def api_link_retrieve( detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND ) - if link.wallet != wallet.wallet.id: + link_wallet = await get_wallet(link.wallet) + + if link_wallet.user != key_info.wallet.user: raise HTTPException( detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN ) @@ -98,8 +101,8 @@ async def check_username_exists(username: str): async def api_link_create_or_update( data: CreatePayLinkData, request: Request, - link_id=None, - wallet: WalletTypeInfo = Depends(get_key_type), + link_id: Optional[str] = None, + key_info: WalletTypeInfo = Depends(require_admin_key), ): if data.min > data.max: raise HTTPException( @@ -151,6 +154,21 @@ async def api_link_create_or_update( detail=f"Invalid username: {ex}", status_code=HTTPStatus.BAD_REQUEST ) + # if wallet is not provided, use the wallet of the key + if not data.wallet: + data.wallet = key_info.wallet.id + + new_wallet = await get_wallet(data.wallet) + if not new_wallet: + raise HTTPException( + detail="Wallet does not exist.", status_code=HTTPStatus.FORBIDDEN + ) + + if new_wallet.user != key_info.wallet.user: + raise HTTPException( + detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN + ) + if link_id: link = await get_pay_link(link_id) @@ -159,11 +177,6 @@ async def api_link_create_or_update( detail="Pay link does not exist.", status_code=HTTPStatus.NOT_FOUND ) - if link.wallet != wallet.wallet.id: - raise HTTPException( - detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN - ) - if data.username and data.username != link.username: await check_username_exists(data.username) @@ -172,14 +185,14 @@ async def api_link_create_or_update( if data.username: await check_username_exists(data.username) - link = await create_pay_link(data, wallet_id=wallet.wallet.id) + link = await create_pay_link(data) assert link return {**link.dict(), "lnurl": link.lnurl(request)} @lnurlp_ext.delete("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) -async def api_link_delete(link_id, wallet: WalletTypeInfo = Depends(get_key_type)): +async def api_link_delete(link_id: str, wallet: WalletTypeInfo = Depends(get_key_type)): link = await get_pay_link(link_id) if not link: