Primitive account deletion via DELETE /account

This commit is contained in:
Ben Gotow 2016-07-11 16:56:18 -07:00
parent 8e0cd92bad
commit 492ac21bb6
7 changed files with 64 additions and 16 deletions

View file

@ -1,4 +1,5 @@
const Serialization = require('../serialization');
const {DatabaseConnector} = require('nylas-core');
module.exports = (server) => {
server.route({
@ -21,4 +22,28 @@ module.exports = (server) => {
reply(Serialization.jsonStringify(account));
},
});
server.route({
method: 'DELETE',
path: '/account',
config: {
description: 'Deletes the current account and all data from the Nylas Cloud.',
notes: 'Notes go here',
tags: ['accounts'],
validate: {
params: {
},
},
},
handler: (request, reply) => {
const account = request.auth.credentials;
account.destroy().then((saved) =>
DatabaseConnector.destroyAccountDatabase(saved.id).then(() =>
reply(Serialization.jsonStringify({status: 'success'}))
)
).catch((err) => {
reply(err).code(500);
})
},
});
};

View file

@ -79,11 +79,7 @@ class DatabaseConnector {
const dbname = `a-${accountId}`;
if (process.env.DB_HOSTNAME) {
const sequelize = new Sequelize(null, process.env.DB_USERNAME, process.env.DB_PASSWORD, {
host: process.env.DB_HOSTNAME,
dialect: "mysql",
logging: false,
})
const sequelize = this._sequelizePoolForDatabase(null);
return sequelize.authenticate().then(() =>
sequelize.query(`CREATE DATABASE \`${dbname}\``)
);
@ -91,6 +87,18 @@ class DatabaseConnector {
return Promise.resolve()
}
destroyAccountDatabase(accountId) {
const dbname = `a-${accountId}`;
if (process.env.DB_HOSTNAME) {
const sequelize = this._sequelizePoolForDatabase(null);
return sequelize.authenticate().then(() =>
sequelize.query(`CREATE DATABASE \`${dbname}\``)
);
}
fs.removeFileSync(path.join(STORAGE_DIR, `${dbname}.sqlite`));
return Promise.resolve()
}
_sequelizeForShared() {
const sequelize = this._sequelizePoolForDatabase(`shared`);
const modelsPath = path.join(__dirname, 'models/shared');

View file

@ -17,7 +17,11 @@ module.exports = (db, sequelize) => {
});
}
})
// TODO delete account from redis
// sequelize.addHook("afterDelete", ({dataValues, $modelOptions}) => {
// })
sequelize.addHook("afterDestroy", ({dataValues, $modelOptions}) => {
if ($modelOptions.name.singular === 'account') {
PubsubConnector.notifyAccount(dataValues.id, {
type: MessageTypes.ACCOUNT_DELETED,
});
}
})
}

View file

@ -270,9 +270,11 @@ class IMAPConnection extends EventEmitter {
}
end() {
if (this._imap) {
this._imap.end();
this._imap = null;
}
this._queue = [];
this._imap.end();
this._imap = null;
this._connectPromise = null;
}

View file

@ -1,5 +1,6 @@
module.exports = {
ACCOUNT_CREATED: "ACCOUNT_CREATED",
ACCOUNT_UPDATED: "ACCOUNT_UPDATED",
ACCOUNT_DELETED: "ACCOUNT_DELETED",
SYNCBACK_REQUESTED: "SYNCBACK_REQUESTED",
}

View file

@ -178,6 +178,7 @@ class SyncProcessManager {
return;
}
this._logger.info({account_id: accountId}, `ProcessManager: Starting worker for Account`)
this._workers[account.id] = new SyncWorker(account, db, () => {
this.removeWorkerForAccountId(accountId)
});

View file

@ -27,7 +27,6 @@ class SyncWorker {
this._logger = global.Logger.forAccount(account)
this._syncTimer = null;
this._expirationTimer = null;
this._destroyed = false;
this.syncNow({reason: 'Initial'});
@ -37,6 +36,8 @@ class SyncWorker {
}
cleanup() {
clearTimeout(this._syncTimer);
this._syncTimer = null;
this._destroyed = true;
this._listener.dispose();
this.closeConnection()
@ -51,13 +52,19 @@ class SyncWorker {
_onMessage(msg) {
const {type} = JSON.parse(msg);
switch (type) {
case MessageTypes.ACCOUNT_UPDATED:
this._onAccountUpdated(); break;
case MessageTypes.SYNCBACK_REQUESTED:
this.syncNow({reason: 'Syncback Action Queued'}); break;
case MessageTypes.ACCOUNT_CREATED:
// No other processing currently required for account creation
break;
case MessageTypes.ACCOUNT_UPDATED:
this._onAccountUpdated();
break;
case MessageTypes.ACCOUNT_DELETED:
this.cleanup();
this._onExpired();
break;
case MessageTypes.SYNCBACK_REQUESTED:
this.syncNow({reason: 'Syncback Action Queued'});
break;
default:
this._logger.error({message: msg}, 'SyncWorker: Invalid message')
}
@ -208,7 +215,7 @@ class SyncWorker {
const now = Date.now();
const syncGraphTimeLength = 60 * 30; // 30 minutes, should be the same as SyncGraph.config.timeLength
let lastSyncCompletions = [...this._account.lastSyncCompletions]
let lastSyncCompletions = [].concat(this._account.lastSyncCompletions)
lastSyncCompletions = [now, ...lastSyncCompletions]
while (now - lastSyncCompletions[lastSyncCompletions.length - 1] > 1000 * syncGraphTimeLength) {
lastSyncCompletions.pop();