vox-common/authentication.js
function checkStanza(hubClient, stanza, fields, author, opt_sigValue) {
  var sig = opt_sigValue === undefined ? stanza.sig : opt_sigValue;
  if (!sig) {
    throw new errors.AuthenticationError('No `sig` field in stanza');
  }
  if (!stanza.updatedAt || typeof(stanza.updatedAt) != 'number') {
    throw new errors.AuthenticationError('Invalid `updatedAt` field in stanza');
  }
  return hubClient.getUserProfile(author, stanza.updatedAt)
    .then(function(userProfile) {
      var verifier = ursa.createVerifier('sha1');
      updateWithFields(verifier, stanza, fields);
      var pubkeyStr = userProfile.pubkey;
      var pubkey = ursa.createPublicKey(pubkeyStr);
      var ok = verifier.verify(pubkey, stanza.sig, 'base64');
      if (ok) {
        return true;
      }
      debug('First verification failed', author);
      // The signatures do not match.  Refetch the author's profile directly
      // from the hub, then try again.
      if (Date.now() - userProfile.syncedAt < MIN_ENTITY_RESYNC_MS) {
        debug('Not refetching user profile', author);
        return false;
      }
      return hubClient.getUserProfileFromHub(author, stanza.updatedAt)
        .then(function(userProfile) {
          // The pubkeys are still the same, so don't bother re-checking.
          if (userProfile.pubkey == pubkeyStr) {
            debug('Pubkeys identical, not reverifying', author);
            return false;
          }
          // The pubkeys are different, so perhaps that's why the first check
          // failed.
          var pubkey = ursa.createPublicKey(userProfile.pubkey);
          return verifier.verify(userProfile.pubkey, sig, 'base64');
        })
    })
    .catch(errors.NotFoundError, function(err) {
      throw new errors.AuthenticationError(
          'No such user registered with the Hub: ' + author);
    })
    .then(function(ok) {
      if (!ok) {
        throw new errors.AuthenticationError('Stanza signatures do not match for user ' + author);
      }
      return ok;
    });
}
function checkStanza(hubClient, stanza, fields, author, opt_sigValue) {
  var sig = opt_sigValue === undefined ? stanza.sig : opt_sigValue;
  if (!sig) {
    throw new errors.AuthenticationError('No `sig` field in stanza');
  }
  if (!stanza.updatedAt || typeof(stanza.updatedAt) != 'number') {
    throw new errors.AuthenticationError('Invalid `updatedAt` field in stanza');
  }
  return hubClient.getUserProfile(author, stanza.updatedAt)
    .then(function(userProfile) {
      var verifier = ursa.createVerifier('sha1');
      updateWithFields(verifier, stanza, fields);
      var pubkeyStr = userProfile.pubkey;
      var pubkey = ursa.createPublicKey(pubkeyStr);
      var ok = verifier.verify(pubkey, stanza.sig, 'base64');
      if (ok) {
        return true;
      }
      debug('First verification failed', author);
      // The signatures do not match.  Refetch the author's profile directly
      // from the hub, then try again.
      if (Date.now() - userProfile.syncedAt < MIN_ENTITY_RESYNC_MS) {
        debug('Not refetching user profile', author);
        return false;
      }
      return hubClient.getUserProfileFromHub(author, stanza.updatedAt)
        .then(function(userProfile) {
          // The pubkeys are still the same, so don't bother re-checking.
          if (userProfile.pubkey == pubkeyStr) {
            debug('Pubkeys identical, not reverifying', author);
            return false;
          }
          // The pubkeys are different, so perhaps that's why the first check
          // failed.
          var pubkey = ursa.createPublicKey(userProfile.pubkey);
          return verifier.verify(userProfile.pubkey, sig, 'base64');
        })
    })
    .catch(errors.NotFoundError, function(err) {
      throw new errors.AuthenticationError(
          'No such user registered with the Hub: ' + author);
    })
    .then(function(ok) {
      if (!ok) {
        throw new errors.AuthenticationError('Stanza signatures do not match for user ' + author);
      }
      return ok;
    });
}
function checkStanza ( hubClient , stanza , fields , author , opt_sigValue ) { var sig = opt_sigValue === undefined ? stanza . sig : opt_sigValue ; if ( ! sig ) { throw new errors . AuthenticationError ( 'No `sig` field in stanza' ) ; } if ( ! stanza . updatedAt || typeof ( stanza . updatedAt ) != 'number' ) { throw new errors . AuthenticationError ( 'Invalid `updatedAt` field in stanza' ) ; } return hubClient . getUserProfile ( author , stanza . updatedAt ) . then ( function ( userProfile ) { var verifier = ursa . createVerifier ( 'sha1' ) ; updateWithFields ( verifier , stanza , fields ) ; var pubkeyStr = userProfile . pubkey ; var pubkey = ursa . createPublicKey ( pubkeyStr ) ; var ok = verifier . verify ( pubkey , stanza . sig , 'base64' ) ; if ( ok ) { return true ; } debug ( 'First verification failed' , author ) ; // The signatures do not match.  Refetch the author's profile directly // from the hub, then try again. if ( Date . now ( ) - userProfile . syncedAt < MIN_ENTITY_RESYNC_MS ) { debug ( 'Not refetching user profile' , author ) ; return false ; } return hubClient . getUserProfileFromHub ( author , stanza . updatedAt ) . then ( function ( userProfile ) { // The pubkeys are still the same, so don't bother re-checking. if ( userProfile . pubkey == pubkeyStr ) { debug ( 'Pubkeys identical, not reverifying' , author ) ; return false ; } // The pubkeys are different, so perhaps that's why the first check // failed. var pubkey = ursa . createPublicKey ( userProfile . pubkey ) ; return verifier . verify ( userProfile . pubkey , sig , 'base64' ) ; } ) } ) . catch ( errors . NotFoundError , function ( err ) { throw new errors . AuthenticationError ( 'No such user registered with the Hub: ' + author ) ; } ) . then ( function ( ok ) { if ( ! ok ) { throw new errors . AuthenticationError ( 'Stanza signatures do not match for user ' + author ) ; } return ok ; } ) ; }
Verifies that the stanza's signature matches the author's public key on file
at the Hub.

May fetch updated user profile information from the Hub.

@param {HubClient} hubClient A HubClient instance used to fetch user profile
information.
@param {Object} stanza The stanza to check
@param {String} stanza.sig The stanza's signature field.
@param {Array<String>} fields The names of the stanza fields to check.
@param {String} author The name of the purported author of the stanza.
@param {String?} opt_sigValue The sig value to check.  If unset, defaults to
`stanza.sig`.
@return {Promise<true>} Iff the signature is valid
@throws {errors.AuthenticationError} If the signature is invalid or the user
cannot be found.
Verifies that the stanza s signature matches the author s public key on file at the Hub .