mirror of
https://github.com/lnbits/lnbits.git
synced 2025-09-28 04:46:18 +02:00
moved code for generating new dns name and updating the invoice in database to the invoiceListener
This commit is contained in:
@@ -62,53 +62,7 @@ async def set_subdomain_paid(payment_hash: str) -> Subdomains:
|
|||||||
)
|
)
|
||||||
|
|
||||||
subdomain = await get_subdomain(payment_hash)
|
subdomain = await get_subdomain(payment_hash)
|
||||||
|
return subdomain
|
||||||
### SEND REQUEST TO CLOUDFLARE
|
|
||||||
url = "https://api.cloudflare.com/client/v4/zones/" + domaindata.cf_zone_id + "/dns_records"
|
|
||||||
header = {"Authorization": "Bearer " + domaindata.cf_token, "Content-Type": "application/json"}
|
|
||||||
aRecord = subdomain.subdomain + "." + subdomain.domain_name
|
|
||||||
cf_response = ""
|
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
try:
|
|
||||||
r = await client.post(
|
|
||||||
url,
|
|
||||||
headers=header,
|
|
||||||
json={
|
|
||||||
"type": subdomain.record_type,
|
|
||||||
"name": aRecord,
|
|
||||||
"content": subdomain.ip,
|
|
||||||
"ttl": 0,
|
|
||||||
"proxed": False,
|
|
||||||
},
|
|
||||||
timeout=40,
|
|
||||||
)
|
|
||||||
cf_response = r.text
|
|
||||||
except AssertionError:
|
|
||||||
cf_response = "Error occured"
|
|
||||||
|
|
||||||
### Use webhook to notify about cloudflare registration
|
|
||||||
if domaindata.webhook:
|
|
||||||
async with httpx.AsyncClient() as client:
|
|
||||||
try:
|
|
||||||
r = await client.post(
|
|
||||||
domaindata.webhook,
|
|
||||||
json={
|
|
||||||
"domain": subdomain.domain_name,
|
|
||||||
"subdomain": subdomain.subdomain,
|
|
||||||
"record_type": subdomain.record_type,
|
|
||||||
"email": subdomain.email,
|
|
||||||
"ip": subdomain.ip,
|
|
||||||
"cost:": str(subdomain.sats) + " sats",
|
|
||||||
"duration": str(subdomain.duration) + " days",
|
|
||||||
"cf_response": cf_response,
|
|
||||||
},
|
|
||||||
timeout=40,
|
|
||||||
)
|
|
||||||
except AssertionError:
|
|
||||||
webhook = None
|
|
||||||
|
|
||||||
subdomain = await get_subdomain(payment_hash)
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
async def get_subdomain(subdomain_id: str) -> Optional[Subdomains]:
|
async def get_subdomain(subdomain_id: str) -> Optional[Subdomains]:
|
||||||
|
@@ -1,47 +1,80 @@
|
|||||||
|
from http import HTTPStatus
|
||||||
|
from quart.json import jsonify
|
||||||
import trio # type: ignore
|
import trio # type: ignore
|
||||||
import json
|
import json
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
|
from .crud import get_domain, set_subdomain_paid
|
||||||
|
from lnbits.core.crud import get_user, get_wallet
|
||||||
from lnbits.core import db as core_db
|
from lnbits.core import db as core_db
|
||||||
from lnbits.core.models import Payment
|
from lnbits.core.models import Payment
|
||||||
from lnbits.tasks import register_invoice_listener
|
from lnbits.tasks import register_invoice_listener
|
||||||
|
|
||||||
from .crud import get_pay_link
|
|
||||||
|
|
||||||
|
|
||||||
async def register_listeners():
|
async def register_listeners():
|
||||||
invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
|
invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
|
||||||
register_invoice_listener(invoice_paid_chan_send)
|
register_invoice_listener(invoice_paid_chan_send)
|
||||||
await wait_for_paid_invoices(invoice_paid_chan_recv)
|
await wait_for_paid_invoices(invoice_paid_chan_recv)
|
||||||
|
|
||||||
|
|
||||||
async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel):
|
async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel):
|
||||||
async for payment in invoice_paid_chan:
|
async for payment in invoice_paid_chan:
|
||||||
await on_invoice_paid(payment)
|
await on_invoice_paid(payment)
|
||||||
|
|
||||||
|
|
||||||
async def on_invoice_paid(payment: Payment) -> None:
|
async def on_invoice_paid(payment: Payment) -> None:
|
||||||
if "lnurlp" != payment.extra.get("tag"):
|
print(payment)
|
||||||
|
if "lnsubdomain" != payment.extra.get("tag"):
|
||||||
# not an lnurlp invoice
|
# not an lnurlp invoice
|
||||||
return
|
return
|
||||||
|
|
||||||
if payment.extra.get("wh_status"):
|
wallet = await get_wallet(payment.wallet_id)
|
||||||
# this webhook has already been sent
|
await payment.set_pending(False)
|
||||||
return
|
subdomain = await set_subdomain_paid(payment_hash=payment.payment_hash)
|
||||||
|
domain = await get_domain(subdomain.domain)
|
||||||
|
|
||||||
pay_link = await get_pay_link(payment.extra.get("link", -1))
|
### SEND REQUEST TO CLOUDFLARE
|
||||||
if pay_link and pay_link.webhook_url:
|
url = "https://api.cloudflare.com/client/v4/zones/" + domain.cf_zone_id + "/dns_records"
|
||||||
|
header = {"Authorization": "Bearer " + domain.cf_token, "Content-Type": "application/json"}
|
||||||
|
aRecord = subdomain.subdomain + "." + subdomain.domain_name
|
||||||
|
cf_response = ""
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
try:
|
try:
|
||||||
r = await client.post(
|
r = await client.post(
|
||||||
pay_link.webhook_url,
|
url,
|
||||||
|
headers=header,
|
||||||
json={
|
json={
|
||||||
"payment_hash": payment.payment_hash,
|
"type": subdomain.record_type,
|
||||||
"payment_request": payment.bolt11,
|
"name": aRecord,
|
||||||
"amount": payment.amount,
|
"content": subdomain.ip,
|
||||||
"comment": payment.extra.get("comment"),
|
"ttl": 0,
|
||||||
"lnurlp": pay_link.id,
|
"proxed": False,
|
||||||
},
|
},
|
||||||
timeout=40,
|
timeout=40,
|
||||||
)
|
)
|
||||||
await mark_webhook_sent(payment, r.status_code)
|
cf_response = r.text
|
||||||
except (httpx.ConnectError, httpx.RequestError):
|
except AssertionError:
|
||||||
await mark_webhook_sent(payment, -1)
|
cf_response = "Error occured"
|
||||||
|
|
||||||
|
### Use webhook to notify about cloudflare registration
|
||||||
|
if domain.webhook:
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
try:
|
||||||
|
r = await client.post(
|
||||||
|
domain.webhook,
|
||||||
|
json={
|
||||||
|
"domain": subdomain.domain_name,
|
||||||
|
"subdomain": subdomain.subdomain,
|
||||||
|
"record_type": subdomain.record_type,
|
||||||
|
"email": subdomain.email,
|
||||||
|
"ip": subdomain.ip,
|
||||||
|
"cost:": str(subdomain.sats) + " sats",
|
||||||
|
"duration": str(subdomain.duration) + " days",
|
||||||
|
"cf_response": cf_response,
|
||||||
|
},
|
||||||
|
timeout=40,
|
||||||
|
)
|
||||||
|
except AssertionError:
|
||||||
|
webhook = None
|
||||||
|
|
||||||
|
return jsonify({"paid": True}), HTTPStatus.OK
|
||||||
|
39
lnbits/extensions/subdomains/util.py
Normal file
39
lnbits/extensions/subdomains/util.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from lnbits.extensions.subdomains.models import Subdomains
|
||||||
|
import trio # type: ignore
|
||||||
|
import json
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
# Python3 program to validate
|
||||||
|
# domain name
|
||||||
|
# using regular expression
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
|
||||||
|
# Function to validate domain name.
|
||||||
|
def isValidDomain(str):
|
||||||
|
# Regex to check valid
|
||||||
|
# domain name.
|
||||||
|
regex = "^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,6}"
|
||||||
|
# Compile the ReGex
|
||||||
|
p = re.compile(regex)
|
||||||
|
|
||||||
|
# If the string is empty
|
||||||
|
# return false
|
||||||
|
if str == None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Return if the string
|
||||||
|
# matched the ReGex
|
||||||
|
if re.search(p, str):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Function to validate IP address
|
||||||
|
def isvalidIPAddress(str):
|
||||||
|
try:
|
||||||
|
socket.inet_aton(str)
|
||||||
|
return True
|
||||||
|
except socket.error:
|
||||||
|
return False
|
@@ -5,8 +5,8 @@ from http import HTTPStatus
|
|||||||
from lnbits.core.crud import get_user, get_wallet
|
from lnbits.core.crud import get_user, get_wallet
|
||||||
from lnbits.core.services import create_invoice, check_invoice_status
|
from lnbits.core.services import create_invoice, check_invoice_status
|
||||||
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||||
from .util import validIPAddress
|
|
||||||
|
|
||||||
|
from .util import isValidDomain, isvalidIPAddress
|
||||||
from . import subdomains_ext
|
from . import subdomains_ext
|
||||||
from .crud import (
|
from .crud import (
|
||||||
create_subdomain,
|
create_subdomain,
|
||||||
@@ -114,8 +114,13 @@ async def api_subdomain_make_subdomain(domain_id):
|
|||||||
|
|
||||||
if not domain:
|
if not domain:
|
||||||
return jsonify({"message": "LNsubdomain does not exist."}), HTTPStatus.NOT_FOUND
|
return jsonify({"message": "LNsubdomain does not exist."}), HTTPStatus.NOT_FOUND
|
||||||
if not validIPAddress(g.data["ip"]):
|
if not isvalidIPAddress(g.data["ip"]):
|
||||||
return jsonify({"message": g.data["ip"] + " Not a valid IP address"}), HTTPStatus.BAD_REQUEST
|
return jsonify({"message": g.data["ip"] + " Not a valid IP address"}), HTTPStatus.BAD_REQUEST
|
||||||
|
if not isValidDomain(g.data["subdomain"] + "." + domain.domain):
|
||||||
|
return (
|
||||||
|
jsonify({"message": g.data["subdomain"] + "." + domain.domain + " Bad domain name"}),
|
||||||
|
HTTPStatus.BAD_REQUEST,
|
||||||
|
)
|
||||||
if g.data["record_type"] not in domain.allowed_record_types:
|
if g.data["record_type"] not in domain.allowed_record_types:
|
||||||
return jsonify({"message": g.data["record_type"] + "Not a valid record"}), HTTPStatus.BAD_REQUEST
|
return jsonify({"message": g.data["record_type"] + "Not a valid record"}), HTTPStatus.BAD_REQUEST
|
||||||
|
|
||||||
@@ -147,12 +152,6 @@ async def api_subdomain_send_subdomain(payment_hash):
|
|||||||
return jsonify({"paid": False}), HTTPStatus.OK
|
return jsonify({"paid": False}), HTTPStatus.OK
|
||||||
|
|
||||||
if is_paid:
|
if is_paid:
|
||||||
wallet = await get_wallet(subdomain.wallet)
|
|
||||||
payment = await wallet.get_payment(payment_hash)
|
|
||||||
await payment.set_pending(False)
|
|
||||||
subdomain = await set_subdomain_paid(payment_hash=payment_hash)
|
|
||||||
return jsonify({"paid": True}), HTTPStatus.OK
|
|
||||||
|
|
||||||
return jsonify({"paid": False}), HTTPStatus.OK
|
return jsonify({"paid": False}), HTTPStatus.OK
|
||||||
|
|
||||||
|
|
||||||
@@ -170,4 +169,3 @@ async def api_subdomain_delete(subdomain_id):
|
|||||||
await delete_subdomain(subdomain_id)
|
await delete_subdomain(subdomain_id)
|
||||||
|
|
||||||
return "", HTTPStatus.NO_CONTENT
|
return "", HTTPStatus.NO_CONTENT
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user