So, I read the documentation about manage the users. I also comes from this example: https://github.com/strongloop/loopback-example-user-management.
Then I try to make a model, called user-basic which bases on built-in model User.
Here's the user-basic.json:
{
"name": "user-basic",
"base": "User",
"idInjection": true,
"properties": {},
"validations": [],
"relations": {},
"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"accessType": "READ",
"permission": "ALLOW"
}
],
"methods": {}
}
Here's the user-basic.js
var config = require('../../server/config.json');
var path = require('path');
module.exports = function(UserBasic) {
UserBasic.afterRemote('create', function(ctx, member, next) {
console.log('> user.afterRemote triggered');
var options = {
type: 'email',
to: UserBasic.email,
from: '[email protected]',
subject: 'Thanks for registering.',
template: path.resolve(__dirname, '../../server/views/verify.ejs'),
redirect: '/verified',
user: UserBasic
};
UserBasic.verify(options, function(err) {
console.log('aaaaa', member.location, err);
if (err) {
next(err);
} else {
next();
}
});
});
//send password reset link when requested
UserBasic.on('resetPasswordRequest', function(info) {
var url = 'http://' + config.host + ':' + config.port + '/reset-password';
var html = 'Click <a href="' + url + '?access_token=' +
info.accessToken.id + '">here</a> to reset your password';
UserBasic.app.models.Email.send({
to: info.email,
from: info.email,
subject: 'Password reset',
html: html
}, function(err) {
if (err) return console.log('> error sending password reset email');
console.log('> sending password reset email to:', info.email);
});
});
};
In DataSource, I am using Cloudant (couchDB), here it is:
{
"db": {
"name": "db",
"connector": "memory"
},
"cloudant-pop": {
"host": "userxxx.cloudant.com",
"port": 443,
"url": "https://userxxx.com",
"database": "population",
"password": "userxxx",
"name": "cloudant-pop",
"connector": "couch",
"db": "population",
"protocol": "https",
"auth": {
"admin": {
"username": "userxxx",
"password": "userxxx"
},
"reader": {
"username": "userxxx",
"password": "userxxx"
},
"writer": {
"username": "userxxx",
"password": "userxxx"
}
},
"user": "userxxx"
},
"emailDs": {
"name": "emailDs",
"connector": "mail",
"transports": [
{
"type": "smtp",
"host": "smtp.gmail.com",
"secure": true,
"port": 465,
"tls": {
"rejectUnauthorized": false
},
"auth": {
"user": "[email protected]",
"pass": "aaa"
}
}
]
}
}
This is my model-config.json, Since I want to store the user credential to my Cloudant DB so I connect my user-basic model to my Cloudant Datasource:
"user-basic": {
"dataSource": "cloudant-pop",
"public": true,
"options": {
"emailVerificationRequired": true
}
}
I ran the server and try POST a new user via http://0.0.0.0:3008/explorer. It gives me an error:
{
"error": {
"name": "TypeError",
"status": 500,
"message": "UserBasic.verify is not a function",
"stack": "TypeError: UserBasic.verify is not a function\n at /Users/yogieputra/Desktop/backend_powercube/common/models/user-basic.js:23:23\n at Function.<anonymous> (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback/lib/model.js:207:11)\n at execStack (/Users/yogieputra/Desktop/backend_powercube/node_modules/strong-remoting/lib/remote-objects.js:480:26)\n at RemoteObjects.execHooks (/Users/yogieputra/Desktop/backend_powercube/node_modules/strong-remoting/lib/remote-objects.js:492:10)\n at phaseAfterInvoke (/Users/yogieputra/Desktop/backend_powercube/node_modules/strong-remoting/lib/remote-objects.js:652:10)\n at runHandler (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-phase/lib/phase.js:130:5)\n at iterate (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)\n at Object.async.eachSeries (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-phase/node_modules/async/lib/async.js:162:9)\n at runHandlers (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-phase/lib/phase.js:139:13)\n at iterate (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-phase/node_modules/async/lib/async.js:146:13)"
}
}
When I check the Database, I got the user data that I've been POST recently.
Can you guys tell me what I've been missing?
Please help
Hey @yogieputra8, check the API docs. The verify method is a prototype method, so you would need to call member.verify judging by your code.
For all your *myModel.js files, the argument passed into the module.exports function is a model class. So in your case, UserBasic is not a user/member, it is a user class. I think you have improperly used it in a couple places.
Let me know if that helps! If it doesn't solve your issue, I'll take another look.
Happy coding!
@richardpringle thank you for the response, I changed my /models/user-basic.js become this:
member.verify(options, function(err) {
console.log('aaaaa', member.location, err);
if (err) {
next(err);
} else {
next();
}
});
And now it gives me another error when I try to POST data via explorer:
Web server listening at: http://0.0.0.0:3008
Browse your REST API at http://0.0.0.0:3008/explorer
> user.afterRemote triggered
events.js:141
throw er; // Unhandled 'error' event
^
Error: You must connect the Email Model to a Mail connector
at Function.Email.send (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback/common/models/email.js:42:11)
at sendEmail (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback/common/models/user.js:429:13)
at /Users/yogieputra/Desktop/backend_powercube/node_modules/loopback/common/models/user.js:407:11
at ModelConstructor.<anonymous> (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/dao.js:2033:21)
at ModelConstructor.next (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/hooks.js:75:12)
at ModelConstructor.<anonymous> (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/dao.js:2032:28)
at ModelConstructor.next (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/hooks.js:75:12)
at /Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/dao.js:2031:28
at doNotify (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/observer.js:93:49)
at doNotify (/Users/yogieputra/Desktop/backend_powercube/node_modules/loopback-datasource-juggler/lib/observer.js:93:49)
I already put the email connector in my datasources, why loopback warn me to connect the Email Model to a Mail connector?
In order to help you further, I'm going to ask you to fork the loopback-sandbox and then send me a link or if you have a public repo on github, I could also take a look at that. It looks to me as though you have setup the "mail" datasource correctly, but not attached it to the Email model in your model-config.json.
Ahh, I get it. I add the email connector to my model-config.json just like this:
"Email": {
"dataSource": "emailDs"
},
And everythings working fine
@richardpringle thank you for the help. Really appreciate that :)
Glad it worked it worked out! Closing the issue now.
I think to prevent this issue from opening again we can clear up the documentation. The example here re-uses user as the model name and the model instance, and it's causing people a lot of confusion. Seen this issue raised more than a couple times. Switching the first instance of user with User would clear everything up.
@crandmck, want me to open a new issue for the above comment?
@enceladus is right, we shouldn't use the same variable name twice. I might also even suggest that the upper/lower-case 'u' might not be enough of a difference for new LoopBack users (developers). Maybe something like userInstance could be used to make things unquestionably clear.
I personally prefer the upper/lower-case convention for instance vs. class but I don't think it's the best for examples.
@richardpringle I'd appreciate it if you could update the docs, since you're up to speed on this specific thing, and I'm at an offsite currently.
@crandmck @enceladus, could you both take a look please? I made some changes so please point out anything that I may have missed.
Cheers
Sorry, forgot to post the link: https://docs.strongloop.com/display/public/LB/Registering+users
Just looked at the docs and it looks better to understand for new loopback users now. Thanks again @richardpringle
Most helpful comment
Sorry, forgot to post the link: https://docs.strongloop.com/display/public/LB/Registering+users