How to handle forgot password/ reset password through link - javascript

How to relay(fetch and auto submit) the code from email into our app upon launching it? Im using react native aws-amplify default forgotPasswordSubmit function.
Auth.forgotPasswordSubmit(username, code, new_password)

docs state this:
import { Auth } from 'aws-amplify';
// Send confirmation code to user's email (this sends the email, and consolelogs what is sent)
Auth.forgotPassword(username)
.then(data => console.log(data))
.catch(err => console.log(err));
// Collect confirmation code and new password, then (this lets you reset the password)
Auth.forgotPasswordSubmit(username, code, new_password)
.then(data => console.log(data))
.catch(err => console.log(err));
To have it so that it automatically goes from the email to the link would require you to do something with the "email template"
specifically, you can make it so that the template send you to a website page with a :slug for the URL that is passed into the "conformation code area" and useEffect could reload the page after this, to submit the information.
though I have not used anything AWS before.

You can refer to this doc for more information:
https://docs.amplify.aws/lib/auth/manageusers/q/platform/js#forgot-password

I guess, you already started the password recovery process with
Auth.forgotPassword(username)
so, you already know the username, and the user probably has received an email with a verification code.
You can't just "fetch" data from an email into your app. The only thing you can do is, creating a link in the email, which, when clicked opens your app. This link will for instance look like https://yourapp.com/recovery?code=12345656 This is called "Deep Linking"
This will allow you to extract the verification code from the clicked link. Now, you will have to ask the user for a new password. Once you have all necessary information (ie the preentered username, the verification code and the new password) available, you can finally call
Auth.forgotPasswordSubmit(username, code, new_password)
I won't provide any code here, as I don't see much sense in copying the docs or some tutorial. Have a look at the docs or one of the many tutorials out there. If you then have specific problems with your code, feel free to update your question with the details.

Related

How can I use firebase without the emulator?

I am learning firebase and I checked this tutorial regards the authentication. (https://www.youtube.com/watch?v=rbuSx1yEgV8&t=502s). In this video, the emulator seems to be essential, however I want to communicate with the server. How do I do it? If I do not initialize the auth emulator ( by removing the connectEmulator() function) I just get the error 'auth/network-request-failed'.
const firebaseConfig = {
//...
};
const user = {
email: 'user#test.me',
password: 'test1234'
}
function func() {
createUserWithEmailAndPassword(auth, user.email, user.password)
.then((userCredential) => {
const user = userCredential.user;
console.log(user)
})
.catch((error) => {
console.log(error)
// ..
});
}
As you can see from the minute 7:37 of that video, I am getting his issue! So I assume I am following the wrong approach. Can someone help me? I would be really grateful.
You should be able to authenticate with the server.
The emulator is optional. Personally I rarely use it, and essentially always use the real online Firebase server. However there are many steps before you are able to authenticate with the server.
Step 1. Check you have copied the configuration correctly
Go to this link, but replace PROJECT_ID with your actual project Id:
https://console.firebase.google.com/u/0/project/PROJECT_ID/settings/general/
Check that you have correctly copied the value of this into your app code from that page. If you have not "added an app", you may need to click "Add app", to get this config to display.
const firebaseConfig = {
... blah blah ...
};
Step 2. Check that you have enabled a "Sign-in provider"
Go to this link (again PROJECT_ID should be replaced by your project Id):
https://console.firebase.google.com/u/0/project/PROJECT_ID/authentication/providers
At least one of the providers needs to be switched on, like so:
Step 3. Your code looks good.
I assume you have set up auth correctly - we can't see that in the snippet above.
Please paste into your question the exact error message you are seeing on the console, as text.
You might want to intensify the debugging as follows:
function func() {
console.log(`user: ${JSON.stringify(user,null,2)}`)
createUserWithEmailAndPassword(auth, user.email, user.password)
.then((userCredential) => {
console.log(`userCredential.user: ${JSON.stringify(userCredential.user,null,2)}`)
})
.catch((error) => {
console.error(error)
});
}
A small thing, but I suggest avoiding using the same variable name, user, for two different things. Javascript will keep them separate, but we as programmers sometimes will get muddled when looking back at the code.
Step 4. Make sure you have authorised the domain you are using.
Go to:
https://console.firebase.google.com/u/0/project/PROJECT_ID/authentication/settings
Make sure you have authorised the domain from which you are "calling" the Firebase server.
If your app is running on "127.0.0.1" instead of "localhost", you might need to add that IP address too. Or if you have deployed, the deployed domain.

What is the proper way to implement authentication in Firebase?

ok so I've built a few apps in Firebase and really enjoy using the simple API but always struggle with auth. see this code
I have a simple email and password "form" (not a form element, just two inputs)
and then a button (div) I click to call this function below
const logUserIn = () => {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((res) => {
console.log('here') // this WORKS but the history redirect below does not work :/
localStorage.setItem('authUser', JSON.stringify(res))
history.push('/account')
})
.catch((error) => {
console.log('ERROR:', error)
})
}
however when I put the lines below
firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('user logged in')
} else {
console.log('user not logged in')
}
})
it seemed to pick it up correctly
but my question is, what is the point of signInWithEmailAndPassword? and also, how do I use both functions together? do I need to call onAuthStateChanged in the .then part of my signInWithEmailAndPassword function?
it's really confusing how to have a consistent state. my app seems to work after I refresh the page but I want it to work without refreshes (obviously)
any ideas on the best approach?
EDIT
also when I click sign out
firebaseApp.auth().onAuthStateChanged((user) => {
if (user) {
history.push('/account')
} else {
console.log('NO USER')
}
})
NO USER logs but then I click on an authenticated route it takes me there until I refresh
The point of signInWithEmailAndPassword is to allow the implementation of classic username/password authentication for people who don't have a Google, Facebook, Twitter, etc. account. If you decide to add it, Google will handle the user accounts and everything, but you'll have to build the login form, complete with the I forgot my password and Register as new user links. Other than that it's simply another provider.
I have a very simple little project on my Github repo which implements user/password authentication along with several others, I suggest you to look into it. I made it as a test assignment for a job interview. It's Angular.
https://github.com/tomcatmwi/morbidomega

firebase javascript injection

I want ask something about firebase security. How to handle following situations?
User is creating account with createUserWithEmailAndPassword() function, then i save his username,email,created_at...to realtime db. But what if data are not saved correctly. His account is created and he is logged in automatically but data is not stored.
I have some registration logic... for example unique usernames... so before creating acc i check if this username exist in realtime db. But he still can call createUserWithEmailandPassword() from js console and account is created.
For situation one:
According to the firebase docs (https://www.firebase.com/docs/web/api/firebase/createuser.html), creating a user does not automatically authenticate them. An additional call to authWithPassword() is required first. In order to ensure that a user isn't authenticated without valid data, you could run a check to the server to make sure the data is saved correctly before authenticating.
Edit: Nevermind that; looks like firebase does auto-auth now - take a look at what I wrote below.
Now a concern with this approach would be if your app allowed people to authenticate with an OAuth provider like gmail, then there is no function for creating the user before authenticating them. What you may need to do is pull the user data from the firebase, determine if it's valid, and if its not valid show a popup or redirect that lets the user fix any invalid data.
For situation two:
If you wanted to make sure that in the case of them calling createUserWithEmailAndPassword() from the console a new user is not created, you could try something like this with promises;
var createUserWithEmailAndPassword = function(username, password) {
var promise = isNewUserValid(username, password);
promise.then(function() {
// Code for creating new user goes here
});
}
In this way, you never expose the actual code that makes a new user because it exists within an anonymous function.
I don't think that this could solve the problem entirely though because firebases API would let anyone create an account using something
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.createUser({
email: "bobtony#firebase.com",
password: "correcthorsebatterystaple"
}
(Taken from https://www.firebase.com/docs/web/api/firebase/createuser.html)
If you wanted to make sure that server side you can't ever create a user with the same user name, you'd need to look into firebases's rules, specifically .validate
Using it, you could make sure that the username doesn't already exist in order to validate the operation of creating a username for an account.
Here's the firebase doc on rules: https://www.firebase.com/docs/security/quickstart.html
And this is another question on stack overflow that is quite similar to yours. Enforcing unique usernames with Firebase simplelogin Marein's answer is a good starting point for implementing the server side validation.
First save the user credentials in the realtime database before you create the user:
var rootRef = firebase.database().ref('child');
var newUser = {
[name]: username,
[email]: useremail,
[joined]: date
};
rootRef.update(newUser);
After adding the Usersinfo into the realtime database create a new user:
firebase.auth().createUserWithEmailAndPassword(useremail, userpassword).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
When an error occured while inserting the data in the realtime database, it will skip the createuser function.
This works fine for me, hope this helps!

How to handle user information using firebase simple login for facebook

I am building a webpage using AngularJS and Firebase. I want to use facebook login to connect information on the webpage with the user. Firebase has a version of simple login which I guess is supposed to simplify the login process.
My problem is that I want to access information about the logged in user in a lot of places on my webpage but I can't find a good way to do it.
This is how I started out:
var userInfo = null;
var ref = new Firebase('https://<yourfirebase>.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(ref, function(error, user) {
if(error)
alert("You are not logged in");
else if(user)
{
//store userinfo in variable
userInfo = user;
}
else
//user logged out
});
//do something with userInfo
alert(userInfo.name);
My first thought was to run this at the top of my page and then use the info about the user. The problem is that the code using userInfo (as in e.g. the alert) will always run before the userInfo variable has been filled and userInfo will return undefined/null.
I then proceeded to always create a new firebasesimplelogin object when i want to retrieve user data. Which of course isn't very good. Especially since every created FirebaseSimpleLogin object will be called again whenever another is called or a user logs out, for example.
So my question is, how do I use FirebaseSimpleLogin to handle and use my user information in the best way?
I would have liked some function to getUserInfo() or check isLoggedIn() for example. How do you do this properly?
You can take a look at this example for thinkster. It's based on using simple login with userid/password. http://www.thinkster.io/angularjs/4DYrJRxTyT/7-creating-your-own-user-data-using-firebase.
You can create a function like getLoggedinUser that runs in $rootScope that will allow you to find the user throughout the application.
UPDATE:
Around the middle of October 2014, firebase made some big changes. This method might still work, but it's better to take advantage of the newer version of firebase, specifically getauth and onauth. These methods will allow you to do the same thing without running on the rootScope. https://www.firebase.com/docs/web/guide/user-auth.html#section-login
Please make a constant to use it everywhere in your App like that
.constant('facebookUrl', 'https://rjrestaurantapp.firebaseio.com');
Then in the controller inject this constant "facebookUrl & "$state" as shown below...
.controller('loginCtrl', function($scope,facebookUrl,$state){
and then you only need to give name of the state where you want to redirect after facebook authentication..
var ref = new Firebase(facebookUrl);
$scope.fbLogin = function () {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
$state.go('restaurant');
}
})
}})
You can see the information in authData object after successfull authentication using facebook ....
please read this doc carefully https://www.firebase.com/docs/web/guide/login/facebook.html
The above is the example of simple login using firebase and for retrieving data for each logged in user, you have to store user information at the time of signin as you know that firebase makes every child with a unique ID .. then you only need to use the offline features of firebase that will find which user is offline and according to that remove the node with the same ID which one is offline, you can find examples in the MANAGING PRESENCE section of the below link ..
https://www.firebase.com/docs/web/guide/offline-capabilities.html

Express and realtime apps. Persist updates from client to server to client

I am writing a realtime app. The basic principle is like a chat, but instead of text messages, users share youtube videos. The backend hasn't been completely done yet, and I don't know how I will do it. But I have some questions for what has been done.
Right now, user authentication with user/pass, FB, Twitter works well, and credentials are being stored in my db. User sign in works fine as well. Error messages get flashed fine.
I'm using mongodb (mongoose) and express on the backend. It is not an API based design because I don't know how to work with user authentication in API's (I can make GET/POST/PUT/DELETE API, just don't know how to fit in authentication in there).
When a user, say, signin's using the homepage, the credentials are verified using req.body.<field> in an express.js route. If authenticated, redirect the user to a dashboard, else redirect to signin with flash messages. So, there are no Ajax calls, and right now, the app isn't realtime in any way. I'd like it to be realtime though.
So, leading to that, I have 3 questions:
I am using a modal window (bootstrap), to ask the user to update profile. The modal shows fine, except the field I want to be shown are not shown. The password and email fields are empty, even though I have a value attribute.
input.form-control.dash(type="password", name="newuserpassword", ng-minlength=8, ng-model="password", value="__USE_EXISTING__")
input.form-control.dash(type="email", name="newuseremail", required=true, ng-model="email", value=user.email)
http://snappy-app.com/s/read.php?pass=9fc7ffa1e2b2140aad5232d5733f4caf
I want that when user edits the "Save" button, a message in the modal should either how any errors, or show that the update was successful. As it is, right now, my update method doesn't do this. Beyond redirecting the user, I don't know how can I achieve what I want.
exports.update_user = function(req, res) {
var user = new User({
'username' : req.user.username,
'password': req.body.newuserpassword || ,
'email': req.body.newuseremail
});
console.log(user);
user.save(function(err) {
if (err) {
console.log(err);
for (var field in err.errors) {
var error = err.errors[field].message;
req.flash('error', error);
}
res.redirect('/dashboard');
} else {
req.logIn(user, function (err) {
if (!err) {
req.flash('success', 'Done!');
} else {
req.flash('error', 'Something went wrong.');
}
});
}
});
}
After the user updates the values by clicking "Save", the modal will close. The user can still click on the "Edit" link to change values yet again, and the modal will open. Now, based on what I have read, the user won't see the changes, because there hasn't been a page/modal reload. How do I make sure that the user sees updated values?
Any help is appreciated.
When I read your text, I think:
"Hum, he tried to make an Ajax call and let the view display the errors or go on"
When I read your code, I think:
"Hum, it's a synchrone "give me all the page" call"
Which version do you want?
The Async one? So we can explain you the Ajax principle and your real problem is an UI update.
The Sync one? It's definitively an UI problem, and you should add a tag for it.

Categories