diff --git a/install/package.json b/install/package.json index fe3476dec9..be67fae93f 100644 --- a/install/package.json +++ b/install/package.json @@ -146,6 +146,7 @@ "webpack": "5.88.2", "webpack-merge": "5.9.0", "winston": "3.10.0", + "workerpool": "6.5.0", "xml": "1.0.1", "xregexp": "5.1.1", "yargs": "17.7.2", diff --git a/src/password.js b/src/password.js index d1b6fc2df5..7c0d01931c 100644 --- a/src/password.js +++ b/src/password.js @@ -2,31 +2,17 @@ const path = require('path'); const crypto = require('crypto'); -const util = require('util'); +const workerpool = require('workerpool'); -const bcrypt = require('bcryptjs'); - -const fork = require('./meta/debugFork'); - -function forkChild(message, callback) { - const child = fork(path.join(__dirname, 'password')); - - child.on('message', (msg) => { - callback(msg.err ? new Error(msg.err) : null, msg.result); - }); - child.on('error', (err) => { - console.error(err.stack); - callback(err); - }); - - child.send(message); -} - -const forkChildAsync = util.promisify(forkChild); +const pool = workerpool.pool( + path.join(__dirname, '/password_worker.js'), { + minWorkers: 1, + } +); exports.hash = async function (rounds, password) { password = crypto.createHash('sha512').update(password).digest('hex'); - return await forkChildAsync({ type: 'hash', rounds: rounds, password: password }); + return await pool.exec('hash', [password, rounds]); }; exports.compare = async function (password, hash, shaWrapped) { @@ -35,8 +21,7 @@ exports.compare = async function (password, hash, shaWrapped) { if (shaWrapped) { password = crypto.createHash('sha512').update(password).digest('hex'); } - - return await forkChildAsync({ type: 'compare', password: password, hash: hash || fakeHash }); + return await pool.exec('compare', [password, hash || fakeHash]); }; let fakeHashCache; @@ -48,34 +33,4 @@ async function getFakeHash() { return fakeHashCache; } -// child process -process.on('message', (msg) => { - if (msg.type === 'hash') { - tryMethod(hashPassword, msg); - } else if (msg.type === 'compare') { - tryMethod(compare, msg); - } -}); - -async function tryMethod(method, msg) { - try { - const result = await method(msg); - process.send({ result: result }); - } catch (err) { - process.send({ err: err.message }); - } finally { - process.disconnect(); - } -} - -async function hashPassword(msg) { - const salt = await bcrypt.genSalt(parseInt(msg.rounds, 10)); - const hash = await bcrypt.hash(msg.password, salt); - return hash; -} - -async function compare(msg) { - return await bcrypt.compare(String(msg.password || ''), String(msg.hash || '')); -} - require('./promisify')(exports); diff --git a/src/password_worker.js b/src/password_worker.js new file mode 100644 index 0000000000..650cd3236d --- /dev/null +++ b/src/password_worker.js @@ -0,0 +1,18 @@ +'use strict'; + +const workerpool = require('workerpool'); +const bcrypt = require('bcryptjs'); + +async function hash(password, rounds) { + const salt = await bcrypt.genSalt(parseInt(rounds, 10)); + return await bcrypt.hash(password, salt); +} + +async function compare(password, hash) { + return await bcrypt.compare(String(password || ''), String(hash || '')); +} + +workerpool.worker({ + hash: hash, + compare: compare, +});