Files
cloudron-box/src/domaindb.js

136 lines
5.0 KiB
JavaScript
Raw Normal View History

2017-10-28 21:42:32 +02:00
/* jslint node:true */
'use strict';
exports = module.exports = {
add: add,
get: get,
getAll: getAll,
update: update,
del: del,
clear: clear
2017-10-28 21:42:32 +02:00
};
var assert = require('assert'),
BoxError = require('./boxerror.js'),
2017-10-28 21:42:32 +02:00
database = require('./database.js'),
safe = require('safetydance');
var DOMAINS_FIELDS = [ 'domain', 'zoneName', 'provider', 'configJson', 'tlsConfigJson' ].join(',');
2018-01-20 10:05:31 -08:00
2017-10-28 21:42:32 +02:00
function postProcess(data) {
data.config = safe.JSON.parse(data.configJson);
2018-01-31 16:56:22 +01:00
data.tlsConfig = safe.JSON.parse(data.tlsConfigJson);
delete data.configJson;
2018-01-31 16:56:22 +01:00
delete data.tlsConfigJson;
2017-10-28 21:42:32 +02:00
return data;
}
function get(domain, callback) {
assert.strictEqual(typeof domain, 'string');
assert.strictEqual(typeof callback, 'function');
2018-01-20 10:05:31 -08:00
database.query(`SELECT ${DOMAINS_FIELDS} FROM domains WHERE domain=?`, [ domain ], function (error, result) {
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
2019-10-24 20:48:38 -07:00
if (result.length === 0) return callback(new BoxError(BoxError.NOT_FOUND, 'Domain not found'));
2017-10-28 21:42:32 +02:00
postProcess(result[0]);
callback(null, result[0]);
});
}
function getAll(callback) {
2018-01-20 10:05:31 -08:00
database.query(`SELECT ${DOMAINS_FIELDS} FROM domains ORDER BY domain`, function (error, results) {
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
2017-10-28 21:42:32 +02:00
results.forEach(postProcess);
callback(null, results);
});
}
function add(name, data, callback) {
2018-01-20 10:14:55 -08:00
assert.strictEqual(typeof name, 'string');
assert.strictEqual(typeof data, 'object');
assert.strictEqual(typeof data.zoneName, 'string');
assert.strictEqual(typeof data.provider, 'string');
assert.strictEqual(typeof data.config, 'object');
assert.strictEqual(typeof data.tlsConfig, 'object');
2017-10-28 21:42:32 +02:00
assert.strictEqual(typeof callback, 'function');
let queries = [
{ query: 'INSERT INTO domains (domain, zoneName, provider, configJson, tlsConfigJson) VALUES (?, ?, ?, ?, ?)', args: [ name, data.zoneName, data.provider, JSON.stringify(data.config), JSON.stringify(data.tlsConfig) ] },
{ query: 'INSERT INTO mail (domain, dkimSelector) VALUES (?, ?)', args: [ name, data.dkimSelector || 'cloudron' ] },
];
database.transaction(queries, function (error) {
if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS, error));
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
2017-10-28 21:42:32 +02:00
callback(null);
});
}
2018-01-20 10:24:11 -08:00
function update(name, domain, callback) {
assert.strictEqual(typeof name, 'string');
assert.strictEqual(typeof domain, 'object');
2017-10-28 21:42:32 +02:00
assert.strictEqual(typeof callback, 'function');
2018-01-20 10:24:11 -08:00
var args = [ ], fields = [ ];
for (var k in domain) {
if (k === 'config') {
fields.push('configJson = ?');
args.push(JSON.stringify(domain[k]));
2018-01-31 16:56:22 +01:00
} else if (k === 'tlsConfig') {
fields.push('tlsConfigJson = ?');
args.push(JSON.stringify(domain[k]));
2018-01-20 10:24:11 -08:00
} else {
fields.push(k + ' = ?');
args.push(domain[k]);
}
}
args.push(name);
database.query('UPDATE domains SET ' + fields.join(', ') + ' WHERE domain=?', args, function (error) {
2019-10-24 20:48:38 -07:00
if (error && error.reason === BoxError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND, 'Domain not found'));
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
2017-10-28 21:42:32 +02:00
callback(null);
});
}
function del(domain, callback) {
assert.strictEqual(typeof domain, 'string');
assert.strictEqual(typeof callback, 'function');
let queries = [
{ query: 'DELETE FROM mail WHERE domain = ?', args: [ domain ] },
{ query: 'DELETE FROM domains WHERE domain = ?', args: [ domain ] },
];
database.transaction(queries, function (error, results) {
if (error && error.code === 'ER_ROW_IS_REFERENCED_2') {
if (error.message.indexOf('apps_mailDomain_constraint') !== -1) return callback(new BoxError(BoxError.CONFLICT, 'Domain is in use by an app or the mailbox of an app. Check the domains of apps and the Email section of each app.'));
if (error.message.indexOf('subdomains') !== -1) return callback(new BoxError(BoxError.CONFLICT, 'Domain is in use by one or more app(s).'));
if (error.message.indexOf('mail') !== -1) return callback(new BoxError(BoxError.CONFLICT, 'Domain is in use by one or more mailboxes. Delete them first in the Email view.'));
return callback(new BoxError(BoxError.CONFLICT, error.message));
}
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
if (results[1].affectedRows !== 1) return callback(new BoxError(BoxError.NOT_FOUND, 'Domain not found'));
2017-10-28 21:42:32 +02:00
callback(null);
});
}
function clear(callback) {
database.query('DELETE FROM domains', function (error) {
if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error));
2017-10-28 21:42:32 +02:00
callback(error);
});
}