vw_small

Hardened fork of Vaultwarden (https://github.com/dani-garcia/vaultwarden) with fewer features.
git clone https://git.philomathiclife.com/repos/vw_small
Log | Files | Refs | README

commit a1c1b9ab3bcfb89b92264ae7b903760ce1afd4a2
parent 395979e834ff3bccbedf87fb386607bbc9ad8557
Author: Daniel GarcĂ­a <dani-garcia@users.noreply.github.com>
Date:   Fri,  8 Oct 2021 22:28:46 +0200

Merge branch 'mail-errors' of https://github.com/BlackDex/vaultwarden into BlackDex-mail-errors

Diffstat:
Msrc/api/admin.rs | 6+++++-
Msrc/mail.rs | 23++++++++++++++++++-----
Msrc/static/templates/admin/base.hbs | 8++++----
Msrc/static/templates/admin/diagnostics.hbs | 4++--
Msrc/static/templates/admin/organizations.hbs | 4++--
Msrc/static/templates/admin/settings.hbs | 7+++----
Msrc/static/templates/admin/users.hbs | 12++++++------
Msrc/util.rs | 12++++++++++++
8 files changed, 52 insertions(+), 24 deletions(-)

diff --git a/src/api/admin.rs b/src/api/admin.rs @@ -18,7 +18,9 @@ use crate::{ db::{backup_database, get_sql_server_version, models::*, DbConn, DbConnType}, error::{Error, MapResult}, mail, - util::{format_naive_datetime_local, get_display_size, get_reqwest_client, is_running_in_docker}, + util::{ + docker_base_image, format_naive_datetime_local, get_display_size, get_reqwest_client, is_running_in_docker, + }, CONFIG, }; @@ -492,6 +494,7 @@ fn diagnostics(_token: AdminToken, ip_header: IpHeader, conn: DbConn) -> ApiResu // Execute some environment checks let running_within_docker = is_running_in_docker(); + let docker_base_image = docker_base_image(); let has_http_access = has_http_access(); let uses_proxy = env::var_os("HTTP_PROXY").is_some() || env::var_os("http_proxy").is_some() @@ -549,6 +552,7 @@ fn diagnostics(_token: AdminToken, ip_header: IpHeader, conn: DbConn) -> ApiResu "web_vault_version": web_vault_version.version, "latest_web_build": latest_web_build, "running_within_docker": running_within_docker, + "docker_base_image": docker_base_image, "has_http_access": has_http_access, "ip_header_exists": &ip_header.0.is_some(), "ip_header_match": ip_header_name == CONFIG.ip_header(), diff --git a/src/mail.rs b/src/mail.rs @@ -485,15 +485,28 @@ fn send_email(address: &str, subject: &str, body_html: String, body_text: String // Match some common errors and make them more user friendly Err(e) => { if e.is_client() { - err!(format!("SMTP Client error: {}", e)); + debug!("SMTP Client error: {:#?}", e); + err!(format!("SMTP Client error: {}", e.to_string())); } else if e.is_transient() { - err!(format!("SMTP 4xx error: {:?}", e)); + debug!("SMTP 4xx error: {:#?}", e); + err!(format!("SMTP 4xx error: {}", e.to_string())); } else if e.is_permanent() { - err!(format!("SMTP 5xx error: {:?}", e)); + debug!("SMTP 5xx error: {:#?}", e); + let mut msg = e.to_string(); + // Add a special check for 535 to add a more descriptive message + if msg.contains("(535)") { + msg = format!("{} - Authentication credentials invalid", msg); + } + err!(format!("SMTP 5xx error: {}", msg)); } else if e.is_timeout() { - err!(format!("SMTP timeout error: {:?}", e)); + debug!("SMTP timeout error: {:#?}", e); + err!(format!("SMTP timeout error: {}", e.to_string())); + } else if e.is_tls() { + debug!("SMTP Encryption error: {:#?}", e); + err!(format!("SMTP Encryption error: {}", e.to_string())); } else { - Err(e.into()) + debug!("SMTP {:#?}", e); + err!(format!("SMTP {}", e.to_string())); } } } diff --git a/src/static/templates/admin/base.hbs b/src/static/templates/admin/base.hbs @@ -62,8 +62,8 @@ headers: { "Content-Type": "application/json" } }).then( resp => { if (resp.ok) { msg(successMsg, reload_page); return Promise.reject({error: false}); } - respStatus = resp.status; - respStatusText = resp.statusText; + const respStatus = resp.status; + const respStatusText = resp.statusText; return resp.text(); }).then( respText => { try { @@ -126,9 +126,9 @@ // get current URL path and assign 'active' class to the correct nav-item (() => { - var pathname = window.location.pathname; + const pathname = window.location.pathname; if (pathname === "") return; - var navItem = document.querySelectorAll('.navbar-nav .nav-item a[href="'+pathname+'"]'); + let navItem = document.querySelectorAll('.navbar-nav .nav-item a[href="'+pathname+'"]'); if (navItem.length === 1) { navItem[0].className = navItem[0].className + ' active'; navItem[0].setAttribute('aria-current', 'page'); diff --git a/src/static/templates/admin/diagnostics.hbs b/src/static/templates/admin/diagnostics.hbs @@ -58,7 +58,7 @@ <dt class="col-sm-5">Running within Docker</dt> <dd class="col-sm-7"> {{#if page_data.running_within_docker}} - <span class="d-block"><b>Yes</b></span> + <span class="d-block"><b>Yes (Base: {{ page_data.docker_base_image }})</b></span> {{/if}} {{#unless page_data.running_within_docker}} <span class="d-block"><b>No</b></span> @@ -329,7 +329,7 @@ supportString += "* Vaultwarden version: v{{ version }}\n"; supportString += "* Web-vault version: v{{ page_data.web_vault_version }}\n"; - supportString += "* Running within Docker: {{ page_data.running_within_docker }}\n"; + supportString += "* Running within Docker: {{ page_data.running_within_docker }} (Base: {{ page_data.docker_base_image }})\n"; supportString += "* Environment settings overridden: "; {{#if page_data.overrides}} supportString += "true\n" diff --git a/src/static/templates/admin/organizations.hbs b/src/static/templates/admin/organizations.hbs @@ -37,8 +37,8 @@ <span class="d-block"><strong>Size:</strong> {{attachment_size}}</span> {{/if}} </td> - <td class="text-end pe-2 small"> - <a class="d-block" href="#" onclick='deleteOrganization({{jsesc Id}}, {{jsesc Name}}, {{jsesc BillingEmail}})'>Delete Organization</a> + <td class="text-end px-0 small"> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='deleteOrganization({{jsesc Id}}, {{jsesc Name}}, {{jsesc BillingEmail}})'>Delete Organization</button> </td> </tr> {{/each}} diff --git a/src/static/templates/admin/settings.hbs b/src/static/templates/admin/settings.hbs @@ -219,11 +219,10 @@ onChange(); // Trigger the event initially checkbox.addEventListener("change", onChange); } - // These are formatted because otherwise the - // VSCode formatter breaks But they still work - // {{#each config}} {{#if grouptoggle}} + + {{#each config}} {{#if grouptoggle}} masterCheck("input_{{grouptoggle}}", "#g_{{group}} input"); - // {{/if}} {{/each}} + {{/if}} {{/each}} // Two functions to help check if there were changes to the form fields // Useful for example during the smtp test to prevent people from clicking save before testing there new settings diff --git a/src/static/templates/admin/users.hbs b/src/static/templates/admin/users.hbs @@ -61,16 +61,16 @@ {{/each}} </div> </td> - <td class="text-end pe-2 small"> + <td class="text-end px-0 small"> {{#if TwoFactorEnabled}} - <a class="d-block" href="#" onclick='remove2fa({{jsesc Id}})'>Remove all 2FA</a> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='remove2fa({{jsesc Id}})'>Remove all 2FA</button> {{/if}} - <a class="d-block" href="#" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</a> - <a class="d-block" href="#" onclick='deleteUser({{jsesc Id}}, {{jsesc Email}})'>Delete User</a> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</button> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='deleteUser({{jsesc Id}}, {{jsesc Email}})'>Delete User</button> {{#if user_enabled}} - <a class="d-block" href="#" onclick='disableUser({{jsesc Id}}, {{jsesc Email}})'>Disable User</a> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='disableUser({{jsesc Id}}, {{jsesc Email}})'>Disable User</button> {{else}} - <a class="d-block" href="#" onclick='enableUser({{jsesc Id}}, {{jsesc Email}})'>Enable User</a> + <button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='enableUser({{jsesc Id}}, {{jsesc Email}})'>Enable User</button> {{/if}} </td> </tr> diff --git a/src/util.rs b/src/util.rs @@ -419,6 +419,18 @@ pub fn is_running_in_docker() -> bool { Path::new("/.dockerenv").exists() || Path::new("/run/.containerenv").exists() } +/// Simple check to determine on which docker base image vaultwarden is running. +/// We build images based upon Debian or Alpine, so these we check here. +pub fn docker_base_image() -> String { + if Path::new("/etc/debian_version").exists() { + "Debian".to_string() + } else if Path::new("/etc/alpine-release").exists() { + "Alpine".to_string() + } else { + "Unknown".to_string() + } +} + // // Deserialization methods //