Skip to content

Commit

Permalink
feat(ui): Automatically refresh the page when the backend version cha…
Browse files Browse the repository at this point in the history
…nged
  • Loading branch information
Hypfer committed Dec 11, 2021
1 parent ffe9f37 commit 905ada1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 7 deletions.
11 changes: 4 additions & 7 deletions backend/lib/webserver/middlewares/VersionMiddleware.js
Expand Up @@ -3,17 +3,14 @@ const Tools = require("../../Tools");
const version = Tools.GET_VALETUDO_VERSION();
const commitId = Tools.GET_COMMIT_ID();
/**
* The main purpose of these headers is to make it easier
* to find internet-facing valetudo instances using shodan.io
* so that I can be mad about them
* These headers are used by the frontend to determine if the backend was updated
* so that it can force a refresh.
* Using headers for that prevents us from periodically polling the backend for its version.
*
* It also makes it much easier to find publicly accessible Valetudo instances on shodan.io
* Don't do that.
* Use a VPN or at least a reverse-proxy with proper auth.
*
* By ignoring this warning, you opt-in to valetudo
* telemetry data collection via the cloud
*
*
* @param {object} req
* @param {object} res
* @param {Function} next
Expand Down
34 changes: 34 additions & 0 deletions frontend/src/api/client.ts
Expand Up @@ -54,6 +54,40 @@ export const valetudoAPI = axios.create({
baseURL: "../api/v2",
});

let currentCommitId = "unknown";

valetudoAPI.interceptors.response.use(response => {
/*
As using an outdated frontend with an updated backend might lead to undesirable
or even catastrophic results, we try to automatically detect this state and
act accordingly.
By just looking at the response headers of any api request, we avoid additional
periodic API requests for polling the current version.
If something such as a reverse proxy strips these headers, the check will not work.
Users of advanced setups like these should remember to press ctrl + f5 to force refresh
after each Valetudo update
*/
if (response.headers["x-valetudo-commit-id"]) {
if (currentCommitId !== response.headers["x-valetudo-commit-id"]) {
if (currentCommitId === "unknown") {
currentCommitId = response.headers["x-valetudo-commit-id"];
} else {
/*
While we could display a textbox informing the user that the backend changed,
there wouldn't be any benefit to that as the refresh is mandatory anyways
By just calling location.reload() here, we avoid having to somehow inject the currentCommitId
value from this mostly stateless api layer into the React application state
*/
location.reload();
}
}
}

return response;
});

const SSETracker = new Map<string, () => () => void>();

const subscribeToSSE = <T>(
Expand Down

0 comments on commit 905ada1

Please sign in to comment.