From b126a69c110d25da78bf34ae140eb8fb8392246e Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Thu, 16 Jul 2020 14:25:02 -0400 Subject: [PATCH] [#1317] Begin writing duplicate email script --- server/controllers/aws.controller.js | 21 +++++ server/migrations/emailConsolidation.js | 101 ++++++++++++++++++++++++ server/migrations/start.js | 3 +- 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 server/migrations/emailConsolidation.js diff --git a/server/controllers/aws.controller.js b/server/controllers/aws.controller.js index 0b7d5d85..6c0cb13b 100644 --- a/server/controllers/aws.controller.js +++ b/server/controllers/aws.controller.js @@ -119,6 +119,27 @@ export function copyObjectInS3(req, res) { }); } +export function moveObjectToUserInS3(url, userId) { + return new Promise((resolve, reject) => { + const objectKey = getObjectKey(url); + const fileExtension = getExtension(objectKey); + const newFilename = uuid.v4() + fileExtension; + const params = { + Bucket: `${process.env.S3_BUCKET}`, + CopySource: `${process.env.S3_BUCKET}/${objectKey}`, + Key: `${userId}/${newFilename}`, + ACL: 'public-read' + }; + const move = client.moveObject(params); + move.on('err', (err) => { + reject(err); + }); + move.on('end', (data) => { + resolve(`${s3Bucket}${userId}/${newFilename}`); + }); + }); +} + export function listObjectsInS3ForUser(userId) { let assets = []; return new Promise((resolve) => { diff --git a/server/migrations/emailConsolidation.js b/server/migrations/emailConsolidation.js new file mode 100644 index 00000000..7b8dd1d8 --- /dev/null +++ b/server/migrations/emailConsolidation.js @@ -0,0 +1,101 @@ +import mongoose from 'mongoose'; +import User from '../models/user'; +import Project from '../models/project'; +import Collection from '../models/collection'; +import { moveObjectToUserInS3 } from '../controllers/aws.controller'; + + +const mongoConnectionString = process.env.MONGO_URL; +const { ObjectId } = mongoose.Types; +// Connect to MongoDB +mongoose.Promise = global.Promise; +mongoose.connect(mongoConnectionString, { useNewUrlParser: true, useUnifiedTopology: true }); +mongoose.set('useCreateIndex', true); +mongoose.connection.on('error', () => { + console.error('MongoDB Connection Error. Please make sure that MongoDB is running.'); + process.exit(1); +}); + +/* + * Requires the MongoDB Node.js Driver + * https://mongodb.github.io/node-mongodb-native + */ + +const agg = [ + { + $project: { + email: { + $toLower: [ + '$email' + ] + } + } + }, { + $group: { + _id: '$email', + total: { + $sum: 1 + } + } + }, { + $match: { + total: { + $gt: 1 + } + } + }, { + $sort: { + total: -1 + } + } +]; + +let currentUser = null; +let duplicates = null; +User.aggregate(agg).then((result) => { + const email = result[0]._id; + return User.find({ email }).collation({ locale: 'en', strength: 2 }) + .sort({ createdAt: 1 }).exec(); +}).then((result) => { + [currentUser, ...duplicates] = result; + duplicates = duplicates.map(dup => dup._id); + console.log(duplicates); + return Project.find({ + user: { $in: duplicates } + }).exec(); +}).then((sketches) => { + const saveSketchPromises = []; + sketches.forEach((sketch) => { + const moveSketchFilesPromises = []; + sketch.files.forEach((file) => { + if (file.url.includes('assets.editor.p5js.org')) { + const fileSavePromise = moveObjectToUserInS3(file.url, currentUser._id) + .then((newUrl) => { + file.url = newUrl; + }); + moveSketchFilesPromises.push(fileSavePromise); + } + }); + const sketchSavePromise = Promise.all(moveSketchFilesPromises).then(() => { + sketch.user = ObjectId(currentUser._id); + return sketch.save(); + }); + saveSketchPromises.push(sketchSavePromise); + }); + return Promise.all(saveSketchPromises); + // iterate through the results + // check if any files are on AWS + // if so, move them to the right user bucket + // then, update the user to currentUser + // then, after updating all of the projects + // also update the collections + // delete other users + // update user email so it is all lowercase + // then, send the email +}).then(() => Collection.updateMany( + { owner: { $in: duplicates } }, + { $set: { owner: ObjectId(currentUser.id) } } +)).then(() => User.deleteMany({ _id: { $in: duplicates } })).catch((err) => { + console.log(err); +}); + diff --git a/server/migrations/start.js b/server/migrations/start.js index a3127620..3fc2e6e4 100644 --- a/server/migrations/start.js +++ b/server/migrations/start.js @@ -2,6 +2,7 @@ require('@babel/register'); require('@babel/polyfill'); const path = require('path'); require('dotenv').config({ path: path.resolve('.env') }); -require('./populateTotalSize'); +require('./emailConsolidation'); +// require('./populateTotalSize'); // require('./moveBucket'); // require('./truncate');