elementary / flatpak-authenticator

Authenticate Flatpak installs from an elementary remote
https://elementary.io
GNU General Public License v3.0
4 stars 1 forks source link

Securely save payment info locally [$150] #6

Open cassidyjames opened 7 years ago

cassidyjames commented 7 years ago

We should find a way to securely and optionally save payment info on the local machine.


There is a bounty on this issue on Bountysource

--- There is a **[$150 open bounty](https://www.bountysource.com/issues/43381818-securely-save-payment-info-locally?utm_campaign=plugin&utm_content=tracker%2F57667267&utm_medium=issues&utm_source=github)** on this issue. Add to the bounty at [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F57667267&utm_medium=issues&utm_source=github).
danirabbit commented 7 years ago

Shouldn't we instead make use of Stripe's customer feature? If we create customers instead we can do things like subscriptions or list previous purchases from other machines

cassidyjames commented 7 years ago

Yes, that's likely the way forward. In which case we'll need to save a customer token locally, I believe.

cassidyjames commented 7 years ago

I'll have to (have @btkostner) look at the API a bit more, but after discussing this on Slack and in-person with @bencates, I think the way forward is:

cassidyjames commented 7 years ago

We will likely also need a way to not used a saved payment method in case the card has changed or whatever. In other app stores I see something like

|-----------------------------------|
|             AppCenter             |
|               Vocal               |
|                                   |
| [x] Use saved card ending in 1234 |
|                                   |
|             [ Cancel ] [ Pay $5 ] |
-------------------------------------

... and then un-checking the card would swap that line out with our existing "new card" entries.

danirabbit commented 7 years ago

some things worth noting:

btkostner commented 7 years ago

Couple things to note:

The difference right now, the token we get from stripe expires if it's not used, and is a single use only token.

danirabbit commented 7 years ago

I think point 2 is kind of moot because this would be the same case if your credentials were hijacked. "Unlimited" is also quiet some hyperbole since Stripe has fraud detection and will block large transactions. If I'm not mistaken, this customer ID is tied to our store as well right? So it's not as if this token can be used to do anything other than purchase apps which can already be downloaded for free.

I think we need to be clear that the intention here is not to create a multi-device account or establish purchase history. The only goal is to allow users to purchase again on the same device without having to re-enter their credentials.

KedarBrooks commented 7 years ago

Posted a pull request for this bounty (#354)

Lewiscowles1986 commented 6 years ago

Just a note

We need to figure out how to send libsoup data in the POST body. Right now we are using GET parameters, which are not protected with https, and visible to everyone.

From a "sniff the network packet" point of view a GET request (with parameters) is safe. I used to believe the same thing (oh it's unsafe, it must be sent unencrypted) but apparently, you cannot sniff get params over the network. While it is less secure than post because it can often be trapped by web-logs, browser add-ons etc, it is not transparently transmitted. Because I'm assuming this is transmitted from a local machine it should if you use libsecret be safe for users.

Coming from https://github.com/elementary/houston/issues/588 (I think I'll close that issue, it makes more sense to do locally)

How would it be possible to transfer this if a user were to upgrade from current release to the next major distro-release?

Garbee commented 6 years ago

A thought on the suggested UX, there should probably be "use saved card ending in XXXX" entries with a "Use new card" option at the end when clicked would trigger the form showing up. It's not exactly intuitive that unchecking a saved card feature would show the new form. Also, confusing if multiple cards are saved. Checkboxes tend to indicate multiple choice not singular. So a radio control system seems more adept for this scenario.

danirabbit commented 6 years ago

Gonna punt this feature since we're already end of April

razcakappa commented 6 years ago

Instead of using the StripAPI to store and retrieve card data, what if we store card details as secret items in a secret collection on a keyring instead? libsecret-1 library supports this method.

On UI, upon selecting a saved card from a saved card list , particular card details can be retrieved and feed to the payment form (StripeDialog).

Garbee commented 6 years ago

@razcakappa That isn't feasible since then Elementary is liable for PCI compliance. As I understand it, you can't store the CVC code in the same place as the rest of the card information. At least, not as a place that also intends to charge from that information.

Taking advantage of stripe's tokenizing removes almost all PCI concerns.

ghost commented 5 years ago

So despite the title, the real issue is to let StripeAPI store the payment info and just store the Stripe customer ID and limited card info (last 4 digits and unique Stripe ID) locally, along with creating the actual input form for sending the new card info to Stripe or using the already stored Customer Stripe info. Is that correct?

Just trying to understand the scope of the issue.

cassidyjames commented 5 years ago

@terndrup that sounds correct to me. I can aid with the UX/implementation of the UI for re-using card info as well.

davidmhewitt commented 4 years ago

Worth pointing out that I have a functional prototype of this that came out of the time freed up by the (postponed) AppCenter for everyone sprint:

The libelementary-account-testing branch in conjunction with https://github.com/davidmhewitt/elementary-account-api and https://github.com/davidmhewitt/elementary-account-api

This isn't production ready code or design yet, but hopefully we can continue this when the in-person sprint gets rescheduled.