validatesLengthOf not working on password field due to hashing - loopbackjs

I am trying to validate the password when a user is registered, but the validation is not done on the plain text but hashed value. How do i fix this?
My user model is client:
module.exports = function(client) {
client.validatesLengthOf('password', {min: 20})
};

Validations are for a model itself. I mean it affects on operation hooks not remote hooks.
You need to create a remote hook like this :
client.beforeRemote('create', function(ctx, instance, next){
if(ctx.args.data.password.length < 20){
return next(PsswordValidationError);
/* assuming you have this error object
or return any error validation you want */
}
next();
});

Related

Modify ChangeStream Responce In Loopback 3

First off, if you're not familiar with change streams, please read this.
It seems, when using lb to scaffold applications, that a change stream endpoint is automatically created for models. I have already successfully implemented a change stream where, on submitting a new model instance to my Statement model the changes are sent to all connected clients in real time. This works great.
Except it only sends the modelInstance of the Statement model. I need to know a bit about the user that submitted the statement as well. Since Statement has a hasOne relationship with my user model I would normally make my query with an includes filter. But I'm not making a query here... that's not how change streams work. The node server sends the information to the client without any query for that information being sent first.
My question is, how can I hook the outgoing changestream in the Statement model so that I can pull in the needed data from the user module? Something like:
module.exports = function(Statement) {
Statement.hookChangeStream(function(ctx, statementInstance, cb) {
const myUser = Statement.app.models.myUser
myUser.findOne({ 'where': { 'id': statementInstance.userId } }, function(err, userInstance) {
if (err !== undefined && err !== null) cb(err, null);
// strip sensitive data from user model
cleanUserInstance = someCleanerFunc(userInstance);
// add cleaned myUser modelInstance to Statement modelInstance
statementInstance.user = cleanUserInstance;
cb(null, true);
}
});
}
Can this be done? If so, how?

Unit tests on methods/publication that requires authentication in meteor

I'm writing unit test for my Meteor 1.4.2 application, where few of my methods requires authentication before processing.
How should I test these methods?
So far, I've written a test with practicalmeteor:mocha to create a new user and login with that user.
describe('login method', function () {
let logingKey;
beforeEach(function () {
Meteor.users.remove({});
const createUser = Meteor.server.method_handlers['registerUser'];
let params = {
username: 'testUsername'
}
res = createUser.apply({}, [params]);
logingKey = res.key;
});
it('can provide authentication', function () {
const loginUser = Meteor.server.method_handlers['login'];
let params = {
key: logingKey
}
console.log(params);
loginUser.apply({}, [params]);
});
I've written a custom login handler to login with the generated key which works fine with application, but in test results I'm getting following error.
Error: Cannot read property 'id' of undefined
at AccountsServer.Ap._setLoginToken (packages/accounts-base/accounts_server.js:889:35)
at packages/accounts-base/accounts_server.js:288:10
at Object.Meteor._noYieldsAllowed (packages/meteor.js:671:12)
at AccountsServer.Ap._loginUser (packages/accounts-base/accounts_server.js:287:10)
at AccountsServer.Ap._attemptLogin (packages/accounts-base/accounts_server.js:349:12)
at Object.methods.login (packages/accounts-base/accounts_server.js:533:21)
at Object.methodMap.(anonymous function) (packages/meteorhacks_kadira.js:2731:30)
at Test.<anonymous> (imports/api/methods/loginUser.tests.js:30:17)
at run (packages/practicalmeteor:mocha-core/server.js:34:29)
at Context.wrappedFunction (packages/practicalmeteor:mocha-core/server.js:63:33)
What could be wrong here? any suggestions are welcome, thanks in advance.
Original post on meteor forum
UPDATE
Ok! here is my confustion, Let say I've a write a unit test for this method, How should I verify or get the userId here.
Meteor.methods({
userStatus:function(update){
check(update, {online: String})
if (! this.userId) {
throw new Meteor.Error('error-not-authorized','User need to login', {method: "userStatus"})
}
try {
Meteor.users.update(Meteor.userId(),{$set: {'status.online': !!parseInt(update.online)}})
} catch (e) {
console.error("Error",e);
}
}
});
You are directly invoking a method handler without an appropriate context (which should be a Method Invocation object, while you provide an empty object). The login method handler attempts to get the connection id and fails to do so.
If you want to test the integration of your package with the accounts-base package (and basically you do, as you are calling some of its code), you can create a connection and call the method with that connection.
let connection = DDP.connect(Meteor.absoluteUrl());
// prepare the login data
const params = {/*...*/};
connection.call('login', params);
// test post conditions
connection.disconnect();
Edit (following question edit):
The answer remains pretty much the same. Once you have called the login method and logged in the user, the connection state on the server should include the logged-in user's id. Now you can call the methods that require the user to be logged in.
Note that you should probably use this.userId on all occasions (and not Meteor.userId()).

Ember.js - How to handle error with DS.store.findRecord() method

I am using following simple code to retrieve user
from server.
var someUser = this.store.findRecord('user', 0);
I am using this for retrieving the user. if user is not found on 0 id,
server returns 404. and error as per json api.
but how do i know about error on client side about it ?
Taken from Ember guides:
Use store.findRecord() to retrieve a record by its type and ID. This
will return a promise that fulfills with the requested record.
Since the return value is a promise, you can use it as any other promise:
this.store.findRecord('user', 0)
.then(function(user){
// user has been found
someUser = user;
}).catch(function(error){
// user not found or any other error
});

Meteor share sessions data between client and server

I'm building a restricted signup. I want user with a specific code passed in a url to be able to signup and not others. I'm using the accounts package.
I can prevent account creation in the Accounts.onCreateUser method. I'm looking for a way to tell the server if the client had an authorised signup code. With a classic form (email+password) I can just add an extra hidden field. How can I achieve the same result if the user signs up with let's say Facebook?
Since Meteor doesn't use cookies, I can't store this info in a cookie that the server would access. Session variable are not accessible server side. And since I'm not controlling what got send with the account-facebook creation, I can't use a Session variable on the client side that I'd pass along when the user presses sign up.
Any idea"?
Just add the special token to the user object being passed to Accounts.createUser():
var user = {
email: email,
password: password,
profile: {
token: token
}
};
Accounts.createUser(user, function (error, result) {
if (error) {
console.log(error)
}
});
On the server side you can access this in the Accounts.onCreateUser():
Accounts.onCreateUser(function(options, user) {
console.log(options);
console.log(user);
});
I think it's in the options variable that you will find your token, so it would be options.profile.token.
for me, the best option here was passing in custom parameters to loginbuttons.
see the package docs:
https://github.com/ianmartorell/meteor-accounts-ui-bootstrap-3
Where it outlines the below:
accountsUIBootstrap3.setCustomSignupOptions = function() {
return {
mxpDistinctId: Session.get('mxpdid'),
leadSource: Session.get('leadSource')
}
};

In Ember.js, how do you make requests to an API that are outside of the REST convention?

I would like to request a 'reset password' endpoint e.g GET -> user/password/reset on an API. What is the best way to map this request in ember.js? It doesn't seem appropriate to setup a full ember.js model for this kind of request, as it doesn't have a proper ID and is not really a request for a record, but a triggered event with a success/fail response. Am I incorrectly implementing the REST convention or is there another way to do this?
You can use a simple ember-object to represent password reset and then basic ajax. Something like this:
App.User.reopenClass({
resetPassword: function(subreddit) {
return $.getJSON("user/password/reset").then(
function(response) {
console.log('it worked');
return true;
},
function(response) {
console.log('fail');
return false;
}
);
}
});
See http://eviltrout.com/2013/03/23/ember-without-data.html
That said, this could be a sign that the API endpoint should change. Ideally GET requests should not have side effects, so a GET that resets a password is not recommended. If you think of reset as a password reset request, the reset password endpoint that makes the most sense is POST -> user/password/reset to create a new request.