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

Hi team, see latest iteration on this flow:
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:

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.
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...
Password recovery:
Notes:
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: https://github.com/medic/cht-docs/pull/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.

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.

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 馃檪

@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

3 - No internet connection

4 - Disabling the token

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

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!
Most helpful comment
Received feedback that the temporary password flow may be too complicated for CHWs and have iterated to simplify using a magic link: