2018-10-03 22:06:08 +00:00
var fs = require ( 'fs' ) ;
2018-09-28 05:37:08 +00:00
module . exports = function ( s , config , lang ) {
//Authenticator functions
s . api = { }
2018-10-06 04:33:51 +00:00
s . superUsersApi = { }
2018-09-29 15:00:51 +00:00
s . factorAuth = { }
2018-09-28 05:37:08 +00:00
s . failedLoginAttempts = { }
2019-07-08 03:40:02 +00:00
//
2019-07-08 04:02:08 +00:00
var getUserByUid = function ( params , columns , callback ) {
2019-07-08 03:01:16 +00:00
if ( ! columns ) columns = '*'
s . sqlQuery ( ` SELECT ${ columns } FROM Users WHERE uid=? AND ke=? ` , [ params . uid , params . ke ] , function ( err , r ) {
if ( ! r ) r = [ ]
var user = r [ 0 ]
callback ( err , user )
} )
}
var getUserBySessionKey = function ( params , callback ) {
s . sqlQuery ( 'SELECT * FROM Users WHERE auth=? AND ke=?' , [ params . auth , params . ke ] , function ( err , r ) {
if ( ! r ) r = [ ]
var user = r [ 0 ]
callback ( err , user )
} )
}
var loginWithUsernameAndPassword = function ( params , columns , callback ) {
if ( ! columns ) columns = '*'
s . sqlQuery ( ` SELECT ${ columns } FROM Users WHERE mail=? AND (pass=? OR pass=?) LIMIT 1 ` , [ params . username , params . password , s . createHash ( params . password ) ] , function ( err , r ) {
if ( ! r ) r = [ ]
var user = r [ 0 ]
createSession ( user )
callback ( err , user )
} )
}
var getApiKey = function ( params , columns , callback ) {
if ( ! columns ) columns = '*'
s . sqlQuery ( ` SELECT ${ columns } FROM API WHERE code=? AND ke=? ` , [ params . auth , params . ke ] , function ( err , r ) {
if ( ! r ) r = [ ]
var apiKey = r [ 0 ]
callback ( err , apiKey )
} )
}
var loginWithApiKey = function ( params , callback ) {
getApiKey ( params , '*' , function ( err , apiKey ) {
var isSessionKey = false
if ( apiKey ) {
createSession ( apiKey , {
auth : params . auth ,
2019-07-08 03:57:55 +00:00
permissions : JSON . parse ( apiKey . details ) ,
2019-07-08 03:01:16 +00:00
details : { }
} )
getUserByUid ( apiKey , 'mail,details' , function ( err , user ) {
if ( user ) {
try {
editSession ( params , {
mail : user . mail ,
details : s . parseJSON ( user . details ) ,
2019-07-08 04:08:52 +00:00
lang : s . getLanguageFile ( user . details . lang )
2019-07-08 03:01:16 +00:00
} )
} catch ( er ) {
console . log ( er )
}
}
callback ( err , s . api [ params . auth ] )
} )
} else {
getUserBySessionKey ( params , function ( err , user ) {
if ( user ) {
isSessionKey = true
createSession ( apiKey , {
2019-07-08 03:58:33 +00:00
details : JSON . parse ( user . details ) ,
2019-07-08 03:01:16 +00:00
permissions : { }
} )
callback ( err , user , isSessionKey )
}
} )
}
} )
}
var createSession = function ( user , additionalData ) {
if ( user ) {
if ( ! additionalData ) additionalData = { }
if ( ! user . ip ) user . ip = '0.0.0.0'
user . auth = s . gid ( 20 )
user . details = JSON . parse ( user . details )
user . permissions = { }
s . api [ user . auth ] = Object . assign ( user , additionalData )
}
}
var editSession = function ( user , additionalData ) {
if ( user ) {
if ( ! additionalData ) additionalData = { }
Object . keys ( additionalData ) . forEach ( function ( value , key ) {
s . api [ user . auth ] [ key ] = value
} )
}
}
var failHttpAuthentication = function ( res , req , message ) {
if ( ! message ) message = lang [ 'Not Authorized' ]
res . end ( s . prettyPrint ( {
ok : false ,
2019-07-08 04:05:02 +00:00
msg : message
2019-07-08 03:01:16 +00:00
} ) )
}
var resetActiveSessionTimer = function ( activeSession ) {
clearTimeout ( activeSession . timeout )
activeSession . timeout = setTimeout ( function ( ) {
delete ( activeSession )
} , 1000 * 60 * 5 )
}
s . auth = function ( params , onSuccessComplete , res , req ) {
2018-09-28 05:37:08 +00:00
if ( req ) {
//express (http server) use of auth function
2019-07-08 03:01:16 +00:00
params . ip = req . headers [ 'cf-connecting-ip' ] || req . headers [ 'x-forwarded-for' ] || req . connection . remoteAddress
var onFail = function ( message ) {
failHttpAuthentication ( res , req , message )
2018-09-28 05:37:08 +00:00
}
} else {
//socket.io use of auth function
2019-07-08 03:01:16 +00:00
var onFail = function ( ) {
2018-09-28 05:37:08 +00:00
//maybe log
}
}
2019-07-08 03:01:16 +00:00
var onSuccess = function ( user ) {
var activeSession = s . api [ params . auth ]
if (
activeSession . ip . indexOf ( '0.0.0.0' ) > - 1 ||
activeSession . ip . indexOf ( params . ip ) > - 1
) {
2018-12-17 00:54:06 +00:00
if ( ! user . lang ) {
var details = s . parseJSON ( user . details ) . lang
user . lang = s . getDefinitonFile ( user . details . lang ) || s . copySystemDefaultLanguage ( )
}
2019-07-08 03:01:16 +00:00
onSuccessComplete ( user )
2018-09-28 05:37:08 +00:00
} else {
2019-07-08 03:01:16 +00:00
onFail ( )
2018-09-28 05:37:08 +00:00
}
}
2019-07-08 03:01:16 +00:00
if ( s . group [ params . ke ] && s . group [ params . ke ] . users && s . group [ params . ke ] . users [ params . auth ] ) {
var activeSession = s . group [ params . ke ] . users [ params . auth ]
activeSession . permissions = { }
if ( ! activeSession . lang ) {
activeSession . lang = s . copySystemDefaultLanguage ( )
2018-12-17 00:54:06 +00:00
}
2019-07-08 03:01:16 +00:00
onSuccessComplete ( activeSession )
2018-09-28 05:37:08 +00:00
} else {
2019-07-08 03:01:16 +00:00
if ( s . api [ params . auth ] && s . api [ params . auth ] . details ) {
var activeSession = s . api [ params . auth ]
onSuccess ( activeSession )
if ( activeSession . timeout ) {
resetActiveSessionTimer ( activeSession )
2018-09-28 05:37:08 +00:00
}
} else {
2019-07-08 03:01:16 +00:00
if ( params . username && params . username !== '' && params . password && params . password !== '' ) {
loginWithUsernameAndPassword ( params , '*' , function ( err , user ) {
if ( user ) {
params . auth = user . auth
resetActiveSessionTimer ( s . api [ params . auth ] )
onSuccess ( user )
2018-09-28 05:37:08 +00:00
} else {
2019-07-08 03:01:16 +00:00
onFail ( )
2018-09-28 05:37:08 +00:00
}
} )
} else {
2019-07-08 03:01:16 +00:00
loginWithApiKey ( params , function ( err , user , isSessionKey ) {
if ( isSessionKey ) resetActiveSessionTimer ( s . api [ params . auth ] )
if ( user ) {
onSuccess ( s . api [ params . auth ] )
2018-09-28 05:37:08 +00:00
} else {
2019-07-08 03:01:16 +00:00
onFail ( )
2018-09-28 05:37:08 +00:00
}
} )
}
}
}
}
//super user authentication handler
2018-10-05 21:19:29 +00:00
s . superAuth = function ( params , callback , res , req ) {
2018-10-03 22:06:08 +00:00
var userFound = false
2018-10-05 21:19:29 +00:00
var userSelected = false
2018-10-06 06:20:16 +00:00
var adminUsersSelected = null
2018-10-03 22:06:08 +00:00
try {
2018-10-06 06:20:16 +00:00
var success = function ( ) {
2019-04-03 03:47:03 +00:00
var chosenConfig = config
2018-10-06 06:20:16 +00:00
if ( req && res ) {
2019-04-03 03:47:03 +00:00
chosenConfig = s . getConfigWithBranding ( req . hostname )
2019-07-08 03:01:16 +00:00
res . setHeader ( 'Content-Type' , 'application/json' )
2018-10-06 06:20:16 +00:00
var ip = req . headers [ 'cf-connecting-ip' ] || req . headers [ "CF-Connecting-IP" ] || req . headers [ "'x-forwarded-for" ] || req . connection . remoteAddress ;
var resp = {
ok : userFound ,
ip : ip
}
if ( userFound === false ) {
resp . msg = lang [ 'Not Authorized' ]
res . end ( s . prettyPrint ( resp ) )
}
if ( userSelected ) {
resp . $user = userSelected
}
if ( adminUsersSelected ) {
resp . users = adminUsersSelected
}
}
callback ( {
ip : ip ,
2019-07-08 03:40:02 +00:00
$user : userSelected ,
users : adminUsersSelected ,
2019-04-03 03:47:03 +00:00
config : chosenConfig ,
2018-10-06 06:20:16 +00:00
lang : lang
} )
}
2018-10-06 04:33:51 +00:00
var foundUser = function ( ) {
if ( params . users === true ) {
s . sqlQuery ( 'SELECT * FROM Users WHERE details NOT LIKE ?' , [ '%"sub"%' ] , function ( err , r ) {
adminUsersSelected = r
2018-10-06 06:20:16 +00:00
success ( )
2018-10-06 04:33:51 +00:00
} )
} else {
2018-10-06 06:20:16 +00:00
success ( )
2018-09-28 05:37:08 +00:00
}
2018-10-06 04:33:51 +00:00
}
if ( params . auth && s . superUsersApi [ params . auth ] ) {
userFound = true
userSelected = s . superUsersApi [ params . auth ] . $user
foundUser ( )
} else {
var superUserList = JSON . parse ( fs . readFileSync ( s . location . super ) )
superUserList . forEach ( function ( superUser , n ) {
if (
userFound === false &&
(
params . auth && superUser . tokens && superUser . tokens [ params . auth ] || //using API key (object)
params . auth && superUser . tokens && superUser . tokens . indexOf && superUser . tokens . indexOf ( params . auth ) > - 1 || //using API key (array)
(
2018-10-06 06:20:16 +00:00
params . mail && params . mail . toLowerCase ( ) === superUser . mail . toLowerCase ( ) && //email matches
2018-10-06 04:33:51 +00:00
(
params . pass === superUser . pass || //user give it already hashed
superUser . pass === s . createHash ( params . pass ) || //hash and check it
superUser . pass . toLowerCase ( ) === s . md5 ( params . pass ) . toLowerCase ( ) //check if still using md5
)
)
)
) {
userFound = true
userSelected = superUser
foundUser ( )
}
} )
}
2018-10-03 22:06:08 +00:00
} catch ( err ) {
2018-10-05 21:19:29 +00:00
console . log ( 'The following error may mean your super.json is not formatted correctly.' )
2018-10-03 22:06:08 +00:00
console . log ( err )
}
if ( userFound === true ) {
return true
2018-09-28 05:37:08 +00:00
} else {
2018-12-13 04:05:07 +00:00
if ( res ) res . end ( s . prettyPrint ( {
ok : false ,
msg : lang [ 'Not Authorized' ]
} ) )
2018-10-03 22:06:08 +00:00
return false
2018-09-28 05:37:08 +00:00
}
}
2019-04-06 05:27:22 +00:00
s . basicOrApiAuthentication = function ( username , password , callback ) {
var splitUsername = username . split ( '@' )
2019-06-05 23:08:34 +00:00
if ( splitUsername [ 1 ] && splitUsername [ 1 ] . toLowerCase ( ) . indexOf ( 'shinobi' ) > - 1 ) {
2019-07-08 03:01:16 +00:00
getApiKey ( params , 'ke,uid' , callback )
2019-06-05 23:08:34 +00:00
} else {
2019-07-08 03:01:16 +00:00
loginWithUsernameAndPassword ( params , 'ke,uid' , callback )
2019-04-06 05:27:22 +00:00
}
}
2018-09-28 05:37:08 +00:00
}