commit b6fde857a74b24cbc71631468b13656f01e370c7
parent 3c66deb5cc7a4387e4176d2a5bdd3f321f09a6bd
Author: BlackDex <black.dex@gmail.com>
Date: Thu, 28 May 2020 20:25:25 +0200
Added version check to diagnostics
- Added a version check based upon the github api information.
Diffstat:
2 files changed, 112 insertions(+), 26 deletions(-)
diff --git a/src/api/admin.rs b/src/api/admin.rs
@@ -319,6 +319,24 @@ pub struct WebVaultVersion {
version: String,
}
+fn get_github_api(url: &str) -> Result<Value, Error> {
+ use reqwest::{header::USER_AGENT, blocking::Client};
+ let github_api = Client::builder().build()?;
+
+ let res = github_api
+ .get(url)
+ .header(USER_AGENT, "Bitwarden_RS")
+ .send()?;
+
+ let res_status = res.status();
+ if res_status != 200 {
+ error!("Could not retrieve '{}', response code: {}", url, res_status);
+ }
+
+ let value: Value = res.error_for_status()?.json()?;
+ Ok(value)
+}
+
#[get("/diagnostics")]
fn diagnostics(_token: AdminToken, _conn: DbConn) -> ApiResult<Html<String>> {
use std::net::ToSocketAddrs;
@@ -331,10 +349,31 @@ fn diagnostics(_token: AdminToken, _conn: DbConn) -> ApiResult<Html<String>> {
let github_ips = ("github.com", 0).to_socket_addrs().map(|mut i| i.next());
let dns_resolved = match github_ips {
- Ok(Some(a)) => a.ip().to_string() ,
+ Ok(Some(a)) => a.ip().to_string(),
_ => "Could not resolve domain name.".to_string(),
};
+ let bitwarden_rs_releases = get_github_api("https://api.github.com/repos/dani-garcia/bitwarden_rs/releases/latest");
+ let latest_release = match &bitwarden_rs_releases {
+ Ok(j) => j["tag_name"].as_str().unwrap(),
+ _ => "-",
+ };
+
+ let bitwarden_rs_commits = get_github_api("https://api.github.com/repos/dani-garcia/bitwarden_rs/commits/master");
+ let mut latest_commit = match &bitwarden_rs_commits {
+ Ok(j) => j["sha"].as_str().unwrap(),
+ _ => "-",
+ };
+ if latest_commit.len() >= 8 {
+ latest_commit = &latest_commit[..8];
+ }
+
+ let bw_web_builds_releases = get_github_api("https://api.github.com/repos/dani-garcia/bw_web_builds/releases/latest");
+ let latest_web_build = match &bw_web_builds_releases {
+ Ok(j) => j["tag_name"].as_str().unwrap(),
+ _ => "-",
+ };
+
let dt = Utc::now();
let server_time = dt.format("%Y-%m-%d %H:%M:%S").to_string();
@@ -342,6 +381,9 @@ fn diagnostics(_token: AdminToken, _conn: DbConn) -> ApiResult<Html<String>> {
"dns_resolved": dns_resolved,
"server_time": server_time,
"web_vault_version": web_vault_version.version,
+ "latest_release": latest_release,
+ "latest_commit": latest_commit,
+ "latest_web_build": latest_web_build.replace("v", ""),
});
let text = AdminTemplateData::diagnostics(diagnostics_json).render()?;
diff --git a/src/static/templates/admin/diagnostics.hbs b/src/static/templates/admin/diagnostics.hbs
@@ -6,14 +6,30 @@
<div class="row">
<div class="col-md">
<dl class="row">
- <dt class="col-sm-5">Server Installed</dt>
+ <dt class="col-sm-5">Server Installed
+ <span class="badge badge-success d-none" id="server-success" title="Latest version is installed.">Ok</span>
+ <span class="badge badge-warning d-none" id="server-warning" title="There seems to be an update available.">Update</span>
+ <span class="badge badge-danger d-none" id="server-failed" title="Unable to determine latest version.">Unknown</span>
+ </dt>
<dd class="col-sm-7">
<span id="server-installed">{{version}}</span>
</dd>
- <dt class="col-sm-5">Web Installed</dt>
+ <dt class="col-sm-5">Server Latest</dt>
+ <dd class="col-sm-7">
+ <span id="server-latest">{{diagnostics.latest_release}}<span id="server-latest-commit" class="d-none">-{{diagnostics.latest_commit}}</span></span>
+ </dd>
+ <dt class="col-sm-5">Web Installed
+ <span class="badge badge-success d-none" id="web-success" title="Latest version is installed.">Ok</span>
+ <span class="badge badge-warning d-none" id="web-warning" title="There seems to be an update available.">Update</span>
+ <span class="badge badge-danger d-none" id="web-failed" title="Unable to determine latest version.">Unknown</span>
+ </dt>
<dd class="col-sm-7">
<span id="web-installed">{{diagnostics.web_vault_version}}</span>
</dd>
+ <dt class="col-sm-5">Web Latest</dt>
+ <dd class="col-sm-7">
+ <span id="web-latest">{{diagnostics.latest_web_build}}</span>
+ </dd>
</dl>
</div>
</div>
@@ -45,29 +61,57 @@
</main>
<script>
- const d = new Date();
- const year = d.getUTCFullYear();
- const month = String((d.getUTCMonth()+1)).padStart(2, '0');
- const day = String(d.getUTCDate()).padStart(2, '0');
- const hour = String(d.getUTCHours()).padStart(2, '0');
- const minute = String(d.getUTCMinutes()).padStart(2, '0');
- const seconds = String(d.getUTCSeconds()).padStart(2, '0');
- const browserUTC = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
- document.getElementById("time-browser-string").innerText = browserUTC;
+ (() => {
+ const d = new Date();
+ const year = d.getUTCFullYear();
+ const month = String((d.getUTCMonth()+1)).padStart(2, '0');
+ const day = String(d.getUTCDate()).padStart(2, '0');
+ const hour = String(d.getUTCHours()).padStart(2, '0');
+ const minute = String(d.getUTCMinutes()).padStart(2, '0');
+ const seconds = String(d.getUTCSeconds()).padStart(2, '0');
+ const browserUTC = year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + seconds;
+ document.getElementById("time-browser-string").innerText = browserUTC;
+
+ const serverUTC = document.getElementById("time-server-string").innerText;
+ const timeDrift = (Date.parse(serverUTC) - Date.parse(browserUTC)) / 1000;
+ if (timeDrift > 30 || timeDrift < -30) {
+ document.getElementById('time-warning').classList.remove('d-none');
+ } else {
+ document.getElementById('time-success').classList.remove('d-none');
+ }
+
+ // Check if the output is a valid IP
+ const isValidIp = value => (/^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(value) ? true : false);
+ if (isValidIp(document.getElementById('dns-resolved').innerText)) {
+ document.getElementById('dns-success').classList.remove('d-none');
+ } else {
+ document.getElementById('dns-warning').classList.remove('d-none');
+ }
+
+ let serverInstalled = document.getElementById('server-installed').innerText;
+ let serverLatest = document.getElementById('server-latest').innerText;
+ if (serverInstalled.indexOf('-') > -1 && serverLatest !== '-') {
+ document.getElementById('server-latest-commit').classList.remove('d-none');
+ serverLatest += document.getElementById('server-latest-commit').innerText;
+ }
+
+ const webInstalled = document.getElementById('web-installed').innerText;
+ const webLatest = document.getElementById('web-latest').innerText;
+
+ checkVersions('server', serverInstalled, serverLatest);
+ checkVersions('web', webInstalled, webLatest);
- const serverUTC = document.getElementById("time-server-string").innerText;
- const timeDrift = (Date.parse(serverUTC) - Date.parse(browserUTC)) / 1000;
- if (timeDrift > 30 || timeDrift < -30) {
- document.getElementById('time-warning').classList.remove('d-none');
- } else {
- document.getElementById('time-success').classList.remove('d-none');
- }
+ function checkVersions(platform, installed, latest) {
+ if (installed === '-' || latest === '-') {
+ document.getElementById(platform + '-failed').classList.remove('d-none');
+ return;
+ }
- // Check if the output is a valid IP
- const isValidIp = value => (/^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(value) ? true : false);
- if (isValidIp(document.getElementById('dns-resolved').innerText)) {
- document.getElementById('dns-success').classList.remove('d-none');
- } else {
- document.getElementById('dns-warning').classList.remove('d-none');
- }
+ if (installed !== latest) {
+ document.getElementById(platform + '-warning').classList.remove('d-none');
+ } else {
+ document.getElementById(platform + '-success').classList.remove('d-none');
+ }
+ }
+ })();
</script>
\ No newline at end of file