Meteor.loginWithPassword returns Error: Incorrect password [403] - authentication

I would like to add programmatically few users and login with one of them in my meteor app. I could not find any methods to add users at server side; so I added two buttons at client side to generate users and login with one of them. I can create users (I see them in mogodb) but I cannot login, getting Error: Incorrect password [403]. What I am missing?
This is client.js code
Template.hello.events({
'click #createUsers': function () {
console.log("Creating users...");
var users = [
{ email: "dgra#gmail.com", username: "gra", name: "gra", roles: ['admin'] }
];
_.each(users, function (user) {
Accounts.createUser({
email: user.email,
password: "admin",
profile: { username: user.username },
profile: { name: user.name },
roles: user.roles
});
});
},
'click #logIn': function () {
console.log("logIn gra...");
Meteor.loginWithPassword("dgra#gmail.com", "admin", function (err) {
if (err) {
console.log("loginError: " + err);
}
});
}
});

I could not find any methods to add users at server side
You can add users from the server. As the docs point out, Accounts.createUser runs anywhere. Here is a working example:
server/initialize.js
var insertUser = function() {
var user = {
email: 'dgra#gmail.com',
username: 'gra',
name: 'gra'
};
Accounts.createUser({
username: user.username,
email: user.email,
password: 'admin',
profile: {
name: user.name
}
});
};
Meteor.startup(function() {
if (Meteor.users.find().count() === 0) {
insertUser();
}
});
A few points:
You can add only one profile object.
Accounts.createUser only takes the arguments shown in the docs, so you can't add arbitrary objects.
If you are trying to use roles, the example there shows the roles being added after the account is created.
In the code above, I only add the user if there are no users in the database. This is convenient for testing since the user will automatically be inserted after a meteor reset (no button pushing requred).

Related

How to modify currentUserStore in mobx-state-tree

I'm trying to wrap my head around mobx-state-tree and whipped up a simple currentUserStore to hold some data for a logged in user and allow login/logout:
import { types } from "mobx-state-tree";
import { client } from '../../../helpers/client';
const User = types
.model("User", {
name: types.string,
email: types.string,
type: types.string,
token: types.string,
roles: types.array(types.string),
})
export const CurrentUserStore = types
.model("CurrentUserStore", {
user: types.optional(types.maybeNull(User), () => null)
})
.actions((currentUserStore) => ({
async login(login, password) {
const result = await client.post(`auth`, {
email: login,
password,
});
const { name, email, type, token, roles } = result
currentUserStore.user = User.create({ name, email, type, token, roles })
localStorage.setItem('authUser', JSON.stringify(result));
},
logout() {
currentUserStore.user = null
localStorage.removeItem('authUser')
},
}));
When calling the login function, I get the error Cannot modify 'CurrentUserStore#/currentUserStore', the object is protected and can only be modified by using an action.. There's something I'm missing here, but not exactly sure why I shouldn't be able to do something like this after reading through example where the store is modified directly in an action like this.
Once I moved the modification out of an async func, it worked. Just changed to this:
async login(login, password) {
const result = await client.post(`auth`, {
email: login,
password,
});
this.setUser(User.create(result))
localStorage.setItem('authUser', JSON.stringify(result));
},
logout() {
currentUserStore.user = null
localStorage.removeItem('authUser')
},
setUser(user) {
self.user = user
}

Invalid credentials postman

I hard coded the users in my seed file
I can view the the users in the database
But when i try to test the details in the database i get an error "invalid credentials"
I don't know why it says that when the user is already in the database
This is the seeds file
const noPassword = "$2a$12$ZQwXBTq7UMgmugpy5zz9SOdG4JvEa3Bj5MofQl9fIMFb1wTSGU9.C"; exports.seed = function (knex) { // Deletes ALL existing entries return knex("users") .truncate() .then(function () { // Inserts seed entries return knex("users").insert([ { email: "danielAsuquo15#gmail.com", first_name: "Daniel", last_name: "Asuquo", password:noPassword, }, { email: "josiahdamiwilliams#gmail.com", first_name: "josiah", last_name: "williams", password:noPassword, }, ]); }); };

How can I authenticate users with Feathers.js

I'm trying to log in a user using the vuex store.
onSubmit() {
this.$store
.dispatch("auth/authenticate", {
username: "Sibi",
password: "123",
strategy: "local"
})
.then(function(result) {
console.log("Authenticated!", result);
})
.catch(function(error) {
console.error("Error authenticating!", error);
});
}
I have followed the docs and everything seems to be working for the signup.
Even if I hardcode the username and password it still shows Invalid

Should a new Collection be created upon Model.create()

Am working with mongoose and have two models. The User model and the Service model, when a user logs in the method will findOne() user if one exists or create() a new user based on the what's passed in from req.body.
My Service Schema is like this:
const serviceSchema = new mongoose.Schema({
name: {
type: String,
default: 'contentEditor'
},
display: {
type: String,
default: 'Content Editor'
},
accessLevel: {
type: Number,
min: 0,
max: 4,
default: 4
}
});
My User Schema is a bit bigger, I've removed some of the field/value pairs but the part where I embed the Service Schema looks like this:
const userSchema = new mongoose.Schema(
{
email: {
type: String,
required: [true, 'Must have a email address'],
trim: true,
unique: true,
},
firstName: {
type: String,
},
lastName: {
type: String,
},
services: {
type: [serviceSchema],
ref: 'Services',
default: [serviceSchema],
},
},
);
When I hit the /api/v1/login endpoint a new user will be created with the Service document correctly but within the Mongoose database only a User collection exists. How do I make it so that both a Users collection and Services collection are created?
Edit: Below is the function that I create/find the user with when they login. When an existing User is found, by their email it will return that user if the user is not found then it will create a new one...
Both behaviours are as expected including adding the Services to the newly created User. What isn't expected is that only ONE collection is added to the DB.
const login = catchAsync(async ({ body: { email, password } }, res, next) => {
if (!email || !password) {
return next(new AppError('Please provide email and password', 400));
}
const { Success } = await webApi(email, password);
const mongoUser = await User.findOne({ email });
if (Success && mongoUser) {
return createSendtoken(mongoUser, 200, res);
}
if (Success && !mongoUser) {
const newUser = await User.create({ email });
return createSendtoken(newUser, 201, res);
}
return next(new AppError('User not found', 404));
});
Make sure you are making the serviceSchema a mongoose model.
const Services = mongoose.model('Service', serviceSchema)
You also have to save it using mongooses model.save() function

Backand: Sign user in immediately after registering?

Having trouble doing this - is it even possible?
Sign-up Email Verification is off, and I'm doing this in the config:
BackandProvider.setAppName( 'test' );
BackandProvider.runSigninAfterSignup( true );
// ... tokens, etc.
Getting this back in the response after hitting the /1/user/signup endpoint:
data : {
currentStatus : 1,
listOfPossibleStatus : [...],
message : "The user is ready to sign in",
token : "...",
username : "tester#test.com"
}
Do I need to make another API call? Can't find where and with which params.
Yes, you must make another API call to get token after sign up. If you use the Backand SDK by default it makes the second call.
$scope.signup = function (form) {
return Backand.signup(form.firstName, form.lastName,
form.username, form.password,
form.password,
{company: form.company})
.then(function (response) {
$scope.getUserDetails();
return response;
});
};
If you lool at the SDK code, this is what happens there:
self.signup = function (firstName, lastName, email, password, confirmPassword, parameters) {
return http({
method: 'POST',
url: config.apiUrl + urls.signup,
headers: {
'SignUpToken': config.signUpToken
},
data: {
firstName: firstName,
lastName: lastName,
email: email,
password: password,
confirmPassword: confirmPassword,
parameters: parameters
}
}).then(function (response) {
$rootScope.$broadcast(EVENTS.SIGNUP);
if (config.runSigninAfterSignup
&& response.data.currentStatus === 1) {
return self.signin(email, password);
}
return response;
})
};