From 25270c0b75f736cfa3939703d7d92ace1e527a06 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sun, 19 Jun 2016 03:02:32 -0700 Subject: [PATCH] Initial commit --- .eslintrc | 46 +++ .gitignore | 2 + api/app.js | 71 +++++ api/decorators/connections.js | 10 + api/package.json | 19 ++ api/routes/accounts.js | 24 ++ api/routes/threads.js | 31 ++ api/serialization.js | 25 ++ core/config/development.json | 11 + core/database-connection-factory.js | 78 +++++ core/migrations/20160617002207-create-user.js | 33 ++ core/models/account/category.js | 24 ++ core/models/account/message.js | 21 ++ core/models/account/message_uid.js | 14 + core/models/account/thread.js | 15 + core/models/shared/account-token.js | 18 ++ core/models/shared/account.js | 21 ++ core/package.json | 16 + process.json | 24 ++ storage/a-1.sqlite | Bin 0 -> 293888 bytes storage/shared.sqlite | Bin 0 -> 4096 bytes sync/app.js | 19 ++ sync/package.json | 17 + sync/sync-worker-pool.js | 16 + sync/sync-worker.js | 297 ++++++++++++++++++ 25 files changed, 852 insertions(+) create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 api/app.js create mode 100644 api/decorators/connections.js create mode 100644 api/package.json create mode 100644 api/routes/accounts.js create mode 100644 api/routes/threads.js create mode 100644 api/serialization.js create mode 100644 core/config/development.json create mode 100644 core/database-connection-factory.js create mode 100644 core/migrations/20160617002207-create-user.js create mode 100644 core/models/account/category.js create mode 100644 core/models/account/message.js create mode 100644 core/models/account/message_uid.js create mode 100644 core/models/account/thread.js create mode 100644 core/models/shared/account-token.js create mode 100644 core/models/shared/account.js create mode 100644 core/package.json create mode 100644 process.json create mode 100644 storage/a-1.sqlite create mode 100644 storage/shared.sqlite create mode 100644 sync/app.js create mode 100644 sync/package.json create mode 100644 sync/sync-worker-pool.js create mode 100644 sync/sync-worker.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..002cc8677 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,46 @@ +{ + "parser": "babel-eslint", + "extends": "airbnb", + "globals": { + "NylasEnv": false, + "$n": false, + "waitsForPromise": false, + "advanceClock": false, + "TEST_ACCOUNT_ID": false, + "TEST_ACCOUNT_NAME": false, + "TEST_ACCOUNT_EMAIL": false, + "__base": false + }, + "env": { + "browser": true, + "node": true, + "jasmine": true + }, + "rules": { + "arrow-body-style": "off", + "prefer-arrow-callback": ["error", {"allowNamedFunctions": true}], + "eqeqeq": ["error", "smart"], + "id-length": "off", + "object-curly-spacing": "off", + "max-len": "off", + "new-cap": ["error", {"capIsNew": false}], + "no-console": "off", + "no-constant-condition": "off", + "no-loop-func": "off", + "no-shadow": "error", + "no-underscore-dangle": "off", + "object-shorthand": "off", + "quotes": "off", + "global-require": "off", + "quote-props": ["error", "consistent-as-needed", { "keywords": true }], + "no-param-reassign": ["error", { "props": false }], + "semi": "off", + "import/no-unresolved": ["error", {"ignore": ["nylas-exports", "nylas-component-kit", "electron", "nylas-store", "react-dom/server", "nylas-observables", "windows-shortcuts", "moment-round", "chrono-node", "event-kit", "enzyme"]}], + "react/no-multi-comp": "off", + "react/prop-types": ["error", {"ignore": ["children"]}], + "react/sort-comp": "error" + }, + "settings": { + "import/resolver": {"node": {"extensions": [".es6", ".jsx", ".coffee", ".json", ".cjsx", ".js"]}} + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..9daa8247d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +node_modules diff --git a/api/app.js b/api/app.js new file mode 100644 index 000000000..a763f6a9d --- /dev/null +++ b/api/app.js @@ -0,0 +1,71 @@ +const Hapi = require('hapi'); +const HapiSwagger = require('hapi-swagger'); +const HapiBasicAuth = require('hapi-auth-basic'); +const Inert = require('inert'); +const Vision = require('vision'); +const Package = require('./package'); +const fs = require('fs'); +const path = require('path'); +global.__base = path.join(__dirname, '..') + +const server = new Hapi.Server(); +server.connection({ port: 3000 }); + +const plugins = [Inert, Vision, HapiBasicAuth, { + register: HapiSwagger, + options: { + info: { + title: 'Nylas API Documentation', + version: Package.version, + }, + }, +}]; + +let sharedDb = null; +const DatabaseConnectionFactory = require(`${__base}/core/database-connection-factory`) +DatabaseConnectionFactory.forShared().then((db) => { + sharedDb = db; +}); + +const validate = (request, username, password, callback) => { + const {AccountToken} = sharedDb; + + AccountToken.find({ + where: { + value: username, + }, + }).then((token) => { + if (!token) { + callback(null, false, {}); + return + } + token.getAccount().then((account) => { + callback(null, true, account); + }); + }); +}; + +const attach = (directory) => { + const routesDir = path.join(__dirname, directory) + fs.readdirSync(routesDir).forEach((filename) => { + if (filename.endsWith('.js')) { + const routeFactory = require(path.join(routesDir, filename)); + routeFactory(server); + } + }); +} + +server.register(plugins, (err) => { + if (err) { throw err; } + + attach('./routes/') + attach('./decorators/') + + server.auth.strategy('api-consumer', 'basic', { validateFunc: validate }); + server.auth.default('api-consumer'); + + server.start((startErr) => { + if (startErr) { throw startErr; } + console.log('Server running at:', server.info.uri); + }); +}); diff --git a/api/decorators/connections.js b/api/decorators/connections.js new file mode 100644 index 000000000..509d969ee --- /dev/null +++ b/api/decorators/connections.js @@ -0,0 +1,10 @@ +/* eslint func-names:0 */ + +const DatabaseConnectionFactory = require(`${__base}/core/database-connection-factory`); + +module.exports = (server) => { + server.decorate('request', 'getAccountDatabase', function () { + const account = this.auth.credentials; + return DatabaseConnectionFactory.forAccount(account.id); + }); +} diff --git a/api/package.json b/api/package.json new file mode 100644 index 000000000..33e8d55fe --- /dev/null +++ b/api/package.json @@ -0,0 +1,19 @@ +{ + "name": "api", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "hapi": "^13.4.1", + "hapi-auth-basic": "^4.2.0", + "hapi-swagger": "^6.1.0", + "inert": "^4.0.0", + "joi": "^8.4.2", + "vision": "^4.1.0" + } +} diff --git a/api/routes/accounts.js b/api/routes/accounts.js new file mode 100644 index 000000000..6f0ca9d61 --- /dev/null +++ b/api/routes/accounts.js @@ -0,0 +1,24 @@ +const Serialization = require('../serialization'); + +module.exports = (server) => { + server.route({ + method: 'GET', + path: '/account', + config: { + description: 'Returns the current account.', + notes: 'Notes go here', + tags: ['accounts'], + validate: { + params: { + }, + }, + response: { + schema: Serialization.jsonSchema('Account'), + }, + }, + handler: (request, reply) => { + const account = request.auth.credentials; + reply(Serialization.jsonStringify(account)); + }, + }); +}; diff --git a/api/routes/threads.js b/api/routes/threads.js new file mode 100644 index 000000000..d9ccb910f --- /dev/null +++ b/api/routes/threads.js @@ -0,0 +1,31 @@ +const Joi = require('joi'); +const Serialization = require('../serialization'); + +module.exports = (server) => { + server.route({ + method: 'GET', + path: '/threads', + config: { + description: 'Returns threads', + notes: 'Notes go here', + tags: ['threads'], + validate: { + params: { + }, + }, + response: { + schema: Joi.array().items( + Serialization.jsonSchema('Account') + ), + }, + }, + handler: (request, reply) => { + request.getAccountDatabase().then((db) => { + const {Thread} = db; + Thread.findAll({limit: 50}).then((threads) => { + reply(Serialization.jsonStringify(threads)); + }) + }) + }, + }); +}; diff --git a/api/serialization.js b/api/serialization.js new file mode 100644 index 000000000..6e0da9b90 --- /dev/null +++ b/api/serialization.js @@ -0,0 +1,25 @@ +const Joi = require('joi'); + +function replacer(key, value) { + // force remove any disallowed keys here + return value; +} + +function jsonSchema(modelName) { + if (modelName === 'Account') { + return Joi.object().keys({ + id: Joi.number(), + email_address: Joi.string(), + }) + } + return null; +} + +function jsonStringify(models) { + return JSON.stringify(models, replacer, 2); +} + +module.exports = { + jsonSchema, + jsonStringify, +} diff --git a/core/config/development.json b/core/config/development.json new file mode 100644 index 000000000..aab9d4b95 --- /dev/null +++ b/core/config/development.json @@ -0,0 +1,11 @@ +{ + "storage": { + "database": "account-$ACCOUNTID", + "username": null, + "password": null, + "options": { + "dialect": "sqlite", + "storage": "./account-$ACCOUNTID.sqlite" + } + } +} diff --git a/core/database-connection-factory.js b/core/database-connection-factory.js new file mode 100644 index 000000000..d9dd80a9b --- /dev/null +++ b/core/database-connection-factory.js @@ -0,0 +1,78 @@ +const Sequelize = require('sequelize'); +const fs = require('fs'); +const path = require('path'); + +const STORAGE_DIR = path.join(__base, 'storage'); +if (!fs.existsSync(STORAGE_DIR)) { + fs.mkdirSync(STORAGE_DIR); +} + +class DatabaseConnectionFactory { + constructor() { + this._pools = {}; + } + + _readModelsInDirectory(sequelize, dirname) { + const db = {}; + for (const filename of fs.readdirSync(dirname)) { + if (filename.endsWith('.js')) { + const model = sequelize.import(path.join(dirname, filename)); + db[model.name] = model; + } + } + Object.keys(db).forEach((modelName) => { + if ("associate" in db[modelName]) { + db[modelName].associate(db); + } + }); + + return db; + } + + _sequelizeForAccount(accountId) { + const sequelize = new Sequelize(accountId, '', '', { + storage: path.join(STORAGE_DIR, `a-${accountId}.sqlite`), + dialect: "sqlite", + }); + + const modelsPath = path.join(__dirname, 'models/account'); + const db = this._readModelsInDirectory(sequelize, modelsPath) + + db.sequelize = sequelize; + db.Sequelize = Sequelize; + + return sequelize.authenticate().then(() => + sequelize.sync() + ).thenReturn(db); + } + + forAccount(accountId) { + this._pools[accountId] = this._pools[accountId] || this._sequelizeForAccount(accountId); + return this._pools[accountId]; + } + + _sequelizeForShared() { + const sequelize = new Sequelize('shared', '', '', { + storage: path.join(STORAGE_DIR, 'shared.sqlite'), + dialect: "sqlite", + }); + + const modelsPath = path.join(__dirname, 'models/shared'); + const db = this._readModelsInDirectory(sequelize, modelsPath) + + db.sequelize = sequelize; + db.Sequelize = Sequelize; + + return sequelize.authenticate().then(() => + sequelize.sync() + ).thenReturn(db); + } + + forShared() { + this._pools.shared = this._pools.shared || this._sequelizeForShared(); + return this._pools.shared; + } + +} + +module.exports = new DatabaseConnectionFactory() diff --git a/core/migrations/20160617002207-create-user.js b/core/migrations/20160617002207-create-user.js new file mode 100644 index 000000000..1b8f61170 --- /dev/null +++ b/core/migrations/20160617002207-create-user.js @@ -0,0 +1,33 @@ +'use strict'; +module.exports = { + up: function(queryInterface, Sequelize) { + return queryInterface.createTable('Users', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + first_name: { + type: Sequelize.STRING + }, + last_name: { + type: Sequelize.STRING + }, + bio: { + type: Sequelize.TEXT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: function(queryInterface, Sequelize) { + return queryInterface.dropTable('Users'); + } +}; \ No newline at end of file diff --git a/core/models/account/category.js b/core/models/account/category.js new file mode 100644 index 000000000..b56b5c9d9 --- /dev/null +++ b/core/models/account/category.js @@ -0,0 +1,24 @@ +module.exports = (sequelize, Sequelize) => { + const Category = sequelize.define('Category', { + name: Sequelize.STRING, + role: Sequelize.STRING, + syncState: { + type: Sequelize.STRING, + defaultValue: '{}', + get: function get() { + return JSON.parse(this.getDataValue('syncState')) + }, + set: function set(val) { + this.setDataValue('syncState', JSON.stringify(val)); + }, + }, + }, { + classMethods: { + associate: ({MessageUID}) => { + Category.hasMany(MessageUID) + }, + }, + }); + + return Category; +}; diff --git a/core/models/account/message.js b/core/models/account/message.js new file mode 100644 index 000000000..ced3bd00d --- /dev/null +++ b/core/models/account/message.js @@ -0,0 +1,21 @@ +module.exports = (sequelize, Sequelize) => { + const Message = sequelize.define('Message', { + subject: Sequelize.STRING, + snippet: Sequelize.STRING, + body: Sequelize.STRING, + headers: Sequelize.STRING, + date: Sequelize.DATE, + unread: Sequelize.BOOLEAN, + starred: Sequelize.BOOLEAN, + }, { + classMethods: { + associate: ({MessageUID}) => { + // is this really a good idea? + // Message.hasMany(Contact, {as: 'from'}) + Message.hasMany(MessageUID, {as: 'uids'}) + }, + }, + }); + + return Message; +}; diff --git a/core/models/account/message_uid.js b/core/models/account/message_uid.js new file mode 100644 index 000000000..632bef539 --- /dev/null +++ b/core/models/account/message_uid.js @@ -0,0 +1,14 @@ +module.exports = (sequelize, Sequelize) => { + const MessageUID = sequelize.define('MessageUID', { + uid: Sequelize.STRING, + }, { + classMethods: { + associate: ({Category, Message}) => { + MessageUID.belongsTo(Category) + MessageUID.belongsTo(Message) + }, + }, + }); + + return MessageUID; +}; diff --git a/core/models/account/thread.js b/core/models/account/thread.js new file mode 100644 index 000000000..1c63b9ccc --- /dev/null +++ b/core/models/account/thread.js @@ -0,0 +1,15 @@ +module.exports = (sequelize, Sequelize) => { + const Thread = sequelize.define('Thread', { + first_name: Sequelize.STRING, + last_name: Sequelize.STRING, + bio: Sequelize.TEXT, + }, { + classMethods: { + associate: (models) => { + // associations can be defined here + }, + }, + }); + + return Thread; +}; diff --git a/core/models/shared/account-token.js b/core/models/shared/account-token.js new file mode 100644 index 000000000..a9ff17986 --- /dev/null +++ b/core/models/shared/account-token.js @@ -0,0 +1,18 @@ +module.exports = (sequelize, Sequelize) => { + const AccountToken = sequelize.define('AccountToken', { + value: Sequelize.STRING, + }, { + classMethods: { + associate: ({Account}) => { + AccountToken.belongsTo(Account, { + onDelete: "CASCADE", + foreignKey: { + allowNull: false, + }, + }); + }, + }, + }); + + return AccountToken; +}; diff --git a/core/models/shared/account.js b/core/models/shared/account.js new file mode 100644 index 000000000..9195662d9 --- /dev/null +++ b/core/models/shared/account.js @@ -0,0 +1,21 @@ +module.exports = (sequelize, Sequelize) => { + const Account = sequelize.define('Account', { + emailAddress: Sequelize.STRING, + }, { + classMethods: { + associate: ({AccountToken}) => { + Account.hasMany(AccountToken, {as: 'tokens'}) + }, + }, + instanceMethods: { + toJSON: function toJSON() { + return { + id: this.id, + email_address: this.emailAddress, + } + }, + }, + }); + + return Account; +}; diff --git a/core/package.json b/core/package.json new file mode 100644 index 000000000..184b16d50 --- /dev/null +++ b/core/package.json @@ -0,0 +1,16 @@ +{ + "name": "core", + "version": "1.0.0", + "description": "", + "main": "database-connection-factory.js", + "dependencies": { + "mysql": "^2.10.2", + "sequelize": "^3.23.3", + "sqlite3": "^3.1.4" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/process.json b/process.json new file mode 100644 index 000000000..ee13cea43 --- /dev/null +++ b/process.json @@ -0,0 +1,24 @@ +{ + "apps": [ + { + "name": "api", + "script": "api/app.js", + "watch": true, + "instances": "max", + "exec_mode": "cluster", + "env": { + "NODE_ENV": "development" + }, + "env_production": { + "NODE_ENV": "production" + } + }, + { + "name": "sync", + "script": "sync/app.js", + "watch": true, + "instances": "max", + "exec_mode": "cluster" + } + ] +} diff --git a/storage/a-1.sqlite b/storage/a-1.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..2ef02b1ce81263c8c8122f11d48e35a8b448d97d GIT binary patch literal 293888 zcmeFaYm6gVb|#ipIWs+-qm(q#YG);_cA~R2Q&pYGNAS(8%ADpi$xM>Tb+iy@mwCSg+x=Vc5Xhu;c|SEbKr2W5C!yHn96gSlAX| z8D1OkAN}!nZaf%42AQwwndwnwcV&|CIQQOj&pG$pbI+rEl9Pra*OZl>Fy#De-&lM0 zZ0%EyTU%S}uB|=$KK>d%-@pg@XZ$=fKCJlLU32~EpMDb$JX`;BdhFZlfBx)t#q)oG zZhh+;-(sWv-N5<>-}|lKdiJ+o4~1G+%!{fjv_#eT`;9~?6|1DUN-UmBai1HPKj&V4 zE;T;qvV}_OAXVaurEES{y5Npd7hJ4bInEaFUOrW*>~No}quP~NAAZiA#!87ytn|_s z48Ef4eQ7Wd7q8dk#&qG~wkR}2MP0bw5QgICToPTZWb-LN9rYDF`Z-t07B0}cmpp4~ zC@6|Jf3=P$hhig!E*Jo~!f}NwRC76kG$7#4w_g>Xf9reO+s`f-($woNsQ9faUXR3n zU7Y*6ZbRYR&6j6&u%a3dXnN7U;4a!$mI>W_$cR%?)v#% zZ`d7)2Dxpoch~D(efMPJgS8*bLwy>^>W3e!xn>{>ysO-oiuTxuHCG8sPE=AFO@!YbIjLVt=UO-xGm;%MNrP^sYwz&N85Zm6K)Mt$x#nSx|Mq zA#~;bQW`K`bfy90Zt)u*tbIJgY(eD(}T(?711hxG%h{w-?&siT^idcUdz{6)B ztbNY}_-I&Q?hn7SiQnt%|MS}V|GoYv`1AhfJqF%m;OmTmUs_-P_?fOHRSV8?fQSc{$H;DXY2p*`hU3o`|JPi`oFpUZ>;~F_1|0nSJtQN!*zN6YF%9a zeEqZa)AbVu?CXrdue9&K|K+n^Km&g`rdG1qk~kbGeOFN!ws*NVHF*T>_0t~P0!aOq z*l$UF(Os8&`_Iyg{#bbK~4qmc$!zmrLZU z9Q(+j59~Tr3RkBukNYmDE7(@-a#K;=;kGoo#mKo78#)(j^rZfl`Hotb6#zs(%}Z@* zsP1yHT<&e9R4rFhNzTRZaPinhs{GdL#TR#Uhs#v*xwrXLxg0x4(c4~rXLEz&DsR(S zdNGqNzfB*P@^8zT<5Gnl0Ek?ya8SkbWlqFEHGtJJ;J3PRP3STJ<=ETPRH>XjE&zLe z@X$A2;n&&^F}MHE5Af^%`fdFBvybuXPq*;v|M&>M{so6$|C~0~fBe_*>mUDB{QA#- z6Tkl9Z{XK|^6U8ZAN>{l`upF*um9jL(VE48D8;T^&F_*H{4@9r@D|Jm=Zt$*kFAK?#)8~psP^o*wQfA#prMAKAua=~--eBh+2-yC_SJj)-+TKX z_xVr3{zvTcium7V)u-?8f8Jx@JqG?lV1W4l`LjPB$* z+3$VGG_*>a4&7A!&j)tROuzaNt*j|2>hP`ONmUnS0p~k4Nyf2X>YUCTA9*Il)};5^ z=TA=iB>w*n4*J&rtM&T&ci*4?*-ok6pa0>sw*3D5@6ktW>=gTF_56=@j`;uE&oXQ4 ze}6sw{QrIa?>ygo_Gi!j9xlB9c@PGUf7N!#OE#HhRI|kRrTab@cT2zW!P*P+kk=Da z>TOv6p9Zt=-4E8jZ-u$kQ^4qj-L_=-XBcS;;a3fCzrLhzX#_P_#HtwGMqRnqa1OCMRZrb{5I=Fb^aNZF{ zPXzu8OMsW&0dNrcFG&5GJP`(ip{Ne|PmN`FmyVt|I(jlssb&XPbf{ER${JY=FY*;lG}FP^|CA1g>G9`humkpFHDD8 zZk`={q4CA1i+HdpP4wffR2g02qz1>w;@(&q{pN9E^ Nxi?GEw6FJ?TRaSlXoq3k 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 z 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 xTGhF|snm7Bb literal 0 HcmV?d00001 diff --git a/storage/shared.sqlite b/storage/shared.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..60b0d053d6888e58dfeaa081eb714239b65f4a39 GIT binary patch literal 4096 zcmeH}K~LK-6vyqj1663N;QzOjD$@i{Q2NqZs3fgrXR1cED_A>8$@( zbn>WIg{}o{W->7?o%VIwW_e`L%Ow;MwWqAqH#hNc&L^3S#rprA@JYrapFbOt5~F9y zR^)|zOH``YyLh$UXyBRtlzD+WQA&3yNEf2t1eu54XiS4($`eud?^vt(-o)fL5{EQN zKoVF+0_*r4(rUF+9-YN$e7Sd)zfC^-aj0qe{#VEyBKM+^CJ9Ia%SGU$LYmdm&)pg( ijUtjPzW)!1JS^9= { + const {Account} = db + Account.findAll().then((accounts) => { + accounts.forEach((account) => { + workerPool.addWorkerForAccount(account); + }); + }); +}); + +global.workerPool = workerPool; diff --git a/sync/package.json b/sync/package.json new file mode 100644 index 000000000..07c308f66 --- /dev/null +++ b/sync/package.json @@ -0,0 +1,17 @@ +{ + "name": "imap-experiment", + "version": "1.0.0", + "description": "", + "main": "app.js", + "dependencies": { + "bluebird": "^3.4.1", + "imap": "^0.8.17" + }, + "devDependencies": {}, + "scripts": { + "start": "node app.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} diff --git a/sync/sync-worker-pool.js b/sync/sync-worker-pool.js new file mode 100644 index 000000000..8423d0ceb --- /dev/null +++ b/sync/sync-worker-pool.js @@ -0,0 +1,16 @@ +const SyncWorker = require('./sync-worker'); +const DatabaseConnectionFactory = require(`${__base}/core/database-connection-factory`) + +class SyncWorkerPool { + constructor() { + this._workers = {}; + } + + addWorkerForAccount(account) { + DatabaseConnectionFactory.forAccount(account.id).then((db) => { + this._workers[account.id] = new SyncWorker(account, db); + }); + } +} + +module.exports = SyncWorkerPool; diff --git a/sync/sync-worker.js b/sync/sync-worker.js new file mode 100644 index 000000000..429dfd928 --- /dev/null +++ b/sync/sync-worker.js @@ -0,0 +1,297 @@ +const {inspect} = require('util'); +const Promise = require('bluebird'); +const Imap = require('imap'); + +const State = { + Closed: 'closed', + Connecting: 'connecting', + Open: 'open', +} + +const Capabilities = { + Gmail: 'X-GM-EXT-1', + Quota: 'QUOTA', + UIDPlus: 'UIDPLUS', + Condstore: 'CONDSTORE', + Search: 'ESEARCH', + Sort: 'SORT', +} + +class SyncIMAPConnection { + constructor(settings) { + this._queue = []; + this._current = null; + this._state = State.Connecting; + this._capabilities = []; + + this._imap = Promise.promisifyAll(new Imap(settings)); + + this._imap.once('ready', () => { + this._state = State.Open; + for (const key of Object.keys(Capabilities)) { + const val = Capabilities[key]; + if (this._imap.serverSupports(val)) { + this._capabilities.push(val); + } + } + this.processNextOperation(); + }); + this._imap.once('error', (err) => { + console.log(err); + }); + this._imap.once('end', () => { + this._state = State.Closed; + console.log('Connection ended'); + }); + this._imap.connect(); + } + + queueOperation(op) { + this._queue.push(op); + if (this._state === State.Open && !this._current) { + this.processNextOperation(); + } + } + + processNextOperation() { + if (this._current) { return; } + + this._current = this._queue.shift(); + + if (this._current) { + console.log(`Starting task ${this._current.constructor.name}`) + + const result = this._current.run(this._imap); + if (result instanceof Promise === false) { + throw new Error(`processNextOperation: Expected ${this._current.constructor.name} to return promise.`); + } + result.catch((err) => { + this._current = null; + console.error(err); + }); + result.then(() => { + console.log(`Finished task ${this._current.constructor.name}`) + this._current = null; + this.processNextOperation(); + }); + } + } +} + +class SyncMailboxOperation { + constructor(db, {role} = {}) { + this._db = db; + this._category = null; + this._box = null; + } + + _fetch(imap, range) { + return new Promise((resolve, reject) => { + const f = imap.fetch(range, { + bodies: ['HEADER', 'TEXT'], + }); + f.on('message', (msg, uid) => this._receiveMessage(msg, uid)); + f.once('error', reject); + f.once('end', resolve); + }); + } + + _unlinkAllMessages() { + const {MessageUID} = this._db; + return MessageUID.destroy({ + where: { + categoryId: this._category.id, + }, + }) + } + + _receiveMessage(msg, uid) { + let attributes = null; + let body = null; + let headers = null; + + msg.on('attributes', (attrs) => { + attributes = attrs; + }); + msg.on('body', (stream, type) => { + const chunks = []; + stream.on('data', (chunk) => { + chunks.push(chunk); + }); + stream.once('end', () => { + const full = Buffer.concat(chunks).toString('utf8'); + if (type === 'TEXT') { + body = full; + } + if (type === 'HEADERS') { + headers = full; + } + }); + }); + msg.once('end', () => { + this._processMessage(attributes, headers, body, uid); + }); + } + + _processMessage(attributes, headers, body) { + console.log(attributes); + const {Message, MessageUID} = this._db; + + return Message.create({ + unread: attributes.flags.includes('\\Unseen'), + starred: attributes.flags.includes('\\Flagged'), + date: attributes.date, + body: body, + }).then((model) => { + return MessageUID.create({ + MessageId: model.id, + CategoryId: this._category.id, + uid: attributes.uid, + }); + }); + } + + // _flushProcessedMessages() { + // return sequelize.transaction((transaction) => { + // return Promise.props({ + // msgs: Message.bulkCreate(this._processedMessages, {transaction}) + // uids: MessageUID.bulkCreate(this._processedMessageUIDs, {transaction}) + // }) + // }).then(() => { + // this._processedMessages = []; + // this._processedMessageUIDs = []; + // }); + // } + + run(imap) { + const {Category} = this._db; + + return Promise.props({ + box: imap.openBoxAsync('INBOX', true), + category: Category.find({name: 'INBOX'}), + }) + .then(({category, box}) => { + if (this.box.persistentUIDs === false) { + throw new Error("Mailbox does not support persistentUIDs.") + } + + this._category = category; + this._box = box; + + if (box.uidvalidity !== category.syncState.uidvalidity) { + return this._unlinkAllMessages(); + } + return Promise.resolve(); + }) + .then(() => { + const lastUIDNext = this._category.syncState.uidnext; + const currentUIDNext = this._box.uidnext + + if (lastUIDNext) { + if (lastUIDNext === currentUIDNext) { + return Promise.resolve(); + } + + // just request mail >= UIDNext + return this._fetch(imap, `${lastUIDNext}:*`); + } + return this._fetch(imap, `1:*`); + }); + } +} + +class RefreshMailboxesOperation { + constructor(db) { + this._db = db; + } + + _roleForMailbox(box) { + for (const attrib of (box.attribs || [])) { + const role = { + '\\Sent': 'sent', + '\\Drafts': 'drafts', + '\\Junk': 'junk', + '\\Flagged': 'flagged', + }[attrib]; + if (role) { + return role; + } + } + return null; + } + + _updateCategoriesWithBoxes(categories, boxes) { + const {Category} = this._db; + + const stack = []; + const created = []; + const next = []; + + Object.keys(boxes).forEach((name) => { + stack.push([name, boxes[name]]); + }); + + while (stack.length > 0) { + const [name, box] = stack.pop(); + if (box.children) { + Object.keys(box.children).forEach((subname) => { + stack.push([`${name}/${subname}`, box.children[subname]]); + }); + } + + let category = categories.find((cat) => cat.name === name); + if (!category) { + category = Category.build({ + name: name, + role: this._roleForMailbox(box), + }); + created.push(category); + } + next.push(category); + } + + // Todo: decide whether these are renames or deletes + const deleted = categories.filter(cat => !next.includes(cat)); + + return {next, created, deleted}; + } + + run(imap) { + return imap.getBoxesAsync().then((boxes) => { + const {Category, sequelize} = this._db; + + return sequelize.transaction((transaction) => { + return Category.findAll({transaction}).then((categories) => { + const {created, deleted} = this._updateCategoriesWithBoxes(categories, boxes); + + let promises = [Promise.resolve()] + promises = promises.concat(created.map(cat => cat.save({transaction}))) + promises = promises.concat(deleted.map(cat => cat.destroy({transaction}))) + return Promise.all(promises) + }); + }); + }); + } +} + +class SyncWorker { + constructor(account, db) { + this._db = db + this._conns = [] + + const main = new SyncIMAPConnection({ + user: 'inboxapptest1@fastmail.fm', + password: 'trar2e', + host: 'mail.messagingengine.com', + port: 993, + tls: true, + }) + main.queueOperation(new RefreshMailboxesOperation(db)); + main.queueOperation(new SyncMailboxOperation(db, { + role: 'inbox', + })); + this._conns.push(main); + } +} + +module.exports = SyncWorker;