Merge branch 'master' of github.com:nylas/k2

This commit is contained in:
Halla Moore 2016-07-07 14:31:08 -07:00
commit a71e5c6a63
9 changed files with 120 additions and 65 deletions

6
.dockerignore Normal file
View file

@ -0,0 +1,6 @@
.git
.gitignore
README.md
Procfile*
*node_modules*
docs

View file

@ -1,9 +1,25 @@
# This Dockerfile builds a production-ready image of K2 to be used across all
# services. See the Dockerfile documentation here:
# https://docs.docker.com/engine/reference/builder/
# Use the latest Node 6 base docker image
# https://github.com/nodejs/docker-node
FROM node:6
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 8080
# Copy everything (excluding what's in .dockerignore) into an empty dir
COPY . /home
WORKDIR /home
RUN npm install --production
# This will do an `npm install` for each of our modules and then link them all
# together. See more about Lerna here: https://github.com/lerna/lerna We have
# to run this separately from npm postinstall due to permission issues.
RUN node_modules/.bin/lerna bootstrap
# External services run on port 5100. Expose it.
EXPOSE 5100
# We use a start-aws command that automatically spawns the correct process
# based on environment variables (which changes instance to instance)
CMD [ "npm", "run", "start-aws"]

View file

@ -1,2 +0,0 @@
web: node packages/nylas-api/app.js
worker: node packages/nylas-sync/app.js

View file

@ -1,5 +0,0 @@
redis: redis-server
api: node packages/nylas-api/app.js
sync: node packages/nylas-sync/app.js
processor: node packages/nylas-message-processor/app.js
dashboard: node packages/nylas-dashboard/app.js

View file

@ -1,23 +1,33 @@
# K2 - Sync Engine Experiment
# Initial Setup
# Initial Setup:
1. Download https://toolbelt.heroku.com/
## New Computer (Mac):
```
brew install redis
nvm install 6
npm install
```
1. Install [Homebrew](http://brew.sh/)
1. Install [VirtualBox 5+](https://www.virtualbox.org/wiki/Downloads)
1. Install [Docker for Mac](https://docs.docker.com/docker-for-mac/)
1. Install [NVM](https://github.com/creationix/nvm) `brew install nvm`
1. Install Node 6+ via NVM: `nvm install 6`
# Running locally
## New to AWS:
1. Install [Elastic Beanstalk CLI](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-install.html#eb-cli3-install-osx): `brew install awsebcli`
1. Install [AWS CLI](https://aws.amazon.com/cli/): `brew install awscli`
1. Add your AWS IAM Security Credentials to `aws configure`.
1. These are at Console Home -> IAM -> Users -> {{Your Name}} -> Security
Credentials. Note that your private key was only shown unpon creation. If
you've lost your private key you have to deactivate your old key and
create a new one.
1. Get the K2 team private SSH key. (Ignore this when we have a Bastion Host). Ask someone on K2 for a copy of the private SSH key. Copy it to your ~/.ssh folder.
1. `chmod 400 ~/.ssh/k2-keypair.pem`
1. `ssh i ~/.ssh/k2-keypair.pem some-ec2-box-we-own.amazonaws.com`
1. Connect to Elastic Beanstalk instances: `eb init`. Select correct region. Select correct application.
# Developing Locally:
```
npm start
```
## Auth an account
```
curl -X POST -H "Content-Type: application/json" -d '{"email":"inboxapptest2@fastmail.fm", "name":"Ben Gotow", "provider":"imap", "settings":{"imap_username":"inboxapptest1@fastmail.fm","imap_host":"mail.messagingengine.com","imap_port":993,"smtp_host":"mail.messagingengine.com","smtp_port":0,"smtp_username":"inboxapptest1@fastmail.fm", "smtp_password":"trar2e","imap_password":"trar2e","ssl_required":true}}' "http://localhost:5100/auth?client_id=123"
```
# Deploying

View file

@ -5,10 +5,11 @@
"main": "",
"dependencies": {
"bluebird": "3.x.x",
"lerna": "2.0.0-beta.23",
"mysql": "^2.11.1",
"redis": "2.x.x",
"rx": "4.x.x",
"sequelize": "3.x.x",
"sqlite3": "https://github.com/bengotow/node-sqlite3/archive/bengotow/usleep-v3.1.4.tar.gz",
"underscore": "1.x.x"
},
"devDependencies": {
@ -19,7 +20,7 @@
"eslint-plugin-jsx-a11y": "1.x",
"eslint-plugin-react": "5.x",
"eslint_d": "3.x",
"lerna": "2.0.0-beta.23"
"sqlite3": "https://github.com/bengotow/node-sqlite3/archive/bengotow/usleep-v3.1.4.tar.gz"
},
"scripts": {
"start": "foreman start -f Procfile.dev",

View file

@ -31,30 +31,38 @@ const plugins = [Inert, Vision, HapiBasicAuth, HapiBoom, {
}];
let sharedDb = null;
const {DatabaseConnector, SchedulerUtils} = require(`nylas-core`)
DatabaseConnector.forShared().then((db) => {
sharedDb = db;
});
const validate = (request, username, password, callback) => {
const {AccountToken} = sharedDb;
const {DatabaseConnector, SchedulerUtils} = require(`nylas-core`);
AccountToken.find({
where: {
value: username,
},
}).then((token) => {
if (!token) {
callback(null, false, {});
return
}
token.getAccount().then((account) => {
if (!account) {
let getSharedDb = null;
if (sharedDb) {
getSharedDb = Promise.resolve(sharedDb)
} else {
getSharedDb = DatabaseConnector.forShared()
}
getSharedDb.then((db) => {
sharedDb = db;
const {AccountToken} = db;
AccountToken.find({
where: {
value: username,
},
}).then((token) => {
if (!token) {
callback(null, false, {});
return;
return
}
SchedulerUtils.markAccountIsActive(account.id)
callback(null, true, account);
token.getAccount().then((account) => {
if (!account) {
callback(null, false, {});
return;
}
SchedulerUtils.markAccountIsActive(account.id)
callback(null, true, account);
});
});
});
};

View file

@ -9,8 +9,6 @@ const {
DatabaseConnector,
SyncPolicy,
Provider,
PubsubConnector,
MessageTypes,
} = require('nylas-core');
const {GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, GMAIL_REDIRECT_URL} = process.env;
@ -56,10 +54,11 @@ const buildAccountWith = ({name, email, provider, settings, credentials}) => {
account.setCredentials(credentials);
return account.save().then((saved) =>
AccountToken.create({
accountId: saved.id,
}).then((token) =>
Promise.resolve({account: saved, token: token})
AccountToken.create({accountId: saved.id}).then((token) =>
DatabaseConnector.prepareAccountDatabase(saved.id).thenReturn({
account: saved,
token: token,
})
)
);
});

View file

@ -34,16 +34,27 @@ class DatabaseConnector {
return db;
}
_sequelizePoolForDatabase(dbname) {
if (process.env.DB_HOSTNAME) {
return new Sequelize(dbname, process.env.DB_USERNAME, process.env.DB_PASSWORD, {
host: process.env.DB_HOSTNAME,
dialect: "mysql",
logging: false,
});
}
return Sequelize(dbname, '', '', {
storage: path.join(STORAGE_DIR, `${dbname}.sqlite`),
dialect: "sqlite",
logging: false,
})
}
_sequelizeForAccount(accountId) {
if (!accountId) {
return Promise.reject(new Error(`You need to pass an accountId to init the database!`))
}
const sequelize = new Sequelize(accountId, '', '', {
storage: path.join(STORAGE_DIR, `a-${accountId}.sqlite`),
dialect: "sqlite",
logging: false,
});
const sequelize = this._sequelizePoolForDatabase(`a-${accountId}`);
const modelsPath = path.join(__dirname, 'models/account');
const db = this._readModelsInDirectory(sequelize, modelsPath)
@ -64,13 +75,24 @@ class DatabaseConnector {
return this._pools[accountId];
}
_sequelizeForShared() {
const sequelize = new Sequelize('shared', '', '', {
storage: path.join(STORAGE_DIR, 'shared.sqlite'),
dialect: "sqlite",
logging: false,
});
prepareAccountDatabase(accountId) {
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,
})
return sequelize.authenticate().then(() =>
sequelize.query(`CREATE DATABASE \`${dbname}\``)
);
}
return Promise.resolve()
}
_sequelizeForShared() {
const sequelize = this._sequelizePoolForDatabase(`shared`);
const modelsPath = path.join(__dirname, 'models/shared');
const db = this._readModelsInDirectory(sequelize, modelsPath)