2015-07-20 00:09:47 -07:00
'use strict' ;
exports = module . exports = {
get : get ,
getByUsername : getByUsername ,
getByEmail : getByEmail ,
getByAccessToken : getByAccessToken ,
getByResetToken : getByResetToken ,
2016-01-13 12:28:38 -08:00
getOwner : getOwner ,
2016-02-09 09:37:12 -08:00
getAllWithGroupIds : getAllWithGroupIds ,
2015-07-20 00:09:47 -07:00
getAllAdmins : getAllAdmins ,
add : add ,
del : del ,
update : update ,
count : count ,
_clear : clear
} ;
var assert = require ( 'assert' ) ,
database = require ( './database.js' ) ,
debug = require ( 'debug' ) ( 'box:userdb' ) ,
2016-02-08 16:10:44 -08:00
DatabaseError = require ( './databaseerror' ) ,
groups = require ( './groups.js' ) ;
2015-07-20 00:09:47 -07:00
2016-02-08 16:18:00 -08:00
var USERS _FIELDS = [ 'id' , 'username' , 'email' , 'password' , 'salt' , 'createdAt' , 'modifiedAt' , 'resetToken' , 'displayName' ] . join ( ',' ) ;
2015-07-20 00:09:47 -07:00
function get ( userId , callback ) {
assert . strictEqual ( typeof userId , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users WHERE id = ?' , [ userId ] , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , result [ 0 ] ) ;
} ) ;
}
function getByUsername ( username , callback ) {
assert . strictEqual ( typeof username , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-04-01 21:43:48 +02:00
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users WHERE username = ?' , [ username ] , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , result [ 0 ] ) ;
} ) ;
2015-07-20 00:09:47 -07:00
}
function getByEmail ( email , callback ) {
assert . strictEqual ( typeof email , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users WHERE email = ?' , [ email ] , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2016-01-13 12:28:38 -08:00
callback ( null , result [ 0 ] ) ;
} ) ;
}
function getOwner ( callback ) {
assert . strictEqual ( typeof callback , 'function' ) ;
// the first created user it the admin
2016-02-08 16:18:00 -08:00
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users, groupMembers WHERE groupMembers.groupId = ? AND users.id = groupMembers.userId ORDER BY createdAt LIMIT 1' ,
[ groups . ADMIN _GROUP _ID ] , function ( error , result ) {
2016-01-13 12:28:38 -08:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
2015-07-20 00:09:47 -07:00
callback ( null , result [ 0 ] ) ;
} ) ;
}
function getByResetToken ( resetToken , callback ) {
assert . strictEqual ( typeof resetToken , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
if ( resetToken . length === 0 ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , 'Empty resetToken not allowed' ) ) ;
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users WHERE resetToken=?' , [ resetToken ] , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , result [ 0 ] ) ;
} ) ;
}
2016-02-09 09:37:12 -08:00
function getAllWithGroupIds ( callback ) {
2015-07-20 00:09:47 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-02-09 08:52:16 -08:00
database . query ( 'SELECT ' + USERS _FIELDS + ',GROUP_CONCAT(groupMembers.groupId) AS groupIds ' +
' FROM users LEFT OUTER JOIN groupMembers ON users.id = groupMembers.userId ' +
' GROUP BY users.id' , function ( error , results ) {
2015-07-20 00:09:47 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
2016-02-09 08:52:16 -08:00
results . forEach ( function ( result ) {
result . groupIds = result . groupIds ? result . groupIds . split ( ',' ) : [ ] ;
} ) ;
2015-07-20 00:09:47 -07:00
callback ( null , results ) ;
} ) ;
}
function getAllAdmins ( callback ) {
assert . strictEqual ( typeof callback , 'function' ) ;
2016-02-08 16:10:44 -08:00
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users, groupMembers WHERE groupMembers.groupId = ? AND users.id = groupMembers.userId' ,
[ groups . ADMIN _GROUP _ID ] , function ( error , results ) {
2015-07-20 00:09:47 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null , results ) ;
} ) ;
}
function add ( userId , user , callback ) {
assert . strictEqual ( typeof userId , 'string' ) ;
assert . strictEqual ( typeof user . username , 'string' ) ;
assert . strictEqual ( typeof user . password , 'string' ) ;
assert . strictEqual ( typeof user . email , 'string' ) ;
assert . strictEqual ( typeof user . salt , 'string' ) ;
assert . strictEqual ( typeof user . createdAt , 'string' ) ;
assert . strictEqual ( typeof user . modifiedAt , 'string' ) ;
assert . strictEqual ( typeof user . resetToken , 'string' ) ;
2016-01-19 12:39:54 +01:00
assert . strictEqual ( typeof user . displayName , 'string' ) ;
2015-07-20 00:09:47 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2016-02-08 16:18:00 -08:00
var data = [ userId , user . username , user . password , user . email , user . salt , user . createdAt , user . modifiedAt , user . resetToken , user . displayName ] ;
database . query ( 'INSERT INTO users (id, username, password, email, salt, createdAt, modifiedAt, resetToken, displayName) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' ,
2015-07-20 00:09:47 -07:00
data , function ( error , result ) {
if ( error && error . code === 'ER_DUP_ENTRY' ) return callback ( new DatabaseError ( DatabaseError . ALREADY _EXISTS , error ) ) ;
if ( error || result . affectedRows !== 1 ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( null ) ;
} ) ;
}
function del ( userId , callback ) {
assert . strictEqual ( typeof userId , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
2016-02-11 12:02:35 +01:00
// also cleanup the groupMembers table
var queries = [ ] ;
2016-02-11 12:07:43 +01:00
queries . push ( { query : 'DELETE FROM groupMembers WHERE userId = ?' , args : [ userId ] } ) ;
2016-02-11 12:02:35 +01:00
queries . push ( { query : 'DELETE FROM users WHERE id = ?' , args : [ userId ] } ) ;
2016-02-11 12:07:43 +01:00
database . transaction ( queries , function ( error , result ) {
if ( error && error . code === 'ER_NO_REFERENCED_ROW_2' ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND , error ) ) ;
2015-07-20 00:09:47 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
2016-02-11 12:07:43 +01:00
if ( result [ 1 ] . affectedRows !== 1 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND , error ) ) ;
2015-07-20 00:09:47 -07:00
callback ( error ) ;
} ) ;
}
function getByAccessToken ( accessToken , callback ) {
assert . strictEqual ( typeof accessToken , 'string' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
debug ( 'getByAccessToken: ' + accessToken ) ;
database . query ( 'SELECT ' + USERS _FIELDS + ' FROM users, tokens WHERE tokens.accessToken = ?' , [ accessToken ] , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . length === 0 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
callback ( null , result [ 0 ] ) ;
} ) ;
}
function clear ( callback ) {
database . query ( 'DELETE FROM users' , function ( error ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
callback ( error ) ;
} ) ;
}
function update ( userId , user , callback ) {
assert . strictEqual ( typeof userId , 'string' ) ;
assert . strictEqual ( typeof user , 'object' ) ;
assert . strictEqual ( typeof callback , 'function' ) ;
var args = [ ] ;
var fields = [ ] ;
for ( var k in user ) {
fields . push ( k + ' = ?' ) ;
args . push ( user [ k ] ) ;
}
args . push ( userId ) ;
database . query ( 'UPDATE users SET ' + fields . join ( ', ' ) + ' WHERE id = ?' , args , function ( error , result ) {
2016-04-04 12:19:41 +02:00
if ( error && error . code === 'ER_DUP_ENTRY' ) return callback ( new DatabaseError ( DatabaseError . ALREADY _EXISTS , error ) ) ;
2015-07-20 00:09:47 -07:00
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
if ( result . affectedRows !== 1 ) return callback ( new DatabaseError ( DatabaseError . NOT _FOUND ) ) ;
return callback ( null ) ;
} ) ;
}
function count ( callback ) {
assert . strictEqual ( typeof callback , 'function' ) ;
database . query ( 'SELECT COUNT(*) AS total FROM users' , function ( error , result ) {
if ( error ) return callback ( new DatabaseError ( DatabaseError . INTERNAL _ERROR , error ) ) ;
return callback ( null , result [ 0 ] . total ) ;
} ) ;
}