Firebase authentication on App initilisation - firebase

This is works:
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
but this one is not:
$scope.authenticated.currentUser = user.id;
My goal here is to take to take some of the authentication variables (Email+UserID) and then use them to access a profile node ON firebase. On initialization I want the username, email, and a few other things I need for the app.
crossfitApp.controller('globalIdCtrl', ["$scope",'defautProfileData','$q', function ($scope,defautProfileData,$q) {
var dataRef = new Firebase("https://glowing-fire-5401.firebaseIO.com");
$scope.authenticated={
currentUser: $scope.authemail,
emailAddress: "",
settings: "",
};
var chatRef = new Firebase('https://<YOUR-FIREBASE>.firebaseio.com');
var auth = new FirebaseSimpleLogin(chatRef, function(error, user) {
if (error) {
// an error occurred while attempting login
switch(error.code) {
case 'INVALID_EMAIL':
case 'INVALID_PASSWORD':
default:
}
} else if (user) {
// user authenticated with Firebase
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
$scope.authenticated.currentUser = user.id ;//
} else {
// user is logged out
}
});
}]); //GlobaldCtrl

Most likely, you're running into a problem with Angular's HTML Compiler.
Whenever you use an event like ng-click/ng-submit/etc, Angular fires $scope.$apply(), which checks for any changes to your $scope variables and applies them to the DOM.
Since FirebaseSimpleLogin is not part of Angular's purview, it has no idea that when the callback is fired, you've updated $scope.authenticated.currentUser. This would also explain why it works when you call auth.login(), since you're probably invoking that via an ng-click event somewhere, which would fire a digest check and discover the changes.
If this is indeed the case, you can correct this issue by alerting Angular that it needs to run $apply by using $timeout:
crossfitApp.controller('globalIdCtrl', ["$scope",'defautProfileData','$q', '$timeout', function ($scope,defautProfileData,$q, $timeout) {
/* ... */
var auth = new FirebaseSimpleLogin(chatRef, function(error, user) {
if (error) {
/* ... */
} else if (user) {
$timeout(function() {
$scope.authenticated.currentUser = user.id ;//
});
} else {
// user is logged out
}
});

Related

Logout is not clearing all process using oidc client with identity server 4

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();
});

Meteor SignUps Forbidden on Accounts.createUser

I'm getting the error "SignUps Forbidden" when i try to create a user account. Any ideas why?
My packages:
useraccounts:materialize
materialize:materialize
accounts-password
accounts-facebook
service-configuration
accounts-google
accounts-twitter
kadira:blaze-layout
msavin:mongol
kadira:flow-router
kevohagan:sweetalert
Client Code:
Template.register.events({
'click #register-button': function(e, t) {
e.preventDefault();
// Retrieve the input field values
var email = $('#email').val(),
firstName = $('#first-name').val(),
lastName = $('#last-name').val(),
password = $('#password').val(),
passwordAgain = $('#password-again').val();
// Trim Helper
var trimInput = function(val) {
return val.replace(/^\s*|\s*$/g, "");
}
var email = trimInput(email);
// If validation passes, supply the appropriate fields to the
// Meteor.loginWithPassword() function.
Accounts.createUser({
email: email,
firstName: firstName,
lastName: lastName,
password: password
}, function(error) {
if (error) {
return swal({
title: error.reason,
text: "Please try again",
showConfirmButton: true,
type: "error"
});
} else {
FlowRouter.go('/');
}
});
return false;
}
});
Server code
Accounts.onCreateUser(function(options, user) {
user.profile = options.profile || {};
user.profile.firstName = options.firstName;
user.profile.lastName = options.lastName;
user.profile.organization = ["Org"];
user.roles = ["User"];
return user;
});
UPDATE:
Here is a link to the repo
The problem seems to be on .....meteor\local\build\programs\server\packages. If i switch the value to false it's useless because it resets on every build.
// Client side account creation is disabled by default:
// the methos ATCreateUserServer is used instead!
// to actually disable client side account creation use:
//
// AccountsTemplates.config({
// forbidClientAccountCreation: true
// });
Accounts.config({
forbidClientAccountCreation: true
});
I had to remove the useraccounts:materialize in order to solve this problem
I don't think that the current accepted answer is the right one.
If you want to keep your packages yet override the setting you can change the value of Accounts._options.forbidClientAccountCreation in your code.
Set it to true if you want to prevent the account creation, or to false otherwise.

How do call a Meteor server from an Ionic app and have it respect your user ID

When I call try to call a Meteor server from an Ionic app, the user ID is not recognized on the server, despite having successfully logged in.
In the index.html of the Ionic app, before the meteor-client-side.bundle.js is included, the server URL is set:
SERVER_URL = "http://localhost:3000"; // Changes a lot. Run ipconfig. Look for Virtual Box???
window.__meteor_runtime_config__ = {
DDP_DEFAULT_CONNECTION_URL: SERVER_URL,
ACCOUNTS_CONNECTION_URL: SERVER_URL
};
Then, the user logins which is successful and I Meteor.user() looks good.
Meteor.loginWithPassword($scope.credentials.username,
$scope.credentials.password,
function (err) {
if (err) {
alert(err);
} else {
console.log('login success:' + JSON.stringify(Meteor.user()));
But, when the client code, tries to insert:
self.addOwnedProduct = function () {
var newOwnedProduct = {
productID: "ZZZZZZ" + Math.random(),
userID: Meteor.userId()
};
OwnedProducts.insert(newOwnedProduct);
};
The server code, sees the userId as null:
OwnedProducts = new Mongo.Collection("ownedProduct");
OwnedProducts.allow({
insert: function (userId, ownedProduct) {
console.log("Meteor.isServer:" + Meteor.isServer);
console.log("userId:" + userId);
return true || (userId && ownedProduct.userID === userId);
},
Here is a repo that replicates the problem
https://github.com/kokokenada/ionicToMeteorLogin

Custom Meteor enroll template

In my application I want to seed the database with users and send them an enrollment link to activate their account (and choose a password). I also want them to verify/change some profile data.
On the server I seed the database like this:
Meteor.startup(function () {
if(Meteor.users.find().count() === 0) {
var user_id = Accounts.createUser({ email: 'some#email.com', profile: { some: 'profile' } });
Accounts.sendEnrollmentEmail(user_id);
}
})
The enrollment link is sent as expected, but I want to create a custom template for when the url in the email is clicked. Preferably handled by iron-router. (Not using the accounts-ui package).
I tried things like redirecting the user to a custom route like this:
var doneCallback, token;
Accounts.onEnrollmentLink(function (token, done) {
doneCallback = done;
token = token;
Router.go('MemberEnroll')
});
which is not working (it changes the url but not rendering my template)
I also tried to change the enroll URL on the server like this:
Accounts.urls.enrollAccount = function (token) {
return Meteor.absoluteUrl('members/enroll/' + token);
};
But when I do this, the Accounts.onEnrollmentLink callback does not fire.
Also, changing the URL is not documented so I'm not sure its a good practice at all.
Any help is appreciated.
In my application I'm doing like this
this.route('enroll', {
path: '/enroll-account/:token',
template: 'enroll_page',
onBeforeAction: function() {
Meteor.logout();
Session.set('_resetPasswordToken', this.params.token);
this.subscribe('enrolledUser', this.params.token).wait();
},
data: function() {
if(this.ready()){
return {
enrolledUser: Meteor.users.findOne()
}
}
}
})
As enrollment url is like this
http://www.yoursite.com/enroll-account/hkhk32434kh42hjkhk43
when users click on the link they will redirect to this template and you can render your template
In my publication
Meteor.publish('enrolledUser', function(token) {
return Meteor.users.find({"services.password.reset.token": token});
});
After taking the password from the user
Accounts.resetPassword(token, creds.password,function(e,r){
if(e){
alert("Sorry we could not reset your password. Please try again.");
}else{
alert("Logged In");
Router.go('/');
}
})
enroll link
Accounts.urls.enrollAccount = function (token) {
return Meteor.absoluteUrl('enroll-account/' + token);
};
Im afraid now isnt possible, what i did is changing the html and css using "rendered" function but it has some probs with delay
Meteor.startup(function(){
Template["_enrollAccountDialog"].rendered = function(){
document.getElementById('enroll-account-password-label').innerHTML = 'Escolha sua senha';
$('.accounts-dialog').css('background-color','#f4f5f5');
$('.accounts-dialog').css('text-align','center');
$('.accounts-dialog').removeAttr('width');
document.getElementById('login-buttons-enroll-account-button').className = ' create-account-button';
document.getElementById('login-buttons-enroll-account-button').innerHTML = 'Criar conta';
}
});

How do you change the email associated with a user in firebase simple login?

As the title suggests I would like to provide functionality to allow a user to update the email they use to login to my app using Firebase Simple Login. Cannot figure out an elegant way to do this. App uses AngularFire if that is relevant.
Does one exist or do I need to create a new account and delete the old one using the $removeUser() and $createUser() methods?
Update for Firebase 2.1.x
The Firebase SDK now provides a changeEmail method.
var ref = new Firebase('https://<instance>.firebaseio.com');
ref.changeEmail({
oldEmail: 'kato#domain.com',
newEmail: 'kato2#kato.com' ,
password: '******'
}, function(err) {
console.log(err ? 'failed to change email: ' + err : 'changed email successfully!');
});
Historical answer for Firebase 1.x
In Simple Login, this is equivalent to changing the user's ID. So there is no way to do this on the fly. Simply create the new account, remove the old one as you have already suggested.
If you're user profiles in Firebase, you'll want to move those as well. Here's brute force, safe method to migrate an account, including user profiles. You could, naturally, improve upon this with some objectification and futures:
var ref = new Firebase('URL/user_profiles');
var auth = new FirebaseSimpleLogin(ref);
// assume user has logged in, or we obtained their old UID by
// looking up email address in our profiles
var oldUid = 'simplelogin:123';
moveUser( auth, ref, oldUid, '123#abc.com', '456#def.com', 'xxx' );
function moveUser( auth, usersRef, oldUid, oldId, newId, pass ) {
// execute activities in order; first we copy old paths to new
createLogin(function(user) {
copyProfile(user.uid, function() {
// and once they safely exist, then we can delete the old ones
removeOldProfile();
removeOldLogin();
});
});
function copyProfile(newId, next) {
ref.child(oldUid).once('value', function(snap) {
if( snap.val() !== null ) {
ref.child(newId, snap.val(), function(err) {
logError(err);
if( !err ) { next(); }
});
}
});
}
function removeOldProfile() {
ref.child(oldId).remove(logError);
}
function createLogin(next) {
auth.createUser(newId, pass, function(err, user) {
logError(err);
if( !err ) { next(user); }
});
}
function removeOldLogin() {
auth.removeUser(oldId, pass, logError);
}
}
function logError(err) {
if( err ) { console.error(err); }
}

Resources