@@ -7,114 +7,145 @@ var systemUnderTest = proxyquire('../../dist/http-handler', {
77 'raw-body' : getRawBodyStub
88} ) ;
99var createHTTPHandler = systemUnderTest . createHTTPHandler ;
10+ var verifyRequestSignature = systemUnderTest . verifyRequestSignature ;
1011
1112// fixtures
1213var correctSigningSecret = 'SIGNING_SECRET' ;
1314var correctRawBody = '{"type":"event_callback","event":{"type":"reaction_added",' +
1415'"user":"U123","item":{"type":"message","channel":"C123"}}}' ;
1516
16- describe ( 'createHTTPHandler ' , function ( ) {
17+ describe ( 'http-handler ' , function ( ) {
1718 beforeEach ( function ( ) {
18- this . emit = sinon . stub ( ) ;
19- this . res = sinon . stub ( {
20- setHeader : function ( ) { } ,
21- send : function ( ) { } ,
22- end : function ( ) { }
23- } ) ;
24- this . next = sinon . stub ( ) ;
2519 this . correctDate = Math . floor ( Date . now ( ) / 1000 ) ;
26- this . requestListener = createHTTPHandler ( {
27- signingSecret : correctSigningSecret ,
28- emit : this . emit
29- } ) ;
3020 } ) ;
3121
32- it ( 'should verify a correct signing secret' , function ( done ) {
33- var emit = this . emit ;
34- var res = this . res ;
35- var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
36- emit . resolves ( { status : 200 } ) ;
37- getRawBodyStub . resolves ( correctRawBody ) ;
38- res . end . callsFake ( function ( ) {
39- assert . equal ( res . statusCode , 200 ) ;
40- done ( ) ;
22+ describe ( 'verifyRequestSignature' , function ( ) {
23+ it ( 'should return true for a valid request' , function ( ) {
24+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
25+ var isVerified = verifyRequestSignature ( {
26+ signingSecret : correctSigningSecret ,
27+ requestTimestamp : req . headers [ 'x-slack-request-timestamp' ] ,
28+ requestSignature : req . headers [ 'x-slack-signature' ] ,
29+ body : req . body
30+ } ) ;
31+
32+ assert . isTrue ( isVerified ) ;
4133 } ) ;
42- this . requestListener ( req , res ) ;
43- } ) ;
4434
45- it ( 'should fail request signing verification with an incorrect signing secret' , function ( done ) {
46- var res = this . res ;
47- var req = createRequest ( 'INVALID_SECRET' , this . correctDate , correctRawBody ) ;
48- getRawBodyStub . resolves ( correctRawBody ) ;
49- res . end . callsFake ( function ( ) {
50- assert . equal ( res . statusCode , 404 ) ;
51- done ( ) ;
35+ it ( 'should throw for a request signed with a different secret' , function ( ) {
36+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
37+ assert . throws ( ( ) => verifyRequestSignature ( {
38+ signingSecret : 'INVALID_SECRET' ,
39+ requestTimestamp : req . headers [ 'x-slack-request-timestamp' ] ,
40+ requestSignature : req . headers [ 'x-slack-signature' ] ,
41+ body : req . body
42+ } ) , 'Slack request signing verification failed' ) ;
5243 } ) ;
53- this . requestListener ( req , res ) ;
5444 } ) ;
5545
56- it ( 'should fail request signing verification with old timestamp' , function ( done ) {
57- var res = this . res ;
58- var sixMinutesAgo = Math . floor ( Date . now ( ) / 1000 ) - ( 60 * 6 ) ;
59- var req = createRequest ( correctSigningSecret , sixMinutesAgo , correctRawBody ) ;
60- getRawBodyStub . resolves ( correctRawBody ) ;
61- res . end . callsFake ( function ( ) {
62- assert . equal ( res . statusCode , 404 ) ;
63- done ( ) ;
46+ describe ( 'createHTTPHandler' , function ( ) {
47+ beforeEach ( function ( ) {
48+ this . emit = sinon . stub ( ) ;
49+ this . res = sinon . stub ( {
50+ setHeader : function ( ) { } ,
51+ send : function ( ) { } ,
52+ end : function ( ) { }
53+ } ) ;
54+ this . next = sinon . stub ( ) ;
55+ this . correctDate = Math . floor ( Date . now ( ) / 1000 ) ;
56+ this . requestListener = createHTTPHandler ( {
57+ signingSecret : correctSigningSecret ,
58+ emit : this . emit
59+ } ) ;
6460 } ) ;
65- this . requestListener ( req , res ) ;
66- } ) ;
6761
68- it ( 'should handle unexpected error' , function ( done ) {
69- var res = this . res ;
70- var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
71- getRawBodyStub . rejects ( new Error ( 'test error' ) ) ;
72- res . end . callsFake ( function ( result ) {
73- assert . equal ( res . statusCode , 500 ) ;
74- assert . isUndefined ( result ) ;
75- done ( ) ;
62+ it ( 'should verify a correct signing secret' , function ( done ) {
63+ var emit = this . emit ;
64+ var res = this . res ;
65+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
66+ emit . resolves ( { status : 200 } ) ;
67+ getRawBodyStub . resolves ( correctRawBody ) ;
68+ res . end . callsFake ( function ( ) {
69+ assert . equal ( res . statusCode , 200 ) ;
70+ done ( ) ;
71+ } ) ;
72+ this . requestListener ( req , res ) ;
7673 } ) ;
77- this . requestListener ( req , res ) ;
78- } ) ;
7974
80- it ( 'should provide message with unexpected errors in development' , function ( done ) {
81- var res = this . res ;
82- var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
83- process . env . NODE_ENV = 'development' ;
84- getRawBodyStub . rejects ( new Error ( 'test error' ) ) ;
85- res . end . callsFake ( function ( result ) {
86- assert . equal ( res . statusCode , 500 ) ;
87- assert . equal ( result , 'test error' ) ;
88- delete process . env . NODE_ENV ;
89- done ( ) ;
75+ it ( 'should fail request signing verification with an incorrect signing secret' , function ( done ) {
76+ var res = this . res ;
77+ var req = createRequest ( 'INVALID_SECRET' , this . correctDate , correctRawBody ) ;
78+ getRawBodyStub . resolves ( correctRawBody ) ;
79+ res . end . callsFake ( function ( ) {
80+ assert . equal ( res . statusCode , 404 ) ;
81+ done ( ) ;
82+ } ) ;
83+ this . requestListener ( req , res ) ;
9084 } ) ;
91- this . requestListener ( req , res ) ;
92- } ) ;
9385
94- it ( 'should set an identification header in its responses' , function ( done ) {
95- var emit = this . emit ;
96- var res = this . res ;
97- var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
98- emit . resolves ( { status : 200 } ) ;
99- getRawBodyStub . resolves ( correctRawBody ) ;
100- res . end . callsFake ( function ( ) {
101- assert ( res . setHeader . calledWith ( 'X-Slack-Powered-By' ) ) ;
102- done ( ) ;
86+ it ( 'should fail request signing verification with old timestamp' , function ( done ) {
87+ var res = this . res ;
88+ var sixMinutesAgo = Math . floor ( Date . now ( ) / 1000 ) - ( 60 * 6 ) ;
89+ var req = createRequest ( correctSigningSecret , sixMinutesAgo , correctRawBody ) ;
90+ getRawBodyStub . resolves ( correctRawBody ) ;
91+ res . end . callsFake ( function ( ) {
92+ assert . equal ( res . statusCode , 404 ) ;
93+ done ( ) ;
94+ } ) ;
95+ this . requestListener ( req , res ) ;
96+ } ) ;
97+
98+ it ( 'should handle unexpected error' , function ( done ) {
99+ var res = this . res ;
100+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
101+ getRawBodyStub . rejects ( new Error ( 'test error' ) ) ;
102+ res . end . callsFake ( function ( result ) {
103+ assert . equal ( res . statusCode , 500 ) ;
104+ assert . isUndefined ( result ) ;
105+ done ( ) ;
106+ } ) ;
107+ this . requestListener ( req , res ) ;
108+ } ) ;
109+
110+ it ( 'should provide message with unexpected errors in development' , function ( done ) {
111+ var res = this . res ;
112+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
113+ process . env . NODE_ENV = 'development' ;
114+ getRawBodyStub . rejects ( new Error ( 'test error' ) ) ;
115+ res . end . callsFake ( function ( result ) {
116+ assert . equal ( res . statusCode , 500 ) ;
117+ assert . equal ( result , 'test error' ) ;
118+ delete process . env . NODE_ENV ;
119+ done ( ) ;
120+ } ) ;
121+ this . requestListener ( req , res ) ;
122+ } ) ;
123+
124+ it ( 'should set an identification header in its responses' , function ( done ) {
125+ var emit = this . emit ;
126+ var res = this . res ;
127+ var req = createRequest ( correctSigningSecret , this . correctDate , correctRawBody ) ;
128+ emit . resolves ( { status : 200 } ) ;
129+ getRawBodyStub . resolves ( correctRawBody ) ;
130+ res . end . callsFake ( function ( ) {
131+ assert ( res . setHeader . calledWith ( 'X-Slack-Powered-By' ) ) ;
132+ done ( ) ;
133+ } ) ;
134+ this . requestListener ( req , res ) ;
103135 } ) ;
104- this . requestListener ( req , res ) ;
105- } ) ;
106136
107- it ( 'should respond to url verification requests' , function ( done ) {
108- var res = this . res ;
109- var emit = this . emit ;
110- var urlVerificationBody = '{"type":"url_verification","challenge": "TEST_CHALLENGE"}' ;
111- var req = createRequest ( correctSigningSecret , this . correctDate , urlVerificationBody ) ;
112- getRawBodyStub . resolves ( urlVerificationBody ) ;
113- res . end . callsFake ( function ( ) {
114- assert ( emit . notCalled ) ;
115- assert . equal ( res . statusCode , 200 ) ;
116- done ( ) ;
137+ it ( 'should respond to url verification requests' , function ( done ) {
138+ var res = this . res ;
139+ var emit = this . emit ;
140+ var urlVerificationBody = '{"type":"url_verification","challenge": "TEST_CHALLENGE"}' ;
141+ var req = createRequest ( correctSigningSecret , this . correctDate , urlVerificationBody ) ;
142+ getRawBodyStub . resolves ( urlVerificationBody ) ;
143+ res . end . callsFake ( function ( ) {
144+ assert ( emit . notCalled ) ;
145+ assert . equal ( res . statusCode , 200 ) ;
146+ done ( ) ;
147+ } ) ;
148+ this . requestListener ( req , res ) ;
117149 } ) ;
118- this . requestListener ( req , res ) ;
119150 } ) ;
120151} ) ;
0 commit comments