Skip to content

Commit 1f964d1

Browse files
authored
fix: http urls on localhost would create the wrong https url (#87)
* fix: http urls on localhost would create the wrong https url
1 parent 3824b22 commit 1f964d1

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

lnurl/types.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
from .exceptions import InvalidLnurlPayMetadata, InvalidUrl, LnAddressError
2222
from .helpers import _bech32_decode, _lnurl_clean, url_decode, url_encode
2323

24+
INSECURE_HOSTS = ["127.0.0.1", "0.0.0.0", "localhost"]
25+
2426

2527
class ReprMixin:
2628
def __repr__(self) -> str:
@@ -81,7 +83,7 @@ def valid_lnurl_host(url: str) -> AnyUrl:
8183
if not _url.host:
8284
raise InvalidUrl("URL host is required.")
8385
if _url.scheme == "http":
84-
if _url.host not in ["127.0.0.1", "0.0.0.0", "localhost"] and not _url.host.endswith(".onion"):
86+
if _url.host not in INSECURE_HOSTS and not _url.host.endswith(".onion"):
8587
raise InvalidUrl("HTTP scheme is only allowed for localhost or onion addresses.")
8688
return _url
8789

@@ -108,6 +110,12 @@ def __get_validators__(cls) -> Generator:
108110
def query_params(self) -> dict:
109111
return {k: v[0] for k, v in parse_qs(self.query).items()}
110112

113+
@property
114+
def insecure(self) -> bool:
115+
if not self.host:
116+
return True
117+
return self.scheme == "http" or self.host in INSECURE_HOSTS or self.host.endswith(".onion")
118+
111119

112120
class CallbackUrl(Url):
113121
"""URL for callbacks. exclude lud17 schemes."""
@@ -155,7 +163,7 @@ class Lnurl(ReprMixin, str):
155163

156164
def __new__(cls, lightning: str) -> Lnurl:
157165
url = cls.clean(lightning)
158-
_url = url.replace(url.scheme, "https", 1)
166+
_url = url.replace(url.scheme, "http" if url.insecure else "https", 1)
159167
return str.__new__(cls, _url)
160168

161169
def __init__(self, lightning: str):
@@ -165,7 +173,7 @@ def __init__(self, lightning: str):
165173
self.lud17_prefix = None
166174
return str.__init__(url)
167175
self.lud17_prefix = url.scheme
168-
_url = parse_obj_as(Url, url.replace(url.scheme, "https", 1))
176+
_url = parse_obj_as(Url, url.replace(url.scheme, "http" if url.insecure else "https", 1))
169177
self.url = _url
170178
return str.__init__(_url)
171179

tests/test_types.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,19 @@ def test_decode_nolnurl(self, bech32):
199199
with pytest.raises(ValidationError):
200200
parse_obj_as(Lnurl, bech32)
201201

202+
@pytest.mark.parametrize(
203+
"url",
204+
[
205+
"lnurlp://localhost",
206+
"http://localhost",
207+
],
208+
)
209+
def test_insecure_lnurl(self, url: str):
210+
lnurl = parse_obj_as(Lnurl, url)
211+
assert lnurl.url.insecure is True
212+
assert lnurl.url.host == "localhost"
213+
assert lnurl.url.startswith("http://")
214+
202215

203216
class TestLnurlPayMetadata:
204217
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)