Closed kavimuru closed 2 years ago
I am looking at it today for sure but it can take some time to go over all proposals.
Half way through the proposals. This is my top priority.
I'll update my proposal in a few hours.
Ok. I have reviewed a lot of things. I will try my best to cover everything but ping me if I miss something.
Node-keytar
and safestorage
GD.Node-keytar => Use system Keychain to store passwords for different usernames for a particular service. By default, the service which stores the credentials will be able to access those without a password prompt.
Yes, by entering the prompted password. But it does not make it unsafe. You can change the passwords or delete them by simply going to the system keychain and feeding the user password. If the user's account password is already compromised or an attacker has access to the system. You can not guarantee any safety. (You can read the terms and conditions somewhere on any apple product. I am sure they must have denied taking responsibility for such incidents)
If the user's password is not compromised as well as the system(the user is prompted to feed the password, it is impossible for any application to programmatically feed the information in the UI prompt unless the system is compromised), there is no way a password can be stolen by any application.
safeStorage => Use System keychain process to store the encryption seed/key. It will create a new entry in the system keychain for our app. Again, which can be changed or accessed via any app if they know the user password. It does not store app credentials in the system keychain.
Allows to easily encrypt data without the overhead of managing encryption keys.
I think both safeStorage and node-keytar can be combined together to give the user the best autofill experience. However, a single safeStorage
can be used to create a solution to manage all types of autofill. Storing passwords in userland is just not considered good practice even if encryption is used. However, it might be safe to store the password with encryption.
We will have to think about it again. I will come back to it.
Note: I am not a security expert and I am not aware of any loopholes in the implementation of both of these packages. There might be bugs leading to unauthorized access. I am considering the positive side where these packages are working as intended.
Common challenges for this issue.
main
, renderer
, or both? node-keytar
or safestorage
?Can all of you please answer these questions in your existing proposal at the end of it?
@ntdiary Autofill library sounds like a complex solution. AFAICT, there will be many challenges with it. It might not work with all the forms. But yeah, we can focus on our app first and make it work.
Let us know your estimated timeline and design plan for the same if you are considering going for it to understand better.
can fill more than one field at a time, for example, it should also fill password after selecting the username. can filter candidates. can manage the passwords or cards data (add / edit / delete).
I agree with these.
Your videos are looking good too. But the proposal is lacking a lot of information. I hope you can answer my questions from the previous comment.
@azimgd Your proposal is by far the most complete one.
It would be good if autofill works by filling all the fields in the form. for example, the user selects a username on the email field and the password gets filled in.
Questions to all:
Things need discussion:
Status: waiting for the updates on the existing proposals.
Incomplete solution. We won't be able to save debit card info AFAICT (let me know if I am wrong here).
Well, node-keytar
's API calls it "password" but you can store any string. So we could still store card information.
And regarding the things that need discussion:
1. Will Onyx be a good target to store the data(encryption or not)?
I think Onyx is good for managing and getting state throughout an app. In this case, do we need to use password or card information state throughout the app? I don't think so. The password/card information should only be there when submitting the form.
2. Should we show a native autofill popup or a custom?
I'm planning on implementing something like datalist
for the suggestions. That way it would be consistent with the browser version. And maybe an icon next to the input field that would show a modal/popup to manage passwords.
RE: SafeStorage Cons
it is not a go-to solution to store user passwords. we will have to manage the encrypted data ourselves. Change to encryption keys will break the existing data. Require logic to detect the decryption failure and take action about the stored data. Extra overhead of managing the data.
While I don't agree with the most points being a con, my main idea here is to have a single source of truth being Onyx. Data stored there is encrypted, and encryption key is stored in the OS Keychain.
An alternative solution (partial proposal upd on: https://github.com/Expensify/App/issues/10107#issuecomment-1275606422) is to store encrypted credentials using JSON directly inside Keychain using node-keytar
.
JSON Object may look like this:
{
'debit-card': [
{
label: 'John Doe Visa **72',
form: {
fullname: 'John',
number: '1234123412341234',
month: 12,
year: 2024,
}
}
],
'authorization': [
label: 'john@gmail.com',
form: {
username: 'john@gmail.com',
password: '12341234',
}
]
}
https://user-images.githubusercontent.com/4882133/197191516-b5acb91d-292d-494c-ae40-f1de0cdbc326.mov
Here is the initial prototype for what we are trying to achieve: https://github.com/azimgd/expensify-app/pull/1/files I'm missing some pieces that I'm planning to implement once assigned:
<Form autofill="debit-card"/>
// dispatch an event with Debit Card details as a payload for "debit-card" form
// once "John Doe Visa **72" is pressed from the dropdown, this will fill values for [month], [year] ...
<Form autofill="debit-card"/>
<TextInput name="month" />
<TextInput name="year" />
</Form>
Autofill is handled at renderer. Data encryption happens at main.
There are some challenges with node-keytar mentioned here: https://github.com/Expensify/App/issues/10107#issuecomment-1286907036
I'm not sure if we are able to implement desired functionality with a native popup.
While I don't agree with most points being a con.
I agree. I wasn't comparing both as they are just different tools IMO. Just tried to summarize it.
https://user-images.githubusercontent.com/4882133/198288410-ce15a0dd-77c1-4146-a7f8-15eb36a31c1f.mov
Usage: https://github.com/azimgd/form-autofill/blob/main/src/App.js
there will be many challenges with it. It might not work with all the forms. But yeah, we can focus on our app first and make it work.
@parasharrajat Yeah, I strongly agree, the work at hand is the most important, and I think it can have a good start and direction.😄 this is a demo variant. It's just to demonstrate autofill, so simply store the data in the indexedDB.
Autofill popup implementation.
This variant is implemented by js + dom + css
.
Autofill information storage.
Actually, I want to provide several kinds of storage to use, such as localStorage/indexedDB/keychain etc.
Which process will handle autofill main, renderer, or both?
Both. This variant mainly runs in the renderer
process. Encryption or keychain storage is also handled by main
process.
Challenges of installing/maintaining the library you are proposing e.g. node-keytar or safestorage?
I think both of these are not too difficult for me.
Will Onyx be a good target to store the data(encryption or not)?
I'm planning to provide a default autofill admin UI, may be similar to the image below.(of course, try to be consistent with our app style). But if we want to implement this admin popup in our app. Maybe Onyx
will be useful ?
Should we show a native autofill popup or a custom?
What does a native autofill popup mean? If it is datalist
, I can add some more discussion about it tomorrow. 🙂
Some notes on 'datalist' :
Actually, this is roughly my main idea, also from chromium autofill
component. We can only implement a relatively simple version. And based on this idea, there are several variants to try, such as c native
or datalist
or js
or our react-native component.
Take this card form as an example:
It contains not only a card input box, but also a password input box and even an address input box.
I think it would be better to find out the form type based on the information of the input box. autofill
should try to make it invisible to our components. (small changes and burdens)
I have spent a week looking for a c native solution, unfortunately I didn't find a very simple solution (but haven't given up)
for this js variant:
And this is library entry file. It works by listening to events (We can also use custom events if needed). Now, It can parse the target element name
to display the related form popup. For the autosave
, there will be further optimizations.
But I'm not sure if you're interested in this way, can you share with me your opinion? Thanks 🙂
If this can't be accepted, I think I can propose another variant of our app component
?
This is the demo video:
https://user-images.githubusercontent.com/8579651/198341092-a986d28c-f41d-4108-812f-8db2f060e4f2.mp4
Thanks for the updates. I will check them shortly.
@parasharrajat
Note: A universal solution which can be applied to normally any autofillable form will be better. For now, this issue focuses on Add debit card and login forms.
I created an NPM package with that enables form autofill on any <TextInput />
based on the Proposal of mine and Feedbacks given above.
https://github.com/Expensify/App/issues/10107#issuecomment-1277507900 https://github.com/Expensify/App/issues/10107#issuecomment-1275606422 https://github.com/Expensify/App/issues/10107#issuecomment-1292658612 https://github.com/Expensify/App/issues/10107#issuecomment-1293477763
It allows grouped form input persist and autofill. I'm planning on adding both KeyTar and SafeStorage providers.
https://github.com/azimgd/form-autofill https://www.npmjs.com/package/electron-form-autofill
https://github.com/azimgd/expensify-app/pull/2
// just wrap your form and input with this HOC
<FormWrapper name="authentication">
<InputWrapper>
<TextInput ... />
</InputWrapper>
</FormWrapper>
https://user-images.githubusercontent.com/4882133/198690581-b323a358-17d3-4852-a6a7-74bf75f21954.mov
Hi, I want to clarify a bit more, the demo code above just shows my basic process idea, and it will have a better internal structure after reorganization.
On the other hand, it has good extensibility, compatibility and api stability, I'm also planning to use Web components to avoid code collisions. These mean: (includes long-term plans)
And I can always be responsible for maintaining its code quality and performance.
Can we respond to the latest inquiries here @parasharrajat (today or tomorrow)?
Definitely, Looking at the new comments and code samples now.
I will share the update in sometime.
I have made some internal changes in my repo, nothing major changes in the usage. (uses web components. Encryption has not been added)
please let me know if you have any questions. 🙂
Quick feedback: @ntdiary Although I agree with your motive for creating a framework-agnostic solution, it will be complicated for the team to maintain. Most folks in the team, work on React so we prefer to react.
In the end, this is a solution for our app first.
BTW, I will discuss this internally too.
These are currently being reviewed.
@parasharrajat Thanks for your feedback. 😄 Maybe I pay too much attention to a universal solution, and think I can always maintain this library. I'll also consider whether I can write it with react if possible.
Started an internal discussion. https://expensify.slack.com/archives/C02NK2DQWUX/p1667498373237429
Waiting on the discussion before I share the next update here. It might take a day.
I tried to save a simple text on the keychain service login
and get it back which worked but I can't find it in the keychain access app anywhere. (I saved and retrieved the data in one go without closing the app). Thoughts?
Using keytar ? On osx ?
Yeah, keytar on Mac in the main process.
Question: Can we utilize the iCloud chain to save/get the passwords? This should allow us to share the autofill login creads across devices.
Could you try sorting by "Date Modified" ? Depending on implementation it most likely saves as "New Expensify / Chromium Safe Storage"
Can we utilize the iCloud chain to save/get the passwords?
It should theoretically be possible, but most likely would require us to generate our own build of chromium:
require us to generate our own build of chromium:
Not necessarily. We can code our own custom node module. But it is fine if this is complicated.
Still in discussion. Soon we will have some updates.
I'm also adding a react version that will have similar changes to our app as my previous proposal. 🙂 https://github.com/ntdiary/App/pull/1/files (just a demo, still needs to be improved)
If there are still concerns, I can continue to optimize both proposals and make the code conform to our specifications.
video:
https://user-images.githubusercontent.com/8579651/200003480-904983e7-009c-47e3-a2c5-a27aa0151ec5.mp4
I would say let's hold off doing any further analysis on this issue until we have a conclusion on the discussion. Thanks.
Please don't spend any further time providing proposals for this GH. I will provide an update as soon as I can.
Not overdue, Hax will post an update here shortly.
Will have something by tomorrow to share here.
Hey everyone. In recent weeks, we’ve discovered that there’s an opportunity to enhance and improve our password security to a higher degree by moving to a passwordless design. This new design is quickly underway and being led by internal engineers.
We do things dynamically at Expensify, meaning sometimes we pivot or change direction when better ideas come to fruition. Unfortunately this password-related job has become obsolete due to our future plans. But we still want to maintain fairness and compensate the contributors who were most actively involved. We really appreciate your pragmatism and time, and invite your continued involvement in other hard-to-solve jobs.
We did a careful review on our side and are going to pay 25% of the total job bounty to the following contributors:
We feel this payout is the most fair approach since the solution was explored at length in the “proposal phase” of this job. When you have a moment please apply to the following upwork job - https://www.upwork.com/jobs/~01a9e983bc39d24141. Then I'll pay & close this job, so we can shift our #focus to other high priority jobs.
Thanks all!
I would suggest publishing your solution as an open-source library. They might be useful to the community.
Fantastic idea to add @parasharrajat. It could be valuable to your portfolios of work in the future!
have applied, very much looking forward to this new passwordless design. 😄
@ntdiary and @azimgd are paid!
And lastly, @parasharrajat will get paid when he's ready. He asked for a few days to rotate his bank account in upwork and will message me when he's ready - 👍.
I'm going to close this GH down to ensure we are focused on the right thing. @parasharrajat see my last post above to close the loop for your payment.
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Issue was found when executing #9294
Action Performed:
Expected Result:
Autofill should works during login Autofill should works while adding new Debit card
Actual Result:
No autofill for fields at login page No autofill for all fields while adding new Debit card
Workaround:
unknown
Platform:
Where is this issue occurring?
Version Number: Version 1.1.86-1
Reproducible in staging?: y
Reproducible in production?: y
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos:
https://user-images.githubusercontent.com/43996225/181026173-67396956-4e27-4886-9d7b-047dd470e730.mp4
Upwork job URL: https://www.upwork.com/jobs/~01a9e983bc39d24141
Issue reported by: Applause internal team
Slack conversation:
View all open jobs on GitHub