0

I'm running Express with Sequelize/MariaDB and Passport.js for user authentication.

I'm in the signup part (which works) but I can't seem to render and return an activation email asking them to confirm their email.

passport.js (containing authentication strategies)

passport.use('user-signup-email', new LocalStrategy({
    //Process/validate input, check database for existing emails, create user, add to database...

    ...
    if (newUser) {
        var token = jwt.sign( { data: newUser.id }, newUser.login_pass + "-" + newUser.account_created);
        var URLdata = { 
            id:                newUser.id,
            expiration_time:   Date.now() + 86400000,   //24 hours
            url:               token,
            email_info:        mail.createActivationEmail(req.app, newUser.login_key, newUser.user_alias, token)                        
        };

        console.log("info: " + URLdata.email_info);

        ... 
            //Store dynamic URL and email contents (in case of resending) in database with expiration time
            //And then send the email that was just rendered
    }

mail.js

exports.createActivationEmail = (app, recipientAddress, userName, url) => {
    app.render('emails/activation_email', {    
        layout: false,
        page_title: 'Please confirm your account!',
        dynamic_url: url
    }, function(err, rendered) {
        if (err) {
            console.log("Q [" + err + "]");
        }

        console.log("R " + rendered.toString());
        return {  
            from:       adminEmailAddress,
            to:         recipientAddress,
            cc:         false,
            bcc:        false,
            subject:    'Welcome to example.com ' + userName + '!',
            html:       rendered.toString(),
            text:       "TO DO" 
        };
    });
};

The last console.log in passport.js displays "info: undefined." But if I print the output in the mail.js module before returning it, it is fine.

I'm guessing it's an async problem? How would I fix it?
I'm still a little unclear on promises and async-await blocks in this context.

Thanks in advance for any help you can offer!

SKNB
  • 75
  • 2
  • 9
  • You are mixing asynchronous code & syncron/blocking code exection. The `return {...}` inside your callback function is uselles. The object is never reachable from outside the callback function – Marc Apr 02 '20 at 19:33
  • Ah it seems so obvious now, thanks for pointing it out – SKNB Apr 04 '20 at 16:31

1 Answers1

1

You misunderstood callback functions. callbacks are (should, when you write them) asynchron: https://nemethgergely.com/async-function-best-practices/ How to write asynchronous functions for Node.js

I changed your createActivationEmail function. The last argument is now a callback, thats get invoked when your code app.redner is done.

passport.use('user-signup-email', new LocalStrategy({
    //Process/validate input, check database for existing emails, create user, add to database...

    // ...
    if(newUser) {

        var token = jwt.sign({ data: newUser.id }, newUser.login_pass + "-" + newUser.account_created);
        mail.createActivationEmail(req.app, newUser.login_key, newUser.user_alias, token, (err, email_info) => {



            var URLdata = {
                id: newUser.id,
                expiration_time: Date.now() + 86400000,   //24 hours
                url: token,
                email_info
            };


            console.log("info: " + URLdata.email_info);

            //... 
            //Store dynamic URL and email contents (in case of resending) in database with expiration time
            //And then send the email that was just rendered


        });

    }

}));

exports.createActivationEmail = (app, recipientAddress, userName, url, done) => {
    app.render('emails/activation_email', {    
        layout: false,
        page_title: 'Please confirm your account!',
        dynamic_url: url
    }, function(err, rendered) {

        if (err) {
            console.log("Q [" + err + "]");
            cb(err);
            return;
        }

        console.log("R " + rendered.toString());
        
        done(null, {  
            from:       adminEmailAddress,
            to:         recipientAddress,
            cc:         false,
            bcc:        false,
            subject:    'Welcome to example.com ' + userName + '!',
            html:       rendered.toString(),
            text:       "TO DO" 
        });

    });
};
Marc
  • 2,920
  • 3
  • 14
  • 30