mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
* feat: nwc create_connection command (WIP) * feat: allow creating superuser apps from the ui * fix: pass methods rather than scopes in create_connection method * chore: add extra tests * fix: use browser router in http mode * fix: update links to not use hash router * fix: add redirect from hash router url * fix: return nostrWalletConnectUrl in nwc connection success event and message * feat: publish nwa event * chore: use nwc info event instead of nwa event * feat: create custom alby go detail page * chore: allow creating/editing apps with the same name * fix: convert budget from msats to sats (#1111) * chore: address NWA feedback * chore: address feedback - adjust button copy - make create_connection methods consistent with http deeplink flow - remove unused constant - add empty string check before adding lud16 tag - fix test * feat: add support for notification_types in create_connection method * fix: shorter button copy * fix: do not include lud16 tag in published info event * Feat: add lud16 to get_info response (#1128) feat: add lud16 to get_info response * chore: minor alby go screen improvements * fix: incorrect unlock password error message to create app with superuser access * chore: minor ui improvements on alby go detail page * chore: avoid duplicate app names by adding a suffix * chore: move scopes check to apps service, add new tests, DRY controller test setup * fix: scopes component full access scopes and isolated scope group check * fix: use supported capabilities for Alby Go * fix: return correct app name * chore: address minor comments --------- Co-authored-by: im-adithya <imadithyavardhan@gmail.com>
583 lines
16 KiB
Go
583 lines
16 KiB
Go
package nip47
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"slices"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nbd-wtf/go-nostr"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/getAlby/hub/alby"
|
|
"github.com/getAlby/hub/constants"
|
|
"github.com/getAlby/hub/db"
|
|
"github.com/getAlby/hub/nip47/cipher"
|
|
"github.com/getAlby/hub/nip47/models"
|
|
"github.com/getAlby/hub/nip47/permissions"
|
|
"github.com/getAlby/hub/tests"
|
|
)
|
|
|
|
// TODO: test HandleEvent
|
|
// TODO: test a request cannot be processed twice
|
|
// TODO: test if an app doesn't exist it returns the right error code
|
|
|
|
func TestCreateResponse_Nip04(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestCreateResponse(t, svc, "0.0")
|
|
}
|
|
|
|
func TestCreateResponse_Nip44(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestCreateResponse(t, svc, "1.0")
|
|
}
|
|
|
|
func doTestCreateResponse(t *testing.T, svc *tests.TestService, nip47Version string) {
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
Content: "1",
|
|
}
|
|
|
|
reqEvent.ID = "12345"
|
|
|
|
nip47Cipher, err := cipher.NewNip47Cipher(nip47Version, reqPubkey, svc.Keys.GetNostrSecretKey())
|
|
assert.NoError(t, err)
|
|
|
|
type dummyResponse struct {
|
|
Foo int
|
|
}
|
|
|
|
nip47Response := &models.Response{
|
|
ResultType: "dummy_method",
|
|
Result: dummyResponse{
|
|
Foo: 1000,
|
|
},
|
|
}
|
|
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
res, err := nip47svc.CreateResponse(reqEvent, nip47Response, nostr.Tags{}, nip47Cipher, svc.Keys.GetNostrSecretKey())
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, reqPubkey, res.Tags.GetFirst([]string{"p"}).Value())
|
|
assert.Equal(t, reqEvent.ID, res.Tags.GetFirst([]string{"e"}).Value())
|
|
assert.Equal(t, svc.Keys.GetNostrPublicKey(), res.PubKey)
|
|
|
|
decrypted, err := nip47Cipher.Decrypt(res.Content)
|
|
assert.NoError(t, err)
|
|
unmarshalledResponse := models.Response{
|
|
Result: &dummyResponse{},
|
|
}
|
|
|
|
err = json.Unmarshal([]byte(decrypted), &unmarshalledResponse)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, nip47Response.Error)
|
|
assert.Equal(t, nip47Response.ResultType, unmarshalledResponse.ResultType)
|
|
assert.Equal(t, nip47Response.Result, *unmarshalledResponse.Result.(*dummyResponse))
|
|
}
|
|
|
|
func TestHandleResponse_Nip04_WithPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_WithPermission(t, svc, tests.CreateAppWithPrivateKey, "0.0")
|
|
}
|
|
|
|
func TestHandleResponse_Nip44_WithPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_WithPermission(t, svc, tests.CreateAppWithPrivateKey, "1.0")
|
|
}
|
|
|
|
func doTestHandleResponse_WithPermission(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, version string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
app, cipher, err := createAppFn(svc, reqPrivateKey, version)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.GET_BALANCE_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_INFO_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if version != "0.0" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", version})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
assert.NotNil(t, relay.PublishedEvents[0])
|
|
assert.NotEmpty(t, relay.PublishedEvents[0].Content)
|
|
|
|
decrypted, err := cipher.Decrypt(relay.PublishedEvents[0].Content)
|
|
assert.NoError(t, err)
|
|
|
|
type getInfoResult struct {
|
|
Methods []string `json:"methods"`
|
|
}
|
|
|
|
type getInfoResponseWrapper struct {
|
|
models.Response
|
|
Result getInfoResult `json:"result"`
|
|
}
|
|
|
|
unmarshalledResponse := getInfoResponseWrapper{}
|
|
|
|
err = json.Unmarshal([]byte(decrypted), &unmarshalledResponse)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, unmarshalledResponse.Error)
|
|
assert.Equal(t, models.GET_INFO_METHOD, unmarshalledResponse.ResultType)
|
|
expectedMethods := slices.Concat([]string{constants.GET_BALANCE_SCOPE}, permissions.GetAlwaysGrantedMethods())
|
|
assert.ElementsMatch(t, expectedMethods, unmarshalledResponse.Result.Methods)
|
|
}
|
|
|
|
func TestHandleResponse_Nip04_DuplicateRequest(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_DuplicateRequest(t, svc, tests.CreateAppWithPrivateKey, "0.0")
|
|
}
|
|
|
|
func TestHandleResponse_Nip44_DuplicateRequest(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_DuplicateRequest(t, svc, tests.CreateAppWithPrivateKey, "1.0")
|
|
}
|
|
|
|
func doTestHandleResponse_DuplicateRequest(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, version string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
app, cipher, err := createAppFn(svc, reqPrivateKey, version)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.GET_BALANCE_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_INFO_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if version != "0.0" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", version})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
assert.NotNil(t, relay.PublishedEvents[0])
|
|
assert.NotEmpty(t, relay.PublishedEvents[0].Content)
|
|
|
|
relay.PublishedEvents = nil
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
// second time it should not publish
|
|
assert.Nil(t, relay.PublishedEvents)
|
|
}
|
|
|
|
func TestHandleResponse_Nip04_NoPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_NoPermission(t, svc, tests.CreateAppWithPrivateKey, "0.0")
|
|
}
|
|
|
|
func TestHandleResponse_Nip44_NoPermission(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_NoPermission(t, svc, tests.CreateAppWithPrivateKey, "1.0")
|
|
}
|
|
|
|
func doTestHandleResponse_NoPermission(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, version string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
_, cipher, err := createAppFn(svc, reqPrivateKey, version)
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_BALANCE_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if version != "0.0" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", version})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
assert.NotNil(t, relay.PublishedEvents[0])
|
|
assert.NotEmpty(t, relay.PublishedEvents[0].Content)
|
|
|
|
decrypted, err := cipher.Decrypt(relay.PublishedEvents[0].Content)
|
|
assert.NoError(t, err)
|
|
|
|
unmarshalledResponse := models.Response{}
|
|
|
|
err = json.Unmarshal([]byte(decrypted), &unmarshalledResponse)
|
|
assert.NoError(t, err)
|
|
assert.Nil(t, unmarshalledResponse.Result)
|
|
assert.Equal(t, models.GET_BALANCE_METHOD, unmarshalledResponse.ResultType)
|
|
assert.Equal(t, "RESTRICTED", unmarshalledResponse.Error.Code)
|
|
assert.Equal(t, "This app does not have the get_balance scope", unmarshalledResponse.Error.Message)
|
|
}
|
|
|
|
func TestHandleResponse_Nip04_OldRequestForPayment(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_OldRequestForPayment(t, svc, tests.CreateAppWithPrivateKey, "0.0")
|
|
}
|
|
|
|
func TestHandleResponse_Nip44_OldRequestForPayment(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_OldRequestForPayment(t, svc, tests.CreateAppWithPrivateKey, "1.0")
|
|
}
|
|
|
|
func doTestHandleResponse_OldRequestForPayment(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, version string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
app, cipher, err := createAppFn(svc, reqPrivateKey, version)
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.PAY_INVOICE_METHOD,
|
|
}
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.PAY_INVOICE_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Timestamp(time.Now().Add(time.Duration(-6) * time.Hour).Unix()),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if version != "0.0" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", version})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
// it shouldn't return anything for an old request
|
|
assert.Nil(t, relay.PublishedEvents)
|
|
|
|
// change the request to now
|
|
reqEvent.CreatedAt = nostr.Now()
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
assert.NotNil(t, relay.PublishedEvents)
|
|
}
|
|
|
|
func TestHandleResponse_Nip04_IncorrectPubkey(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_IncorrectPubkey(t, svc, tests.CreateAppWithPrivateKey, "0.0")
|
|
}
|
|
|
|
func TestHandleResponse_Nip44_IncorrectPubkey(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
|
|
doTestHandleResponse_IncorrectPubkey(t, svc, tests.CreateAppWithPrivateKey, "1.0")
|
|
}
|
|
|
|
func doTestHandleResponse_IncorrectPubkey(t *testing.T, svc *tests.TestService, createAppFn tests.CreateAppFn, version string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
reqPrivateKey2 := nostr.GeneratePrivateKey()
|
|
|
|
app, cipher, err := createAppFn(svc, reqPrivateKey, version)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.GET_BALANCE_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_BALANCE_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if version != "0.0" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", version})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey2)
|
|
assert.NoError(t, err)
|
|
|
|
// set a different pubkey (this will not pass validation)
|
|
reqEvent.PubKey = reqPubkey
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
assert.Nil(t, relay.PublishedEvents)
|
|
}
|
|
|
|
func TestHandleResponse_NoApp(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
app, cipher, err := tests.CreateAppWithPrivateKey(svc, reqPrivateKey, "1.0")
|
|
assert.NoError(t, err)
|
|
|
|
// delete the app
|
|
err = svc.DB.Delete(app).Error
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_BALANCE_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{[]string{"v", "1.0"}},
|
|
Content: msg,
|
|
}
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
// it shouldn't return anything for an invalid app key
|
|
assert.Nil(t, relay.PublishedEvents)
|
|
}
|
|
|
|
func TestHandleResponse_IncorrectVersions(t *testing.T) {
|
|
svc, err := tests.CreateTestService(t)
|
|
require.NoError(t, err)
|
|
defer svc.Remove()
|
|
// version specifies what cipher will use. If "1.0" is passed,
|
|
// cipher must be NIP-44, otherwise cipher MUST be NIP-04
|
|
doTestHandleResponse_IncorrectVersion(t, svc, "0.0", "1.0")
|
|
doTestHandleResponse_IncorrectVersion(t, svc, "1.0", "0.0")
|
|
doTestHandleResponse_IncorrectVersion(t, svc, "1.0", "")
|
|
}
|
|
|
|
func doTestHandleResponse_IncorrectVersion(t *testing.T, svc *tests.TestService, appVersion, requestVersion string) {
|
|
albyOAuthSvc := alby.NewAlbyOAuthService(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher)
|
|
nip47svc := NewNip47Service(svc.DB, svc.Cfg, svc.Keys, svc.EventPublisher, albyOAuthSvc)
|
|
|
|
reqPrivateKey := nostr.GeneratePrivateKey()
|
|
reqPubkey, err := nostr.GetPublicKey(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
app, cipher, err := tests.CreateAppWithPrivateKey(svc, reqPrivateKey, appVersion)
|
|
assert.NoError(t, err)
|
|
|
|
appPermission := &db.AppPermission{
|
|
AppId: app.ID,
|
|
App: *app,
|
|
Scope: constants.GET_BALANCE_SCOPE,
|
|
}
|
|
err = svc.DB.Create(appPermission).Error
|
|
assert.NoError(t, err)
|
|
|
|
content := map[string]interface{}{
|
|
"method": models.GET_INFO_METHOD,
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(content)
|
|
assert.NoError(t, err)
|
|
|
|
msg, err := cipher.Encrypt(string(payloadBytes))
|
|
assert.NoError(t, err)
|
|
|
|
// don't pass correct version
|
|
reqEvent := &nostr.Event{
|
|
Kind: models.REQUEST_KIND,
|
|
PubKey: reqPubkey,
|
|
CreatedAt: nostr.Now(),
|
|
Tags: nostr.Tags{},
|
|
Content: msg,
|
|
}
|
|
|
|
if requestVersion != "" {
|
|
reqEvent.Tags = append(reqEvent.Tags, []string{"v", requestVersion})
|
|
}
|
|
|
|
err = reqEvent.Sign(reqPrivateKey)
|
|
assert.NoError(t, err)
|
|
|
|
relay := tests.NewMockRelay()
|
|
|
|
nip47svc.HandleEvent(context.TODO(), relay, reqEvent, svc.LNClient)
|
|
|
|
// it shouldn't return anything for an invalid version
|
|
assert.Nil(t, relay.PublishedEvents)
|
|
}
|