Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Dynamic config, multiple studies and fallbacks for single study case #850

Open
shankari opened this issue Jan 27, 2023 · 16 comments · Fixed by e-mission/nrel-openpath-join-page#13

Comments

@shankari
Copy link
Contributor

shankari commented Jan 27, 2023

@asiripanich @lgharib @TTalex @jf87 @ericafenyo

In the original version of e-mission/OpenPATH, as embodied in the e-mission app, we had one common, customer-facing app.
The vision was that we would not dictate the UI - instead, every individual study or program would publish their own app.
This was an extremely optimistic view in two aspects:

  • the ability to recruit people to install the app
  • the ability for potential deployers to create custom apps and publish them in the stores

We then switched to the emTripLog version, in which a single app would serve as the basis for all the complicated under the hood sensing stuff, deployers would change their UI, and simply push out changes in separate "channels". The deployers would then deal with recruitment.
However, this was also too optimistic:

  • most deployers did not actually want to change the UI significantly. They typically could not write javascript code themselves and found it hard to recruit student developers to work on this fairly complex UI
  • even when deployers did create their own user interfaces, they did so in separate branches, without a lot of coordination. This led to a fragmented codebase with hardcoded, half-implemented features, which were not easy to reuse
  • allowing deployers to deploy channels using a third party platform (ionic) introduces a potential attack vector. At least for NREL apps, we would need to apply for a special cyber security exception and I don't know if we would get it.

So for the NREL app aka OpenPATH, we have the following desiderata:

  • We want an emTripLog-like setup where the base app requires participants to join a study to proceed.
    • The NREL "open access" study functions as an "always on" study that deployers can use to test out the app
  • We do not want to download a brand new UI every time. Instead we want to bring UI features as modules into the basic framework to support reuse
  • But we still want to support the customization required for different studies and/or programs

So our current solution is to create a dynamic config file for the UI modules to capture the small number of configurable options that have been requested. Each configurable module listens to the config load event and then configures itself appropriately. So far, the config options have primarily been around setting the summary/consent text, indicating whether display should be in km or miles by default, and whether the deployment is a study or a program.

Downloading the dynamic config and changing modules to use it has already been implemented in the master_for_platform branch. Sample configs are at: https://github.com/e-mission/nrel-openpath-deploy-configs

I would now like to merge master_to_platform into master to avoid maintaining multiple branches.

@shankari
Copy link
Contributor Author

shankari commented Jan 27, 2023

I would like to discuss two high level questions at a community level:

  • for apps that do plan to serve as the foundation for multiple studies (NREL OpenPATH, FourStep) what should the onboarding flow be? @asiripanich thinks that the two QR code approach is too complicated. Of the two OpenPATH installers I heard from in the past two days, one had no problem with it, the other tried to scan the "join" QR code when asked for the "token" QR code. What might a less complicated approach look like?
  • for apps that do not plan to serve as the foundation for multiple studies (WeFlo, Cozy, potential others that use the OpenPATH UI) I assume you want to use the dynamic config since it makes it easier to configure the app, but just load the config locally. How should we specify this so that the initial "join" screen is skipped?
  • Which direction do FabMob and FabMobQc want to go? Do you want a single-purpose app or one that serves as the foundation for multiple studies. Concretely, do you want to offer NREL OpenPATH-like functionality for the EU and Canada, respectively? There does seem to be some level of demand for it 😄

@shankari
Copy link
Contributor Author

Just to clarify - the difference between studies and programs is that studies just want to collect data to understand travel behavior. Programs care about evaluating an intervention, and typically care about, at least internally, associating the token with an individual user. They may want to provide incentives or reimbursements to individual participants.

So for studies, we allow users to log in with an autogenerated token, or to import a login from a previous install.
For programs, users must login with a program-provided token.

The admin dashboard will have a screen to allow program admins to generate their own tokens and to download QR codes to send to participants.

@ericafenyo
Copy link
Contributor

ericafenyo commented Jan 27, 2023 via email

@TTalex
Copy link

TTalex commented Jan 27, 2023

Hello,

From the FabMob side, it's unlikely that we'll be able to offer NREL OpenPath-like functionality for EU on our own. This is because of our lack of resources. So all future plans are linked with Cozy for now.

For the Cozy use case, the long term goal is to do something similar to WeFlo: using native codes integrated in our own custom UI.
In the meantime, our short-term plan is to use two apps:

  • The Cozy app, which will act as a frontend for users, with a mobility-tracking "sub-menu"
  • A sensor app, which will be an UI-less version of e-mission. Very little to no user interaction is expected with this app, its job is to run in the background gathering data and sending it to the backend for processing.

This model is inspired by the Paris public transport system, where you have a main app to buy tickets and plan your route, and another app to use your phone as a digital ticket (via NFC). This two-app system was well received and accepted by users.

@asiripanich
Copy link
Member

What might a less complicated approach look like?

I propose that we use a single token that contains both
information about the study and the login token. I don't see why this is not possible since rMove, if my memory serves me, also uses this single token approach.

This would make the on-boarding process much much less complicated.

I imagine that the first page of OpenPATH contains a single text box for a login token to be entered. The app loads the UI of the study associated with the login token entered. Then the app walks the user through all the usual screens (consent, permission, demo survey, etc.). The app should only start tracking once the user gets to the diary screen.

@shankari
Copy link
Contributor Author

shankari commented Feb 23, 2023

@asiripanich thanks for the suggestion! My only caveat/modification is that we don't want people to type out the code.

  • we had people type out the tokens before, and it is a real problem when they forget letters or use O instead of 0 and so on
  • we want the code to be long for security, but typing out a long code can get very cumbersome. Note that OpenPATH wants to support longitudinal data collection in general, so we don't want to rely on the fact that codes are only live for a short time.
  • ideally, in the glorious future, we would have the "login" be with a full secret key that would also encrypt the data. Again, that is going to be 256-bits or so long. Most encryption keys are shared as files, by copy-pasting into email or as QR codes.

Thoughts?

@asiripanich
Copy link
Member

asiripanich commented Feb 23, 2023

I'm not against scanning one QR code to login but two is WAY too many. :)

I guess we can display two elements on the first page: a text box and a button to scan a QR code?

For my studies, I use Qualtrics to help my participants with the on-boarding procedure. We walk them through how to install the app and give them a login token. But before showing the token, we ask them to provide an email so we can send them their token (in case they lost it).

@shankari
Copy link
Contributor Author

shankari commented May 3, 2023

At the last community meeting, we agreed that we did not want to have two QR codes.
@TTalex and @JGreenlee have both had the experience of scanning the wrong nrelop QR code to join the study and having it fail.

The same experience happened to @dtfitch today

So today, @dtfitch and I brainstormed a bit about what a single QR code might look like since he really wants to use it for an upcoming deployment.

Note also that the issue with @asiripanich's approach of

I propose that we use a single token that contains both information about the study and the login token.

is that it works really well for pre-generated tokens where:

  • study/program admins have a "master list",
  • hand out tokens to participants, and
  • maintain the mapping between participants and tokens

However, not program/study admin wants to do all that work and maintain that mapping.

OpenPATH also supports "studies", where we autogenerate the tokens in the app - the admin has no idea what they are.
A concrete example of this is the Denver CASR rebate program, where they just want to send out a join URL to participants, but they don't want to send out individual emails to voucher recipients, and they would prefer to not know who signed up.

This was a real issue, because if we were autogenerating the token in the app, we would clearly not have it to scan on the first page.

However, one workaround that I thought of today was to autogenerate the token in the join page.
As long as we generate the token randomly every time and transmit it over HTTPS, this seems pretty secure.

The main threat model would be:

  • somebody who stood behind the user and scanned their QR code, or
  • if the QR code/token was cached somewhere, or
  • if the URL to input the QR code/token was stored in the browser history and a malicious app/webpage read it from there

All of these seem pretty unlikely.

  • If people access the page from their phone, it is not going to be easy for others to scan it
  • the QR code could be cached on the phone, but again, if a malicious app is able to read browser caches on the phone, the user has more problems
  • similarly, if a malicious app/webpage is able to read browser history, it also has more problems.

Pros/cons:

  • Pro: only one QR code
  • Con: no validation; if the user scans the wrong QR code (or goes to the wrong join page, and it happens to be a study page), then they will join the wrong study/program. I was going to fix this by validating the token against the study, but if the study is to be inferred from the token, that is obviously not possible.
    This is not a hypothetical, one of the durham participants joined the open access study by mistake.

@JGreenlee @asiripanich @idillon-sfl @dtfitch any high level thoughts?

If we are all agreed, I will let cyber know (since we will change the location where we autogenerate) and then make the changes.
Even if cyber is not super happy with it, I guess I can keep the autogeneration in the app but only invoke it if no token has already been scanned. But that would unnecessarily complicate the onboarding logic and I would prefer to avoid it if possible.

@JGreenlee
Copy link

Check my understanding; is this what's being proposed?

I'm a little confused on the ramifications of this approach. I thought that we generated tokens for studies on the phone anyway, so how does this change anything with regard to security?

@shankari
Copy link
Contributor Author

shankari commented May 3, 2023

@JGreenlee, my preferred approach would actually be:

Screenshot 2023-05-02 at 10 40 55 PM

This has the advantage that the onboarding flow is much simpler. We don't need two control flows depending on whether the scanned value has a token or not. However, it does mean that, for studies, we will autogenerate the token on the join page and not in the app.

If cyber does not allow that, we can fall back to the approach you have outlined. But as I said, I would prefer to avoid the complexity if possible.

@JGreenlee
Copy link

Ah, I didn't realize that by "join page" you meant the website page.

So the website would just randomize the token on every page load?
If the website is the only place people access the QR codes, this works great.

But one potential issue I would foresee is that people might take screenshots and unknowingly give the same token to multiple people.
Also, we'd lose the ability for QR codes to be printed on flyers or projected on screens that multiple people view. Not sure if that's something any studies rely on or would want to rely on.

@shankari
Copy link
Contributor Author

shankari commented May 3, 2023

@TTalex @idillon-sfl @JGreenlee, at the last community meeting, we also discussed merging master_for_platform and master.

A couple of high-level facts:

  • the most visible difference between the master and master_for_platform branches is that the master_for_platform starts with the app-level join page and uses that to download the config
  • however, the join page itself is pretty simple - the javascript is < 50 lines of code, as opposed to the label screen, which is close to 700 lines of code
  • the real complexity comes in making sure that all the components are "config-aware". That they listen to the dynamic config and change their behavior appropriately.

Given this, the easiest approach to merge the two branches is to support an app config which represents the dynamic config location.

App level join page
If the dynamic config location is a file URL (does not start with https), we will not show the app-level join page, and will load the config directly without user intervention simulator_screenshot_A33EADB4-9D57-4EFC-88EB-96824F6C791B

I will probably start with the config location as a string in app.js, although I am open to moving it to config.xml or to a separate json file (inwww/json) depending on feedback.

  • All custom apps need to edit config.xml anyway, so there is not not the concern about additional divergence/merge conflicts etc between the base repo and the forks.
  • And putting it into www/json/ will allow us to have a checked in sample file that can be overridden with a file that is not checked into the repo (similar to connectionConfig.json.sample -> connectionConfig.jso). So again, we will not anticipate any (many?) conflicts.

@shankari
Copy link
Contributor Author

shankari commented May 3, 2023

Also, we'd lose the ability for QR codes to be printed on flyers or projected on screens that multiple people view. Not sure if that's something any studies rely on or would want to rely on.

I'm not super worried about this, since we would just print/display a QR code pointing to the study-specific join web page.

the study-specific join web page (e.g. https://nrel-commute-openpath.nrel.gov/join/) has the links to the google play and apple app store, and the additional instructions ("make sure to use "always", turn off background restrictions, etc), so we ideally do want people to go to that page.

Example study-specific web page: https://nrel-commute-openpath.nrel.gov/join/

But one potential issue I would foresee is that people might take screenshots and unknowingly give the same token to multiple people.

Good point! That is another entry into the threat model that I hadn't considered. But it seems like there is a similar risk with the pre-generated tokens in the program case - program participants share their QR codes with each other, or program admins who hand out the same token to all participants.

That's actually the advantage of unifying the control flows for programs and studies. Now, in both cases, participants login with a pre-generated token.

  • In the program case, the tokens are pregenerated days or weeks ago by the program admins
  • In the study case, the tokens are pregenerated by javascript code on the join web page seconds before the participant sees them

But in both cases, from a participant perspective, they have a token, they scan it, and it is used to login to the server.

Thoughts?

shankari added a commit to e-mission/nrel-openpath-join-page that referenced this issue May 11, 2023
Consistent with
e-mission/e-mission-docs#850 (comment)
have the join page autogenerate the token

Also read the subgroup from the search parameters (if any) and incorporated it
into the token.

The token is of the form `nrelop_[name]_[subgroup]_randomstring`

Added validation:
- if the deployment doesn't have sub-groups defined, set the subgroup to "default"
- if the deployment does have subgroups defined, the subgroup should be present
  and be one of the defined values
    - if either of these is missing, we use the error mechanism defined in
        a212672 to display the error
@shankari
Copy link
Contributor Author

shankari commented May 20, 2023

TODO: potentially replicate the token validation on the server so that only valid tokens can be used to sign in. While unifying the branches, we might also want to add an API key as well, which would reduce the need for token validation.

@shankari
Copy link
Contributor Author

All changes now seem to be done:

shankari added a commit to e-mission/nrel-openpath-join-page that referenced this issue May 20, 2023
They are not actually used, since:
- I have never seen the clipboard action fail
- We always load the page first in English

But at least when we fix e-mission/e-mission-docs#905
we are ready for things to work

This is the final final fix for
e-mission/e-mission-docs#850
@shankari
Copy link
Contributor Author

Reopening to track making the dynamic config be the default, along with loading it from a file for apps that do not serve as the foundation for multiple studies (currently only FabMob/TraceMob).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants