Change Firebase password in Ionic without Authenticating - firebase

I want to change a user's password without authenticating the user, and I want to do this with Ionic.
Currently, this is what I have:
const user = firebase.auth().currentUser;
const credentials = firebase.auth.EmailAuthProvider.credential(user.email,
this._password);
user.reauthenticateWithCredential(credentials)
The problem is that I want to change the user's password without authenticating the user, and that's something I cannot do with firebase.auth().currentUser . The latter won't work if we are dealing with multiple users.

Firebase provides only one way to reset the password without authorization i.e. reset password by email.
You can send a password reset email to a user with the
sendPasswordResetEmail method. For example:
var auth = firebase.auth();
var emailAddress = "user#example.com";
auth.sendPasswordResetEmail(emailAddress).then(function() {
// Email sent.
}).catch(function(error) {
// An error happened.
});
You can also customize email template format. Hope this helps.

It is not possible in the client-side JavaScript SDK to change a user's password without authenticating that user. If it existed it could be called by any malicious user of your app, which would be a pretty massive security risk.
The only way to change a user's password without knowing/specifying their current credentials is through the Firebase Admin SDK. This Admin SDK is made to be run in a trusted environment (such as your development machine, a server you control, or Cloud Functions), and thus can't be abused by users of your app.

Related

Make sure a user verified their email before signing them in

I'm in the middle of adding firebase email/password sign in inside a React app. Specifically, it's an e-commerce site, and users will be signed in anonymously before they create an account (for things like cart data).
Here's the ideal user flow:
User registers by providing an email and password
User is not signed in immediately and instead gets a verification email
If a user tries signing in before verifying their email, they cannot sign in
User then clicks on the verification link and can sign in
I'm having issues with #3 because it appears like the only way to check if an email is verified is by calling:
const { user } = await firebase
.auth()
.signInWithEmailAndPassword(email, password)
if (user?.emailVerified) //let them enter the dashboard
However, this process signs in the user even if the email is not verified. That destroys the data on the anonymous account. And merging the two accounts isn't possible because the user thinks they are not signed in (hence it could cause UX issues if the accounts are already merged).
Any ideas?
If you're using the email+password provider, there is no way to prevent the user from signing in without a verified email address. You can of course keep them from using your app and accessing data, but you can't keep them from signing in.
If you want to ensure the user can only sign in after their email address has been verified, consider using the email link provider. You can then later allow them to set a password on the same account, either through the Admin SDK, or by creating a email+password account and linking that with the email link account. Also see the documentation on differentiating email/password from email link for some of the nuances here.

How can I make a function in which password is changing when a user is not logged in?

onChangePasswordPress = () => {
var user = firebase.auth().currentUser;
user.updatePassword(this.state.newPassword).then(function(){
console.log('Password is changed');
}).catch(function(error){
console.log(error.message)
})
it says currentUser in the 2nd line means only a user who is logged in can change his/her password.So how can we change a password of a user when a user is not logged in his/her account . How to make a function of changing a password when a user is not logged in his/her account in react native
For a user to be able to update their password, they need to have recently signed in. This is a security requirement, as allowing changing a password without being signed in would be a huge security risk.
If the user forgot their password, you can send them a password reset email. This email contains a link they then click that allows them to set a new password.
If you want to allow an application admin to change a user's password, you can build that using the Admin SDK. But to prevent the security risk outlined before, this can only be done from a trusted environment, such as your development machine, a server you control, or Cloud Functions.

Firebase create user with customClaim

I'm using the Firebase SDK on a React Native app. I'm authenticating users with onAuthStateChanged - works great.
If it doesn't return a user, they can sign up using their phone number.
For that I use the following on submitting the phone activation code:
...
const credential = firebase.auth.PhoneAuthProvider.credential(
verificationId,
verificationCode
);
await firebase.auth().signInWithCredential(credential).then((response) => {// creating a record on firestore. onAuthStateChanged will be re-triggered and store the user and token in state});
...
I would also like to set custom claims for the user. How do I do that? I cannot use admin SDK since this is the frontend and I also don't want to. I could fire a call to my graphQL to do it, but there is probably a way to add a custom claim in the flow above. How?
There is no supported way to modify custom claims from within a client app. Since custom claims are normally used to give special secure authorizations, it obviously be a security hole to allow user to assign claims to themselves. That's why it's recommended to use the Admin SDK on a secure backend you control.
Custom claims can only be set from a trusted environment. Otherwise anyone could make any claim they want about themselves, which defeats their purpose of securely adding information to a user profile.

Firebase Auth verify this user

I am currently verifying my user using the Auth JS SDK and Admin Auth SDK combined. I am doing in the following approach:
In the front-end:
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
var current_user = firebase.auth().currentUser;
current_user.getIdToken(true).then(function (idToken) {
$.getJSON('/firebase_token', { token: idToken }, function (user) {
In the back-end:
router.get("/firebase_token", (req, res, next) => {
admin.auth().verifyIdToken(req.query.token).then(function(decodedToken) {
res.send(decodedToken);
})
})
I am wondering if this is a secured approach, because the user can just send whatever token they want from the front-end. For example, an invalid user can send a valid token they copied from a valid account to pass the token verification.
I am wondering if in the admin SDK. There is a way to detect the currently signed in user. In other words, detect this user who is using this instance of the app with the admin SDK?
I am wondering if this is a secured approach, because the user can just send whatever token they want from the front-end. For example, an invalid user can send a valid token they copied from a valid account to pass the token verification.
Yes, that's possible. But then again, if the user got access to a token, that means they probably are the user represented by that token, or they know the credentials of that account. That's not a problem at all - this is the way authentication systems work.
I am wondering if in the admin SDK. There is a way to detect the currently signed in user. In other words, detect this user who is using this instance of the app with the admin SDK?
No, the Admin SDK can't possibly know what all is going on for all of the users using your application. The ID token is exactly the piece of information it needs to verify users. A valid token proves that the user is who they say they are.

is it possible for users to choose any email at the time of password reset in frebase?

I am using ionic 3 and firebase for the backend.In my app I am trying to let users sign up with just username and password. Well firebase by default doesn't provide that option. So I am getting user's input as username (for example: 'mike123') then i add #myapp.com. so it looks like an email: 'mike123#myapp.com'. That is all fine, but a problem just came up when user's want to reset their passwords. Is it possible to let users type in any valid email address at the time they want to reset their password?.
You can change the password of the user by https://firebase.google.com/docs/auth/admin/manage-users#update_a_user. Note that this is in the Firebase Admin SDK, so will require that you run code in a trusted environment, such as a server you control or Cloud Functions.
But faking username+password by faking an email address is non-ideal. I'd consider creating a custom auth provider for your needs.
If the email provided when sending the Reset Password request doesn't exist for any user, then it will fail.
In Android, calling sendPasswordResetEmail with a non-existing email, it would return a:
FirebaseAuthInvalidUserException: There is no user record corresponding to this identifier. The user may have been deleted.
You should ask for a valid email from the user and save their preferred username separately upon the user creation.

Resources