function validateAndEnqueueSignRequest(sender, request, errorCb, successCb) {
  function timeout() {
    errorCb({errorCode: ErrorCodes.TIMEOUT});
  }

  if (!isValidSignRequest(request)) {
    errorCb({errorCode: ErrorCodes.BAD_REQUEST});
    return null;
  }

  // The typecast is necessary because getSignChallenges can return undefined.
  // On the other hand, a valid sign request can't contain an undefined sign
  // challenge list, so the typecast is safe.
  var signChallenges =
      /** @type {!Array<SignChallenge>} */ (getSignChallenges(request));
  var appId;
  if (request['appId']) {
    appId = request['appId'];
  } else if (signChallenges.length) {
    appId = signChallenges[0]['appId'];
  }
  // Sanity check
  if (!appId) {
    console.warn(UTIL_fmt('empty sign appId?'));
    errorCb({errorCode: ErrorCodes.BAD_REQUEST});
    return null;
  }
  var timeoutValueSeconds = getTimeoutValueFromRequest(request);
  // Attenuate watchdog timeout value less than the signer's timeout, so the
  // watchdog only fires after the signer could reasonably have called back,
  // not before.
  timeoutValueSeconds = attenuateTimeoutInSeconds(
      timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
  var watchdog = new WatchdogRequestHandler(timeoutValueSeconds, timeout);
  var wrappedErrorCb = watchdog.wrapCallback(errorCb);
  var wrappedSuccessCb = watchdog.wrapCallback(successCb);

  var timer = createAttenuatedTimer(
      FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
  var logMsgUrl = request['logMsgUrl'];

  // Queue sign requests from the same origin, to protect against simultaneous
  // sign-out on many tabs resulting in repeated sign-in requests.
  var queuedSignRequest = new QueuedSignRequest(
      signChallenges, timer, sender, wrappedErrorCb, wrappedSuccessCb,
      request['challenge'], appId, logMsgUrl);
  if (!gnubbySignRequestQueue) {
    initRequestQueue();
  }
  var requestToken = gnubbySignRequestQueue.queueRequest(
      appId, sender.origin, queuedSignRequest.begin.bind(queuedSignRequest),
      timer);
  queuedSignRequest.setToken(requestToken);

  watchdog.setCloseable(queuedSignRequest);
  return watchdog;
}
/**
 * Validates a sign request using the given sign challenges name, and, if valid,
 * enqueues the sign request for eventual processing.
 * @param {WebRequestSender} sender The sender of the message.
 * @param {Object} request The web page's sign request.
 * @param {function(U2fError)} errorCb Error callback.
 * @param {function(SignChallenge, string, string)} successCb Success callback.
 * @return {Closeable} Request handler that should be closed when the browser
 *     message channel is closed.
 */
Validates a sign request using the given sign challenges name, and, if valid,
enqueues the sign request for eventual processing.
@param {WebRequestSender} sender The sender of the message.
@param {Object} request The web page's sign request.
@param {function(U2fError)} errorCb Error callback.
@param {function(SignChallenge, string, string)} successCb Success callback.
@return {Closeable} Request handler that should be closed when the browser
message channel is closed.
Validates a sign request using the given sign challenges name and if valid enqueues the sign request for eventual processing . @param { WebRequestSender } sender The sender of the message . @param { Object } request The web page ' s sign request . @param { function ( U2fError ) } errorCb Error callback . @param { function ( SignChallenge string string ) } successCb Success callback . @return { Closeable } Request handler that should be closed when the browser message channel is closed .
function validateAndEnqueueSignRequest(sender, request, errorCb, successCb) {
  function timeout() {
    errorCb({errorCode: ErrorCodes.TIMEOUT});
  }
  if (!isValidSignRequest(request)) {
    errorCb({errorCode: ErrorCodes.BAD_REQUEST});
    return null;
  }
  var signChallenges =
       (getSignChallenges(request));
  var appId;
  if (request['appId']) {
    appId = request['appId'];
  } else if (signChallenges.length) {
    appId = signChallenges[0]['appId'];
  }
  if (!appId) {
    console.warn(UTIL_fmt('empty sign appId?'));
    errorCb({errorCode: ErrorCodes.BAD_REQUEST});
    return null;
  }
  var timeoutValueSeconds = getTimeoutValueFromRequest(request);
  timeoutValueSeconds = attenuateTimeoutInSeconds(
      timeoutValueSeconds, MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2);
  var watchdog = new WatchdogRequestHandler(timeoutValueSeconds, timeout);
  var wrappedErrorCb = watchdog.wrapCallback(errorCb);
  var wrappedSuccessCb = watchdog.wrapCallback(successCb);
  var timer = createAttenuatedTimer(
      FACTORY_REGISTRY.getCountdownFactory(), timeoutValueSeconds);
  var logMsgUrl = request['logMsgUrl'];
  var queuedSignRequest = new QueuedSignRequest(
      signChallenges, timer, sender, wrappedErrorCb, wrappedSuccessCb,
      request['challenge'], appId, logMsgUrl);
  if (!gnubbySignRequestQueue) {
    initRequestQueue();
  }
  var requestToken = gnubbySignRequestQueue.queueRequest(
      appId, sender.origin, queuedSignRequest.begin.bind(queuedSignRequest),
      timer);
  queuedSignRequest.setToken(requestToken);
  watchdog.setCloseable(queuedSignRequest);
  return watchdog;
}
function validateAndEnqueueSignRequest ( sender , request , errorCb , successCb ) { function timeout ( ) { errorCb ( { errorCode : ErrorCodes . TIMEOUT } ) ; } if ( ! isValidSignRequest ( request ) ) { errorCb ( { errorCode : ErrorCodes . BAD_REQUEST } ) ; return null ; } var signChallenges = ( getSignChallenges ( request ) ) ; var appId ; if ( request [ 'appId' ] ) { appId = request [ 'appId' ] ; } else if ( signChallenges . length ) { appId = signChallenges [ 0 ] [ 'appId' ] ; } if ( ! appId ) { console . warn ( UTIL_fmt ( 'empty sign appId?' ) ) ; errorCb ( { errorCode : ErrorCodes . BAD_REQUEST } ) ; return null ; } var timeoutValueSeconds = getTimeoutValueFromRequest ( request ) ; timeoutValueSeconds = attenuateTimeoutInSeconds ( timeoutValueSeconds , MINIMUM_TIMEOUT_ATTENUATION_SECONDS / 2 ) ; var watchdog = new WatchdogRequestHandler ( timeoutValueSeconds , timeout ) ; var wrappedErrorCb = watchdog . wrapCallback ( errorCb ) ; var wrappedSuccessCb = watchdog . wrapCallback ( successCb ) ; var timer = createAttenuatedTimer ( FACTORY_REGISTRY . getCountdownFactory ( ) , timeoutValueSeconds ) ; var logMsgUrl = request [ 'logMsgUrl' ] ; var queuedSignRequest = new QueuedSignRequest ( signChallenges , timer , sender , wrappedErrorCb , wrappedSuccessCb , request [ 'challenge' ] , appId , logMsgUrl ) ; if ( ! gnubbySignRequestQueue ) { initRequestQueue ( ) ; } var requestToken = gnubbySignRequestQueue . queueRequest ( appId , sender . origin , queuedSignRequest . begin . bind ( queuedSignRequest ) , timer ) ; queuedSignRequest . setToken ( requestToken ) ; watchdog . setCloseable ( queuedSignRequest ) ; return watchdog ; }
Validates a sign request using the given sign challenges name, and, if valid,
 enqueues the sign request for eventual processing.
Validates a sign request using the given sign challenges name and if valid enqueues the sign request for eventual processing .
// The typecast is necessary because getSignChallenges can return undefined. // On the other hand, a valid sign request can't contain an undefined sign // challenge list, so the typecast is safe. /** @type {!Array<SignChallenge>} */ // Sanity check // Attenuate watchdog timeout value less than the signer's timeout, so the // watchdog only fires after the signer could reasonably have called back, // not before. // Queue sign requests from the same origin, to protect against simultaneous // sign-out on many tabs resulting in repeated sign-in requests.