Open aGuttman opened 2 years ago
Proposed solution: Have the app display a QR code that can be scanned by the app running on the user's new phone, which will allow the user to transfer ownership of the account and data to the new phone. As a backup, on creating a new account, generate QR code, ask the user to share it to some other app/service (email, SMS, etc...) and send it to themselves (or some other private place they will be able to access later) so they have it available to them if needed.
@aGuttman By tomorrow: Add another row to the profile screen that popups the privacy policy or "QR code coming soon"
@aGuttman Ah, we do have a QR code generator in the server repo. It is angular-qrcode
(https://github.com/e-mission/e-mission-server/blob/master/webapp/bower.json#L13) and is used here:
https://github.com/e-mission/e-mission-server/blob/master/webapp/www/templates/client_setup.html#L38
and
https://github.com/e-mission/e-mission-server/blob/master/webapp/www/templates/client_setup.html#L66
@aGuttman I have created a new release for the devapp: https://github.com/e-mission/e-mission-devapp/releases/tag/v3.2.3 I have tested, and it is compatible with the tip of the phone master.
So this dependency (https://github.com/e-mission/e-mission-docs/issues/724#issuecomment-1116718312) should now be resolved:
Dependency: get new version of devapp up
Added row with popup to profile screen. QR code not yet generated, but will go in popup. Pull request created.
@sebastianbarry Installing angular-qrcode
using bower hangs consistently at
bower cached git://github.com/monospaced/bower-qrcode-generator.git#0.2.0
bower validate 0.2.0 against git://github.com/monospaced/bower-qrcode-generator.git#v0.2.0
and then fails with
bower ECMDERR Failed to execute "git ls-remote --tags --heads git://github.com/monospaced/bower-qrcode-generator.git", exit code of #128 fatal: unable to connect to github.com: github.com[0: 140.82.112.4]: errno=Operation timed out
Additional error details:
fatal: unable to connect to github.com:
github.com[0: 140.82.112.4]: errno=Operation timed out
This is because the main repo has an incorrect bower.json
.
npm uses package.json
, where the dependencies are
"dependencies": {
"angular": ">=1.0.6",
"qrcode-generator": "^1.1.0"
}
bower uses bower.json
, where the dependencies are:
"dependencies": {
"angular": ">=1.0.6",
"qrcode-generator": "git://github.com/monospaced/bower-qrcode-generator.git#v0.2.0"
}
Retrieving the bower dependency hangs.
Potential solutions are:
manual/lib
like the other packages thereNormally, we would submit a fix to the angular-qrcode
repo, but it has been deprecated so they are unlikely to merge any fixes.
In fact, there is an existing issue that refers to this: https://github.com/monospaced/angular-qrcode/issues/78
@sebastianbarry please make sure to put your findings about the library here. And for the long term, don't forget to create a tag for your change instead of using master.
There are 3 issues to take note of:
"qrcode-generator": "git://github.com/monospaced/bower-qrcode-generator.git#v0.2.0"
which will not work because of issue https://github.com/monospaced/angular-qrcode/issues/78What did I change?
"qrcode-generator": "https://github.com/monospaced/bower-qrcode-generator.git#0.2.0"
"angular-qrcode": "https://github.com/sebastianbarry/angular-qrcode.git#v7.3.0"
in the bower.json of our e-mission-phone projectThe goal of this is that it will remove the load errors we see in the console when interacting with the QR code button on the app, which have stopped since implementing this. However the QR code is still not displaying
monospaced/angular-qrcode
is not working (http://monospaced.github.io/angular-qrcode/)The 3 issues mentioned above have been resolved
Turns out we did not need to change the dependency to get it to work. I copied the settings from e-mission-server and the QR code generation began working Changes can be seen in https://github.com/e-mission/e-mission-phone/pull/829/
Next step is to share the QR code so people can save it in drive or via email or text it to themselves. There is an existing example of sharing text in the share button on the profile page. We need to share an image in this case.
We use the cordova social sharing plugin for sharing (that is the window.plugins.socialsharing
); we call the shareWithOptions
method from it
you need to look at the documentation to figure out how to share an image (hint: base64 is your friend)
The app displays a QR code using the monospaced/angular-qrcode library like so
<qrcode class="col" aria-label="qrcode for user email" data="{{settings.auth.email}}" size="220" download></qrcode>
The app shares using the cordova social sharing plugin
window.plugins.socialsharing
Using a file location
Using base64 image data
data="{{settings.auth.email}}"
into the base64 data for a QR code, and pass that into the cordova socailsharing plugin
This is how I think we should solve thisUsing a URL
@sebastianbarry
Agree that using a URL is out. Downloads are a bit tricky in a hybrid mobile app, and an additional consideration is that saving the file could potentially be a security leak if another app (e.g. photo app/google drive) has access to the phone filesystem. Agree that base64 is the way to go
although the monospaced/angular-qrcode
doesn't have an existing public interface to expose the data, it generates this under the hood anyway. And it is open source. So a couple of options are:
Hint: the second option and the canvas
methods are your friend. Look at the components of the qrcode
directive in the inspector as well.
I found through testing that adding the "download
" modifier on the qrcode HTML element automatically generates the base64 image data for the QR code, shown here
That being said, how do we save that HTML element containing the href=...
base64 data into a variable, that we can then call in our Angularjs code here?:
@SebastianBarry angular1 comes with an integrated jquery-lite, and I think we also include jquery explicitly. So you can select an element using class $('.<class>') or id
$('#
jquery is super well known and there's a lot of documentation on how to use it to traverse the HTML DOM (e.g. search for "jquery find element by id") and extract values.
Created view QR code button, and created share QR code button [working] You can view the PR here: [https://github.com/e-mission/e-mission-phone/pull/840]
$scope.settings.auth.email
or $scope.getEmail()
, but I just wasn't able to figure out how to get this to work in the general-settings.js code inside the prepopulateQRMessage variableThe Share button looks like the bottom is getting clipped off by some unknown box. I tried playing with the HTML in qrc.html but I could not get it to stop cutting off the bottom
What concretely did you do to play with it?
I was thinking it would be a good idea to also share the email token while also sharing the QR code image (so that the sharing message is set to the $scope.settings.auth.email or $scope.getEmail(), but I just wasn't able to figure out how to get this to work in the general-settings.js code inside the prepopulateQRMessage variable
The qr code does represent the email token, so this is lower priority. You can file it as a potential enhancement for the future and move on.
The Share button looks like the bottom is getting clipped off by some unknown box. I tried playing with the HTML in qrc.html but I could not get it to stop cutting off the bottom
What concretely did you do to play with it?
I just adjusted the width and height values, do you have any other idea how I can play with it?
I was thinking it would be a good idea to also share the email token while also sharing the QR code image (so that the sharing message is set to the $scope.settings.auth.email or $scope.getEmail(), but I just wasn't able to figure out how to get this to work in the general-settings.js code inside the prepopulateQRMessage variable
The qr code does represent the email token, so this is lower priority. You can file it as a potential enhancement for the future and move on.
Will do
I just adjusted the width and height values, do you have any other idea how I can play with it?
That sound right. When you adjusted the values, did it not change the box? Did you try to view the elements in the debugger and see what the source of the mysterious box is in the HTML?
Increasing the values of the percentages for width and height by 5% did not affect the Share button in any way
These pictures show the different elements on this popover for the QR code.
I'm not seeing any other element interacting or cutting off the button.
I even tried changing it back and forth from a clickable <div>
to a clickable <button>
and neither seems to affect at all the way the button displays on my iPhone emulator
I still have not been able to get my android emulator, even from the e-mission/e-mission-phone:master
my android app just blank white screens after the IP-entering screen
See https://github.com/e-mission/e-mission-phone/pull/840 for changes
I updated the HTML for qrc.html and now it is displaying properly
Next step is to scan the QR code. And I really think that we may actually want to redesign the login screen a bit as well. QR code is clearly the easiest way to get a long string in, but:
And now we will have another button to scan QR code; wondering if this is too many options and is confusing.
Plan:
example of where we scan the QR code in our existing codebase https://github.com/e-mission/e-mission-phone/blob/ceo_ebike_project/www/js/checkinout.js
we again use a native plugin (similar to socialshare
) that will open the camera, read the QR code and give it to us as a string.
This plugin cordova.plugins.barcodeScanner.scan
and I think it can actually scan either barcode or QR code so we should check that it is actually a QR code.
We should also potentially add some wrapping to the QR code instead of it just being the raw token because if people sign some other random QR code, we don't want it to be their token. In other words, we don't want tokens like https://coolevent.biz
But let's start with the unwrapped token, get it to work and then wrap the token in the next step.
https://github.com/e-mission/e-mission-phone/pull/841
I started a PR with my first attempt at adding a scanQR code feature to the login screen.
I had some comments in there about things I was getting stuck on, mainly
Added a $scope.scanQRCode function but it also does not have any meaninful code in it. This is how I think we should do it (by having the scanQRCode function and then calling it from the popover button), but I was struggling to get the function to call. I don't know how to type it (is it just "$scope.scanQRCode();" and it starts working?)
And
Added scripts needed to run scan QR code
Is this how it should be done? Are these lines meaningful, or did I just add useless scripts?
I also was wondering if you could help point me in the right direction with what we actually want to put in the scanQRCode function. Will it look very similar to the e-mission-server code for scanning the bike label? https://github.com/e-mission/e-mission-phone/blob/ceo_ebike_project/www/js/checkinout.js
const scanBikeLabel = function() {
return new Promise(function(resolve, reject) {
if (!$scope.scanEnabled) {
reject(new Error("plugins not yet initialized, please retry later"));
} else {
cordova.plugins.barcodeScanner.scan(
function (result) {
if (result.format == "QR_CODE" &&
result.cancelled == false) {
try {
const bikeLabel = getScannedLabel(result.text);
resolve(bikeLabel);
} catch(e) {
reject(e);
}
} else {
reject(new Error("invalid QR code"+result.text));
}
},
function (error) {
reject(error);
});
}
});
}
@sebastianbarry I had forgotten about the requirement to have a physical phone to test the QR code stuff. I should send you some of the test android phones, but wanted to get the NREL app in the stores first.
The time required to troubleshoot the steps required to run the app on your iPhone is not worth it at this time. My recollection is that it was so painful when prior undergrads tried it that I ended up giving them test android phones as well.
If you happen to have an old android phone around, you can continue with this project. Otherwise, I think you should move on to the summer improvement that you have chosen.
After merging the change to the edit_config branch, we get
Program | Study |
---|---|
@sebastianbarry I added the "scan token" functionality to the login screen (as you can see above).
Pending tasks now are focused around usability
Can you please finish these before #640?
Added Save step to the intro. See PR https://github.com/e-mission/e-mission-phone/pull/854
@sebastianbarry do any of your testers have android phones? Saving to google drive does not seem to save the token text, only the token QR code. Sending via SMS does seem to save both. Might need to experiment with different "save" methods and ensure that both text and image are saved.
will close this after next round of feedback and final edits to the popup.
I do not have a tester with an Android phone near me at the moment. However, I tested the Google Drive sharing on my iPhone and it looks like its working properly
Can we get a video or screenshot of it not working on an Android?
@sebastianbarry It looks like if I save to drive, it only saves the png
https://user-images.githubusercontent.com/2423263/178424023-cb2ac1d6-4162-46c9-bc8d-dca344bdd30e.mov
@shankari I added the Spanish translation in https://github.com/e-mission/e-mission-translate/pull/15 but in the PR I showed how some of the English is hard-coded and I need help translating it.
The PR is for e-mission-translate, but for the hard-coded English I think it needs to be changed in e-mission-phone
Added Spanish translation to the hard-coded English sections in the login popups. See https://github.com/e-mission/e-mission-phone/pull/863
"Shankari, K."
- you need to convert to a directive (that is what I have scheduled for the next sprint)
- and also have time to address any other feedback from friends and family
so you can create this module:
Example of service
.factory("MultiLabelService", function(ConfirmHelper, InputMatcher, $timeout) {
used from here
surveyoptions.MULTILABEL = {
filter: "MultiLabelInfScrollFilters",
service: "MultiLabelService",
elementTag: "multilabel"
}
The MultiLabelService
may not be the best example of how to use it since we use it via an $injector
for greater decoupling. But we use DiaryHelper
(in www/js/diary/services.js
) in the more traditional way in multiple places
first get it to work with the scope
but that is still sub-optimal because then you are tying together the two modules because the Opcode services depends on the $scope
structure of intro.js
. If you changed it, the service could break
there is a way to get a $scope
from the $rootScope
and so you probably want to change to passing in the token and creating a new scope to set the token in
another option is to see if you can change the intro code so that the popup is not invoked from javascript but can be a button in the HTML
because then you can use a directive for the button
and angular will automatically create a scope for you
<button>Save your OPcode</button>
becomes
<save-opcode>Save your opcode</save-opcode>
<div button save-opcode>Save your opcode</div>
One complexity is that you need to keep track of whether the user has already saved the opcode. Note that the button that checks this is the "Login" button while the button that saved the flag that the opcode is already saved is the save button. So you can't put that logic in the controller like you did before.
So you should make a service that is only called from this module and will save that state of whether the save has happened or not. Note that you need to think about the state in the service needs to be and checked.
Concretely, let's say that the controller logic is:
The behavior then is that:
A way to change the logic is:
save-opcode
directive has a parameter that is something like "checkIfSaved"The behavior then is that:
<save-opcode alwaysSave=true></save-opcode>
in the multi-label UI, trip
is a parameter and recomputeDelay
is a parameter
This is the multilabel UI: https://github.com/e-mission/e-mission-phone/blob/master/www/js/survey/multilabel/multi-label-ui.js
Converted the "Save Opcode" into a directive and implemented the directive: (e-mission-phone changes) https://github.com/e-mission/e-mission-phone/pull/867 (e-mission-translate changes) https://github.com/e-mission/e-mission-translate/pull/16
"Shankari, K."
- and also have time to address any other feedback from friends and family
I also noticed that in my branch's version of login.html, there is not the "study" section for the "study" or "program" distinction in this file, so they both are being displayed:
...
<center><h3>Login via anonymous token (OPcode) </h3></center>
<center>OPcode {{randomToken}}</center></div>
<div class="intro-text">
This unique randomly generated token (OPcode) is your identifier in the system.
<p> </p>
Nobody other than you knows that you are associated with this OPcode. If you
want to communicate with the research team about the data collected about you,
please be prepared to provide this OPcode.
<div class="intro-space"></div>
<button class="button button-block button-balanced" ng-click="loginNew()">Login as {{randomToken}}</button>
If you already have an OPcode from a previous install, you can use it instead to retain the same account. Note that there are no incorrect tokens. If you enter a OPcode that does not match an existing one, we will create a new account.
<div class="intro-space"></div>
<button class="button button-block button-energized" ng-click="typeExisting()">Type existing OPcode</button>
<center> <b> - OR - </b> </center>
<div class="intro-space"></div>
<button class="button button-block button-royal" ng-click="scanExisting()">Scan existing OPcode</button>
</div> <!-- program_or_study == 'study' -->
</div> <!-- overall div -->
...
This also isn't in the e-mission-phone master branch
However it is in the e-mission-phone master_for_platform branch
I pushed my PR out with the style of the master
branch, that doesn't have the "study" section defined. But I submitted my PR to the master_for_platform
branch, so I'm not sure if these changes will be updated automatically or not
@sebastianbarry the master branch does not have a separate section for the program.
that is because master does not have any distinction between studies and programs - it only has the study configuration.
the difference between studies and programs is part of the dynamic_config
, which is only available (currently) in the master_for_platform
branch.
If you are submitting a PR for the master_for_platform
branch, you should start with that branch and retain the difference between studies and programs. Otherwise, we will end up with the situation where the study part of the login is always displayed, even for programs.
@sebastianbarry are you done with interviews related to this? Can we close this issue? You should be able to close it directly...
Currently, if users lose/forget their token, they have no way to recover their account when changing phones/recovering from a wipe. We want to create a way to allow account recovery in these instances without needing to store any additional info about the user.