@@ -11,7 +11,7 @@ import querystring from 'querystring';
1111
1212import { ApiResponseError , BitGoRequest } from '@bitgo/sdk-core' ;
1313
14- import { AuthVersion , VerifyResponseOptions } from './types' ;
14+ import { AuthVersion , VerifyResponseInfo , VerifyResponseOptions } from './types' ;
1515import { BitGoAPI } from './bitgoAPI' ;
1616
1717const debug = Debug ( 'bitgo:api' ) ;
@@ -214,44 +214,23 @@ export function setRequestQueryString(req: superagent.SuperAgentRequest): void {
214214}
215215
216216/**
217- * Verify that the response received from the server is signed correctly.
218- * Right now, it is very permissive with the timestamp variance .
217+ * Validate a completed verification response and throw a descriptive `ApiResponseError` if it
218+ * indicates the response is invalid or outside the acceptable time window .
219219 */
220- export function verifyResponse (
220+ function assertVerificationResponse (
221221 bitgo : BitGoAPI ,
222222 token : string | undefined ,
223- method : VerifyResponseOptions [ 'method' ] ,
224223 req : superagent . SuperAgentRequest ,
225224 response : superagent . Response ,
226- authVersion : AuthVersion
227- ) : superagent . Response {
228- // we can't verify the response if we're not authenticated
229- if ( ! req . isV2Authenticated || ! req . authenticationToken ) {
230- return response ;
231- }
232-
233- const verificationResponse = bitgo . verifyResponse ( {
234- url : req . url ,
235- hmac : response . header . hmac ,
236- statusCode : response . status ,
237- text : response . text ,
238- timestamp : response . header . timestamp ,
239- token : req . authenticationToken ,
240- method,
241- authVersion,
242- } ) ;
243-
225+ verificationResponse : VerifyResponseInfo
226+ ) : void {
244227 if ( ! verificationResponse . isValid ) {
245- // calculate the HMAC
246- const receivedHmac = response . header . hmac ;
247- const expectedHmac = verificationResponse . expectedHmac ;
248- const signatureSubject = verificationResponse . signatureSubject ;
249228 // Log only the first 10 characters of the token to ensure the full token isn't logged.
250229 const partialBitgoToken = token ? token . substring ( 0 , 10 ) : '' ;
251230 const errorDetails = {
252- expectedHmac,
253- receivedHmac,
254- hmacInput : signatureSubject ,
231+ expectedHmac : verificationResponse . expectedHmac ,
232+ receivedHmac : response . header . hmac ,
233+ hmacInput : verificationResponse . signatureSubject ,
255234 requestToken : req . authenticationToken ,
256235 bitgoToken : partialBitgoToken ,
257236 } ;
@@ -271,5 +250,62 @@ export function verifyResponse(
271250 errorDetails
272251 ) ;
273252 }
253+ }
254+
255+ /**
256+ * Verify that the response received from the server is signed correctly.
257+ * Right now, it is very permissive with the timestamp variance.
258+ */
259+ export function verifyResponse (
260+ bitgo : BitGoAPI ,
261+ token : string | undefined ,
262+ method : VerifyResponseOptions [ 'method' ] ,
263+ req : superagent . SuperAgentRequest ,
264+ response : superagent . Response ,
265+ authVersion : AuthVersion
266+ ) : superagent . Response {
267+ if ( ! req . isV2Authenticated || ! req . authenticationToken ) {
268+ return response ;
269+ }
270+
271+ const verificationResponse = bitgo . verifyResponse ( {
272+ url : req . url ,
273+ hmac : response . header . hmac ,
274+ statusCode : response . status ,
275+ text : response . text ,
276+ timestamp : response . header . timestamp ,
277+ token : req . authenticationToken ,
278+ method,
279+ authVersion,
280+ } ) ;
281+
282+ assertVerificationResponse ( bitgo , token , req , response , verificationResponse ) ;
283+ return response ;
284+ }
285+
286+ export async function verifyResponseAsync (
287+ bitgo : BitGoAPI ,
288+ token : string | undefined ,
289+ method : VerifyResponseOptions [ 'method' ] ,
290+ req : superagent . SuperAgentRequest ,
291+ response : superagent . Response ,
292+ authVersion : AuthVersion
293+ ) : Promise < superagent . Response > {
294+ if ( ! req . isV2Authenticated || ! req . authenticationToken ) {
295+ return response ;
296+ }
297+
298+ const verificationResponse = await bitgo . verifyResponseAsync ( {
299+ url : req . url ,
300+ hmac : response . header . hmac ,
301+ statusCode : response . status ,
302+ text : response . text ,
303+ timestamp : response . header . timestamp ,
304+ token : req . authenticationToken ,
305+ method,
306+ authVersion,
307+ } ) ;
308+
309+ assertVerificationResponse ( bitgo , token , req , response , verificationResponse ) ;
274310 return response ;
275311}
0 commit comments