method/setFailCount.js

/* eslint-disable promise/always-return */
/* eslint-disable promise/no-nesting */
/**
 * @module method/setFailCount
 */

const admin = require('firebase-admin');
const FieldValue = admin.firestore.FieldValue;

const db = admin.firestore();

/**
 * Update a user’s fail count on Firebase
 *
 * @param  {object} user - User object
 * @param  {string} user.uid - Firebase User ID, e.g. hk_wx5555556.
 * @param  {boolean} toIncrease - Whether to increase the fail count.
 * Increase fail count if true, reset fail count if false.
 *
 * @return {object} Write result from Firebase.
 */

const setFailCount = (user, toIncrease) => {
  return admin.auth().getUser(user.uid).then((authUser) => {
    const userMetaRef = db.collection('appUserMeta').doc(authUser.uid);

    return db.runTransaction((transaction) => {
      return transaction.get(userMetaRef).then((userMeta) => {
        const theUserMeta = userMeta.exists
          ? userMeta.data()
          : null;

        if (theUserMeta) {
          let failCount = theUserMeta['failCount'] || 0;

          // if toIncrease is set to true
          if (toIncrease === true) {
            // when failCount is smaller than 5
            if (failCount < 5) {
              failCount = failCount + 1
            }

            // if failCount became 5 after updating
            if (failCount === 5) {
              // Update passwordResettable to initialize reset
              transaction.update(userMetaRef, {
                passwordResettable: false,
              });
            }
          } else {
            // reset failCount to 0 is toIncrease is set to false
            failCount = 0

            // delete passwordResettable from userMeta
            transaction.update(userMetaRef, {
              passwordResettable: FieldValue.delete(),
            });
          }

          // update userMeta with new failCount
          transaction.update(userMetaRef, {
            failCount: failCount,
          });
        } else {
          throw new Error('User meta object cannot be found.')
        }
      });
    });
  }).then((status) => {
    console.info('[Success] Updated log in fail count in database');
    return status;
  }).catch((error) => {
    console.error('[Failure] Error updating log in fail count:', error);
    throw error;
  });
};

module.exports = setFailCount;