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 ,
2018-12-07 14:35:04 -08:00
clear : clear
2017-10-28 21:42:32 +02:00
} ;
var assert = require ( 'assert' ) ,
2019-10-24 11:13:48 -07:00
BoxError = require ( './boxerror.js' ) ,
2017-10-28 21:42:32 +02:00
database = require ( './database.js' ) ,
safe = require ( 'safetydance' ) ;
2020-02-13 21:12:49 -08:00
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 ) ;
2017-11-13 00:09:01 +01:00
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 ) {
2019-10-24 11:13:48 -07:00
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 ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( new BoxError ( BoxError . DATABASE _ERROR , error ) ) ;
2017-10-28 21:42:32 +02:00
results . forEach ( postProcess ) ;
callback ( null , results ) ;
} ) ;
}
2020-03-31 12:04:46 -07:00
function add ( name , data , callback ) {
2018-01-20 10:14:55 -08:00
assert . strictEqual ( typeof name , 'string' ) ;
2020-03-31 12:04:46 -07:00
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' ) ;
2020-03-31 12:04:46 -07:00
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 ) {
2019-10-24 11:13:48 -07:00
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' ) ) ;
2019-10-24 11:13:48 -07:00
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' ) ;
2020-03-31 12:04:46 -07:00
let queries = [
{ query : 'DELETE FROM mail WHERE domain = ?' , args : [ domain ] } ,
{ query : 'DELETE FROM domains WHERE domain = ?' , args : [ domain ] } ,
] ;
database . transaction ( queries , function ( error , results ) {
2020-03-07 13:57:37 -08:00
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 ) ) ;
}
2020-03-31 12:04:46 -07:00
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( new BoxError ( BoxError . DATABASE _ERROR , error ) ) ;
2020-03-31 12:04:46 -07:00
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 ) {
2019-10-24 11:13:48 -07:00
if ( error ) return callback ( new BoxError ( BoxError . DATABASE _ERROR , error ) ) ;
2017-10-28 21:42:32 +02:00
callback ( error ) ;
} ) ;
}