When requested expiry duration not in list, choose the closest, not default.
The problem
Requesting custom expiry can lead to unexpected surprise.
There are many third party clients for Privatebin. Also there are many Privatebin servers/hosts. Which is great btw! :partying_face:
Each server may have it's own custom values of expiry duration which only the first party client is aware of.
Similarly, third party clients, may support any custom value the user provides, or a fixed set decided by developer.
Currently when the server sees a value not in it's configured set, it falls back to the default value. Problem is clients are not aware of this. Also, it can be very different from the one requested.
For example, requesting paste with expiry "1min" on privatebin.net, results in paste with expiry "1day". When there are actually five durations (5min, 10min, 30min, 1hour, 12hours) in between.
The solution
The server should pick the closest duration to the one requested among it's set of expiry values. It may use the Alternatively, if feasible, it should just use the given expiry as is, as long as it is within its max / min expiry range.
Alternatives
- An alternative is to scrape individual privatebin hosts, and extract expiry times from the very thorough and brilliant find an instance directory.
- Perhaps the directory itself can additionally scrape supported expiry durations, and provide it on the page? Clients may then get the supported values from there programmatically and cache it locally.
Additional context
What if we just rejected creating the paste if the client sends an invalid expiry? That way the error isn't silent, but obvious and the user can deal with it (=visit the website and lookup which ones are possible to select).
The second point would be nice to consider as well: How to discover supported expiration times as a third-party client? At the moment, you'd have to parse the HTML and fish the select element with ID "pasteExpiration" out of the tag soup and the contained options will be the currently valid ones. So this would require an extra round-trip, at least if the attempted one fails (the suggestion above).
If the directory were to do this, I wouldn't quite know how to visualize this for display - I'd say raise a ticket for such a feature over there, if you or anyone else has some suggestions on how to pull this off with little space in the table.
What if we just rejected creating the paste if the client sends an invalid expiry? That way the error isn't silent, but obvious and the user can deal with it (=visit the website and lookup which ones are possible to select).
Programmatically, it seems like the right thing to do. If it were this way from the beginning that would have been fine.
However now, clients probably depend on this permissive behavior. And I think it is indeed useful. It allows clients to use any server without having to hard-code all expiry values. And without the user having to manually visit website every time.
Without a way to programmatically retrieve correct values, I think not failing is better.
(=visit the website and lookup which ones are possible to select).
I was going to suggest adding an new api instead, to get the pertinent details from server. But maybe there's a more easier way..
What if we do reject creating the paste like you suggest, but the error message includes the correct/valid expiry values?
If formatting in consistent and easily parse-able, then clients would also be able to use it directly, without needing another round trip, or costly (inconvenient) manual intervention.
If solution is packaged with the rejection then it would be worth it. :)
This would be an error response on the API, so it could make sense to extend the JSON message appropriately. We don't offer any hard guarantees to third party clients API-wise, but such a semi-breaking change would certainly require at least a minor version bump.
At this time, clients can auto-discover the versions, but would have to parse them out of the HTML.
First of all, good point of raising this problem!
What if we just rejected creating the paste if the client sends an invalid expiry?
I'd agree here, this sounds good.
About backwards-compatibiity (and yeah having cool things like that Android app in mind). this could maybe be made with a change that addresses the second concern raised in this issue: Currently you'd have to scrape the HTML for the expiration settings/values. To fix this, I'd propose a simple new JSON-API that can return this:
- Some API that returns the expiration values, Maybe rest-like
…/settings/expirationor so, so it could be extended if we were to expose more information. IMHO, this is non-sensitive and already public, this just makes it easier to scrape/consume for third-party clients (and possibly or us, too, if we rewrite this, like required for #312). - The third-party clients then would do another request to fetch the expiration values first and them show them to the user in a proper way, before sending the paste data with the selected value.
IMHO, this way it not only provides a "minor" breaking change that may cause problems for clients, but also a way forward/a solution, what clients can (quite easily, as JSON is easy and the practical API data exchange format nowadays) implement to fix it and even work better than before.
I would like to also draw attention to related discussion https://github.com/PrivateBin/PrivateBin/issues/524 requesting custom (client decided) expiration times. Within server set max/min durations of-course.
If supporting above, then we could have a simpler api. Providing just the maximum expiry and minimum expiry. And clients can then fetch this and validate user entered input before requesting paste.
This would also make the error easier. Could simply say "Expiry outside server accepted range: 5min-1year", or such.
The server would still be able to choose which options to display in the web ui as before. But shall accept any pastes with expiration within it's max/min range.