@@ -7,17 +7,12 @@ chai.use(sinonChai)
77chai . use ( chaiAsPromised )
88const { expect } = chai
99
10- import * as settingsFactory from '../../../../src/factories/settings-factory'
1110import { InvoiceStatus , InvoiceUnit } from '../../../../src/@types/invoice'
1211import { hmacSha256 } from '../../../../src/utils/secret'
1312import { NodelessCallbackController } from '../../../../src/controllers/callbacks/nodeless-callback-controller'
1413
1514const PUBKEY = 'a' . repeat ( 64 )
1615
17- const baseSettings : any = {
18- payments : { processor : 'nodeless' } ,
19- }
20-
2116const validBody = {
2217 uuid : 'nodeless-invoice-id' ,
2318 status : 'paid' ,
@@ -84,15 +79,13 @@ const makeReq = (overrides: any = {}): any => {
8479}
8580
8681describe ( 'NodelessCallbackController' , ( ) => {
87- let createSettingsStub : sinon . SinonStub
8882 let consoleErrorStub : sinon . SinonStub
8983 let previousWebhookSecret : string | undefined
9084
9185 beforeEach ( ( ) => {
9286 previousWebhookSecret = process . env . NODELESS_WEBHOOK_SECRET
9387 process . env . NODELESS_WEBHOOK_SECRET = 'nodeless-test-secret'
9488
95- createSettingsStub = sinon . stub ( settingsFactory , 'createSettings' ) . returns ( baseSettings )
9689 consoleErrorStub = sinon . stub ( console , 'error' )
9790 } )
9891
@@ -103,7 +96,6 @@ describe('NodelessCallbackController', () => {
10396 process . env . NODELESS_WEBHOOK_SECRET = previousWebhookSecret
10497 }
10598
106- createSettingsStub . restore ( )
10799 consoleErrorStub . restore ( )
108100 } )
109101
@@ -119,28 +111,58 @@ describe('NodelessCallbackController', () => {
119111 expect ( res . send ) . to . have . been . calledWith ( '{"status":"error","message":"Malformed body"}' )
120112 } )
121113
122- it ( 'returns 403 when callback signature is invalid' , async ( ) => {
114+ it ( 'returns 400 when callback signature has invalid format ' , async ( ) => {
123115 const { controller, paymentsService } = makeController ( )
124116 const res = makeRes ( )
125117
126118 await controller . handleRequest ( makeReq ( { signature : 'invalid-signature' } ) , res )
127119
128- expect ( res . status ) . to . have . been . calledWith ( 403 )
129- expect ( res . send ) . to . have . been . calledWith ( 'Forbidden ' )
120+ expect ( res . status ) . to . have . been . calledWith ( 400 )
121+ expect ( res . send ) . to . have . been . calledWith ( '{"status":"error","message":"Invalid signature"} ' )
130122 expect ( paymentsService . updateInvoiceStatus ) . to . not . have . been . called
131123 } )
132124
133- it ( 'returns 403 when nodeless is not the configured processor' , async ( ) => {
134- createSettingsStub . returns ( { payments : { processor : 'zebedee' } } )
125+ it ( 'returns 400 when callback signature has wrong length' , async ( ) => {
135126 const { controller, paymentsService } = makeController ( )
136127 const res = makeRes ( )
137128
138- await controller . handleRequest ( makeReq ( ) , res )
129+ await controller . handleRequest ( makeReq ( { signature : '0' . repeat ( 63 ) } ) , res )
130+
131+ expect ( res . status ) . to . have . been . calledWith ( 400 )
132+ expect ( res . send ) . to . have . been . calledWith ( '{"status":"error","message":"Invalid signature"}' )
133+ expect ( paymentsService . updateInvoiceStatus ) . to . not . have . been . called
134+ } )
135+
136+ it ( 'returns 403 when callback signature is a valid-length hex string but does not match' , async ( ) => {
137+ const { controller, paymentsService } = makeController ( )
138+ const res = makeRes ( )
139+
140+ await controller . handleRequest ( makeReq ( { signature : '0' . repeat ( 64 ) } ) , res )
139141
140142 expect ( res . status ) . to . have . been . calledWith ( 403 )
141143 expect ( res . send ) . to . have . been . calledWith ( 'Forbidden' )
142144 expect ( paymentsService . updateInvoiceStatus ) . to . not . have . been . called
143145 } )
146+
147+ it ( 'returns 500 when NODELESS_WEBHOOK_SECRET is not configured' , async ( ) => {
148+ delete process . env . NODELESS_WEBHOOK_SECRET
149+ const { controller, paymentsService } = makeController ( )
150+ const res = makeRes ( )
151+ const rawBody = Buffer . from ( JSON . stringify ( validBody ) )
152+ const req = {
153+ headers : { 'nodeless-signature' : 'does-not-matter' } ,
154+ body : validBody ,
155+ rawBody,
156+ }
157+
158+ await controller . handleRequest ( req as any , res )
159+
160+ expect ( res . status ) . to . have . been . calledWith ( 500 )
161+ expect ( res . setHeader ) . to . have . been . calledWith ( 'content-type' , 'application/json; charset=utf8' )
162+ expect ( res . send ) . to . have . been . calledWith ( '{"status":"error","message":"Internal Server Error"}' )
163+ expect ( paymentsService . updateInvoiceStatus ) . to . not . have . been . called
164+ } )
165+
144166 } )
145167
146168 describe ( 'invoice state handling' , ( ) => {
0 commit comments