get_info_controller_test.go raw
1 package controllers
2
3 import (
4 "context"
5 "encoding/json"
6 "testing"
7
8 "github.com/getAlby/go-nostr"
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11
12 "github.com/getAlby/hub/config"
13 "github.com/getAlby/hub/constants"
14 "github.com/getAlby/hub/db"
15 "github.com/getAlby/hub/nip47/models"
16 "github.com/getAlby/hub/tests"
17 )
18
19 const nip47GetInfoJson = `
20 {
21 "method": "get_info"
22 }
23 `
24
25 func TestHandleGetInfoEvent_NoPermission(t *testing.T) {
26 ctx := context.TODO()
27 svc, err := tests.CreateTestService(t)
28 require.NoError(t, err)
29 defer svc.Remove()
30
31 metadata := map[string]interface{}{
32 "a": 123,
33 }
34
35 app, _, err := svc.AppsService.CreateApp("test", "", 0, "monthly", nil, []string{constants.GET_INFO_SCOPE}, false, metadata)
36 assert.NoError(t, err)
37
38 lightningAddress := "hello@getalby.com"
39 svc.Cfg.SetUpdate("AlbyLightningAddress", lightningAddress, "")
40
41 nip47Request := &models.Request{}
42 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
43 assert.NoError(t, err)
44
45 dbRequestEvent := &db.RequestEvent{}
46 err = svc.DB.Create(&dbRequestEvent).Error
47 assert.NoError(t, err)
48
49 // delete the existing app permissions (the app was created with get_info scope)
50 svc.DB.Exec("delete from app_permissions")
51
52 appPermission := &db.AppPermission{
53 AppId: app.ID,
54 Scope: constants.GET_BALANCE_SCOPE,
55 ExpiresAt: nil,
56 }
57 err = svc.DB.Create(appPermission).Error
58 assert.NoError(t, err)
59
60 var publishedResponse *models.Response
61
62 publishResponse := func(response *models.Response, tags nostr.Tags) {
63 publishedResponse = response
64 }
65
66 NewTestNip47Controller(svc).
67 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
68
69 assert.Nil(t, publishedResponse.Error)
70 infoResponse := publishedResponse.Result.(*getInfoResponse)
71 assert.Nil(t, infoResponse.Alias)
72 assert.Nil(t, infoResponse.Color)
73 assert.Nil(t, infoResponse.Pubkey)
74 assert.Nil(t, infoResponse.Network)
75 assert.Nil(t, infoResponse.BlockHeight)
76 assert.Nil(t, infoResponse.BlockHash)
77 require.NotNil(t, infoResponse.LightningAddress)
78 assert.Equal(t, lightningAddress, *infoResponse.LightningAddress)
79 // get_info method is always granted, but does not return pubkey
80 assert.Contains(t, infoResponse.Methods, models.GET_INFO_METHOD)
81 assert.Equal(t, []string{}, infoResponse.Notifications)
82 require.NotNil(t, infoResponse.Metadata)
83 assert.Equal(t, float64(123), infoResponse.Metadata.(map[string]interface{})["a"])
84 assert.Equal(t, app.ID, infoResponse.Metadata.(map[string]interface{})["id"])
85 assert.Equal(t, app.Name, infoResponse.Metadata.(map[string]interface{})["name"])
86 }
87
88 func TestHandleGetInfoEvent_SubwalletNoPermission(t *testing.T) {
89 ctx := context.TODO()
90 svc, err := tests.CreateTestService(t)
91 require.NoError(t, err)
92 defer svc.Remove()
93
94 lightningAddress := "hello@getalby.com"
95
96 metadata := map[string]interface{}{
97 constants.METADATA_APPSTORE_APP_ID_KEY: constants.SUBWALLET_APPSTORE_APP_ID,
98 "lud16": lightningAddress,
99 }
100
101 svc.Cfg.SetUpdate("LNBackendType", config.LDKBackendType, "")
102
103 app, _, err := svc.AppsService.CreateApp("test", "", 0, "monthly", nil, []string{constants.GET_INFO_SCOPE}, true, metadata)
104 assert.NoError(t, err)
105
106 nip47Request := &models.Request{}
107 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
108 assert.NoError(t, err)
109
110 dbRequestEvent := &db.RequestEvent{}
111 err = svc.DB.Create(&dbRequestEvent).Error
112 assert.NoError(t, err)
113
114 // delete the existing app permissions (the app was created with get_info scope)
115 svc.DB.Exec("delete from app_permissions")
116
117 appPermission := &db.AppPermission{
118 AppId: app.ID,
119 Scope: constants.GET_BALANCE_SCOPE,
120 ExpiresAt: nil,
121 }
122 err = svc.DB.Create(appPermission).Error
123 assert.NoError(t, err)
124
125 var publishedResponse *models.Response
126
127 publishResponse := func(response *models.Response, tags nostr.Tags) {
128 publishedResponse = response
129 }
130
131 NewTestNip47Controller(svc).
132 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
133
134 assert.Nil(t, publishedResponse.Error)
135 infoResponse := publishedResponse.Result.(*getInfoResponse)
136 assert.Nil(t, infoResponse.Alias)
137 assert.Nil(t, infoResponse.Color)
138 assert.Nil(t, infoResponse.Pubkey)
139 assert.Nil(t, infoResponse.Network)
140 assert.Nil(t, infoResponse.BlockHeight)
141 assert.Nil(t, infoResponse.BlockHash)
142 require.NotNil(t, infoResponse.LightningAddress)
143 assert.Equal(t, lightningAddress, *infoResponse.LightningAddress)
144 // get_info method is always granted, but does not return pubkey
145 assert.Contains(t, infoResponse.Methods, models.GET_INFO_METHOD)
146 assert.Equal(t, []string{}, infoResponse.Notifications)
147 require.NotNil(t, infoResponse.Metadata)
148 assert.Equal(t, lightningAddress, infoResponse.Metadata.(map[string]interface{})["lud16"])
149 assert.Equal(t, app.ID, infoResponse.Metadata.(map[string]interface{})["id"])
150 assert.Equal(t, app.Name, infoResponse.Metadata.(map[string]interface{})["name"])
151 }
152
153 func TestHandleGetInfoEvent_WithPermission(t *testing.T) {
154 ctx := context.TODO()
155 svc, err := tests.CreateTestService(t)
156 require.NoError(t, err)
157 defer svc.Remove()
158
159 app, _, err := tests.CreateApp(svc)
160 assert.NoError(t, err)
161
162 nip47Request := &models.Request{}
163 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
164 assert.NoError(t, err)
165
166 dbRequestEvent := &db.RequestEvent{}
167 err = svc.DB.Create(&dbRequestEvent).Error
168 assert.NoError(t, err)
169
170 appPermission := &db.AppPermission{
171 AppId: app.ID,
172 Scope: constants.GET_INFO_SCOPE,
173 ExpiresAt: nil,
174 }
175 err = svc.DB.Create(appPermission).Error
176 assert.NoError(t, err)
177
178 var publishedResponse *models.Response
179
180 publishResponse := func(response *models.Response, tags nostr.Tags) {
181 publishedResponse = response
182 }
183
184 NewTestNip47Controller(svc).
185 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
186
187 assert.Nil(t, publishedResponse.Error)
188 infoResponse := publishedResponse.Result.(*getInfoResponse)
189 assert.Equal(t, tests.MockNodeInfo.Alias, *infoResponse.Alias)
190 assert.Equal(t, tests.MockNodeInfo.Color, *infoResponse.Color)
191 assert.Equal(t, tests.MockNodeInfo.Pubkey, *infoResponse.Pubkey)
192 assert.Equal(t, tests.MockNodeInfo.Network, *infoResponse.Network)
193 assert.Equal(t, tests.MockNodeInfo.BlockHeight, *infoResponse.BlockHeight)
194 assert.Equal(t, tests.MockNodeInfo.BlockHash, *infoResponse.BlockHash)
195 assert.Contains(t, infoResponse.Methods, "get_info")
196 assert.Equal(t, []string{}, infoResponse.Notifications)
197 }
198
199 func TestHandleGetInfoEvent_WithMetadata(t *testing.T) {
200 ctx := context.TODO()
201 svc, err := tests.CreateTestService(t)
202 require.NoError(t, err)
203 defer svc.Remove()
204
205 lightningAddress := "hello@getalby.com"
206 svc.Cfg.SetUpdate("AlbyLightningAddress", lightningAddress, "")
207
208 metadata := map[string]interface{}{
209 "a": 123,
210 }
211
212 app, _, err := svc.AppsService.CreateApp("test", "", 0, "monthly", nil, []string{constants.GET_INFO_SCOPE}, false, metadata)
213 assert.NoError(t, err)
214
215 nip47Request := &models.Request{}
216 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
217 assert.NoError(t, err)
218
219 dbRequestEvent := &db.RequestEvent{}
220 err = svc.DB.Create(&dbRequestEvent).Error
221 assert.NoError(t, err)
222
223 appPermission := &db.AppPermission{
224 AppId: app.ID,
225 Scope: constants.GET_INFO_SCOPE,
226 ExpiresAt: nil,
227 }
228 err = svc.DB.Create(appPermission).Error
229 assert.NoError(t, err)
230
231 var publishedResponse *models.Response
232
233 publishResponse := func(response *models.Response, tags nostr.Tags) {
234 publishedResponse = response
235 }
236
237 NewTestNip47Controller(svc).
238 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
239
240 assert.Nil(t, publishedResponse.Error)
241 infoResponse := publishedResponse.Result.(*getInfoResponse)
242 assert.Equal(t, tests.MockNodeInfo.Alias, *infoResponse.Alias)
243 assert.Equal(t, tests.MockNodeInfo.Color, *infoResponse.Color)
244 assert.Equal(t, tests.MockNodeInfo.Pubkey, *infoResponse.Pubkey)
245 assert.Equal(t, tests.MockNodeInfo.Network, *infoResponse.Network)
246 assert.Equal(t, tests.MockNodeInfo.BlockHeight, *infoResponse.BlockHeight)
247 assert.Equal(t, tests.MockNodeInfo.BlockHash, *infoResponse.BlockHash)
248 assert.Equal(t, lightningAddress, *infoResponse.LightningAddress)
249 assert.Contains(t, infoResponse.Methods, "get_info")
250 assert.Equal(t, []string{}, infoResponse.Notifications)
251 assert.Equal(t, float64(123), infoResponse.Metadata.(map[string]interface{})["a"])
252 }
253
254 func TestHandleGetInfoEvent_SubwalletWithMetadata(t *testing.T) {
255 ctx := context.TODO()
256 svc, err := tests.CreateTestService(t)
257 require.NoError(t, err)
258 defer svc.Remove()
259
260 lightningAddress := "hello@getalby.com"
261
262 metadata := map[string]interface{}{
263 constants.METADATA_APPSTORE_APP_ID_KEY: constants.SUBWALLET_APPSTORE_APP_ID,
264 "lud16": lightningAddress,
265 "a": 123,
266 }
267
268 svc.Cfg.SetUpdate("LNBackendType", config.LDKBackendType, "")
269 app, _, err := svc.AppsService.CreateApp("test", "", 0, "monthly", nil, []string{constants.GET_INFO_SCOPE}, true, metadata)
270 assert.NoError(t, err)
271
272 nip47Request := &models.Request{}
273 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
274 assert.NoError(t, err)
275
276 dbRequestEvent := &db.RequestEvent{}
277 err = svc.DB.Create(&dbRequestEvent).Error
278 assert.NoError(t, err)
279
280 appPermission := &db.AppPermission{
281 AppId: app.ID,
282 Scope: constants.GET_INFO_SCOPE,
283 ExpiresAt: nil,
284 }
285 err = svc.DB.Create(appPermission).Error
286 assert.NoError(t, err)
287
288 var publishedResponse *models.Response
289
290 publishResponse := func(response *models.Response, tags nostr.Tags) {
291 publishedResponse = response
292 }
293
294 NewTestNip47Controller(svc).
295 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
296
297 assert.Nil(t, publishedResponse.Error)
298 infoResponse := publishedResponse.Result.(*getInfoResponse)
299 assert.Equal(t, tests.MockNodeInfo.Alias, *infoResponse.Alias)
300 assert.Equal(t, tests.MockNodeInfo.Color, *infoResponse.Color)
301 assert.Equal(t, tests.MockNodeInfo.Pubkey, *infoResponse.Pubkey)
302 assert.Equal(t, tests.MockNodeInfo.Network, *infoResponse.Network)
303 assert.Equal(t, tests.MockNodeInfo.BlockHeight, *infoResponse.BlockHeight)
304 assert.Equal(t, tests.MockNodeInfo.BlockHash, *infoResponse.BlockHash)
305 assert.Equal(t, lightningAddress, *infoResponse.LightningAddress)
306 assert.Contains(t, infoResponse.Methods, "get_info")
307 assert.Equal(t, []string{}, infoResponse.Notifications)
308 assert.Equal(t, float64(123), infoResponse.Metadata.(map[string]interface{})["a"])
309 }
310
311 func TestHandleGetInfoEvent_WithNotifications(t *testing.T) {
312 ctx := context.TODO()
313 svc, err := tests.CreateTestService(t)
314 require.NoError(t, err)
315 defer svc.Remove()
316
317 app, _, err := tests.CreateApp(svc)
318 assert.NoError(t, err)
319
320 nip47Request := &models.Request{}
321 err = json.Unmarshal([]byte(nip47GetInfoJson), nip47Request)
322 assert.NoError(t, err)
323
324 dbRequestEvent := &db.RequestEvent{}
325 err = svc.DB.Create(&dbRequestEvent).Error
326 assert.NoError(t, err)
327
328 appPermission := &db.AppPermission{
329 AppId: app.ID,
330 Scope: constants.GET_INFO_SCOPE,
331 ExpiresAt: nil,
332 }
333 err = svc.DB.Create(appPermission).Error
334 assert.NoError(t, err)
335
336 appPermission = &db.AppPermission{
337 AppId: app.ID,
338 Scope: constants.NOTIFICATIONS_SCOPE,
339 ExpiresAt: nil,
340 }
341 err = svc.DB.Create(appPermission).Error
342 assert.NoError(t, err)
343
344 var publishedResponse *models.Response
345
346 publishResponse := func(response *models.Response, tags nostr.Tags) {
347 publishedResponse = response
348 }
349
350 NewTestNip47Controller(svc).
351 HandleGetInfoEvent(ctx, nip47Request, dbRequestEvent.ID, app, publishResponse)
352
353 assert.Nil(t, publishedResponse.Error)
354 infoResponse := publishedResponse.Result.(*getInfoResponse)
355 assert.Equal(t, tests.MockNodeInfo.Alias, *infoResponse.Alias)
356 assert.Equal(t, tests.MockNodeInfo.Color, *infoResponse.Color)
357 assert.Equal(t, tests.MockNodeInfo.Pubkey, *infoResponse.Pubkey)
358 assert.Equal(t, tests.MockNodeInfo.Network, *infoResponse.Network)
359 assert.Equal(t, tests.MockNodeInfo.BlockHeight, *infoResponse.BlockHeight)
360 assert.Equal(t, tests.MockNodeInfo.BlockHash, *infoResponse.BlockHash)
361 assert.Contains(t, infoResponse.Methods, "get_info")
362 assert.Equal(t, []string{"payment_received", "payment_sent"}, infoResponse.Notifications)
363 }
364