diff --git a/bin/iredmail.js b/bin/iredmail.js index ccca338..8c0d9b0 100644 --- a/bin/iredmail.js +++ b/bin/iredmail.js @@ -10,6 +10,8 @@ const config = require('../config') // Models const UsedQuota = require('../postgres/models/used-quota') +const Mailbox = require('../postgres/models/mailbox') +const Forwardings = require('../postgres/models/forwardings') class IRedMail { constructor () { @@ -18,7 +20,9 @@ class IRedMail { // Load the models this.models = { - usedQuota: new UsedQuota(this.sequelize) + usedQuota: new UsedQuota(this.sequelize), + mailbox: new Mailbox(this.sequelize), + forwardings: new Forwardings(this.sequelize) } } diff --git a/bin/server.js b/bin/server.js index 1b47ef2..b7e73df 100644 --- a/bin/server.js +++ b/bin/server.js @@ -54,15 +54,17 @@ async function startServer () { await app.listen(config.port) console.log(`Server started on ${config.port}`) - try { - const iRedMail = new IRedMail() - await iRedMail.sequelize.authenticate() - console.log('Connection to the iRedMail postgres database has been established successfully.') + if (process.env.TEST_ENV !== 'unit') { + try { + const iRedMail = new IRedMail() + await iRedMail.sequelize.authenticate() + console.log('Connection to the iRedMail postgres database has been established successfully.') - // Attach to iRedMail instantiation to the context object. - app.context.iRedMail = iRedMail - } catch (err) { - console.log(`Could not connect to iRedMail instance.`) + // Attach to iRedMail instantiation to the context object. + app.context.iRedMail = iRedMail + } catch (err) { + console.log(`Could not connect to iRedMail instance.`) + } } return app diff --git a/config/env/development.js b/config/env/development.js index 47f1615..d797fa3 100644 --- a/config/env/development.js +++ b/config/env/development.js @@ -9,5 +9,5 @@ export default { module.exports = { session: 'secret-boilerplate-token', token: 'secret-jwt-token', - database: 'mongodb://localhost:27017/p2pvps-server-dev' + database: 'mongodb://localhost:27017/iredmail-dev' } diff --git a/config/env/production.js b/config/env/production.js index a68e550..1364106 100644 --- a/config/env/production.js +++ b/config/env/production.js @@ -9,5 +9,5 @@ export default { module.exports = { session: 'secret-boilerplate-token', token: 'secret-jwt-token', - database: 'mongodb://localhost:27017/p2pvps-server-prod' + database: 'mongodb://localhost:27017/iredmail-prod' } diff --git a/config/env/test.js b/config/env/test.js index 9cc99f1..bcf077f 100644 --- a/config/env/test.js +++ b/config/env/test.js @@ -9,5 +9,5 @@ export default { module.exports = { session: 'secret-boilerplate-token', token: 'secret-jwt-token', - database: 'mongodb://localhost:27017/p2pvps-server-test' + database: 'mongodb://localhost:27017/irestmail-test' } diff --git a/config/index.js b/config/index.js index d8e1d3a..ed7edc8 100644 --- a/config/index.js +++ b/config/index.js @@ -7,7 +7,7 @@ try { } // Default to development environment. -const env = process.env.NODE_ENV || 'development' +const env = process.env.APP_ENV || 'development' // Load the config object for the selected environment. const config = require(`./env/${env}`) diff --git a/package.json b/package.json index 5222802..b4fed41 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "start": "node index.js", - "test": "NODE_ENV=test nyc --reporter=text ./node_modules/.bin/mocha --exit", + "test": "APP_ENV=test TEST_ENV=unit nyc --reporter=text ./node_modules/.bin/mocha --exit", + "test:integration": "APP_ENV=test TEST_ENV=integration nyc --reporter=text ./node_modules/.bin/mocha --timeout 15000 --exit", "lint": "eslint src/**/*.js", "docs": "./node_modules/.bin/apidoc -i src/ -o docs", "coverage": "nyc report --reporter=text-lcov | coveralls", diff --git a/postgres/models/forwardings.js b/postgres/models/forwardings.js new file mode 100644 index 0000000..e33a8ed --- /dev/null +++ b/postgres/models/forwardings.js @@ -0,0 +1,42 @@ +/* + Forwardings table in the iRedMail postgres database. + + The constructor cxpects an instantiation of the sequalize class. Returns a + Sequelize model. +*/ + +'use strict' + +const Sequelize = require('sequelize') + +class Forwardings { + // Expects an instantiation of the sequalize class. Returns a Sequelize model. + constructor (sequelize) { + return sequelize.define( + 'forwardings', + { + id: { type: Sequelize.INTEGER, primaryKey: true }, + address: Sequelize.STRING, + forwarding: Sequelize.STRING, + domain: Sequelize.STRING, + dest_domain: Sequelize.STRING, + is_maillist: Sequelize.INTEGER, + is_list: Sequelize.INTEGER, + is_forwarding: Sequelize.INTEGER, + is_alias: Sequelize.INTEGER, + active: Sequelize.INTEGER + }, + { + timestamps: false, + // disable the modification of tablenames; By default, sequelize will automatically + // transform all passed model names (first parameter of define) into plural. + // if you don't want that, set the following + freezeTableName: true, + // define the table's name + tableName: 'forwardings' + } + ) + } +} + +module.exports = Forwardings diff --git a/postgres/models/mailbox.js b/postgres/models/mailbox.js new file mode 100644 index 0000000..2cc82eb --- /dev/null +++ b/postgres/models/mailbox.js @@ -0,0 +1,80 @@ +/* + mailbox table in the iRedMail postgres database. + + The constructor expects an instantiation of the sequalize class. Returns a + Sequelize model. +*/ + +'use strict' + +const Sequelize = require('sequelize') + +class Mailbox { + // Expects an instantiation of the sequalize class. Returns a Sequelize model. + constructor (sequelize) { + return sequelize.define( + 'mailbox', + { + username: { type: Sequelize.STRING, primaryKey: true }, + password: Sequelize.STRING, + name: Sequelize.STRING, + language: Sequelize.STRING, + storagebasedirectory: Sequelize.STRING, + storagenode: Sequelize.STRING, + maildir: Sequelize.STRING, + quota: Sequelize.BIGINT, + domain: Sequelize.STRING, + transport: Sequelize.STRING, + department: Sequelize.STRING, + rank: Sequelize.STRING, + employeeid: Sequelize.STRING, + isadmin: Sequelize.INTEGER, + isglobaladmin: Sequelize.INTEGER, + enablesmtp: Sequelize.INTEGER, + enablesmtpsecured: Sequelize.INTEGER, + enableimaptls: Sequelize.INTEGER, + enabledeliver: Sequelize.INTEGER, + enablelda: Sequelize.INTEGER, + enablemanagesieve: Sequelize.INTEGER, + enablemanagesievesecured: Sequelize.INTEGER, + enablesieve: Sequelize.INTEGER, + enablesievesecured: Sequelize.INTEGER, + enablesievetls: Sequelize.INTEGER, + enableinternal: Sequelize.INTEGER, + enabledoveadm: Sequelize.INTEGER, + 'enablelib-storage': Sequelize.INTEGER, + 'enableindexer-worker': Sequelize.INTEGER, + enablelmtp: Sequelize.INTEGER, + enabledsync: Sequelize.INTEGER, + enablesogo: Sequelize.INTEGER, + allow_nets: Sequelize.STRING, + lastlogindate: Sequelize.DATE, + lastloginipv4: Sequelize.INET, + lastloginprotocol: Sequelize.STRING, + disclaimer: Sequelize.STRING, + allowedsenders: Sequelize.STRING, + rejectedsenders: Sequelize.STRING, + allowedrecipients: Sequelize.STRING, + rejectedrecipients: Sequelize.STRING, + settings: Sequelize.STRING, + passwordlastchange: Sequelize.DATE, + created: Sequelize.DATE, + modified: Sequelize.DATE, + expired: Sequelize.DATE, + active: Sequelize.INTEGER + }, + { + timestamps: false, + // disable the modification of tablenames; By default, sequelize will automatically + // transform all passed model names (first parameter of define) into plural. + // if you don't want that, set the following + freezeTableName: true, + // define the table's name + tableName: 'mailbox' + } + + ) + } +} + +module.exports = Mailbox diff --git a/src/modules/iredmail/controller.js b/src/modules/iredmail/controller.js new file mode 100644 index 0000000..a765b1c --- /dev/null +++ b/src/modules/iredmail/controller.js @@ -0,0 +1,65 @@ +// const User = require('../../models/users') + +const util = require('util') +util.inspect.defaultOptions = { depth: 1 } + +async function createUser (ctx) { + try { + const modelMailbox = await ctx.iRedMail.models.mailbox.sync() + const modelForwardings = await ctx.iRedMail.models.forwardings.sync() + + // http://docs.sequelizejs.com/ + // await modelMailbox.create({}) + + ctx.body = {} + } catch (err) { + console.log(`Error in iredmail.createUser(): `, err) + ctx.throw(500, err.message) + } +} + +/* + Create a new user by manipulating the postgres database. +*/ +async function getUsers (ctx) { + try { + // Sync the model. + // const model = await ctx.iRedMail.models.usedQuota.sync() + const model = await ctx.iRedMail.models.mailbox.sync() + // const model = await ctx.iRedMail.models.forwardings.sync() + + // Get every model in the database. + const data = await model.findAll() + + // Get just the user name. + const users = data.map(x => x.username) + + ctx.body = users + } catch (err) { + console.log(`Error in iredmail.getUsers(): `, err) + ctx.throw(500, err.message) + } + /* + const user = new User(ctx.request.body.user) + try { + await user.save() + } catch (err) { + ctx.throw(422, err.message) + } + + const token = user.generateToken() + const response = user.toJSON() + + delete response.password + + ctx.body = { + user: response, + token + } + */ +} + +module.exports = { + createUser, + getUsers +} diff --git a/src/modules/iredmail/router.js b/src/modules/iredmail/router.js new file mode 100644 index 0000000..63ff9a9 --- /dev/null +++ b/src/modules/iredmail/router.js @@ -0,0 +1,21 @@ +// const ensureUser = require('../../middleware/validators') +const iredmail = require('./controller') + +module.exports.baseUrl = '/iredmail' + +module.exports.routes = [ + { + method: 'POST', + route: '/adduser', + handlers: [ + iredmail.createUser + ] + }, + { + method: 'GET', + route: '/', + handlers: [ + iredmail.getUsers + ] + } +] diff --git a/test/a03-iredmail.spec.js b/test/a03-iredmail.spec.js new file mode 100644 index 0000000..1cc0a09 --- /dev/null +++ b/test/a03-iredmail.spec.js @@ -0,0 +1,78 @@ +/* +*/ + +'use strict' + +const rp = require('request-promise') +const assert = require('chai').assert + +const IRedMail = require('../bin/iredmail') + +const util = require('util') +util.inspect.defaultOptions = { depth: 1 } + +const LOCALHOST = 'http://localhost:5000' + +describe('#iRedMail', () => { + let testType = 'unit' + + before(async () => { + // Detect integration test flag. + if (process.env.TEST_ENV === 'integration') { + testType = 'integration' + + // iRedMail = new IRedMail() + // await iRedMail.sequelize.authenticate() + } + }) + + describe('#createUser', () => { + if (process.env.TEST_ENV === 'integration') { + it('should get database models', async () => { + try { + // console.log(`Hello world!`) + + const options = { + method: 'POST', + uri: `${LOCALHOST}/iredmail/adduser`, + resolveWithFullResponse: true, + json: true, + body: { + } + } + + let result = await rp(options) + console.log(`result: ${util.inspect(result.body)}`) + } catch (err) { + console.log(`Error in #createUser test: `, err) + } + }) + } + }) + + describe('#getUsers', () => { + if (process.env.TEST_ENV === 'integration') { + it('should get usernames of all users in mailbox table', async () => { + try { + // console.log(`Hello world!`) + + const options = { + method: 'GET', + uri: `${LOCALHOST}/iredmail`, + resolveWithFullResponse: true, + json: true + } + + let result = await rp(options) + // console.log(`result: ${util.inspect(result.body)}`) + + // Returns an array of username/email strings. + assert.isArray(result.body) + assert.isString(result.body[0]) + } catch (err) { + console.log(`Error in #createUser test: `, err) + } + }) + } + }) +})