You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the event that there is ever a serious bug with the frontend or backend, we want to be able to force users to update their clients.
Imagine the following:
user X loads app.umbra.cash in a new browser tab
we discover that there is a serious bug in the frontend (and/or how it interacts with the backend)
we patch the bug and deploy the new code to the server that distributes it
user X still has the old, vulnerable code running in his/her browser tab
user X does not refresh his/her tab before using the frontend
user X uses the stale frontend and BAD THING happens
Unless we have a mechanism to force refresh clients, there will always be a long tail of outdated versions in the wild.
Implementation
There are two obvious triggers we could use for refreshes:
refresh after a certain amount of time (e.g. a week) even if there has been no backend update
refresh each time there is a (major|minor|patch) version update to the backend
Trigger 1 has the benefit of refreshing the app even if no backend calls have been made. For example, after you've connected to the network, you can send funds with the protocol without touching the backend again. You just sign the transaction that the frontend creates for you, and your wallet sends it to the network.
I think 2 would probably be all that we need, though. Most wallets will require you to reconnect after a prolonged period away from a dapp, and doing so will hit the /tokens route of the backend.
As it is, the backend already returns a version number with each response which we could use:
My suggestion would be to refresh on every major or minor release of the backend. Refreshing on patch releases would likely just result in a lot of refreshing for our users, which isn't great UX.
To implement this, it would probably be sufficient to just store the backend version in a cookie or local storage or something, TBD. When the frontend first loads, it stores the first version it sees from the backend. Then, each time it makes a request to the backend, it confirms that the version in the cookie matches the version coming back from the API. If it doesn't, we force the user to refresh. A power user could always manipulate his/her cookies to get around the check. But I think at that point, it's on them and we just let them do what they want. The protocol is ultimately open anyway.
An alternative to this approach would be to give the frontend a version too. Then on each API request we check that the frontend version is >= the backend version. Then we don't have to worry about power users getting around our protections by modifying cookies (now they'd have to modify the javascript itself). But the downside of this approach is that we'd be coupling frontend and backend deploys: it wouldn't be possible to deploy the backend without first deploying the frontend. We'd also need to be careful: if the backend was deployed before the frontend, users could be stuck in an infinite refresh loop where the frontend keeps telling them to refresh b/c its version lags the backend version, but when it does refresh it just pulls frontend code with a version that is still out of date.
UX
We probably want to put an overlay on the app to disable it, with copy to the effect of "Your application is out of date, please reload [button]". This is what google sheets does, for example, when I've had a tab open for months. It's straightforward. You just click the button (it's all you can do) and that's it.
The text was updated successfully, but these errors were encountered:
Another (all too timely) usecase for this... if a version of your frontend calls out to an address that was recently sanctioned 😬 you'd want a way to immediately prevent anyone who still has that code in their browser from using it
The 'version' that already exists that is described above is not an API version.. it is a TokenList version that comes from the uniswap library type definitions in the Umbra API. A change in this version value indicates a change in the token list being provided by the Umbra API.. not a change in the API itself. I'd propose that as we make the Umbra API return a 'version' from every API endpoint ( https://github.com/ScopeLift/umbra-api/issues/58 ), we name it something different to uniquely identify it, such as umbraApiVersion.
Background
In the event that there is ever a serious bug with the frontend or backend, we want to be able to force users to update their clients.
Imagine the following:
Unless we have a mechanism to force refresh clients, there will always be a long tail of outdated versions in the wild.
Implementation
There are two obvious triggers we could use for refreshes:
Trigger 1 has the benefit of refreshing the app even if no backend calls have been made. For example, after you've connected to the network, you can send funds with the protocol without touching the backend again. You just sign the transaction that the frontend creates for you, and your wallet sends it to the network.
I think 2 would probably be all that we need, though. Most wallets will require you to reconnect after a prolonged period away from a dapp, and doing so will hit the
/tokens
route of the backend.As it is, the backend already returns a version number with each response which we could use:
My suggestion would be to refresh on every major or minor release of the backend. Refreshing on patch releases would likely just result in a lot of refreshing for our users, which isn't great UX.
To implement this, it would probably be sufficient to just store the backend version in a cookie or local storage or something, TBD. When the frontend first loads, it stores the first version it sees from the backend. Then, each time it makes a request to the backend, it confirms that the version in the cookie matches the version coming back from the API. If it doesn't, we force the user to refresh. A power user could always manipulate his/her cookies to get around the check. But I think at that point, it's on them and we just let them do what they want. The protocol is ultimately open anyway.
An alternative to this approach would be to give the frontend a version too. Then on each API request we check that the frontend version is >= the backend version. Then we don't have to worry about power users getting around our protections by modifying cookies (now they'd have to modify the javascript itself). But the downside of this approach is that we'd be coupling frontend and backend deploys: it wouldn't be possible to deploy the backend without first deploying the frontend. We'd also need to be careful: if the backend was deployed before the frontend, users could be stuck in an infinite refresh loop where the frontend keeps telling them to refresh b/c its version lags the backend version, but when it does refresh it just pulls frontend code with a version that is still out of date.
UX
We probably want to put an overlay on the app to disable it, with copy to the effect of "Your application is out of date, please reload [button]". This is what google sheets does, for example, when I've had a tab open for months. It's straightforward. You just click the button (it's all you can do) and that's it.
The text was updated successfully, but these errors were encountered: