From 0a86fe8dc80346a288e7756967225877e7941b16 Mon Sep 17 00:00:00 2001 From: Jeremy Klein Date: Tue, 4 Jun 2024 17:03:34 -0700 Subject: [PATCH] Add a function for overriding the receiver domain in the lnurlp. This is useful for cases where the receiver domain is not the same as the incoming request Host, for example when the request is being proxied to another internal service. --- uma/test/uma_test.go | 14 ++++++++++++++ uma/uma.go | 14 +++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/uma/test/uma_test.go b/uma/test/uma_test.go index 868c851..432edf7 100644 --- a/uma/test/uma_test.go +++ b/uma/test/uma_test.go @@ -117,6 +117,20 @@ func TestSignAndVerifyLnurlpRequest(t *testing.T) { require.NoError(t, err) } +func TestSignAndVerifyLnurlpRequestReplacingDomain(t *testing.T) { + privateKey, err := secp256k1.GeneratePrivateKey() + require.NoError(t, err) + queryUrl, err := uma.GetSignedLnurlpRequestUrl(privateKey.Serialize(), "$bob@vasp3.com", "vasp1.com", true, nil) + require.NoError(t, err) + queryUrl.Host = "vasp2.com" + query, err := uma.ParseLnurlpRequestWithReceiverDomain(*queryUrl, "vasp3.com") + require.NoError(t, err) + require.Equal(t, *query.UmaVersion, uma.UmaProtocolVersion) + require.Equal(t, query.ReceiverAddress, "$bob@vasp3.com") + err = uma.VerifyUmaLnurlpQuerySignature(*query.AsUmaRequest(), getPubKeyResponse(privateKey), getNonceCache()) + require.NoError(t, err) +} + func TestParseLnurlpRequestUnsupportedVersion(t *testing.T) { privateKey, err := secp256k1.GeneratePrivateKey() require.NoError(t, err) diff --git a/uma/uma.go b/uma/uma.go index ea9aa24..fb5eab0 100644 --- a/uma/uma.go +++ b/uma/uma.go @@ -264,6 +264,18 @@ func IsUmaLnurlpQuery(url url.URL) bool { // // url: the full URL of the uma request. func ParseLnurlpRequest(url url.URL) (*protocol.LnurlpRequest, error) { + return ParseLnurlpRequestWithReceiverDomain(url, url.Host) +} + +// ParseLnurlpRequestWithReceiverDomain Parses the message into an LnurlpRequest object using an overridden receiver UMA domain. +// +// This is useful for cases where the receiver domain is not the same as the incoming request Host, for example when the +// request is being proxied to another internal service. +// Args: +// +// url: the full URL of the uma request. +// receiverDomain: the domain of the receiver UMA of the payment. This is used to override the domain in the URL. +func ParseLnurlpRequestWithReceiverDomain(url url.URL, receiverDomain string) (*protocol.LnurlpRequest, error) { query := url.Query() signature := query.Get("signature") vaspDomain := query.Get("vaspDomain") @@ -292,7 +304,7 @@ func ParseLnurlpRequest(url url.URL) (*protocol.LnurlpRequest, error) { if len(pathParts) != 4 || pathParts[1] != ".well-known" || pathParts[2] != "lnurlp" { return nil, errors.New("invalid uma request path") } - receiverAddress := pathParts[3] + "@" + url.Host + receiverAddress := pathParts[3] + "@" + receiverDomain nilIfEmpty := func(s string) *string { if s == "" {