-1

I have a login in an web app, which reads from the MongoDB and sorts it into the sorted array using lodash. The problem is that my console.log("sorted in /api/login:", sorted); for some reason returns nothing, which doesn't make console.log output yeet... How do I fix this? I already tried putting some more awaits, but that didn't help me. What is this promise alignment everyone is talking about? I can't find any info online about it..

var express = require('express');
const app = express();
const User = require('./models/user.js');
var _ = require('lodash');
const sorted = [];
User.find({},{ firstname: 1, password: 1 }, async function(err, users) {
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  await console.log("sorted:", sorted);
});

app.post('/api/login', apiLimiter, async function (req, res){
  try  {
    console.log("sorted in /api/login:", sorted);
    console.log("Req firstname: ",req.body.firstname)
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    console.log("Hashed pw: ", hashedPassword);
    console.log(await bcrypt.compare('testtest',hashedPassword));
    // const user = { id: req.body.id, username: req.body.username, password: req.body.password };
    var user = new User({firstname: req.body.firstname, eMail: req.body.eMail, password: hashedPassword });
    sorted.forEach(async ([eMail, password]) => {
      await bcrypt.compare(password, users[eMail]).then((e, r) => {
        // r = true if hash = hashed pw
        console.log("Yeet");
      });
    });
    jwt2.sign({user}, 'secrethere', { expiresIn: '15min'}, (err, token) =>{
    res.json({
      token
    });
  });
  } catch (err) {
    res.status(500).send()
    console.log(err);
  }
});

My user.js:

const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
  firstname: {
    type: String,
    required: true,
    unique: true
  },
  lastname: String,
  eMail: {
    type: String,
    required: true,
    unique: true
  },
  password: String,
  active: Boolean
});

module.exports = mongoose.model("User", userSchema);

Update

Errors I get when implementing the recommended answer:

(node:17080) UnhandledPromiseRejectionWarning: ReferenceError: users is not defined at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:17080) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:17080) UnhandledPromiseRejectionWarning: ReferenceError: users is not defined at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:17080) UnhandledPromiseRejectionWarning: ReferenceError: users is not defined at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:38 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:17080) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

Update2

(node:11252) UnhandledPromiseRejectionWarning: Error: data and hash arguments required at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) at C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 at new Promise () at Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:11252) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:11252) UnhandledPromiseRejectionWarning: Error: data and hash arguments required at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) at C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 at new Promise () at Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:11252) UnhandledPromiseRejectionWarning: Error: data and hash arguments required at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:209:17) at C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:29:12 at new Promise () at Object.module.exports.promise (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\promises.js:20:12) at Object.compare (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:205:25) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:11252) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

Update 3

Now I get these errors:

(node:14268) UnhandledPromiseRejectionWarning: Error: data and hash arguments required at Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:14268) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:14268) UnhandledPromiseRejectionWarning: Error: data and hash arguments required
at Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:14268) UnhandledPromiseRejectionWarning: Error: data and hash arguments required
at Object.compareSync (C:\Users\User\Documents\Carina\Canopus\node_modules\bcrypt\bcrypt.js:167:15) at C:\Users\User\Documents\Carina\Canopus\src\app.js:252:20 at Array.forEach () at C:\Users\User\Documents\Carina\Canopus\src\app.js:251:12 (node:14268) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

Munchkin
  • 857
  • 5
  • 24
  • 51

1 Answers1

1

Your problem is that when you call a route in express that is function that starts from app.post('/api/login', apiLimiter, async function (req, res).

So this code never gets called, just put this inside function (inside of try) and everything should work

const sorted = [];
User.find({},{ firstname: 1, password: 1 }, async function(err, users) {
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  await console.log("sorted:", sorted);
});

UPDATE, working code with function

var express = require('express');
const app = express();
const User = require('./models/user.js');
var _ = require('lodash');

async function getSorted(){
const sorted = [];
let users = await User.find({},{ firstname: 1, password: 1 });
  const flattenUsers = _(users).map(({firstname, password}) => ([firstname, password])).flatten().value();
  console.log(flattenUsers);
  const sorted = await flattenUsers.reduce((a, e, i) => (i % 2 || a.push([]), a[a.length - 1].push(e), a), []);
  console.log("sorted:", sorted);
return Promise.resolve([sorted,users])
}
app.post('/api/login', apiLimiter, async function (req, res){


  try  {
  let [sorted,users] = await getSorted();
    console.log("sorted in /api/login:", sorted);
    console.log("Req firstname: ",req.body.firstname)
    const hashedPassword = await bcrypt.hash(req.body.password, 10);
    console.log("Hashed pw: ", hashedPassword);
    console.log(await bcrypt.compare('testtest',hashedPassword));
    // const user = { id: req.body.id, username: req.body.username, password: req.body.password };
    var user = new User({firstname: req.body.firstname, eMail: req.body.eMail, password: hashedPassword });
    sorted.forEach(async ([eMail, password]) => {
      let result = bcrypt.compareSync(password, users[eMail]);
        // result = true if hash = hashed pw
        console.log("Yeet");
      });
    });
    jwt2.sign({user}, 'secrethere', { expiresIn: '15min'}, (err, token) =>{
    res.json({
      token
    });
  });
  } catch (err) {
    res.status(500).send()
    console.log(err);
  }
});
phlosopher_mk
  • 340
  • 1
  • 3
  • 11
  • Yeet doesn't get printed out :/ and the `console.log("sorted in /api/login:", sorted);` still prints out nothing probably because it's out of scope – Munchkin Dec 10 '19 at 13:53
  • Yeah, now the problem is because User.find is promise so you will need to put await before User.find. – phlosopher_mk Dec 10 '19 at 14:01
  • Can you edit the answer accordingly? It throws me a syntax error the way you wrote it – Munchkin Dec 10 '19 at 14:06
  • @Munchkin here you go. – phlosopher_mk Dec 10 '19 at 14:16
  • changed const to var now I get `UnhandledPromiseRejectionWarning: ReferenceError: users is not defined`. Updated the question to contain the full list of errors P.S Yeet was also not printed out – Munchkin Dec 10 '19 at 14:26
  • @Munchkin yeah sorry man it was the scope error, now you get the users from the first function too. I updated the answer. – phlosopher_mk Dec 10 '19 at 14:50
  • Okey man, so now this is related to you bcrypt logic, you can't use async in foreach , please use promise.all . – phlosopher_mk Dec 10 '19 at 15:14
  • where exactly do I use it? – Munchkin Dec 10 '19 at 15:33
  • You should wrap foreach into Promise.all, see this example https://stackoverflow.com/a/38362312/3255220 – phlosopher_mk Dec 10 '19 at 15:37
  • Could you write an example on how to implement it for my code? – Munchkin Dec 10 '19 at 15:38
  • @Munchkin sorry man,it's just the map with promises, read about promises. But for now you can use compareSync instead of compare and don't care about promises. I updated the answer. – phlosopher_mk Dec 10 '19 at 15:48
  • "Yeet" still doesn't get printed out and I still get errors :/ please check the updated question (update 3) for the errors – Munchkin Dec 11 '19 at 10:03
  • Just found out that according to [this](https://stackoverflow.com/questions/42241113/bcrypt-error-data-and-hash-arguments-required) one of my arguments is undefined, which is true - my users[eMail] for some reason is undefined :/ how do I fix it? – Munchkin Dec 11 '19 at 10:49
  • Managed to fix it. – Munchkin Dec 11 '19 at 11:35