I have a page with a condition using a reactive variable that is initially false, but when you login, using facebook or google it changes to true, and the content of the page changes.
When i login using facebook everything goes well but when i login using google, the variable "isAuthenticated" doesn't changes to true, but if i navigate to another page, it appears as the user is logged in, so i thing what is happening is that when i do if(Meteor.userId()) authentication with google is not done yet, so it skips this step and doesnt changes the value of the variable. How can i wait till the authentication is completed? If i click again in the login with google it then enters the condition, it only doesnt work when the user is initially not logged in.
This is my login with google method:
'click #google-login': function(event) {
event.preventDefault();
Meteor.loginWithGoogle({}, function(err){
if (err) {
return swal({
title: "Google Login Failed",
timer: 1700,
showConfirmButton: false,
type: "error"
});
throw new Meteor.Error("Google login failed");
Template.instance().authenticated.set(false);
}
});
if(Meteor.userId()){
//Enable idea submission
Template.instance().authenticated.set(true);
}
//Update last login
Meteor.users.update( { _id: Meteor.userId() }, {$set: {"metadata.lastLoginAt": new Date()}});
}
Any help would be appreciated!
First thing you can not set ReactiveVar in meteor.loginWithGoogle function try this
Tracker.autorun(function(){
if (Meteor.userId()) {
//Enable idea submission
Template.instance().authenticated.set(true);
//Update last login
Meteor.users.update({
_id: Meteor.userId()
}, {
$set: {
"metadata.lastLoginAt": new Date()
}
});
}
});
'click #google-login': function(event) {
event.preventDefault();
var self = Template.instance();
Meteor.loginWithGoogle({}, function(err) {
if (err) {
return swal({
title: "Google Login Failed",
timer: 1700,
showConfirmButton: false,
type: "error"
});
throw new Meteor.Error("Google login failed");
self.authenticated.set(false);
} else {}
});
}
Related
We are using Office.context.ui.displayDialogAsync for authentication with OAUTH library (Oidc-client) and below are the findings. Kindly help on the same.
As per attached code we were able to get access token in taskpane.ts file as args in messageHandler...
But when i logged in fresh browser that time only Secure Token Service (STS) login window getting opening.
If i logged out and cleared access token then again trying to logged in that time directly getting in as logged user without opening Secure Token Service (STS) window.
Once i cleared browser cache and all then only i am able to get Secure Token Service (STS) window again... Can you please advise about the scenario to handle? Do we need anything.
Current Scenario
displayDialogAsync getting opened as STS login very first time and able to login successfully. But for the subsequent login it is not getting popup and directly loading the data with tokens.
Expected Scenario
displayDialogAsync should not only open in first time login but also it should open for subsequent login which means if user logged out and trying to login again that time also it should popup.Is there anything need to clear cache for displayDialogAsync? Kindly help.
auth.ts
Office.initialize = function () {
var settings = {
authority: "https://xxxxxx.com/xxxx/xx",
client_id: "https://xxxxxxx.com/",
redirect_uri: "https://localhost:3000/taskpane.html",
// silent_redirect_uri:"https://localhost:3000/taskpane.html",
post_logout_redirect_uri: "https://xxxxxxx.com/",
response_type: "id_token token",
scope: "openid read:xxxx read:xxxxxx read:xxxxxxx",
state: true,
clearHashAfterLogin: false,
filterProtocolClaims: true,
loadUserInfo: true,
nonce:true,
};
Oidc.Log.logger = console;
var mgr = new Oidc.UserManager(settings);
mgr.signinRedirect();
mgr.signinRedirectCallback().then((user) => {
if (user) {
console.log(user);
} else {
mgr.signinPopupCallback().then(function (user) {
window.location.href = '../';
}).catch(function (err) {
console.log(err);
});
throw new Error('user is not logged in');
}
});
};
taskpane.ts
const loginpopup = function () {
if (OfficeHelpers.Authenticator.isAuthDialog())
return;
Office.context.ui.displayDialogAsync(
url,
{ height: 60, width: 60, /*displayInIframe:true*/ },
dialogCallback);
function dialogCallback(asyncResult) {
if (asyncResult.status == "failed") {
switch (asyncResult.error.code) {
case 12004:
console.log("Domain is not trusted");
break;
case 12005:
console.log("HTTPS is required");
break;
case 12007:
console.log("A dialog is already opened.");
break;
default:
console.log(asyncResult.error.message);
break;
}
}
else {
dialog = asyncResult.value;
dialog.addEventHandler(Office.EventType.DialogMessageReceived, messageHandler);
}
}
function messageHandler(arg: any) {
if (arg != "jsonMessage") {
$(".loader").show();
var test = JSON.parse(arg.message).value.split("#")[1].split("&")[1].split("=");
dialog.close();
};
}
}
logout.ts
Office.initialize = () => {
var settings = {
authority: "https://xxxxxx.com/xxxxxx/v1",
client_id: "https://xxxxxxx.com/",
redirect_uri: "https://localhost:3000/logout.html",
post_logout_redirect_uri: "https://localhost:3000/logout.html",
metadata: {
issuer: 'https://xxxxxx.com/xxxxxx/v1',
authorization_endpoint: "https://xxxxxx.com/xxxxxxx/v1/xxxxx"
}
};
var mgr = new Oidc.UserManager(settings);
mgr.signoutRedirect();
mgr.removeUser();
mgr.revokeAccessToken();
mgr.clearStaleState();
$("document").ready(function () {
localStorage.removeItem('accessToken');
localStorage.clear();
});
I have the following function to change the email on a Firebase user account. I want to display an ionic2 alert when complete, whether it was successful or there was an error. From my code below I do get the alert to display BUT it is blank. Most likely it is a timing issue on the Firebase promise but I don't know how to fix it.
private doChangeEmail(data): void {
var myAlert: {
title?: string,
subtitle?: string
} = {};
this.auth.ref.changeEmail({
oldEmail: data.oldemail,
newEmail: data.newemail,
password: data.password
}, function(error) {
if (error) {
switch (error.code) {
case "INVALID_PASSWORD":
myAlert.title = 'Invalid Password';
myAlert.subtitle = 'The specified user account password is incorrect.';
break;
case "INVALID_USER":
myAlert.title = 'Invalid User';
myAlert.subtitle = 'The specified user account does not exist.';
break;
default:
myAlert.title = 'Error creating user';
myAlert.subtitle = error;
}
} else {
myAlert.title = 'DONE';
myAlert.subtitle = 'User email changed successfully!';
}
});
let alert = Alert.create({
title: myAlert.title,
subTitle: myAlert.subtitle,
buttons: [{
text: 'OK',
handler: () => {
}
}]
});
this.nav.present(alert);
}
put the alert code inside the promise result....
this.auth.ref.changeEmail({
oldEmail: data.oldemail,
newEmail: data.newemail,
password: data.password
}, function(error) {
if (error){
// do error stuff..
} else {
// do success stuff..
}
// show alert here...
})
I found the following comment by Frank van Puffelen which solved my issue:
You're using this inside a callback function, where it has a different meaning. One solution is to use fat-arrow/rocket notation for the callback, which ensures this is what you expect it to be:
The correct syntax should be
this.auth.ref.changeEmail({
oldEmail: data.oldemail,
newEmail: data.newemail,
password: data.password
}, (error) => {
if (error){
// do error stuff..
} else {
// do success stuff..
}
// show alert here...
})
and the alert shows correclty as pointed out by Aaron Saunders
I am using meteor to build a website similar to reddit. I used the account-ui package for user accounts, but I had trouble getting the user value. I was able to create an account and login, but when I post a comment, it shows that I am an anonymous user. Here's the code -
Template.registerHelper('getUser', function(user_id) {
var user = Meteor.users.findOne({_id: user_id});
if (user) {
return user.username;
}
else {
return "anon";
}
});
post a comment -
Template.comment_form.events({
"submit .js-save-comment-form":function(event){
if (Meteor.user()) {
// here is an example of how to get the comment out of the form:
var comment = event.target.comment.value;
console.log("The comment is: "+comment);
Comments.insert({
website: Router.current().params._id,
comment: comment,
createdOn: new Date(),
user: Meteor.user()._id
});
event.target.comment.value = "";
}
else {
alert('You need to be logged in to submit comments!');
}
return false; // stop the form submit from reloading the page
}
});
I was logged in as user test, but when I posted a comment, it shows it's posted by anon, which means the server didn't return the user value
See if this makes the usernames show up. It's not the production solution, but it should give you some idea what's going on if it works.
Meteor.publish(null, function () {
if (!this.userId) return null;
return Meteor.users.find({},{fields: {'username': 1, '_id': 1}});
});
I sent enrollment email to the user and when he enters password and other details I'm trying to reset the password but it is throwing error
uncaught error extpected to find a document to change
As you can see in the mage
I've subscribed to the user record
my code
this.route('enroll', {
path: '/enroll-account/:token',
template: 'enroll_page',
onBeforeAction: function() {
Meteor.logout();
Session.set('_resetPasswordToken', this.params.token);
s = this.subscribe('enrolledUser', this.params.token).wait();
}
}),
After I'm displaying form and on the submit event
onSubmit: function(creds) {
var options = {
_id: Meteor.users.findOne()._id,
name: creds.name
}
var token=Session.get('_resetPasswordToken');
Meteor.call('updateUser', options, function(error, result) {
if(!error) {
Accounts.resetPassword(token, creds.password, function(error) {
if (error) {
toastr.error("Sorry we could not update your password. Please try again.");
return false;
}
else{
toastr.error("Logged In");
Router.go('/');
}
});
} else {
toastr.error("Sorry we could not update your password. Please try again.");
return false;
}
});
this.resetForm();
this.done();
return false;
}
Everything is working fine but resetpassword callback is not triggering and the above error is displaying in console.
my token is get deleted from the user record and I'm able to login using login form but
From the docs
Reset the password for a user using a token received in email. Logs the user in afterwards.
I'm not able to automatically login after resetting the password,above error is throwing
What am I missing here?
this.subscribe('enrolledUser', this.params.token).wait();
here you're subscribing using resetPassword token
when you call Accounts.resetPassword method the method will reset the password and delete the token from user record.
So your subscription is lost and there are no records available in client side to modify
(That is waht the error Expected to find a document to change)
Instead on first subscription save the user Id and subscribe to the user record using Id
so the subscription will not be lost
path: '/enroll-account/:token',
template: 'enroll_page',
onBeforeAction: function() {
Meteor.logout();
Session.set('_resetPasswordToken', this.params.token);
s = this.subscribe('enrolledUser', this.params.token).wait();
},
onAfterAction:function(){
if(this.ready()){
var userid=Meteor.users.findOne()._id;
Meteor.subscribe("userRecord",userid);
}
}
Alternatively, you could do something like as follows in your publication. This worked for me (but mine was a slightly more involved query than this).
Meteor.publish('enrolledUser', function (token) {
check(token, String);
return Meteor.users.find({
$or: [{
_id: this.userId
}, {
'services.password.reset.token': token
}]
});
});
From the docs, it says
Reset the password for a user using a token received in email. Logs the user in afterwards.
So basically, you have to subscribe to the logged in user after the fact as well. A little silly, but whatever.
So I'm using the "Facebook-sdk" plugin. I'm initializing Facebook like this:
FB.init({ appId: 'xxxxxxxxxxx', cookie: true, xfbml: true, oauth: true, status: true });
FB.login(function(){ // get permissions
}, {scope: 'user_friends, read_friendlists, user_photos, email, publish_actions '});
FB.getLoginStatus(function (response) { // to generate AccessToken
if (response.authResponse) {
console.log('LoginStatusResponse: ' + JSON.stringify(response, null, 4));
} else {
console.log('AuthResponse: No');
}
});
Then in response to a button click event, I'm doing:
'click #get_fb_friends' : function(event, template) {
FB.api(
"/me/friends",
function (response) {
if (response && !response.error) {
console.log('GOT them !!!' + JSON.stringify(response, null, 4));
return response;
} else {
console.log('No can do' + JSON.stringify(response, null, 4));
}
});
}
The thing is that I'm getting an empty Data variable:
GOT them !!!{
"data": []
}
PS: The query "/me" returns all information about myself, it's the "/me/friends" that doesn't work.
Can it be a permissions problem ?
Facebook has changed its api a few weeks ago,you can only access a list of your friends when they have personally accepted to use your app.. Nothing to do about it
Like #Wampie said, the API has changed, so you could try to use the v1 API (keep in mind that you'll need to request a new access token).
And you can still invite friends to your app by using the apprequests method.
FB.ui({
method: 'apprequests',
message: 'You should learn more about the Platform.'
}, function(){
console.log(arguments);
});
Example here:
https://www.fbrell.com/fb.ui/apprequests