'use strict'; /** ************************************** * Author: Blade Barringer @crookedneighbor * * Reason: Old code didn't properly validate email * addresses, so we have some users in the db * that do not have valid emails. When a party * or challenge attempts to save the user, * the validation fails. This collects * the bad emails and changes the email to * @example.com ***************************************/ const TaskQueue = require('cwait').TaskQueue; const logger = require('./utils/logger'); const Timer = require('./utils/timer'); const connectToDb = require('./utils/connect').connectToDb; const closeDb = require('./utils/connect').closeDb; const validator = require('validator'); const timer = new Timer(); const DB_URI = 'mongodb://username:password@dsXXXXXX-a0.mlab.com:XXXXX,dsXXXXXX-a1.mlab.com:XXXXX/habitica?replicaSet=rs-dsXXXXXX'; let Users; connectToDb(DB_URI).then((db) => { Users = db.collection('users'); return Promise.resolve(); }) // cached the lookup as a json file // .then(findUsersWithBadEmails) .then(correctEmails) .then(() => { timer.stop(); closeDb(); }).catch(reportError); function reportError (err) { logger.error('Uh oh, an error occurred'); closeDb(); timer.stop(); throw err; } function findUsersWithBadEmails (users) { logger.warn('Fetching users with bad emails...'); return Users.find({'auth.local.email': {$exists: true}}, ['auth.local.email']).toArray().then((docs) => { let invalidEmails = docs.filter((user) => { return !validator.isEmail(user.auth.local.email); }); let result = invalidEmails.map((user) => { return { _id: user._id, email: user.auth.local.email }; }); logger.warn('number of invalid emails:', invalidEmails.length); console.log(result); return Promise.resolve(invalidEmails); }); } function updateUserById (user) { return Users.findOneAndUpdate({ _id: user._id}, {$set: {'auth.local.email': `${user._id }@example.com`}, }, {returnOriginal: false}); } // cached lookup of bad emails const emails = require('../email_logs.json'); function correctEmails () { let queue = new TaskQueue(Promise, 300); logger.warn('About to update', emails.length, 'user email addresses...'); return Promise.map(emails, queue.wrap(updateUserById)).then((result) => { let updates = result.filter(res => res && res.lastErrorObject && res.lastErrorObject.updatedExisting); let failures = result.filter(res => res && !(res.lastErrorObject && res.lastErrorObject.updatedExisting)); logger.warn(updates.length, 'users have been fixed'); if (failures.length > 0) { logger.error(failures.length, 'users could not be found'); } return Promise.resolve(); }); }