function loginAction(evt) {
evt.preventDefault();
const password = inputPasswordEl.current.value;
props.db.getAllUsers()
.then(querySnapshot => {
const users = [];
querySnapshot.forEach(function (doc) {
const userObject = Object.assign({}, doc.data(), { id: doc.id });
users.push(userObject);
});
const userFound = findUserMatch(password, users);
+ export function findUserMatch(password, users) {
return users.find(user => {
return bcrypt.compareSync(password, user.userKey)
});
}
With modern React, I can’t tell whether this is server-side, client-side, or potentially both. If it’s server-side, that’s ideal, because the way the server stops responding to all requests for several minutes will make you fix this before that Firebase query really starts costing (but still, why does this exist). If it’s client-side, are you really exposing every user’s hash to offline attack? export function saveMasterPassword(masterPassword) {
const simpleCrypto = new SimpleCrypto(MASTER_PASS_SECRET);
const cookies = new Cookies();
const masterPass = simpleCrypto.encrypt(masterPassword);
cookies.set(COOKIE_MASTER_PASSWORD, masterPass, { path: '/' });
}
(uppercase values are server-side constants)If you’re serving the same cookie encryption secret to everyone, is it really a secret?
function cypherObject(object) {
const cookies = new Cookies();
const masterPass = getMasterPassword();
var simpleCrypto = new SimpleCrypto(masterPass);
if (typeof object === 'object') {
const object = JSON.stringify(object);
}
return simpleCrypto.encrypt(object);
}
simple-crypto-js uses 100 rounds of PBKDF2 to derive an AES key from `masterPass` here, so your brute-force resistance to an attacker with access to the encrypted secrets comes from 100-round PBKDF2, not 2^10-round bcrypt.I would recommend Bitwarden instead.