Authenticate a user only with password - flutter

I'm making a Flutter application where the user has to register and log in with email and password.
Is there a way to ask the registered user to enter his password every time he wants to log in ?
The output would be like this :
Welcome back UserName#email.com
please type your password to enter the app
I've searched the subject in the FirebaseAuth documentation, but couldn't find any relative information.

You can explicitly sign any current user out when loading the page. See the bottom of the documentation page on email+password authentication for an example.

Realistically and practically speaking, you would use some type of local storage to signal to your app that the user is signed in, or out. If you use page load events only to signout the user, they will be signed out when opening a new tab which would probably be annoying.
You could use an unload event to prompt the user "You will be signed out of this application when you leave this page"
Doing all of that, the onload event could look for that auth state variable in local storage.

Related

Firebase: Standard User Registration/Activation Workflow

I need to implement a standard user registration/activation workflow with Firebase. There doesn't seem to be an obvious way to implement this. When I say "standard", I mean how most email/password accounts work - not necessarily specific to Firebase. I'm sure you're familiar with this. This is the workflow:
User enters their username/password on a form with some validation and submits details
The back-end creates the user record in the database, but the account remains deactivated (i.e. user cannot authenticate - the activated flag is set to false)
The back-end sends an email to the user with a link to activate the account
The user clicks the link in their email which triggers activation. This is probably a Web API of some description.
At this point, the user record's activated flag ticks over to true, and the user can now authenticate
The link probably also has a deep link that opens the app or navigates to a web page
The user can now log into the app
How do I configure Firebase to do all this?
Currently, the app allows the user to register. I am using the Flutterfire SDK. I call createUserWithEmailAndPassword, which successfully creates the user in Firebase. But, the user is already activated. The user should have a state of "disabled" in firebase until the account becomes activated. I can't find any settings to default the user to disabled when the account is first created.
I also managed to get Firebase to send out an activation email by calling sendSignInLinkToEmail, but this call is really designed for email authentication - not email activation. Opening the link should activate the account, but I have not figured out how to do this. This documentation makes it sound like it is possible. Perhaps, the Flutterfire SDK is missing this? I don't want to allow people to log in without a password. I only want to use this call to send out an email.
What am I missing here? Is this non-standard behavior for Firebase? If so, why? If the user is allowed to use an app with an email address that is not activated, they can impersonate someone else. We need to confirm at least that they are custodians of the email address that they are claiming to have.
Do other Firebase people just not worry about this?
Lastly, I know I can achieve this by creating a collection for users in Firebase and putting an "activated" flag there. But, if I do that, I've got to write a cloud function that accepts the link and then updates the user in the collection based on the received link. But I thought this would be automatic in Firebase. If Firebase doesn't have this built-in, I have to put all the security over the top to stop users from authenticating when they have not yet activated their account.
This is a pretty valid concern. I suppose the way around this is to check whether the signed-in user is verified whenever the app is launched. The User object that is returned from Firebase Auth has an emailVerified flag. Check this page for more details.
Using this flag you can choose to show a different screen or pop-up that has a button to send a verification link to the registered email address. Until the user verifies this address, you can limit access to some of the app's screens if you want.
Please note that I have not checked if this emailVerified flag is true for sign ups using Federated login providers like Google Sign-in and Apple Sign In. You might want to check that out.

Can you send a link to the specific page where a user resets their password via Keycloak's API?

We have a PHP/MySQL based User Management System and are integrating it with Keycloak version 16 where we will store users credentials.
Our application does not allow users to self register. We create user accounts on the system. When we do this we do NOT specify a password because we want users to set up their own password.
The current system sends 2 separate emails in 2 different circumstances regarding passwords:
If it's a completely new user who does NOT have an existing password, we send them a link to set up a password.
If it's an existing user who already has a password, the system allows them to reset it, e.g. if they forget their password and can't login.
Keycloak seems to cater for scenario (2) because the login forms have a forgotten password link which opens a form where the user can enter their email address and receive a link which lets them do (2).
Unfortunately it doesn't deal with scenario (1) very well and that's where our problem starts. This has been asked a while ago Send password forgotten mail but it seems that Keycloak didn't support this very well in 2020 and perhaps still doesn't now.
Our "workaround" to this was that we added custom email templates and a custom page (reference: Themes on https://www.keycloak.org/docs/latest/server_development/#emails) which includes wording that caters for both scenarios, e.g. "set your password" rather than "reset your (existing) password". The result of this is that our email and form now reads appropriately for both scenarios (1) and (2).
The problem
We want to be able to send a link to the user that allows them to set their initial password to cover scenario (1).
We know that this page exists because on the login page for Keycloak there is a link to the forgotten password form that handles scenario (2). However, the form requires the user to enter their email address and submit the form. The user then receives an email from Keycloak which contains a URL to the page where they can do this. The URL has the following format:
https://example.com/auth/realms/foo/login-actions/action-token?key=...
The key= contains a ~945 character token. Going to the URL above redirects to the form where the user can reset their password. This next URL does not contain a token but a cookie has been set in the browser - by the previous URL - which makes it functional:
https://example.com/auth/realms/foo/login-actions/required-action?execution=UPDATE_PASSWORD
We can't send either of these URLs to the user because the first one (containing key=) has no API method for us to find out what it is - it's only possible to generate this by going through the "forgotten password" step during login, in the browser.
The second URL (/login-actions/required-action...) won't work either because it relies on the previous URL (containing key=) setting the cookie in the browser. If you try and go to this second URL directly (i.e. bypassing the first URL) it will error.
So neither of these URLs will work because we can't find what the first one is programmatically, and we can't use the second one without knowing the first one.
I found https://lists.jboss.org/pipermail/keycloak-user/2018-October/015910.html and the suggestion is using the Keycloak API to trigger a password reset email. This works - sending an HTTP PUT request containing 'UPDATE_PASSWORD' along with the relevant user ID sends the user an email. The request endpoint has the format PUT /{realm}/users/{id}/execute-actions-email which is documented on the link above.
Up to here all is fine - the user gets an email. However, this email does NOT contain a link that goes directly to the "reset password" page! Instead it sends them an email containing the following text:
Your administrator has just requested that you update your account by performing the following action(s): Update Password. Click on the link below to start this process.
Link to account update
When the user clicks "Link to account update" it then shows them a web page like this:
It is only when they click on the link on this page (the one that says "click here to proceed" on the screenshot) that they arrive at the form where they can reset their password.
This is a really poor user experience because the user gets sent a (badly worded) email with a link to... a page with another link! It should just take them to the password reset page directly. What's more frustrating is the fact that Keycloak is clearly capable of generating/sending the exact email we'd like in this scenario: the one which gets sent when a user manually does a password reset via their browser.
So the problem seems that Keycloak's API doesn't support this incredibly important and common use-case of a user being able to set an initial password, in a user-friendly manner.
I am adding the js script in the template to automatically click "click here to proceed". It's ugly but at least the user doesn't see the page

Dialogflow getting username from Gmail account in inline editor

I have a Dialogflow inline, where when welcome intent is executed I need to call agent.add() so it replies with something like
Hello (username)!
This username is not that the user writes but it's the profile name that he has logged in to the device
In order to get the user's name, you need to request permission from the user. So it usually isn't available as part of the welcoming Intent (at least not the first time they talk to your Action). You need to do one of two things:
Request user information which includes the user name. Once you have requested this information, you can save it so you'll get it the next time the user connects.
Ask the user to sign in. Once they have done so, you'll get an identity token with each request that includes the user's information

Keycloak Implement Reset password flow same as forgot password flow

I am facing an issue with Keycloak:
When user clicks on Forget password button, he is asked to enter basic details. Once details are entered, the user receives a mail with link to change his password. User Changes his password, and is redirected to Login page of the application.
Users account gets locked. Admin uses application to unlock the account. User gets email, clicks on link, and generates new password. User now sees a message : Your account is successfully updated.
What I want to do is that the second flow should work in same way as the first one. i.e when user has given new password, he'd be redirected to login page.
Can someone guide me about how to proceed with this?
Difference I've noticed in two flows is the URL that I receive in both of them is different.
First flow, I get this in mail: http://[keycloak-host]/auth/realms/[realm]/login-actions/reset-credentials?code=[code]
Second flow, I get this URL: http://[keycloak-host]/auth/realms/[realm]/login-actions/execute-actions?key=[key]

Password change update password manager best practice

What is the best practice for dealing with a user changing their password and letting their password managers getting the notice of the change?
If a user request a "forget password" link, the user gets often redirected to a specific page where he can set a new password. After filling this info in, the password is being set on the backend and gets redirected to the logged-in homepage.
But this doesn't pops up or updates the in-browser save password dialog/system/keychain/manager. They mostly get triggered when there is also a text field on the form.
I could redirect it to the login page, but that seems a bit stupid since the user just entered their password, and have to do it again.
I notice this with linkedin a lot and google as well, that when I changed my password, some pages still try autofilling my old password and I get a notice that my password is incorrect.
Does anyone knows how exactly cross-browser all these system work? Or isn't there a standard for triggering/updating password managers? And what seems the best practice? If you log a user auto in after a change, there is a quite big change he again forgets it in a few days. It's bizar how many people enter wrong passwords at a login screen.