diff --git a/models.py b/models.py index ca744cb..59d800e 100644 --- a/models.py +++ b/models.py @@ -5,7 +5,7 @@ from lnurl import Lnurl from lnurl import encode as lnurl_encode from lnurl.types import LnurlPayMetadata -from pydantic import BaseModel +from pydantic import BaseModel, Field ZERO_KEY = "00000000000000000000000000000000" @@ -71,3 +71,8 @@ class Refund(BaseModel): hit_id: str refund_amount: int time: datetime + + +class UIDPost(BaseModel): + UID: str = Field(None, description="The UID of the card.") + LNURLW: str = Field(None, description="The LNURLW of the card.") diff --git a/static/js/index.js b/static/js/index.js index 2208189..b553347 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -148,6 +148,15 @@ window.app = Vue.createApp({ } } }, + computed: { + deeplinkUrl() { + const baseUrl = `boltcard://${this.qrCodeDialog.wipe ? 'reset' : 'program'}` + const url = + this.qrCodeDialog.data.link + + (this.qrCodeDialog.wipe ? '&wipe=true' : '') + return `${baseUrl}?url=${encodeURIComponent(url)}` + } + }, methods: { readNfcTag() { const ndef = new NDEFReader() @@ -229,6 +238,9 @@ window.app = Vue.createApp({ this.qrCodeDialog.data = { id: card.id, link: window.location.origin + '/boltcards/api/v1/auth?a=' + card.otp, + encodedURI: encodeURIComponent( + window.location.origin + '/boltcards/api/v1/auth?a=' + card.otp + ), name: card.card_name, uid: card.uid, external_id: card.external_id, diff --git a/templates/boltcards/index.html b/templates/boltcards/index.html index 838eefb..cd63021 100644 --- a/templates/boltcards/index.html +++ b/templates/boltcards/index.html @@ -463,6 +463,7 @@
Click to copy, then paste to NFC Card Creator > Backup the keys, or wipe the card first! + + Use Boltcard Programmer App +
Close
diff --git a/views_lnurl.py b/views_lnurl.py index f4a39b1..01da89e 100644 --- a/views_lnurl.py +++ b/views_lnurl.py @@ -16,12 +16,14 @@ get_card, get_card_by_external_id, get_card_by_otp, + get_card_by_uid, get_hit, get_hits_today, spend_hit, update_card_counter, update_card_otp, ) +from .models import UIDPost from .nxp424 import decrypt_sun, get_sun_mac boltcards_lnurl_router = APIRouter() @@ -179,6 +181,46 @@ async def api_auth(a, request: Request): return response +# /boltcards/api/v1/auth?a=00000000000000000000000000000000 +@boltcards_lnurl_router.post("/api/v1/auth") +async def api_auth_post(a: str, request: Request, data: UIDPost, wipe: bool = False): + card = None + if wipe: + card = await get_card_by_otp(a) + else: + if not data.UID: + raise HTTPException( + detail="Missing UID.", status_code=HTTPStatus.BAD_REQUEST + ) + + card = await get_card_by_uid(data.UID) + if not card: + raise HTTPException( + detail="Card does not exist.", status_code=HTTPStatus.NOT_FOUND + ) + new_otp = secrets.token_hex(16) + await update_card_otp(new_otp, card.id) + lnurlw_base = ( + f"{urlparse(str(request.url)).netloc}/boltcards/api/v1/scan/{card.external_id}" + ) + response = { + "CARD_NAME": card.card_name, + "ID": str(1), + "K0": card.k0, + "K1": card.k1, + "K2": card.k2, + "K3": card.k1, + "K4": card.k2, + "LNURLW_BASE": "LNURLW://" + lnurlw_base, + "LNURLW": "LNURLW://" + lnurlw_base, + "PROTOCOL_NAME": "NEW_BOLT_CARD_RESPONSE", + "PROTOCOL_VERSION": str(1), + } + if wipe: + response["action"] = "wipe" + return response + + ###############LNURLPAY REFUNDS#################