medic / cht-core

The CHT Core Framework makes it faster to build responsive, offline-first digital health apps that equip health workers to provide better care in their communities. It is a central resource of the Community Health Toolkit.

Home Page:https://communityhealthtoolkit.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support remote first time log in

n-orlowski opened this issue · comments

We need a way to provide usernames and passwords for initial user log in for remote user onboarding. Not exactly sure how this can be done securely as we will likely need to send out login instructions via SMS. A potential solution could be to force users to reset their password on login but open to other suggestions!

We'll also need an affordance for lost or forgotten passwords.

Adding to 3.10.0 for consideration.

It would be relatively simple to add a property to a user to force them to change their password next time they log in and it's a great security feature in general. It's also one step towards a "forgot my password" implementation which would automatically send a generated password and then require the user to reset on first use.

The way I envisage this is to add a second step to the login page. When given the correct credentials, before establishing the CouchDB session, prompt the user to enter a new password twice. Then update the password, establish the session, and redirect to the app as per usual.

As well as prompting users to change their password we should also include an expiry date on the generated password as it can easily be intercepted. Usually this is 24 hours but it may need to be longer in our case to give users enough time to find an internet connection and log in.

@n-orlowski What are your design thoughts on password strength for this flow? I know CHW users have struggled historically with symbols like underscore, and different types of brackets. Are our existing password strength guidelines appropriate/clear and if so, how do we imagine messaging to overcome any educational hurdles so users understand "strong passwords"?

@kennsippell TBH I haven't thought about this! How does this process happen currently?

Based on the strength guidelines is there a way we can guide a strong password, for example suggesting a zip code + initials + age combo? Just thinking out loud here.

@garethbowen would it be possible to use a password token so users don't have to input a generated password and go straight into creating their own? Or do we know if users are familiar with copy and pasting?

Based on the strength guidelines is there a way we can guide a strong password, for example suggesting a zip code + initials + age combo?

Making suggestions goes against best practice because even if a malicious actor doesn't know that information, they know it's likely to be in the format of five numbers, two letters, and two numbers, which makes it much more guessable.

One thing we could do is include a password generator which generates a secure, pseudo random password, that's easy to type on a smartphone.

Would it be possible to use a password token so users don't have to input a generated password and go straight into creating their own?

Is this use case for browser or android app based users? If this is for browser only users we could include the user and pass in the URL being sent to them so it prepopulates and submits the login form? eg: https://dev.medicmobile.org/medic/login?user=gareth&pass=123.

If it's for smartphone users it's harder. What do you mean by token here? How would the token be easier to use than a user and pass?

Or do we know if users are familiar with copy and pasting?

I doubt many users are comfortable with copying on smartphone.

One thing we could do is include a password generator which generates a secure, pseudo random password, that's easy to type on a smartphone.

This sounds ideal!

I was thinking a token but within the browser.. Envisioning a unique link gets sent out that is valid for a certain amount of time that lets users type in their new password without having to type our generated version but having a pre-populated form works just as well

Deprioritised by request from @n-orlowski

Screen Shot 2020-05-27 at 4 05 10 PM

Hi team, see latest iteration on this flow:

  • Flow is triggered by user receiving credentials
  • User opens app, logs in with username and temporary password
  • User is prompted to change password with guidance on strength (copy + meter)
  • User is logged into the app

Also included are affordances for expired temporary passwords, forgotten passwords, and forgotten passwords where the recovery number may be shared between CHWs.

As always, please let me know about any feedback ✌️

This UX is great!

What would a user see at each step if they lose connectivity?

It'll all be cached by the service worker so they will see the page and we can show a helpful error when they try and submit the form.

Received feedback that the temporary password flow may be too complicated for CHWs and have iterated to simplify using a magic link:

Screen Shot 2020-06-09 at 12 46 42 PM

  • Flow is triggered by an SMS either with a message to install the app, or if the app is already installed to log in via magic link (temporary password is hidden by the link)
  • The link opens the app and the user is automatically logged in
  • The user is prompted to set and confirm their PIN
  • Once the PIN is confirmed, a new password is generated (still hidden) enabling users to log into the device easily and safely only using the PIN
  • Every time the app returns from the background of the device, a user should be prompted with the login screen
  • MVP for a forgotten PIN would be a manual process where a user contacts IT support to verify their identity. IT support would then resend a magic link to restart the flow.

This is ready for development. Feel free to pick it up!

Some work has been done towards implementing the PIN for added security in #3237 . Use that as a starting point and then it can be UATed and closed at the same time as this one.

commented

Based on discussion with the Roadmap planning team, we are going to remove the requirement for a PIN to simplify the initial implementation. If a user needs to log-in on multiple devices, they will need an administrator to set a password.

As Max said we're making this simpler for the 3.10.0 implementation...

  1. When creating users the admin should have the option of providing a password (as they do now), or sending a magic link via SMS.
  2. If they pick magic link then we generate a random complex password with a 24 hour expiry.
  3. Then we send a configurable SMS message containing a link to that project's instance with the credentials hashed and we forget the password. NB: Hashing is not secure, and the SMS is not encrypted.
  4. The user clicks the link. If the app is installed it will open the app (that's the magic part). If it's not installed open in a browser. The default SMS message should encourage users to go to the app store and download the app first.
  5. The login page detects the hashed credentials and changes the password to a new random password which nobody knows, and then logs the user in, with no user interaction whatsoever.

Password recovery:

  1. The user contacts the IT administrator
  2. The IT administrator either updates the user to have a configured password, or clicks a "regenerate password" button which generates a new temporary password, sends the magic link to the user, and so on as above.

Notes:

  • The SMS option will not work for users who want to use multiple devices - they should use the configured password option
  • The SMS option will not work for multiple users on one device - they should use the configured password option. The admin app should ensure the user's phone number is unique before sending the SMS.
  • Anyone with access to the device will be able to access the app
  • The user should not be able to log out easily because they will not be able to log in again
  • Password recovery is a manual process

The login page detects the hashed credentials and changes the password to a new random password which nobody knows, and then logs the user in, with no user interaction whatsoever.

I think of that as the magic part!

Ready for AT.

Read through the documentation PR here: medic/cht-docs#220
You'll need to build a custom medic-android app to handle the URLs using the branch: 6380-token-login
Then install the cht-core branch: 6380-remote-login

Addendum to the AT instructions:

In order to enable the Android intent (allowing app links to open in the medic-android app) in the unbranded version, you need to update the code before build, setting your host in the settings:
https://github.com/medic/medic-android/blob/6380-token-login/src/main/res/values/strings.xml#L6

<string name="app_host">myurl.ngrok.io</string>

example branded: https://github.com/medic/medic-android/blob/6380-token-login/src/hope_through_health/res/values/strings.xml#L4

Also, make sure you're building medic-android from 6380-token-login branch.

Thanks @dianabarsan for the added notes. It looks good now.
Tested by adding token_login.app_url and token_login to app_settings.json

 "token_login.app_url": "https://f45889e82732.ngrok.io",
  "token_login": {
    "enabled": true,
    "translation_key": "sms.token.login.help"
  }

and app-host to medic-android (testing with unbranded flavour)
<string name="app_host">f45889e82732.ngrok.io</string>
and sending message generated by creating a user with Enable login via SMS link checked.
image

Message can be retrieved from outgoing messages > due in the admin portal(/admin/#/message-queue/due) if no gateway is set up to send real message - and sent to the phone with any other messaging app.
Clicking on the sent url (on the phone) prompts user to select between default browser and medic (if the app is installed) or just open the app in the browser if the app was not installed (or the app-host not provided.
image

Sorry @dianabarsan - Was too quick to move this to ready to merge. Since it is a new feature and an important one for that, I have asked @n-orlowski to give it a final look and try different use cases/scenarios/error messages etc and give us feedback.
@abbyad Feel free to think of edge cases /eventual gotchas before we close it off.

Curious to know if CHWs will know how to contact the admin if they run into the error state.. Maybe a more suitable message would be to contact their supervisor? Other scenarios look like they work well 🙂

Screen Shot 2020-07-20 at 2 57 18 PM

@n-orlowski I think we definitely could improve on error messages. Not sure how much info we can get from the phone, but it would be a good think of ways check for things like no app installed, wrong version of the app, expired link, etc and ask the user to take appropriate action like download the app, upgrade, contact admin (assuming they are supposed to know how to as @n-orlowski mentioned). Your thoughts @dianabarsan ?

@ngaruko can you list out the different error scenarios that were covered as part of AT, and show what the results were?

no app installed, wrong version of the app, expired link, etc

We send 2 sms, one that contains the token-login link (so we don't risk the sms app splitting the link between messages and becoming unclickable) and one that should contain instructions for the user - which is configurable via token_login.translation_key (https://github.com/medic/cht-docs/blob/6380-token-login/content/en/apps/reference/app-settings/token_login.md#app_settingsjson-token_login). This instructional sms message should cover "no app installed, wrong version of the app" situations, that we don't have control over.

As for other errors, I don't want to flood the issue with print screens :) so I'm linking to the translations that are used in the "landing page".
https://github.com/medic/cht-core/blob/6380-remote-login/ddocs/medic/_attachments/translations/messages-en.properties#L725-L732
We can edit these default translations, like @n-orlowski suggested we could change "admin" to "supervisor" - but these are, again, configurable since they're translatable, and per deployment, they can even include means of contacting support.

Scenarios tested :
1 - App-host not specified (or different the one in settings) OR app not installed >>
What happens: Open the browser - Logged in
Suggestion/Ideal: It would be nice if we could detect when the app is installed but that 'something' is wrong with the version/server/etc or if not installed , prompt/advise the user to get the app

2 - Invalid or tempered with link or disabled link
What happens: Error as expected
image

3 - No internet connection
image

4 - Disabling the token
image

5 - Nitpick When disabling remote login, password and confirm password are not marked with asterisk (for compulsory)
image

I guess the last one is a quick fix @dianabarsan . The rest are edge cases, and if the user is familiar with the app and their phone, and the onboarding process/training is done properly, it should be too much of a pain. Your thoughts @abbyad @n-orlowski ?

Best practice is actually to not use asterisks for the required field but to use an "Optional" label for those that are not required, so I think the last item is fine :)

Thanks @n-orlowski and @dianabarsan . Since the core feature works and most of the rest is configurable, I think we can close this and leave it to the app services to configure as they see fit.

Merged!