Document toolboxDocument toolbox

Email-based sign in (aka "magic link" sign in)

We're going to add a feature that will allow apps to work without the user needing to create or enter a password.

How it will work on the client

First install

  1. Participant installs the app
  2. After consent process, app generates password to sign up user
  3. User consent is submitted, app has session
  4. When session expires, the app uses the generated password to re-authenticate

Reinstalls

  1. Participant installs the app on new device or deletes/reinstalls 
  2. Participant opens app, says “hey I already have an account, here’s the email address” 
  3. App tells server “send me a magic link to this email address" 
  4. App tells participant “check your email for a magic link” 
  5. Participant has to go to email on phone and tap magic link, which takes them to the app to sign them in 
  6. The app generates a new random password and includes it in the magic link sign-in call

How it will work on the server

Two new endpoints will be introduced:


POST/v3/auth/email
auth
no authentication, public endpoint
body
{ "email": "<email.address>", "study": "<studyId>" }
returns202Accepted (email will be sent)

429Too many requests sent (being rate-limited, no further email will be sent)

This endpoint will reject calls to send another email while the prior email request has not timed out (currently 60 seconds). If this is abused, we may need to do further rate limiting. It will also need to verify the email is active in the study before sending an email.


POST/v3/auth/email/signIn
auth
no authentication, public endpoint
body
{ "email": "<email.address>", "study": "<studyId>", "password": "<password>", "token" : "<token>" }
returns200with user session

412with user session

404
{ "statusCode": 404, "entityClass": "Account", "message": "Account not found.", "type": "EntityNotFoundException" }

If the token has been issued, retrieve the user's identity and return a session. Optionally, if a password value has also been submitted, reset the password before returning the session.

Study

Study will have a new email template, the emailSignInTemplate, which will allow researchers to create a message and the message can include a link. If the app needs, for example, to have a link with a subdomain, like https://myApp.sagebridge.org/mobile/verify.html?token=<sometoken>, they will be able to add that. There should be a default using webservices.sagebridge.org.

Verify the template has a ${token} string in it somewhere to substitute the token.

We will also be able to enable/disable this functionality with the emailSignInEnabled flag.

AuthenticationService

methodDescription
requestEmailSignIn(SignIn signIn)
  1. If functionality disabled, throw EndpointNotFoundException
  2. If email present, throw RateLimitExceededException
  3. create token, store in Redis mapped to email, TTL 1 minute
  4. send email using study template to supplied email address
emailSignIn(CriteriaContext context, SignIn signIn)
  1. Retrieve token from Redis using email
  2. If email or token missing, or token doesn't match supplied token, throw 404
  3. Update password, if supplied
  4. Delete Redis entry
  5. Return a user session

Purpose

We want an easy web-to-native app transition that will allow users to complete the online portion of an app and then go to the application having all of their information remembered. 

First Install- Web to Native App

  1. User fills out survey on the web
  2. User signs up using their phone number (on the phone, or in the web page? I think this matters)
  3. SMS is sent which takes user to app store/googe play store so they can download the app
  4. After the app installed the information from the online portion is remembered (ex. consent has been filled out)

Alx: I don't think it's possible to do this. If you have documentation on this, please provide it. For example, branch.io is "fingerprinting" a device in order to re-establish state after an app install... I don't see how this will work if user starts on desktop, and then switches to their phone).

First Install- Native App to Native App

All of the steps above would be the same, except if the user had downloaded the app on their phone rather than starting at the website their magic link would take them directly

to inside the application.

Definitions

Deep Linking- points to content inside of an application, works if the app is installed

Deferred Linking- This takes users to a 'deferred' part of the application after install, non-specific to the user

Contextual Linking- Keeping information all the way through install, this is a seamless experience, best choice

Universal Linking- specific to iOS (only ios >9.0, ~85% of iphone users), makes it so that no hacky javascript is used to redirect the website to a URI link (my://) , requires SSL certificate

App Links- similar to apple version of universal linking. except android still accepts custom uri schemes in their mobile web browser, requires SSL certificate.

Intent-Filter-Link- Specific to android, no SSL certificate required, the dillemma here is that a disambiguation page is brought up and the user can choose to bring up another app instead. (ie. chrome could be a suggestion to open our website)

Web Requirements 

 1. SSL certificate- This is so that your app and website can be tied together, no other application can be suggested once this step is in place

 2.  ./well-known/ directory needs to be hosted on your website and two special files that are recognized by android and ios devices

ex: https://mPower.com/.well-known/<file-name depends on ios/android>

Note: "These two files will be downloaded automatically by every single user that installs or upgrades the app, its recommended that this file get hosted on a CDN

-Because this file is only fetched once when the user first installs or upgrades the app, this file must be live on your website before your app is released. This also means that you can’t add new deep linking url patterns to your app until you push out a new app update to force users to refresh the file."

          3.  You can match links using regex/direct paths/ or path prefixes for a response to get triggered. You can use only use URLs for ios, whereas android still allows for URI. 

URL:

https/mPower.com/...

URI:

mPower:// outdated for ios, apple made universal links for this reason

App Requirements

In both applications the implementation is fairly straightforward, Android Studio has a built in feature that allows you create and test domains on your app. iOS has docs that are also straightforward. Note: neither of these can be tested until the certiciate is in place.

Other Considerations

There are several cases when deep links won't work, links inside the Gmail, Inbox and Facebook apps for instance.

Linking Services

The main selling point of these services is that they allow for keeping information known through install (contextual linking). It has yet to be determined how difficult/or not difficult this is to do without their services. 

branch io

Examples of contextual linking with branch io, the 'magra' example shows an actual link that was texted to recieve an app install link

google firebase

Example of contextual linking  with google firebase here they show an example of how someone could open the app on the web like so:

   <a href="https://abc123.app.goo.gl/?link=https://example.com/content?item%3D1234&apn=com.example.android&ibi=com.example.ios">
   Open this page in our app!
</a>

      In this example we have the link embedded inside the web page, but for our purposes we would want it sent via sms.