2016-05-26 22:34:04 -07:00
'use strict' ;
exports = module . exports = {
add : add ,
del : del ,
2016-09-25 23:21:55 -07:00
listAliases : listAliases ,
listMailboxes : listMailboxes ,
2016-09-25 18:59:11 -07:00
getMailbox : getMailbox ,
getGroup : getGroup ,
getAlias : getAlias ,
2016-09-25 23:21:55 -07:00
2016-09-26 14:02:23 -07:00
getAliasesForName : getAliasesForName ,
setAliasesForName : setAliasesForName ,
2016-09-25 23:21:55 -07:00
2016-09-23 17:35:48 -07:00
getByOwnerId : getByOwnerId ,
2016-09-22 15:55:18 -07:00
delByOwnerId : delByOwnerId ,
2016-05-26 22:34:04 -07:00
2016-12-15 16:13:16 +01:00
updateName : updateName ,
2016-09-22 15:55:18 -07:00
_clear : clear ,
TYPE _USER : 'user' ,
TYPE _APP : 'app' ,
TYPE _GROUP : 'group'
2016-05-26 22:34:04 -07:00
} ;
var assert = require ( 'assert' ) ,
database = require ( './database.js' ) ,
2016-05-27 19:20:42 -07:00
DatabaseError = require ( './databaseerror.js' ) ,
util = require ( 'util' ) ;
2016-05-26 22:34:04 -07:00
2016-09-21 14:51:13 -07:00
var MAILBOX _FIELDS = [ 'name' , 'ownerId' , 'ownerType' , 'aliasTarget' , 'creationTime' ] . join ( ',' ) ;
2016-05-26 22:34:04 -07:00
2016-09-22 15:55:18 -07:00
function add ( name , ownerId , ownerType , callback ) {
2016-05-26 22:34:04 -07:00
assert . strictEqual ( typeof name , 'string' ) ;
2016-09-22 15:55:18 -07:00
assert . strictEqual ( typeof ownerId , 'string' ) ;
assert . strictEqual ( typeof ownerType , 'string' ) ;
2016-05-26 22:34:04 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-25 23:51:39 -07:00
database . query ( 'INSERT INTO mailboxes (name, ownerId, ownerType) VALUES (?, ?, ?)' , [ name , ownerId , ownerType ] , function ( error ) {
2016-09-28 12:00:05 -07:00
if ( error && error . code === 'ER_DUP_ENTRY' ) return callback ( new DatabaseError ( DatabaseError . ALREADY _EXISTS , 'mailbox already exists' ) ) ;
2016-09-21 15:34:58 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null ) ;
} ) ;
}
2016-05-26 22:34:04 -07:00
function clear ( callback ) {
assert . strictEqual ( typeof callback , 'function' ) ;
database . query ( 'TRUNCATE TABLE mailboxes' , [ ] , function ( error ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null ) ;
} ) ;
}
2016-05-27 19:20:42 -07:00
function del ( name , callback ) {
assert . strictEqual ( typeof name , 'string' ) ;
2016-05-26 22:34:04 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-05-27 19:20:42 -07:00
// deletes aliases as well
database . query ( 'DELETE FROM mailboxes WHERE name=? OR aliasTarget = ?' , [ name , name ] , function ( error , result ) {
2016-05-26 22:34:04 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
2016-05-27 17:43:25 -07:00
if ( result . affectedRows === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2016-05-26 22:34:04 -07:00
callback ( null ) ;
} ) ;
}
2016-09-22 15:55:18 -07:00
function delByOwnerId ( id , callback ) {
assert . strictEqual ( typeof id , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
// deletes aliases as well
2016-09-25 23:21:55 -07:00
database . query ( 'DELETE FROM mailboxes WHERE ownerId=?' , [ id ] , function ( error ) {
2016-09-22 15:55:18 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null ) ;
} ) ;
}
2016-12-15 16:13:16 +01:00
function updateName ( oldName , newName , callback ) {
assert . strictEqual ( typeof oldName , 'string' ) ;
assert . strictEqual ( typeof newName , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-12-15 16:42:11 +01:00
// skip if no changes
if ( oldName === newName ) return callback ( null ) ;
2016-12-15 16:13:16 +01:00
database . query ( 'UPDATE mailboxes SET name=? WHERE name=?' , [ newName , oldName ] , function ( error , result ) {
if ( error && error . code === 'ER_DUP_ENTRY' ) return callback ( new DatabaseError ( DatabaseError . ALREADY _EXISTS , 'mailbox already exists' ) ) ;
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . affectedRows !== 1 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null ) ;
} ) ;
}
2016-09-25 18:59:11 -07:00
function getMailbox ( name , callback ) {
assert . strictEqual ( typeof name , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-28 10:26:41 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE name = ? AND (ownerType = ? OR ownerType = ?) AND aliasTarget IS NULL' , [ name , exports . TYPE _APP , exports . TYPE _USER ] , function ( error , results ) {
2016-09-25 18:59:11 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( results . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , results [ 0 ] ) ;
} ) ;
}
2016-09-25 23:21:55 -07:00
function listMailboxes ( callback ) {
2016-09-25 18:59:11 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-28 10:26:41 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE (ownerType = ? OR ownerType = ?) AND aliasTarget IS NULL ORDER BY name' , [ exports . TYPE _APP , exports . TYPE _USER ] , function ( error , results ) {
2016-09-25 18:59:11 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null , results ) ;
} ) ;
}
function getGroup ( name , callback ) {
assert . strictEqual ( typeof name , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-27 16:27:22 -07:00
// This can be merged into a single query but cannot get 'not found' information
// SELECT users.username FROM mailboxes
// INNER JOIN groupMembers ON mailboxes.ownerId = groupMembers.groupId
// INNER JOIN users ON groupMembers.userId = users.id
// WHERE mailboxes.name = <name>
2016-09-28 10:26:41 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE name = ? AND ownerType = ? AND aliasTarget IS NULL' , [ name , exports . TYPE _GROUP ] , function ( error , results ) {
2016-09-25 18:59:11 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( results . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2016-09-27 16:27:22 -07:00
database . query ( 'SELECT users.username FROM groupMembers INNER JOIN users ON groupMembers.userId = users.id WHERE groupMembers.groupId = ?' , [ results [ 0 ] . ownerId ] , function ( error , memberList ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
results [ 0 ] . members = memberList . map ( function ( m ) { return m . username ; } ) ;
callback ( null , results [ 0 ] ) ;
} ) ;
2016-09-25 18:59:11 -07:00
} ) ;
}
2016-09-23 17:35:48 -07:00
function getByOwnerId ( ownerId , callback ) {
assert . strictEqual ( typeof ownerId , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-25 23:21:55 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE ownerId = ? ORDER BY name' , [ ownerId ] , function ( error , results ) {
2016-09-23 17:35:48 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( results . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2016-09-25 23:21:55 -07:00
callback ( null , results ) ;
2016-09-23 17:35:48 -07:00
} ) ;
}
2016-09-26 14:02:23 -07:00
function setAliasesForName ( name , aliases , callback ) {
2016-05-27 19:20:42 -07:00
assert . strictEqual ( typeof name , 'string' ) ;
assert ( util . isArray ( aliases ) ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-25 23:21:55 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE name = ? ' , [ name ] , function ( error , results ) {
2016-05-27 19:20:42 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
2016-09-25 23:21:55 -07:00
if ( results . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2016-05-27 19:20:42 -07:00
2016-09-25 23:21:55 -07:00
var queries = [ ] ;
queries . push ( { query : 'DELETE FROM mailboxes WHERE aliasTarget = ?' , args : [ name ] } ) ;
aliases . forEach ( function ( alias ) {
queries . push ( { query : 'INSERT INTO mailboxes (name, aliasTarget, ownerId, ownerType) VALUES (?, ?, ?, ?)' ,
args : [ alias , name , results [ 0 ] . ownerId , results [ 0 ] . ownerType ] } ) ;
} ) ;
database . transaction ( queries , function ( error ) {
if ( error && error . code === 'ER_DUP_ENTRY' ) return callback ( new DatabaseError ( DatabaseError . ALREADY _EXISTS , error . message ) ) ;
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null ) ;
} ) ;
2016-05-27 19:20:42 -07:00
} ) ;
}
2016-09-26 14:02:23 -07:00
function getAliasesForName ( name , callback ) {
2016-05-27 19:20:42 -07:00
assert . strictEqual ( typeof name , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
database . query ( 'SELECT name FROM mailboxes WHERE aliasTarget=? ORDER BY name' , [ name ] , function ( error , results ) {
2016-05-26 22:34:04 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
2016-05-27 19:20:42 -07:00
results = results . map ( function ( r ) { return r . name ; } ) ;
2016-05-26 22:34:04 -07:00
callback ( null , results ) ;
} ) ;
}
2016-09-25 18:59:11 -07:00
2016-09-25 23:21:55 -07:00
function listAliases ( callback ) {
2016-09-25 18:59:11 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-09-25 23:21:55 -07:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE aliasTarget IS NOT NULL ORDER BY name' , function ( error , results ) {
2016-09-25 18:59:11 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null , results ) ;
} ) ;
}
function getAlias ( name , callback ) {
assert . strictEqual ( typeof name , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2017-02-14 10:42:32 -08:00
database . query ( 'SELECT ' + MAILBOX _FIELDS + ' FROM mailboxes WHERE name = ? AND aliasTarget IS NOT NULL' , [ name ] , function ( error , results ) {
2016-09-25 18:59:11 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( results . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , results [ 0 ] ) ;
} ) ;
}