javascript - Generate new verification token -
i'm know how create method, or if there method generate new token email. want create option in site "send new verification email", user needs put email. i'm using mandril, i'm using custom way send emails , verify users:
function generateverificationtoken(context, user, callback) { const { req } = context; req.app.models.user.generateverificationtoken(user, (error, token) => { if (error) { return callback(error, null); } callback(null, token); }); } user.afterremote('create', (context, user, next) => { generateverificationtoken(context, user, (error, token) => { if (error) { return next(error); } user.verificationtoken = token; user.save((error) => { if (error) { return next(error); } loopback.email.send({ to: user.email, template: { name: 'signup-confirm', }, global_merge_vars: [{ name: 'href', content:`http://localhost:3000/api/accounts/confirm?uid=${user.id}&token=${token}&redirect=http://localhost:4200/login/token-verification&verification=1` }] }, (error) => { next(error); }); }); }); });
thanks in advance!
(note: question bit tricky because involves several modifications that, although not hard, might require refactoring of code. also, see warning note @ end please.)
1. override user model
(note: although in model, found better inside user
consistency's sake, though there's bit more do.)
to override user model, can 2 things. people add new user
model (in lowercase) , overriding there, prefer use spencer mefford's more elegant way of doing it.
you should check whole gist because there's lot more going on, summarize bit, need create new boot script, ideally name starting "0" (boot scripts executed in alphabetical order , need have model ready before rest of stuff), example
server/boot/0-user-model-override.js
then add necessary boilerplate:
module.exports = function (app) { var user = app.models.user; var email = app.models.email; var role = app.models.role; var rolemapping = app.models.rolemapping; var acl = app.models.acl; /* * if initial setup, create acl entry, * otherwise configure relationships * (this needs done every time server started) */ if(process.env.init_setup == "true"){ acl.create({ model: 'user', property: 'customendpoint1', accesstype: 'execute', principaltype: 'role', principalid: '$everyone', permission: 'allow' }, function (err, acl) { // create acl if (err) console.error(err); }); } rolemapping.belongsto(user); rolemapping.belongsto(role); user.hasmany(role, {through: rolemapping, foreignkey: 'principalid'}); user.hasmany(rolemapping, {foreignkey: 'principalid'}); role.hasmany(user, {through: rolemapping, foreignkey: 'roleid'}); // add custom endpoints user.customendpoint1 = function(param1, cb) {...}; user.remotemethod('customendpoint1',...){...}; };
the boilerplate there because need manually add acl entry sets permissions allow request new verification email. if not done, by default user model denies access non-authenticated users.
also, note create acl entry in db when doing initial setup, i.e. once (unless setup new db).
however need configure relationships between user, role , rolemapping every time start server, otherwise access errors valid users , other strange behaviors.
(note: although quite bit of work, think being able add new functionality user model allow keep user management belongs.)
after setup can e.g.
post https://myserver/api/users/newverificationemail
2. create endpoint request new link
to add endpoint other model:
user.newverificationemail = function(email, cb) { console.log("a new verification email requested for: " + email); cb(null); }; user.remotemethod( 'newverificationemail', { accepts: [ {arg: 'email', type: 'string'} ], http: { verb: 'post' } } );
3. call verify method , send email
to send verification email have few options. can either:
- re-use
user.verify()
method (located in user.js model file) , default smtp emailer - re-use
user.verify()
method own emailer (to send via api example) - do hand, i.e. generate token yourself, saving user collection , sending email,
user.verify()
does. requires write confirmation logic yet more work.
user.verify() default emailer
to re-use verify method need generate verify link (except token part, added method itself), configure options, , call method.
user.newverificationemail = function(email, cb) { console.log("a new verification email requested"); var usermodel = user.constructor; // note: user.id need query db // user instance requested email var verifylink = 'https://' + hostaddress + ':' + portnumber + restapiroot + '/users/confirm' + '?uid=' + user.id + '&redirect=https://' + hostaddress + '/verified?user_id='+user.id; var options = { type: 'email', mailer: email, to: user.email, from: 'sender@example.com', subject: 'my email subject', template: path.resolve(__dirname, '../views/verify.ejs'), user: user, verifyhref: verifylink, host: myemailhost, port: myemailport }; user.verify(options, function(err, response) { if (err) { console.log(err); } console.log("account verification email sent " + options.to); cb(null); }); };
create email verification template
the email sent 1 specified in options.template
, i.e. server/views/verify.ejs
this file should contain verification link generated again. can add whatever html want, sure add verifyhref variable:
please click <a href="<%= verifyhref %>">this link</a> verify email
after these changes done, should send email whenever post request api/users/newverificationlink
user.verify() custom emailer
i haven't yet finished implementing solution, involves creating own email connector use provider's api (e.g. mandrill, mailgun, etc) , passing model in options.mailer
field.
warning: haven't tested code , there several variable values need specify (e.g. hostaddress
, portnumber
, restapiroot
, etc). code in answer has been extracted several pieces of project i'm working on , although it's complete, need verify there no missing callbacks , other typos , compiler errors provide code search user object corresponding provided email (which easy do).
Comments
Post a Comment