2018-01-04 15:15:21 -05:00
/ * *
* @ description MeshCentral Common Library
* @ author Ylian Saint - Hilaire
* @ copyright Intel Corporation 2018
* @ license Apache - 2.0
* @ version v0 . 0.1
* /
2018-08-29 20:40:30 -04:00
/*xjslint node: true */
/*xjslint plusplus: true */
/*xjslint maxlen: 256 */
/*jshint node: true */
/*jshint strict: false */
/*jshint esversion: 6 */
"use strict" ;
2018-08-27 15:24:15 -04:00
2018-08-29 20:40:30 -04:00
const crypto = require ( "crypto" ) ;
2017-08-28 12:27:45 -04:00
// Binary encoding and decoding functions
2018-08-29 20:40:30 -04:00
module . exports . ReadShort = function ( v , p ) { return ( v . charCodeAt ( p ) << 8 ) + v . charCodeAt ( p + 1 ) ; } ;
module . exports . ReadShortX = function ( v , p ) { return ( v . charCodeAt ( p + 1 ) << 8 ) + v . charCodeAt ( p ) ; } ;
module . exports . ReadInt = function ( v , p ) { return ( v . charCodeAt ( p ) * 0x1000000 ) + ( v . charCodeAt ( p + 1 ) << 16 ) + ( v . charCodeAt ( p + 2 ) << 8 ) + v . charCodeAt ( p + 3 ) ; } ; // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
module . exports . ReadIntX = function ( v , p ) { return ( v . charCodeAt ( p + 3 ) * 0x1000000 ) + ( v . charCodeAt ( p + 2 ) << 16 ) + ( v . charCodeAt ( p + 1 ) << 8 ) + v . charCodeAt ( p ) ; } ;
module . exports . ShortToStr = function ( v ) { return String . fromCharCode ( ( v >> 8 ) & 0xFF , v & 0xFF ) ; } ;
module . exports . ShortToStrX = function ( v ) { return String . fromCharCode ( v & 0xFF , ( v >> 8 ) & 0xFF ) ; } ;
module . exports . IntToStr = function ( v ) { return String . fromCharCode ( ( v >> 24 ) & 0xFF , ( v >> 16 ) & 0xFF , ( v >> 8 ) & 0xFF , v & 0xFF ) ; } ;
module . exports . IntToStrX = function ( v ) { return String . fromCharCode ( v & 0xFF , ( v >> 8 ) & 0xFF , ( v >> 16 ) & 0xFF , ( v >> 24 ) & 0xFF ) ; } ;
module . exports . MakeToArray = function ( v ) { if ( ! v || v == null || typeof v == "object" ) return v ; return [ v ] ; } ;
module . exports . SplitArray = function ( v ) { return v . split ( "," ) ; } ;
module . exports . Clone = function ( v ) { return JSON . parse ( JSON . stringify ( v ) ) ; } ;
module . exports . IsFilenameValid = ( function ( ) { var x1 = /^[^\\/:\*\?"<>\|]+$/ , x2 = /^\./ , x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i ; return function isFilenameValid ( fname ) { return module . exports . validateString ( fname , 1 , 4096 ) && x1 . test ( fname ) && ! x2 . test ( fname ) && ! x3 . test ( fname ) && ( fname [ 0 ] != '.' ) ; } ; } ) ( ) ;
2017-08-28 12:27:45 -04:00
// Move an element from one position in an array to a new position
module . exports . ArrayElementMove = function ( arr , from , to ) { arr . splice ( to , 0 , arr . splice ( from , 1 ) [ 0 ] ) ; } ;
// Print object for HTML
2018-08-29 20:40:30 -04:00
module . exports . ObjectToStringEx = function ( x , c ) {
var r = "" , i ;
2017-08-28 12:27:45 -04:00
if ( x != 0 && ( ! x || x == null ) ) return "(Null)" ;
2018-08-29 20:40:30 -04:00
if ( x instanceof Array ) { for ( i in x ) { r += '<br />' + gap ( c ) + "Item #" + i + ": " + module . exports . ObjectToStringEx ( x [ i ] , c + 1 ) ; } }
else if ( x instanceof Object ) { for ( i in x ) { r += '<br />' + gap ( c ) + i + " = " + module . exports . ObjectToStringEx ( x [ i ] , c + 1 ) ; } }
2017-08-28 12:27:45 -04:00
else { r += x ; }
return r ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// Print object for console
2018-08-29 20:40:30 -04:00
module . exports . ObjectToStringEx2 = function ( x , c ) {
var r = "" , i ;
2017-08-28 12:27:45 -04:00
if ( x != 0 && ( ! x || x == null ) ) return "(Null)" ;
2018-08-29 20:40:30 -04:00
if ( x instanceof Array ) { for ( i in x ) { r += '\r\n' + gap2 ( c ) + "Item #" + i + ": " + module . exports . ObjectToStringEx2 ( x [ i ] , c + 1 ) ; } }
else if ( x instanceof Object ) { for ( i in x ) { r += '\r\n' + gap2 ( c ) + i + " = " + module . exports . ObjectToStringEx2 ( x [ i ] , c + 1 ) ; } }
2017-08-28 12:27:45 -04:00
else { r += x ; }
return r ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// Create an ident gap
2018-08-29 20:40:30 -04:00
module . exports . gap = function ( c ) { var x = '' ; for ( var i = 0 ; i < ( c * 4 ) ; i ++ ) { x += ' ' ; } return x ; } ;
module . exports . gap2 = function ( c ) { var x = '' ; for ( var i = 0 ; i < ( c * 4 ) ; i ++ ) { x += ' ' ; } return x ; } ;
2017-08-28 12:27:45 -04:00
// Print an object in html
2018-08-29 20:40:30 -04:00
module . exports . ObjectToString = function ( x ) { return module . exports . ObjectToStringEx ( x , 0 ) ; } ;
module . exports . ObjectToString2 = function ( x ) { return module . exports . ObjectToStringEx2 ( x , 0 ) ; } ;
2017-08-28 12:27:45 -04:00
// Convert a hex string to a raw string
2018-08-29 20:40:30 -04:00
module . exports . hex2rstr = function ( d ) {
2017-08-28 12:27:45 -04:00
var r = '' , m = ( '' + d ) . match ( /../g ) , t ;
2018-08-29 20:40:30 -04:00
while ( t = m . shift ( ) ) { r += String . fromCharCode ( '0x' + t ) ; }
return r ;
} ;
2017-08-28 12:27:45 -04:00
// Convert decimal to hex
2018-08-29 20:40:30 -04:00
module . exports . char2hex = function ( i ) { return ( i + 0x100 ) . toString ( 16 ) . substr ( - 2 ) . toUpperCase ( ) ; } ;
2017-08-28 12:27:45 -04:00
// Convert a raw string to a hex string
2018-08-29 20:40:30 -04:00
module . exports . rstr2hex = function ( input ) {
2017-08-28 12:27:45 -04:00
var r = '' , i ;
for ( i = 0 ; i < input . length ; i ++ ) { r += module . exports . char2hex ( input . charCodeAt ( i ) ) ; }
return r ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// UTF-8 encoding & decoding functions
2018-08-29 20:40:30 -04:00
module . exports . encode _utf8 = function ( s ) { return unescape ( encodeURIComponent ( s ) ) ; } ;
module . exports . decode _utf8 = function ( s ) { return decodeURIComponent ( escape ( s ) ) ; } ;
2017-08-28 12:27:45 -04:00
// Convert a string into a blob
2018-08-29 20:40:30 -04:00
module . exports . data2blob = function ( data ) {
2017-08-28 12:27:45 -04:00
var bytes = new Array ( data . length ) ;
for ( var i = 0 ; i < data . length ; i ++ ) bytes [ i ] = data . charCodeAt ( i ) ;
var blob = new Blob ( [ new Uint8Array ( bytes ) ] ) ;
return blob ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// Generate random numbers
2018-08-29 20:40:30 -04:00
module . exports . random = function ( max ) { return Math . floor ( Math . random ( ) * max ) ; } ;
2017-08-28 12:27:45 -04:00
// Split a comma seperated string, ignoring commas in quotes.
module . exports . quoteSplit = function ( str ) {
var tmp = '' , quote = 0 , result = [ ] ;
for ( var i in str ) { if ( str [ i ] == '"' ) { quote = ( quote + 1 ) % 2 ; } if ( ( str [ i ] == ',' ) && ( quote == 0 ) ) { tmp = tmp . trim ( ) ; result . push ( tmp ) ; tmp = '' ; } else { tmp += str [ i ] ; } }
if ( tmp . length > 0 ) result . push ( tmp . trim ( ) ) ;
return result ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// Convert list of "name = value" into object
module . exports . parseNameValueList = function ( list ) {
var result = [ ] ;
for ( var i in list ) {
var j = list [ i ] . indexOf ( '=' ) ;
if ( j > 0 ) {
var v = list [ i ] . substring ( j + 1 ) . trim ( ) ;
if ( ( v [ 0 ] == '"' ) && ( v [ v . length - 1 ] == '"' ) ) { v = v . substring ( 1 , v . length - 1 ) ; }
result [ list [ i ] . substring ( 0 , j ) . trim ( ) ] = v ;
}
}
return result ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
// Compute the MD5 digest hash for a set of values
module . exports . ComputeDigesthash = function ( username , password , realm , method , path , qop , nonce , nc , cnonce ) {
var ha1 = crypto . createHash ( 'md5' ) . update ( username + ":" + realm + ":" + password ) . digest ( "hex" ) ;
var ha2 = crypto . createHash ( 'md5' ) . update ( method + ":" + path ) . digest ( "hex" ) ;
return crypto . createHash ( 'md5' ) . update ( ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2 ) . digest ( "hex" ) ;
2018-08-29 20:40:30 -04:00
} ;
2017-08-28 12:27:45 -04:00
2018-08-29 20:40:30 -04:00
module . exports . toNumber = function ( str ) { var x = parseInt ( str ) ; if ( x == str ) return x ; return str ; } ;
module . exports . escapeHtml = function ( string ) { return String ( string ) . replace ( /[&<>"'`=\/]/g , function ( s ) { return { '&' : '&' , '<' : '<' , '>' : '>' , '"' : '"' , "'" : ''' , '/' : '/' , '`' : '`' , '=' : '=' } [ s ] ; } ) ; } ;
module . exports . escapeHtmlBreaks = function ( string ) { return String ( string ) . replace ( /[&<>"'`=\/]/g , function ( s ) { return { '&' : '&' , '<' : '<' , '>' : '>' , '"' : '"' , "'" : ''' , '/' : '/' , '`' : '`' , '=' : '=' , '\r' : '<br />' , '\n' : '' } [ s ] ; } ) ; } ;
2018-01-04 18:59:57 -05:00
// Lowercase all the names in a object recursively
module . exports . objKeysToLower = function ( obj ) {
for ( var i in obj ) {
if ( i . toLowerCase ( ) !== i ) { obj [ i . toLowerCase ( ) ] = obj [ i ] ; delete obj [ i ] ; } // LowerCase all key names
if ( typeof obj [ i ] == 'object' ) { module . exports . objKeysToLower ( obj [ i ] ) ; } // LowerCase all key names in the child object
2018-08-29 20:40:30 -04:00
}
2018-01-04 18:59:57 -05:00
return obj ;
2018-08-29 20:40:30 -04:00
} ;
2018-04-05 19:45:56 -04:00
2018-07-13 22:18:43 -04:00
// Escape and unexcape feild names so there are no invalid characters for MongoDB
2018-08-29 20:40:30 -04:00
module . exports . escapeFieldName = function ( name ) { return name . split ( '%' ) . join ( '%25' ) . split ( '.' ) . join ( '%2E' ) . split ( '$' ) . join ( '%24' ) ; } ;
module . exports . unEscapeFieldName = function ( name ) { return name . split ( '%2E' ) . join ( '.' ) . split ( '%24' ) . join ( '$' ) . split ( '%25' ) . join ( '%' ) ; } ;
2018-07-13 22:18:43 -04:00
// Escape all links
2018-08-29 20:40:30 -04:00
module . exports . escapeLinksFieldName = function ( docx ) { var doc = module . exports . Clone ( docx ) ; if ( doc . links != null ) { for ( var j in doc . links ) { var ue = module . exports . escapeFieldName ( j ) ; if ( ue !== j ) { doc . links [ ue ] = doc . links [ j ] ; delete doc . links [ j ] ; } } } return doc ; } ;
module . exports . unEscapeLinksFieldName = function ( doc ) { if ( doc . links != null ) { for ( var j in doc . links ) { var ue = module . exports . unEscapeFieldName ( j ) ; if ( ue !== j ) { doc . links [ ue ] = doc . links [ j ] ; delete doc . links [ j ] ; } } } return doc ; } ;
//module.exports.escapeAllLinksFieldName = function (docs) { for (var i in docs) { module.exports.escapeLinksFieldName(docs[i]); } };
module . exports . unEscapeAllLinksFieldName = function ( docs ) { for ( var i in docs ) { docs [ i ] = module . exports . unEscapeLinksFieldName ( docs [ i ] ) ; } } ;
2018-07-13 22:18:43 -04:00
2018-04-05 19:45:56 -04:00
// Validation methods
2018-08-29 20:40:30 -04:00
module . exports . validateString = function ( str , minlen , maxlen ) { return ( ( str != null ) && ( typeof str == 'string' ) && ( ( minlen == null ) || ( str . length >= minlen ) ) && ( ( maxlen == null ) || ( str . length <= maxlen ) ) ) ; } ;
module . exports . validateInt = function ( int , minval , maxval ) { return ( ( int != null ) && ( typeof int == 'number' ) && ( ( minval == null ) || ( int >= minval ) ) && ( ( maxval == null ) || ( int <= maxval ) ) ) ; } ;
module . exports . validateArray = function ( array , minlen , maxlen ) { return ( ( array != null ) && Array . isArray ( array ) && ( ( minlen == null ) || ( array . length >= minlen ) ) && ( ( maxlen == null ) || ( array . length <= maxlen ) ) ) ; } ;
module . exports . validateStrArray = function ( array , minlen , maxlen ) { if ( ( ( array != null ) && Array . isArray ( array ) ) == false ) return false ; for ( var i in array ) { if ( ( typeof array [ i ] != 'string' ) && ( ( minlen == null ) || ( array [ i ] . length >= minlen ) ) && ( ( maxlen == null ) || ( array [ i ] . length <= maxlen ) ) ) return false ; } return true ; } ;
module . exports . validateObject = function ( obj ) { return ( ( obj != null ) && ( typeof obj == 'object' ) ) ; } ;
2018-10-16 17:51:54 -04:00
module . exports . validateEmail = function ( email , minlen , maxlen ) { if ( module . exports . validateString ( email , minlen , maxlen ) == false ) return false ; var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ ; return emailReg . test ( email ) ; } ;
2018-08-29 20:40:30 -04:00
module . exports . validateUsername = function ( username , minlen , maxlen ) { return ( module . exports . validateString ( username , minlen , maxlen ) && ( username . indexOf ( ' ' ) == - 1 ) ) ; } ;