2017-01-27 67 views
0

Я использую Паспорт, Nodemailer, Sequelize и Express для обработки верификации учетных записей пользователей, которые зарегистрировались по электронной почте в приложении.Sequelize findВсе запрос, возвращающий неверные результаты

Чтобы проверить эту функцию, я использую Mailinator счета, чтобы зарегистрироваться и отправить по электронной почте (вместе с строкой запроса, содержащей электронную почту пользователя и уникально определяются код) на указанный адрес Mailinator с использованием Nodemailer. Затем я открываю письмо в Nodemailer, нажимает ссылку подтверждения, которая обновляет флаг проверки в базе данных и проверяет пользователя.

Этот процесс работает так, как я ожидаю, для одного пользователя, который подписывается по электронной почте. Когда второй пользователь подписывается, электронное письмо с подтверждением отправляется так же, как и раньше, с именем пользователя и уникальными кодами подтверждения в строке запроса, но на этот раз от пользователя возвращается несколько пользователей. findAll запрос через Sequelize при нажатии ссылки. Мой запрос предназначен для findAll возможных совпадений как адресов электронной почты, так и верификационных кодов (поскольку каждый пользователь может только войти в систему с одним адресом электронной почты, а коды подтверждения уникальны), но по какой-то причине запрос возвращает все совпадения из этого запроса.

Вот код для справки:

/* Sending the emails */ 

emails.sendActivationEmail = function(user){ 
    const qso = {username: user.username, activationCode: user.activationCode}; 
    const qs = querystring.stringify(qso); 
    const from = new helper.Email(<[email protected]>); 
    const to = new helper.Email(user.username); 
    const subject = 'Welcome to My Site!'; 
    const content = new helper.Content('text/html', "<p> Thanks for signing up " + 
    "for our psych study, please <a href=\"http://localhost:7000/users/validate/account?" + 
    qs + "\">confirm your email</a></p>"); 

    const mail = new helper.Mail(from, subject, to, content); 

    sendMail(mail); //invokes SendGrid mail helper function 
} 

/* Function invoked when user clicks on verification link in email */ 

emails.validateUserAccount = function(req, res){ 
    const url = parseUrl(req.url); 
    const query = querystring.parse(url.query); 

    db.User.findAll({where: query}).then(function(matches){ 
     if(matches.length !== 1){ 
      res.send('error: multiple users found'); 
     } 
     else{ 
      db.User.update({ 
       isVerified : true 
      }, 
      { 
       where: { 
        username: matches[0].username 
       } 
      }); 
      req.session.user = matches[0]; 
      res.redirect('/'); 
     } 
    }).catch(function(err){ 
     console.error(err); 
     res.send(err); 
    }); 
} 

заявление Консольного в функции validateUserAccount() показывает, что запрос точно так, как я ожидаю, ({username: <emailAddress>, activationCode: <uniqueCode>}). Однако инструкции console.log, сделанные в первой строке после выполнения запроса findAll, показывают, что все пользователи возвращаются из запроса, что должно быть невозможно, если запрос WHERE передается правильно, что похоже на то, записанные сообщения. Почему пользователь. findAll возвращает неверные результаты по моему запросу?

+1

Возможно, вы захотите использовать 'Model.findOne()' вместо 'findAll()' для добавления 'LIMIT 1' и вернуть один результат, хотя это не ваша основная проблема. – doublesharp

ответ

1

Проблема здесь состоит в том, что вы используете возвращаемое значение querystring.parse()

Как обозначено в узле документации:

Примечание: Объект, возвращаемый querystring.parse() метод не прототипически простираются от объекта JavaScript. Это означает, что типичные методы Object, такие как obj.toString(), obj.hasOwnProperty() и другие, не определены и не будут работать.

Скорее всего, статья where ожидает фактический объект JS.

Кроме того, как упоминалось в @doublesharp, вы, вероятно, захотите получить одну строку и проверить ее, в отличие от findAll входящих строк и затем фильтрации. Кроме того, вы должны использовать обратные вызовы. Вы пишете код блокировки прямо сейчас.

+0

Посмотрите на документацию, есть большая вероятность, что вы правы, но если я не могу использовать querystring.parse(), как извлечь из имени пользователя и activationCode для создания нового объекта для запроса? –

+0

Это справедливо. Попробуйте использовать JSON.stringify по возвращаемому значению parse, затем JSON. Перенесите его в объект и передайте его, чтобы узнать, работает ли это. Если нет, нам придется найти другой способ заставить его работать. – steviejay

+0

Следующий код работал в validateUserAccount(): var url = parseUrl (req.url); var parsedQs = querystring.parse (url.query); query = JSON.parse (JSON.stringify (parsedQs)); const code = query.activationCode; const name = query.username; Затем я просто поместил код и имя в запрос where непосредственно с помощью findOne вместо findAll. –