@@ -3,6 +3,7 @@ const crypto = require('crypto');
33const moment = require ( 'moment' ) ;
44const MongoClient = require ( 'mongodb' ) . MongoClient ;
55
6+ const PASS_VER = 1 ;
67var db , accounts ;
78MongoClient . connect ( process . env . DB_URL , { useNewUrlParser : true } , function ( e , client ) {
89 if ( e ) {
@@ -39,13 +40,23 @@ exports.manualLogin = function(user, pass, callback)
3940 if ( o == null ) {
4041 callback ( 'user-not-found' ) ;
4142 } else {
42- validatePassword ( pass , o . pass , function ( err , res ) {
43- if ( res ) {
44- callback ( null , o ) ;
45- } else {
46- callback ( 'invalid-password' ) ;
47- }
48- } ) ;
43+ if ( o . pass_ver === undefined || o . pass_ver === 0 ) {
44+ validatePasswordV0 ( pass , o . pass , function ( err , res ) {
45+ if ( res ) {
46+ callback ( null , o ) ;
47+ } else {
48+ callback ( 'invalid-password' ) ;
49+ }
50+ } ) ;
51+ } else if ( o . pass_ver === 1 ) {
52+ validatePasswordV1 ( pass , o . pass , function ( err , res ) {
53+ if ( res ) {
54+ callback ( null , o ) ;
55+ } else {
56+ callback ( 'invalid-password' ) ;
57+ }
58+ } ) ;
59+ }
4960 }
5061 } ) ;
5162}
@@ -104,6 +115,7 @@ exports.addNewAccount = function(newData, callback)
104115 } else {
105116 saltAndHash ( newData . pass , function ( hash ) {
106117 newData . pass = hash ;
118+ newData . pass_ver = PASS_VER ;
107119 // append date stamp when record was created //
108120 newData . date = moment ( ) . format ( 'MMMM Do YYYY, h:mm:ss a' ) ;
109121 accounts . insertOne ( newData , callback ) ;
@@ -122,8 +134,11 @@ exports.updateAccount = function(newData, callback)
122134 email : data . email ,
123135 country : data . country
124136 }
125- if ( data . pass ) o . pass = data . pass ;
126- accounts . findOneAndUpdate ( { _id :getObjectId ( data . id ) } , { $set :o } , { returnOriginal : false } , callback ) ;
137+ if ( data . pass ) {
138+ o . pass = data . pass ;
139+ o . pass_ver = PASS_VER ;
140+ }
141+ accounts . findOneAndUpdate ( { _id :getObjectId ( data . id ) } , { $set :o } , { upsert :true , returnOriginal :false } , callback ) ;
127142 }
128143 if ( newData . pass == '' ) {
129144 findOneAndUpdate ( newData ) ;
@@ -137,9 +152,8 @@ exports.updateAccount = function(newData, callback)
137152
138153exports . updatePassword = function ( passKey , newPass , callback )
139154{
140- saltAndHash ( newPass , function ( hash ) {
141- newPass = hash ;
142- accounts . findOneAndUpdate ( { passKey :passKey } , { $set :{ pass :newPass } , $unset :{ passKey :'' } } , { returnOriginal : false } , callback ) ;
155+ saltAndHash ( newPass , function ( hash ) {
156+ accounts . findOneAndUpdate ( { passKey :passKey } , { $set :{ pass :hash , pass_ver :PASS_VER } , $unset :{ passKey :'' } } , { upsert :true , returnOriginal :false } , callback ) ;
143157 } ) ;
144158}
145159
@@ -187,17 +201,42 @@ var md5 = function(str) {
187201
188202var saltAndHash = function ( pass , callback )
189203{
190- var salt = generateSalt ( ) ;
191- callback ( salt + md5 ( pass + salt ) ) ;
204+ const hasher = 'sha256' ;
205+ const iterations = 10000 ;
206+ const hashLength = 32 ;
207+ const saltBytes = 16 ;
208+ let salt , hash ;
209+ crypto . randomBytes ( saltBytes , function ( err , buf ) {
210+ if ( err ) throw err ;
211+ salt = buf . toString ( 'hex' ) ;
212+ crypto . pbkdf2 ( pass , salt , iterations , hashLength , hasher , function ( err , derivedKey ) {
213+ if ( err ) throw err ;
214+ hash = derivedKey . toString ( 'hex' ) ;
215+ callback ( [ salt , hash ] . join ( '$' ) ) ;
216+ } ) ;
217+ } ) ;
192218}
193219
194- var validatePassword = function ( plainPass , hashedPass , callback )
220+ var validatePasswordV0 = function ( plainPass , hashedPass , callback )
195221{
196222 var salt = hashedPass . substr ( 0 , 10 ) ;
197223 var validHash = salt + md5 ( plainPass + salt ) ;
198224 callback ( null , hashedPass === validHash ) ;
199225}
200226
227+ var validatePasswordV1 = function ( plainPass , hashedPass , callback )
228+ {
229+ const hasher = 'sha256' ;
230+ const iterations = 10000 ;
231+ const hashLength = 32 ;
232+ const salt = hashedPass . split ( '$' ) [ 0 ] ;
233+ crypto . pbkdf2 ( plainPass , salt , iterations , hashLength , hasher , function ( err , derivedKey ) {
234+ if ( err ) throw err ;
235+ let validHash = [ salt , derivedKey . toString ( 'hex' ) ] . join ( '$' ) ;
236+ callback ( null , hashedPass === validHash ) ;
237+ } ) ;
238+ }
239+
201240var getObjectId = function ( id )
202241{
203242 return new require ( 'mongodb' ) . ObjectID ( id ) ;
0 commit comments