-
Notifications
You must be signed in to change notification settings - Fork 71
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
Implement iOs Native password system #125
Comments
Putting my hand up to work on this one. @perry-mitchell has there been any work on the Android side yet? Just want to make sure that any required bridge implementations expose themselves uniformly across Android and iOS. |
So I've spent the last couple of hours prototyping iOS autocomplete and have come upon a pretty significant limitation that will need some discussion before going forward. Some background first: To enable autofill in iOS, the app must implement an AutoFill Credential Provider Extension (1). On iOS all Extensions run in a container (sandbox) separate to the main application, and are therefore treated for the most part like a separate mini-app. A part of this sandboxing is the Application's memory and stored data - just like normal Applications installed on the same device, the Extension cannot directly access the main application's data, and vice-versa. Apple does however provide a mechanism to get around this - using "App Groups" to associate the Extension and the main app, and using Now the for the limitation: React Native's The only real way I can see around this is to replace the To make things more complicated, both As you may be thinking, replacing
Sorry for the wall of text, keen to hear people's thoughts. Relevant Links:
|
Wow, thanks for the deep dive! Incredible that you've uncovered so much.
Actually, I was thinking that we could simply use the new storage just for the sharing of credentials between the app and extension.. What do you think? The current data stored using If we do go the way of moving everything into keychain storage, we should also write a migration snippet to move existing vaults over to the new storage on startup.
This looks great! I've stumbled on it before.. Nice that it supports both platforms too.
We could handle android as a second port of call.. Let's get this working on iOS first and then we can do another release for android. So @se1exin what do you think the extension would look like? Just simple iOS native code? Is there any need for 2-way data flow here, or can the parent app simply write credentials into the storage for the extension to provide as auto-fill content? |
Thanks for the feedback @perry-mitchell !
I had that thought as well but can see an edge case that could fail to ensure autofill credentials are in-sync with the user's other devices at the time that the autofill extension is invoked. For example, if I create/update a password on my PC, then go to login to the service on iPhone but do not open the Buttercup App first, the new/updated password will not have been synchronised to intermediate datastore and will not be available in autofill. If that makes sense? We could of course show a message or similar to educate the user that they need to do this first, but personally I think doing so is a bit clunky/not a great user experience. That being said... I can also appreciate user benefit vs development time and introduced complexity/risk, and in this case I am very much on-the-fence about how worthwhile it would be to go all-the-way with a new storage backend to mitigate an admittedly infrequent edge case. Perhaps this could just be chalked up to technical debt so the feature can be delivered quicker; you can always go the whole-hog later on if it does turn out to be an annoyance to users. ..I leave that decision to you guys 😉 I'm happy to build it either way.
I actually wanted to discuss this in my last post, but it was well long enough already 😅. How I see it, the user will be displayed an overlay with a list of potential logins (I see it much like the browser extension login suggestions) with credentials matching the service ID (e.g. domain name) sorted to the top. Tapping a credential closes the overlay and executes the autofill. The AutoFill Extension API also has the ability to show a single credential directly in the iOS keyboard in the top bar, but I was not able to get that to work in my prototyping - I think it would be awesome to see that work though, for when there is a single direct matching credential. This is all assuming that we use one-way data flow with an intermediate datastore, as the credentials will be available to the extension when it is invoked. Going down the two-way dataflow path, we'd need to ask the user to unlock their archive as an additional first step in the overlay, and would likely loose the ability to show a single match directly in the iOS keyboard without the need for the overlay. As for UI/Design of the overlay, I was thinking I'd use the existing Buttercup RN Components and listing styling etc (as the overlay will still be React Native - not Native iOS), and start sending some screenshots etc once that part was underway. Keen to hear your feedback on all of the above @perry-mitchell |
Yeah, this makes sense. I don't really like the idea that the credentials available from the extension could be out of sync.. So perhaps it'd be better if we could simply design it with this in mind. Of course that means that we need to bake the functionality that allows unlocking vaults and searching for entries into the extension.
Yep, this sounds ideal to me. Obviously with a react-native generated interface too I guess.
Yep, this definitely sounds like something we'd want also. It sounds incredible!
Well here's the thing.. If we're using the keychain, could we not just write the credentials (upon each unlock) into the keychain storage so they're immediately available? We could provide a way to unlock and update as well, perhaps.. And for ease of use we could force users to use touch/face ID to unlock (not accepting a password-based unlock process). There's a lot of choices here on the design of the extension but I'm sure many will end up not being possible. I've got 0 idea of how this will look once it's complete but I just have a bad feeling there'll be some number of brick walls 😅
Well what would be ideal would be the use of our current RN components in the new extension. The encryption code is handled by an iOS/Android-JNI bridge and some native code that calls a Rust binary.. It's not super portable. It'd be great if the extension could literally be the same app, just with another entry point or something to that effect. No idea if this is possible or whether this might breach some memory constraints. @se1exin Great stuff! This is exciting. |
@Thomazella I wonder if this is due to the touch-unlock requirement for keychain access? I'd suppose so. I guess those passwords would simply be the ones already stored by the OS (unless you're using another password manager).
Yep, we'd need to build the UI to provide a sort of portal into the Buttercup app (via the extension we're discussing). |
@perry-mitchell yeah. I was just using stock safari. I had some saved passwords for some sites.
just an ideia: Register buttercup:// url to open app on ios. Somehow differentiate from a regular app open (native code in appDelegate.m maybe). then: app.js
|
I've just spent a few more hours playing around with one and two-way data flow solutions (for lack of better terms), and have some more findings... Note: These are just my findings, it would be awesome if there is anyone out there that has worked with the iOS AutoFill Extension before, and that could lend some additional insight! One-way data flow
I've tested adding an additional step in Two-way data flow
I've also tested replacing ...the Crypto bridge is not available in the AutoFill Extension, as iOS does not allow direct access to the main app's native code. We can however work around this by exporting the Crypto bridge and related native code as a Framework, and then import the Framework into both the main app and AutoFill Extension Xcode Targets (the only allowed way to share code between Apps/Extensions). I'm also not sure at this point if we are able to pull down an Archive over the network in the Extension. Additionally, a few UI elements are blocked in the Extension by iOS, such as ActionSheets and Alerts, as the Extension is not actually a fully-fledged iOS application, however these can easily be just omitted from the Extension UI.
Unfortunately, these are all pretty much in conflict with each other if AsyncStorage is kept as primary Archive Source storage, as nearly everything that ButtercupCore puts into AsyncStorage will need to be replicated into the Keystore for the Extension to have access to unlock. And if we're doing that then it doesn't make much sense to also write the unlocked credentials into the Keychain as well. I really like how simple it was to switch out ..So where to from here? To me there are one of two distinct paths that can taken:
I've been checking out the Search functionality merged in #130 and the work done there should serve as the perfect base for the main Extension UI.
Spot on - the extension JS would be another entry point exposed via React Native's
Unfortunately iOS's AutoFill Extension API is a bit more complicated than that.. but if you've read this far you probably don't need me to tell you that now 😂
Yep, this is starting to feel a little bit like a maze 😛.. |
So it looks like I just needed to sleep on it. I jumped in this morning and was able to easily link the Crypto Bridge into the Extension without pulling the Crypto Bridge code out of the main project, and whola the Extension is able to decrypt Archives, including pulling them over the network. Two-way data flow works 🎉 I've started moving ahead with two-way data flow and have already implemented Keychain based storage, including auto migration of data from My work so far is in the branch TODO List:
A quick preview to demonstrate Keychain storage, Cyrpto, and network Archives working and being shared successfully between the main app and the extension: |
This made my week.. Awesome news!
This is nuts.. well done! You've made incredible progress already. Definitely can't wait to give this a test run. I completely understand that it may still be early stages, but what is your plan with the "Passwords" button above the keyboard? Should it open some smaller frame to display something from the app? Just wondering about usability when opening the whole Buttercup app for a password. I haven't honestly used this feature with another password manager so I'm a total novice when it comes to how Apple have implemented it. Loving the progress here! 🚀 |
@se1exin wow, awesome! Didn't fully understand the gif: after tapping passwords on the top of the keyboard, it invokes the extension? If so, whatever it used to show before user installs buttercup is still accessible? This is definitely a good step forward :D |
This is incredible! Great work guys I can’t wait to try this in action 🚀🥳 |
Thanks for the positive feedback everyone 😎
Yeh sorry the gif isn't that helpful, I could only record 30s with my gif recorder program so had to rush through the process. Tapping a username/password field brings up the iOS keyboard as per usual, if the user has Autofill enabled (in iOS settings) then iOS will add the 'Passwords' button above the keyboard - this is all handled by iOS outside of Buttercup. Tapping the 'Passwords' link asks iOS for installed Apps with AutoFill functionality, and if Buttercup is enabled as an AutoFill provider (in iOS Settings), iOS invokes the Buttercup AutoFill Extension. Again, this is all handled by iOS. At this point I can only assume iOS will also display any other items you may have in your Keyboard QuickBar, but I don't actually have other things in my QuickBar, so I'm unable to test. If your able to suggest a test scenario I'd be happy to try and reproduce and test what happens (e.g. "Install App X and enable feature Y to add new item to iOS Quickbar").
Good question. In the demo gif I am loading the entire existing JS App into the extension frame purely to demonstrate that it is possible to load and display an RN JS App in the autofill extension environment. The only reason it is showing the entire Buttercup app is because I have just simply not gotten to the step of building a dedicated UI for it. I think I mentioned it in a previous comment, but the plan at the moment is to create a new RN entry point based on and similar to the Search Screen from #130, but... ...I'm a very keen to hear feedback on what people think the Extension frame UI should have and should look like. Hopefully over my last few comments I have successfully outlined the many constraints that have to be considered, but seeing as they are quite dense here is a summary:
--
Edit: Nevermind - just figured out how to show a single direct match as well!! More details and hopefully a demo soon! |
Yeah this sounds excellent. Definitely a great idea to perform a quick domain search using the one provided by iOS. Ideally we'd have some combination of the following:
🤯 |
A quick update, direct AutoFill from the iOS Keyboard QuickBar is now working 🎉.
Thanks @perry-mitchell. The UI is now all that is left to do, so will get started with it and work on your 3 points in that order. |
This is amazing man! Great work wow |
Hi @se1exin! Hope all is going well mate. Please let us know if you need a hand with anything. If there's something that we could add in the core to be of more use we can also do that quite quickly. |
@perry-mitchell thanks! I've been chipping away at it over the week, but it's also been the first week back at work, so it's been a busy one! I should have a PR ready over this weekend though. Will shout out if I need a hand with anything! Edit: The UI is nearly complete with results for domain and search results working. Last thing to do is handle error cases such as failed Touch ID or no archives with Touch ID at all. For no Touch ID at all I was thinking of failing back to manual unlock of Archives via an adapted ArchivesList page. Demo of UI so far. Search works as well but had to keep the gif short 😉: |
Wow! It just keeps getting better. I knew this feature would be great but I didn't have any idea it would be this powerful. Definitely a feather in the cap of mobile password managers. Thanks for seeing this through. Definitely agree regarding work - I also just got back, and it's manic 😅 |
@perry-mitchell the PR is ready 🤘 |
Released in 1.8.0. |
Hi devs
Would it be possible to make use of ios password autofill implementation into buttercup ?
Some other password manager did and this functionnality is a game changer in ios ecosystem.
congrat for everything, very nice project
The text was updated successfully, but these errors were encountered: