Meteor custom login procedure - meteor

This Meteor app has the insecure and autopublish removed and accounts-ui accounts-password added.
The code below needs to get the username and password, send them the to server which will run a method validateUser that returns true if valid.
validateUser tries to login to another server on the web, and returns true if successful, then my code should create a user account for this user.
The app is crashing because of this line
Accounts.createUser(useername: digest[0], password: digest[1]);
But even if it does not, Is this the meteor way to get this particular task done? Thanks
Edit:
After adding {} to the problem line in order to pass an object as suggested in the comments, I now get this error printed in the terminal;
Exception while invoking method 'logMeIn' Error: Match error: Failed Match.OneOf or Match.Optional validation in field password
<template name="myLogin">
<input type="text" name="username">
<input type="text" name="password">
<button id="logMe">log me in</button>
</template>
Template.myLogin.events({
'click #logMe': function() {
var credentials = [$('#password').val(), $('#username').val()];
Meteor.call('logMeIn', credentials, function(err, result) {
if (result) {
console.log('logged in!');
}
});
}
});
// on the server
Meteor.methods({
logMeIn: function(credenticals) {
//do work , if logged in, do next line
console.log("user account created");
Accounts.createUser({useername: credenticals[0], password: credenticals[1]});
}
});

Match error: Failed Match.OneOf - is because this method checks if email or username is presented in the object you are passing. You have typo in username and don't have email.
Next thing you are saying, after fixing typo you get Exception while invoking method 'logMeIn' Error: Match error: Expected string, got object in field username
This is because you have array with two undefined "members". Look at your jquery selectors. You are trying to select by id # but have inputs without ids.
Please organise yourself.

Your line
Accounts.createUser({useername: credenticals[0], password: credenticals[1]});
Has two typos, it should be
Accounts.createUser({username: credentials[0], password: credentials[1]});

Related

Firebase user.delete() method works but with error

I am using angular, and have an application that stores user details, and login info. When trying to delete a user, I am first deleting all the user related information. Then asking the user to re-authenticate themselves, after authentication, user gets logged out, and their basic details fetched to show profile id deleted followed by their sign-in info using user.delete().
All this works as expected, but at the end I am getting an error. Why am I am getting this error even when I have already logged out the user of the application.
Error Message: {code: "auth/user-token-expired", message: "The user's credential is no longer valid. The user must sign in again.", a: null}
My code -
deleteAccount(){
var userToDelete = firebase.auth().currentUser;
this.logout();
this.store.dispatch(UI.StartAppLoad({status:'Deleting User Details...'}));
this.userService.DeleteUser(userToDelete.uid)
.then((res)=>{
console.log(res);
}).catch(this.HandleError.bind(this));
userToDelete.delete().then(
(res)=>{
console.log(res);
this.uiService.showSnackbar('User Account Deleted',null,3000);
this.store.dispatch(UI.LoadApp());
}
).catch(this.HandleError.bind(this));
}
logout() {
this.afAuth.signOut();
}
where, HandleError is used to display the Error Message in a snackbar.
deleteAccount() is called after the user successfully authenticates themselves.
Instead of getting the error message displayed, I want to display the message 'User Account Deleted'.
Entire Flow -
onDeleteAccount(){
const confirmResult = this.uiService.showConfirm({
isDanger:true,
title:'Delete Account?',
content:'All your user account data will be permamnently deleted.'+
' You will need to create a new account later. Are you sure you want to continue?',
okText:'Delete'
});
confirmResult.subscribe(async isDelete=>{
if(isDelete){
this.store.dispatch(UI.StartAppLoad({status:'Deleting Excercise Data...'}));
const isResetDone = await this.trainingService.resetPastExercise();
if(isResetDone){
this.store.dispatch(UI.StartAppLoad({status:'Deleting Follow list...'}));
this.userService.clearFollowList();
this.authService.actionToPerform.next(actions.Delete_Account);
this.store.dispatch(UI.LoadApp());
this.router.navigate([AppRoutes.ReAuthenticate]);
}
}
});
}
Authenticate Page's submit() method:
this.authService.reauthenticate({
email:form.value.email,
password:form.value.password
});
this.authService.deleteAccount();
AuthService:
reauthenticate(authdata: AuthData) {
this.store.dispatch(UI.StartLoading());
var credential = firebase.auth.EmailAuthProvider.credential(
authdata.email,
authdata.password
);
this.afAuth.currentUser.then((user) => {
user.reauthenticateWithCredential(credential)
.then((res)=>{
this.prevPwd = authdata.password;
console.log(res);
this.store.dispatch(UI.StopLoading());
})
.catch(this.HandleError.bind(this))
});
}
And then the above method deleteAccount()
Please suggest.
As explained in the doc, this happens because:
delete() is a security-sensitive operation that requires the user to
have recently signed in.
The doc also indicates that:
If this requirement isn't met, ask the user
to authenticate again and then call firebase.User.reauthenticateWithCredential.
So, you need to handle this specific error and do as indicated by the doc, i.e. "ask the user to authenticate again and then call reauthenticateWithCredential."

Exception from sub books id dMBTck6CaSupWbEna TypeError: Cannot read property ‘emails’ of null

I am getting an Exception whenever a user logged in into his account, and I cant see the collection data until the page is been refreshed… **[but I am not getting any exception if I use it like
Books.find({“customer_name”:this.userId);
instead of
Books.find({“customer_name”:Meteor.user().emails[0].address);
and I don't need that step because in my app users collection finding should be based on their email id, not by userId…]**
my code is shown below :
Someone, please help me out:frowning_face:
server - main.js:
var My_collection;
Meteor.publish(‘books’, function() {
My_collection =
Books.find({“customer_name”:Meteor.user().emails[0].address);
return My_collection;
client -main.js:
Template.viewBooks.helpers({
books() {
return Books.find({}, { sort: { books_order: -1 } }).fetch();
},
});
client - main.html
{{#each books}}
{{books_id}}
{{/each}}
ERROR:
App running at: http://localhost:3000/ I20171205-16:06:49.773(5.5)?
Exception from sub transactions id wQ9DpjjABEiPzMZ9P TypeError: Cannot
read property ‘emails’ of null I20171205-16:06:49.872(5.5)? at
Subscription._handler (server/main.js:16:75)
I20171205-16:06:49.873(5.5)? at maybeAuditArgumentChecks
(packages/ddp-server/livedata_server.js:1768:12)
I20171205-16:06:49.873(5.5)? at
DDP.CurrentPublicationInvocation.withValue
(packages/ddp-server/livedata_server.js:1043:15)
I20171205-16:06:49.873(5.5)? at
Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1134:15)
I20171205-16:06:49.873(5.5)? at Subscription.runHandler
(packages/ddp-server/livedata_server.js:1041:51)
I20171205-16:06:49.873(5.5)? at
packages/ddp-server/livedata_server.js:826:41
I20171205-16:06:49.874(5.5)? at Function..each..forEach
(packages/underscore.js:147:22) I20171205-16:06:49.874(5.5)? at
packages/ddp-server/livedata_server.js:822:9
I20171205-16:06:49.874(5.5)? at
Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1134:15)
I20171205-16:06:49.874(5.5)? at Session._setUserId
(packages/ddp-server/livedata_server.js:816:34)
It’s generally bad practice to use Meteor.user() on the server. Without having enough information surrounding how you’re publishing and subscribing to your collections, and since you’re saying you aren’t getting any errors when you use this.userId, you can find the email address the following way:
var currentUser = Meteor.users.findOne(this.userId);
var userEmail = currentUser.emails[0].address;
Then use it in Books.find
If you can provide more information about the subscription and the publication, i’d be able to help out more

Meteor Accounts-ui to wait for email verification before user access

A Meteor web app on the local machine uses Accounts-password and Accounts-ui.
The user enters email and password in order to create a new account.
It needs to be configured so that the user gets a userId (thus become a currentUser) only after verifying the creation of the accounts via email.
The app has an smtp variable set up. It send the verification email fine. but it failed to prevent the user to 'login' before the verification. How can it be made so that it only gives a valid userId after the verification? Thanks
//server
Accounts.onCreateUser(function(options, user) {
Accounts.config({
sendVerificationEmail: true
});
return user;
});
It's not quite as simple as all that. Meteor needs a user to have an ID in order to send them an email. What you want to do is probably not actually prevent a login, but prevent the In order to do what you want, you'll have to prevent them from seeing anything when they are logged in. Something like this in your top-level template:
{{#if userVerified}}
// Body of your app here
{{> Template.dynamic template=main}}
{{else}}
You are not yet verified
{{/if}}
And this in the corresponding .js file:
Template.body.helpers({
userVerified () {
const user = Meteor.user();
return user.emails[0].verified;
}
});
I define a global helper:
Template.registerHelper('isVerified',function(){ // return a true or false depending on whether the referenced user's email has been verified
if ( Meteor.user() && Meteor.user().emails ) return Meteor.user().emails[0].verified; // look at the current user
else return false;
});
And then in any template (typically my master template) I can do:
{{#if isVerified}}
content that only verified users should see
{{else}}
Please check your email for your verification link!
{{/if}}
As #Season has pointed out, the verification requires that a userId be created in order to link it to the verification email.
What you could do is prevent a user from logging in if they haven't verified their email. See this answer to another question which accomplishes that:
https://stackoverflow.com/a/24940581/3512709

Getting the error: "No such email address for user." when calling Accounts.sendVerificationEmail( userId ) in meteor

I am getting an error when I try to send an email verification link to the user. I have used the email feature of Meteor in other projects without any issues. But in the current project, I am getting this error and I have no idea what could be causing it.
The user.emails[0].address does have an email address.
Exception while invoking method 'sendVerificationLink' Error: No such email address for user.
at AccountsServer.Accounts.sendVerificationEmail (packages/accounts password/password_server.js:745:11)
at [object Object].sendVerificationLink(server/user/users_methods.js:25:23)
I am using METEOR#1.3-beta.11 and my code is as follows:
**Client:**
let user = { email: signupEmail,password: password }
Accounts.createUser(user, (err) => {
if(!err) {
Meteor.call('sendVerificationLink');
}
})
**Server:**
Meteor.startup(function () {
process.env.MAIL_URL = 'smtp://postmaster%40sandboxd9...7.mailgun.org:<pwrd>#smtp.mailgun.org:587';
});
...
Meteor.methods({
sendVerificationLink() {
let userId = Meteor.userId();
if ( userId ) {
return Accounts.sendVerificationEmail( userId );
}
}
});
process.env.MAIL_URL and mailgun is set correctly. I have tested it from server using the following server code and the email was delivered correctly.
Email.send({
to: "xxxxx#gmail.com",
from: "xxxxx#gmail.com",
subject: "Example Email",
text: "This is a test email."
});
I found the error after a day of wasted debugging. There is nothing wrong in the code I posted above in my original question. There was an error in the schema definition for User collection with another package that I had installed - jagi:astronomy. The validation rule for 'Verified' (email verified flag) was set to string. It should have been boolean. I still don't understand why that would prevent from sending out the verification email though. Email field validation itself was correct and email was saved. But once I changed the validation rule to Boolean for 'Verified' field to boolean, the error went away.

Can't authenticate using email and password

I'm trying to authenticate a user with a custom login form. I designed the form, and I'm trying to authenticate users like this:
Template['account.login'].events
'submit #login-form': (e, t) ->
e.preventDefault()
Meteor.loginWithPassword(
t.find('#login_username').value,
t.find('#login_password').value,
(err)->
console.log(err)
)
return false
Relevant Template(in JADE - sorry):
form.smart-form.client-form#login-form(novalidate)
fieldset
section
label.input
input#login_username(type="text", name="username")
section
label.input
input#login_password(type="password", name="password")
footer
button.btn.btn-primary(type="submit", id="login.btn.login") Login
From the resource I found online, this would be correct. However, I get this exception thrown on the server:
Exception while invoking method 'login' Error: Match error: Failed Match.Where validation in field username in field user.username
You forgot to add a tab and Meteor.loginWithPassword() is running outside the Template event. Paste your coffeescript code at http://js2.coffee/ and you'll see it right away.

Resources