PayButton / paybutton-server

Manage eCash payments received through your online business.
MIT License
6 stars 2 forks source link

Support for locking web content / paywalls #43

Open Klakurka opened 2 years ago

Klakurka commented 2 years ago

Part of https://github.com/PayButton/paybutton/issues/30 (client-side)

Considerations / Questions:

Must Have:

Should Have:

Could Have:

Klakurka commented 2 years ago

Considerations:

Klakurka commented 2 years ago

Alt option: support 3rd party storage solutions so they can store their stuff on those instead.

Klakurka commented 1 year ago

What about using browser fingerprints or other session info sent back to the server upon payment that can be used to auto-unlock content without issues when refreshing the page or navigating around?

Klakurka commented 1 year ago

In addition to the data to actually display, the button (likely can just do this client-side) will need to have the div id to know what to replace on the page if the payment is successful.

vorg-code commented 1 year ago

I think it is a good idea for them to store their own data, otherwise we would have cloud-like concerns to worry about like storage space, replication, bandwidth throughput, security, speed, etc.

If our customers store the data encrypted and then insert a little bit of our code (just like paybutton) that sends this encrypted data to our server alongside the user's address, we could verify the payment and send back the decrypted data or send a 0 otherwise. If that little bit of code doesn't find the user's address, it maybe offers a web3 login of some sort via a button in the encrypted content's place or an automatic popup like metamask. We would have to store the keys for each content (and each deposit address) and be able to link each deposited amount found to each content.

That is assuming we are able to get the user's address in a reliable secure way... when we enter a web3 enabled website like pancakeswap, it logs in metamask automatically and that goal is achieved, for example. Do we have something like that?

Browser fingerprints, local storage, cookies... they are not reliable, if we clean browsing data or change browsers or computers (I have 2 at home for example, windows and macos), then I can't access the content I paid for, I would anticipate a lot of complaints.

chedieck commented 1 year ago

I also think is not good to concern ourselves with storing the raw data, at least for now. We probably should start storing only URLs to the real data to be unlocked and a URL to the preview of the data (e.g could be a blurred image or some text)

As for the authentication, as @vorg-code mentioned, cookies are not that reliable. Since requiring login is, on the other hand, a kind of a hassle, maybe we could go in the middle way with something like what Mullvad VPN has: the user clicks a button and generate an account number/hash: some string with high entropy that they should be responsible for saving. Ofc, if they were to lose that, they would lose all the content, so maybe traditional email log-in could also be an option, for those who prefer 3rd party security over anonymity. Then we could also create a cookie for the generated account number, so that the user have their session saved and do not need to fetch it every time.

Implementation:

I am thinking something like:

  1. Here, on paybutton-server, we create a new table, let's call it Content
  2. Thinking as simply as possible, content could have an id, an preview_url, and unlocked_url. The admin, through the front end, can set what is the URL for the content to be unlocked and for the preview (we could support creating this types of preview automatically in the future too).
  3. Then, on their website, the admin can use the wordpress plugin/ paybutton library to lock some content. Let's continue with the image example:
  4. Instead of having some img on the website like <img src=URL></img>, they could have <Content props=... > which would take as props the id of the content (this data would be fetched from their running instance of paybutton-server) and the account number of the user accessing the page. Then the user would see the preview & have to option to pay for it, or the content, depending if they already payed or not.

Then, for the payment security handling, we would ideally use the BIP70 protocol; and after completion, in another table we assiociate the accountNumber with the contentId to mark it as payed.

vorg-code commented 1 year ago

Agreed with the server side's implementation and data structuring, however a random string that the user has to save and remember just to unlock content in random websites is so much worse than a metamask login that pops up because the website has some web3 enabled capabilities and the random string is not needed because it is your wallet's address.

Is it possible for us to implement this feature in another cryptocurrency using smart contracts? Something cheap to transact like polygon maybe.

Klakurka commented 1 year ago

We're going to stick with eCash which can do stuff like this but I think we can do a bit better than requiring logins.

I have concerns about the ease-of-use for website developers to set up paywalls so we'll want to seriously consider that issue when coming up with our solution.

What about saving several pieces of data (eg. browser fingerprint, IP address, and payment tx input addresses)? We could provide them with a short code derived from their fingerprint that they can save and enter later as a fallback. If we allowed entering codes like this though, it would necessitate some sort of expiry to prevent them from just sharing it with tons of people. We could also use eCash aliases instead of codes potentially.

vorg-code commented 1 year ago

How about we create a browser extension for this? It would detect automatically if there is locked content in the webpage and, if so, provide a signed message with the user's wallet private key (proof of identity), so that our <Content> tag could get it, decrypt it with the wallet's public key and verify if that address already paid for that content and unlock it automatically or not. Users would only need to install the extension and pay whenever they want to see something, without saving any strings. Also they wouldn't be able to share this access with other people.

If the extension can use the private key to sign without storing the private key, that would be great.

vorg-code commented 1 year ago

Maybe this can be of some use here: https://www.npmjs.com/package/@samrock5000/cashscript

chedieck commented 1 year ago

(nvm the missclick)

However a random string that the user has to save and remember just to unlock content in random websites is so much worse than a metamask login that pops up because the website has some web3 enabled capabilities and the random string is not needed because it is your wallet's address.

Asking they to save some string/password is kind of unavoidable, metamask asks you to save your private key too. But as I said, the idea is that we save the session in a cookie so they don't have to input it every time. Metamask, being an extension, has a more resilient session in the sense you can clear the cache & cookies and not lose your session, but I think that requiring users to install some specific Paybutton extension is too much.

What about saving several pieces of data (eg. browser fingerprint, IP address, and payment tx input addresses)? We could provide them with a short code derived from their fingerprint that they can save and enter later as a fallback. If we allowed entering codes like this though, it would necessitate some sort of expiry to prevent them from just sharing it with tons of people.

I don't see the need for generating this fallback code from fingerprinting, it could be just randomness.

Klakurka commented 9 months ago

Maybe we can do this as a PayButton Module, and then hosting it ourselves under a subdomain.