Encrypt connction credentials, move conn settings to acct

This commit is contained in:
Ben Gotow 2016-06-21 18:29:58 -07:00
parent b7cd644a83
commit 19de776e00
7 changed files with 101 additions and 36 deletions

View file

@ -78,9 +78,6 @@ class DatabaseConnectionFactory {
db.sequelize = sequelize;
db.Sequelize = Sequelize;
const transactionLog = new TransactionLog(db);
transactionLog.setupSQLHooks(sequelize)
return sequelize.authenticate().then(() =>
sequelize.sync()
).thenReturn(db);

View file

@ -1,6 +1,9 @@
module.exports = (sequelize, Sequelize) => {
const AccountToken = sequelize.define('AccountToken', {
value: Sequelize.STRING,
value: {
type: Sequelize.UUID,
defaultValue: Sequelize.UUIDV4,
},
}, {
classMethods: {
associate: ({Account}) => {

View file

@ -1,15 +1,15 @@
const crypto = require('crypto');
const {JSONType} = require('../../database-types');
const algorithm = 'aes-256-ctr';
const password = 'd6F3Efeq';
module.exports = (sequelize, Sequelize) => {
const Account = sequelize.define('Account', {
emailAddress: Sequelize.STRING,
syncPolicy: {
type: Sequelize.STRING,
get: function get() {
return JSON.parse(this.getDataValue('syncPolicy'))
},
set: function set(val) {
this.setDataValue('syncPolicy', JSON.stringify(val));
},
},
connectionSettings: JSONType('connectionSettings'),
connectionCredentials: Sequelize.STRING,
syncPolicy: JSONType('syncPolicy'),
}, {
classMethods: {
associate: ({AccountToken}) => {
@ -23,6 +23,29 @@ module.exports = (sequelize, Sequelize) => {
email_address: this.emailAddress,
}
},
setCredentials: function setCredentials(json) {
if (!(json instanceof Object)) {
throw new Error("Call setCredentials with JSON!")
}
const cipher = crypto.createCipher(algorithm, password)
let crypted = cipher.update(JSON.stringify(json), 'utf8', 'hex')
crypted += cipher.final('hex');
this.connectionCredentials = crypted;
},
decryptedCredentials: function decryptedCredentials() {
const decipher = crypto.createDecipher(algorithm, password)
let dec = decipher.update(this.connectionCredentials, 'hex', 'utf8')
dec += decipher.final('utf8');
try {
return JSON.parse(dec);
} catch (err) {
return null;
}
},
},
});

Binary file not shown.

View file

@ -8,14 +8,61 @@ const DatabaseConnectionFactory = require(`${__base}/core/database-connection-fa
const SyncWorkerPool = require('./sync-worker-pool');
const workerPool = new SyncWorkerPool();
DatabaseConnectionFactory.setup()
DatabaseConnectionFactory.forShared().then((db) => {
const {Account} = db
Account.findAll().then((accounts) => {
accounts.forEach((account) => {
workerPool.addWorkerForAccount(account);
const seed = (db) => {
const {Account, AccountToken} = db;
const account = Account.build({
emailAddress: 'inboxapptest1@fastmail.fm',
connectionSettings: {
imap: {
host: 'mail.messagingengine.com',
port: 993,
tls: true,
},
},
syncPolicy: {
afterSync: 'idle',
interval: 30 * 1000,
folderSyncOptions: {
deepFolderScan: 5 * 60 * 1000,
},
expiration: Date.now() + 60 * 60 * 1000,
},
})
account.setCredentials({
imap: {
user: 'inboxapptest1@fastmail.fm',
password: 'trar2e',
},
smtp: {
user: 'inboxapptest1@fastmail.fm',
password: 'trar2e',
},
});
return account.save().then((obj) =>
AccountToken.create({
AccountId: obj.id,
}).then((token) => {
console.log(`Created seed data. Your API token is ${token.value}`)
})
);
}
const start = () => {
DatabaseConnectionFactory.forShared().then((db) => {
const {Account} = db;
Account.findAll().then((accounts) => {
if (accounts.length === 0) {
seed(db).then(start);
}
accounts.forEach((account) => {
workerPool.addWorkerForAccount(account);
});
});
});
});
}
DatabaseConnectionFactory.setup()
start();
global.workerPool = workerPool;

View file

@ -7,15 +7,6 @@ class SyncWorkerPool {
}
addWorkerForAccount(account) {
account.syncPolicy = {
afterSync: 'idle',
interval: 30 * 1000,
folderSyncOptions: {
deepFolderScan: 5 * 60 * 1000,
},
expiration: Date.now() + 60 * 60 * 1000,
}
DatabaseConnectionFactory.forAccount(account.id).then((db) => {
this._workers[account.id] = new SyncWorker(account, db);
});

View file

@ -72,13 +72,17 @@ class SyncWorker {
return this._conn.connect();
}
return new Promise((resolve) => {
const conn = new IMAPConnection(this._db, {
user: 'inboxapptest1@fastmail.fm',
password: 'trar2e',
host: 'mail.messagingengine.com',
port: 993,
tls: true,
});
const settings = this._account.connectionSettings;
const credentials = this._account.decryptedCredentials();
if (!settings || !settings.imap) {
throw new Error("ensureConnection: There are no IMAP connection settings for this account.")
}
if (!credentials || !credentials.imap) {
throw new Error("ensureConnection: There are no IMAP connection credentials for this account.")
}
const conn = new IMAPConnection(this._db, Object.assign({}, settings.imap, credentials.imap));
conn.on('mail', () => {
this.onConnectionIdleUpdate();
})