I'm having a problem of using variables between functions. As you can see down below User.username is available and good at the sign up page, but when you go to the login page I told it to first alert the value of User.username, and it alerts undefined? I'm confused here. I'm pretty sure I'm missing a concept here. Anyways Thank you so much!:
Here is a plunkr: http://plnkr.co/edit/qB3Gkeq5ji1YQyy0kpGH
Here is my script.js:
app.controller("AuthCtrl", ["$scope", "Auth","$rootScope",
function($scope, Auth, $rootScope) {
var User = {}
$scope.createUser = function(username, email, password) {
$rootScope.usernames = username
User.username = username
$scope.message = null;
$scope.error = null;
var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
ref2.createUser({
email: $scope.email,
password: $scope.password
}, function(error, userData) {
if (error) {
switch (error.code) {
case "EMAIL_TAKEN":
alert("The new user account cannot be created because the email is already in use. Try to login");
break;
case "INVALID_EMAIL":
alert("The specified email is not a valid email.");
break;
case "INVALID_PASSWORD":
alert("The Specified Passowrd Is not valid.")
break;
default:
alert("Error creating user:", error);
}
} else {
alert("Successfully created user account with username" + User.username);
window.location.hash = "/User"
}
});
};
$scope.logIn = function(){
alert(User.username)
$rootScope.usernames = User.username
$scope.message = null;
$scope.error = null;
var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
ref2.authWithPassword({
"email" : $scope.logInemail,
"password" : $scope.logInemailpassword
}, function(error, userData){
if(error){
alert("Login Failed Because : " + error)
}
else{
alert("Logged In!")
window.location.hash = "/User"
}
})
}
/* $scope.removeUser = function() {
$scope.message = null;
$scope.error = null;
Auth.$removeUser({
email: $scope.email,
password: $scope.password
}).then(function() {
$scope.message = "User removed";
}).catch(function(error) {
$scope.error = error;
});
};*/
}
]);
When page reloads the entire javascript is re executed. So user object populated in registration process is no longer available in login function because page has reloaded on clicking on signup button.
So we need to store the user name in cookie so that we can access it any time. Even when its removed from javascript runtime it will be there in the browser cache.
Its risky to store passwords in cookies for security issues.
On successful registration save the username in cookie.
Some thing like this
document.cookie ="username =" +username + "; " +"email ="+ email;
In login function get cookie values and check if email of user is same as entered
function getCookie(name ) {
var pairs = document.cookie.split("; "),
count = pairs.length, parts;
while ( count-- ) {
parts = pairs[count].split("=");
if ( parts[0] === name )
return parts[1];
}
return false;
}
var username=getCookie("username");
var email=getCookie("username");
if($scope.logInemail ==email)
{
alert(username);
}
You have to remember that a web application is a communication between the browser the the web server. The browser and the server can be on different machines (even if they aren't when you are testing.)
There are two ways to make this work
While the browser and the server communicate some information is saved and passed back and forth on both ends -- this is called a cookie. This is the most common way to do save data between pages. The browser requests a page. When it get the reply from the server it contains a cookie. The next time the browser requests a page it includes the cookie in it's request. In this way the server knows the request is related to the prior request.
The server is smart enough to keep track of all "sessions" by different browsers. It then saves session data about that communication -- when it gets the next request from the same browser it goes to the session data and retrieves information about that that browser and what it was doing. (Often this is done with cookies.)
Related
I'm using the Stripe API and this is using the customer email address in the database however we've just had an issue where someone is signing in to the page using a different case to their sign up and it is not showing them as subscribed.
Obviously I'd like to convert the Stripe emails to all be lowercase but I'm not sure how to do this after getting the email. I am converting the user input to be all lowercase but that just means that if the email in Stripe is not lowercase they are not showing as subscribed.
Thanks in advance
$(document).ready(function() {
var productIDFull = "prod_key00000";
var email = '#User.Identity.Name';
var emailLower = email.toLowerCase();
// check if user has made a purchase in stripe for this product
var hasPurchasedFull = false;
$.ajax({
type: "GET",
url: 'https://api.stripe.com/v1/customers?email=' + emailLower,
headers: {
'authorization': 'Bearer sk_live_0000'
},
success: function(data) {
var isSubscribed = false;
// loop through each customer returned
$.each(data.data,
function(i, customer) {
console.log(customer);
var subscriptions = customer.subscriptions;
console.log(subscriptions);
// loop through each sub
$.each(subscriptions.data,
function(j, subscription) {
console.log(subscription);
var subData = subscription.items.data;
// loop through each plan
$.each(subData,
function(k, planData) {
console.log(planData);
if (planData.plan.product == 'prod_Kc3e_0000' && planData.plan.usage_type == 'licensed') {
isSubscribed = true;
}
});
});
I am converting the user input to be all lowercase but that just means
that if the email in Stripe is not lowercase they are not showing as
subscribed.
This sounds expected based on Stripe's documentation: https://stripe.com/docs/api/customers/list?lang=curl#list_customers-email
The email value is case sensitive, so customer Test#example.com will not be returned if you list customers with email test#example.com
I think a better way to handle this is to store a mapping of Stripe customer IDs and email addresses in an internal database and compare against this database instead of a customer list call.
I am working on a small web app and I have hit a roadblock that I can't seem to overcome. I am able to register a new account, but I would like to save additional data to a database right after signing up.
This is what I have that I am confident that works fine.
$("#user-sign-up-button").click(function(){
var firstName = $("#new-user-first-name").val();
var secondName = $("#new-user-surname").val();
var charity = $("#new-user-charity-account").val();
var userEmail = $("#new-user-email").val();
var userPassword = $("#new-user-password").val();
var secondPassword = $("#new-user-repeated").val();
firebase.auth().createUserWithEmailAndPassword(userEmail, userPassword)
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
});
Now in regards to saving the additional variables to the database I have tried both of the below within .then part of createuserWithEmailAndPassword.
.then(
function(user){
var root = firebase.database().ref();
var uid = user.uid;
alert(uid);
var postData = { firstName: first_name,
secondName: second_name,
email: user_email,
isCharity: charity };
root.child("users").child(uid).set(postData);
}
function writeUserData(first_name, second_name, charity, user_email) {
firebase.database().ref('users/' + user.uid).set({
firstName: first_name,
secondName: second_name,
email: user_email,
isCharity: charity
});
)
Both of the above solutions work within onAuthStateChanged but I want to capture the data at sign up, not every time someone signs in.
Any assistance would be great.
You must use .onAuthStateChanged to get at firebase.auth().currentUser. It's asynchronous and will be empty/null until it resolves. Also, don't forget that new email based accounts will not be .emailValidated:true until they have clicked a verification email link. ...something to consider.
I want to signup new users (through auth) and then add them (with their names and other info) to my user list database in realtime DB. I can't figure out what I'm doing wrong. Authentication works great but the new user is not being added to the DB.
var fname = document.getElementById('fname').value;
var lname = document.getElementById('lname').value;
var email = document.getElementById('email').value;
in the code below, I register them then add their names to the DB and then send a verification email.
function handleRegister() {
var ref = firebase.database().ref();
console.log(email);
console.log(fname);
if (email.length < 4) {
alert('Please enter an email address.');
return;
}
if (password.length < 4) {
alert('Please enter a password.');
return;
}
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
var uid = firebase.auth().currentUser.uid;
// [START_EXCLUDE]
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
firebase.auth().onAuthStateChanged(user => {
if(user) {
var postData = {
Fullname: fname + lname,
email: email,
};
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + uid ] = postData;
return firebase.database().ref().update(updates);
}
})
} else {
console.log(error);
}
})
Authentication and send email verification works fine but names are not being added to the DB. Also if there is a better approach to achieve auth,add to DB and send email verification, please let me know. Please help.
This is the updated addition
var addusertoDB = function(user){
var uid = firebase.getAuth().uid;
var postData = {
Firstname: fname,
Lastname: lname,
email: email,
}
// Get a key for a new Post.
var newPostKey = firebase.database().ref().child('Users').push().uid
// Write the new post's data simultaneously in the posts list and the user's post list.
var updates = {};
updates['/Users/' + newPostKey] = postData;
// updates['/user-posts/' + '/' + newPostKey] = postData;
return firebase.database().ref().update(updates);
}
and handle register has been updated to
firebase.auth().createUserWithEmailAndPassword(email, password).then(
addusertoDB).catch(handleCreateUserError);
it's finally being added to the DB (without the uid) but firebase.getAuth().uid is not getting the uid. the error I'm getting is "firebase.getAuth is not a function"
You are trying to handle both the errors and the user update in the same function you have passed to catch(). This means that any code inside that function is only run when firebase.auth().createUserWithEmailAndPassword(email, password) fails.
From the firebase documentation:
createUserWithEmailAndPassword
createUserWithEmailAndPassword(email, password) returns
firebase.Promise containing non-null firebase.User
Creates a new user account associated with the specified email address
and password.
On successful creation of the user account, this user will also be
signed in to your application.
This means that on the successful creation of a user you will have access to the new user via a callback passed into then().
You probably want something like this:
var doSomethingWithNewUser = function(user) {
// Manipulate the newly created User however you like here.
// You don't have to sign them in again.
};
var handleCreateUserError = function(error) {
var errorCode = error.code;
var errorMessage = error.message;
// Do whatever you want with the error codes.
};
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(doSomethingWithNewUser)
.catch(handleCreateUserError);
I found similar questions to mine, but in all of those examples, the variable was part of the model. I am trying to pass a variable that is created in javascript, which is not part of the model.
Code:
$(document).ready(function () {
var url = document.URL;
var index = url.indexOf("?email=");
var email;
/* If there is an EMAIL in URL, check directory to confirm it's valid */
if (index > -1) {
/* There is an email */
email = url.substr((index + 7));
email = email.substr(0, (email.length - 4)) + "##mymail.ca";
/* Check directory to see if this email exists */
#Html.Action("CheckDirectory", "Home", new { email = ???});
}
});
Is there a way to fill in the ??? with the email above?
You can pass your value as a GET parameter in the controller URL:
$(document).ready(function () {
var url = document.URL;
var index = url.indexOf("?email=");
var email;
/* If there is an EMAIL in URL, check directory to confirm it's valid */
if (index > -1) {
/* There is an email */
email = url.substr((index + 7));
email = email.substr(0, (email.length - 4)) + "##mymail.ca";
/* Check directory to see if this email exists */
window.location.href = '/CheckDirectory/Home?email=' + email;
}
});
To answer your question of
Is there a way to fill in the ??? with the email above?
No. The Razor code is similar to, say, PHP, or any other server-side templating language - it's evaluated on the server before the response is sent. So, if you had something like
#Url.Action("checkdirectory", "home")
in your script, assuming it's directly in a view, it would get replaced by a generated URL, like
/home/checkdirectory
Your code, which uses
#Html.Action("checkdirectory", "home")
actually executes a separate action, and injects the response as a string into the view where it's called. Probably not what you were intending.
So, let's try to get you on the right path. Assuming your controller action looks something like
[HttpGet]
public ActionResult CheckDirectory(string email = "")
{
bool exists = false;
if(!string.IsNullOrWhiteSpace(email))
{
exists = YourCodeToVerifyEmail(email);
}
return Json(new { exists = exists }, JsonRequestBehavior.AllowGet);
}
You could, using jQuery (because XMLHttpRequests are not fun to normalize), do something like
$(function(){
var url = '#Url.Action("checkdirectory", "home")';
var data = { email : $('#email').val() };
$.get(url, data)
.done(function(response, status, jqxhr) {
if(response.exists === true) {
/* your "email exists" action */
}
else {
/* your "email doesn't exist" action */
}
})
.fail(function(jqxhr, status, errorThrown) {
/* do something when request errors */
});
});
This assumes you have an <input /> element with an id of email. Adjust accordingly. Also, the Url helper can only be used within a view; if you're doing this in a separate JavaScript file, replace it with a hard-coded string (or whatever else works for you).
Edit:
Since it seems I didn't entirely get what you were trying to do, here's an example of returning a different view based on the "type" of user:
public ActionResult ScheduleMe(string email = "")
{
if(!string.IsNullOrWhiteSpace(email))
{
ActionResult response = null;
var userType = YourCodeToVerifyEmail(email);
// Assuming userType would be strings like below
switch(userType)
{
case "STAFF":
response = View("StaffScheduler");
break;
case "STUDENT":
response = View("StudentScheduler");
break;
default:
response = View("ReadOnlyScheduler");
break;
}
return response;
}
return View("NoEmail");
}
This assumes you would have 4 possible views: the three you mentioned, plus an "error" view when no email parameter was given (you could also handle that by redirecting to another action). This variation also assumes a user has somehow navigated to something like hxxp://yourdomain.tld/home/scheduleme?email=peter#innotech.com
I'm using the javascript api for Google Auth 2.0 . I'm running into the problem where the users email is not showing up, even though I request with https://www.googleapis.com/auth/userinfo.email .
My code looks like this:
gapi.auth.authorize({
client_id : 'xxxxxxxxxx.apps.googleusercontent.com',
scope : ['https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile'],
immediate : false
}, function(result) {
if (result != null) {
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId' : 'me'
});
request.execute(function(resp) {
console.log(resp);
});
});
}
});
What am I missing to get the user's email?
While the userinfo.email role gives you access to the information, the plus v1 client doesn't provide it. You will need to make an additional call to a different endpoint to get the info.
You will need the oauth2 v2 endpoint, which you can request with gapi.client.load('oauth2', 'v2', callback). The endpoint itself that you want is gapi.client.oauth2.userinfo.get(). This is untested, but the code might look something like:
gapi.client.load('oath2','v2',function(){
gapi.client.oauth2.userinfo.get().execute(function(resp){
console.log(resp);
});
});
See How can I get the user's email address in google apps? and Why can't I retrieve the users email from Google Plus API after getting permission for some related questions and https://developers.google.com/accounts/docs/OAuth2 for more details from the official doc.
Here's how I did it:
function tryAuth() {
var clientId = CLIENT_ID;
var configString = {
client_id: clientId,
scope: SCOPE,
immediate: 'false'
};
gapi.auth.authorize(configString, handleAuthResult);
}
Where SCOPE = 'https://www.googleapis.com/auth/fusiontables email';
Replace https://www.googleapis.com/auth/fusiontables scope with your scope but keep ' email' .
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
var access_token = authResult.access_token;
alert('Successfully logged in.' + access_token);
tryGetEmail(access_token);
}
And then
function tryGetEmail(access_token) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + access_token, false );
xmlHttp.send( null );
if(xmlHttp.status == 200) {
var strJSON = xmlHttp.responseText;
var objJSON = eval("(function(){return " + strJSON + ";})()");
email = objJSON.email;
alert('got email ' + email);
}
}
The userinfo endpoint and oauth2 v2 are being deprecated. The older answers are for the old system. All the details for migration are here:
https://developers.google.com/+/api/auth-migration#email
In short: put 'email' instead of 'h ttps://www.googleapis.com/auth/userinfo.email' for your scope, and the G+ email will be included as the first entry of the 'emails' property in the 'person' object you're fetching. There's also apparently an option described in the link to pull it out of the ID token, referenced in the link above.
Full example