1

I am trying to send a verification email to let users confirm their emails. Through the back-end and nodemailer user receives the email now. But when you click the link inside email it shows error. It's because Front-end is Angular and running on localhost:4200 and Node.js is running on localhost:30000. Here is the code:

 const body = {
            username: Helpers.firstUpper(value.username),
            email: Helpers.lowerCase(value.email),
            password: hash,
          };
          User.create(body)
            .then(user => {
              const token = jwt.sign({ data: user }, dbConfig.secret, {
                expiresIn: '5h'
              });
              res.cookie('auth', token);
              res
                .status(HttpStatus.CREATED)
                .json({ message: 'User created successfully', user, token });
                var emailtoken = new emailToken({ _userId: user._id, emailtoken: crypto.randomBytes(16).toString('hex') });
                emailtoken.save(function (err) {
                    if (err) { return res.status(500).send({ msg: err.message }); }
                    var transporter = nodemailer.createTransport({
                        service: 'Sendgrid',
                        auth: { api_key:'api key is here' }
                    });
                    var mailOptions = {
                        from: 'email@email.com',
                        to: user.email, subject: 'Account Verification Token',
                        text: 'Hello,\n\n' + 'Please verify your account by clicking the link: \nhttp:\/\/' + req.headers.host + '\/confirmation\/' + emailtoken.emailtoken
                    }

                    transporter.sendMail(mailOptions, function (err) {
                    })          
                })
            })
            .catch(err => {
                res
                    .status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .json({ message: 'Error occured' });
            });
          });
        },

I found something like this on other question's answers:

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200'); // Change this to your Angular 2 port number
    res.setHeader('Access-Control-Request-Method', '*');
    res.setHeader('Access-Control-Allow-Methods', 'POST');
    res.setHeader('Access-Control-Allow-Headers', '*');

Where should I implement this code? Also, What should I add in an Angular part to make confirmation link inside email work as expected?

NewTech Lover
  • 1,185
  • 4
  • 20
  • 44

1 Answers1

0

I think the best way would be to store the `FRONTEND_URI as a configuration/environment.

Another way, would be following this answer

However, a solution that I think might be more appropriate, is to replace the scenario as follows:

On clicking the link, a request to your backend should be sent, where it activates your email, and then redirects the user to the frontend URL (say stored in configuration/environment).

That way, the angular component (which you will redirect to) will be displaying a static page, just indicating if the verification was successful, and indicating any errors otherwise.

abdullahkady
  • 1,051
  • 1
  • 8
  • 8
  • Does it mean I should have /confirmation rout as in email it's explained? And what's then how should it redirect to /sign-in page in Angular for example? – NewTech Lover Dec 16 '18 at 12:40
  • Exactly! In your current scenario, how do you plan to proceed with the "activation"? you will have to somehow get the token back in another request, and compare it with the server stored tokens, find the matching token, and -if you want- match it with the user's id as well, then you activate his account (assuming it's a flag or something to be set) – abdullahkady Dec 16 '18 at 18:21