mirror of
https://github.com/dani-garcia/vaultwarden
synced 2024-12-14 17:43:46 +01:00
Merge branch 'BlackDex-mail-errors' into main
This commit is contained in:
commit
f67854c59c
8 changed files with 52 additions and 24 deletions
|
@ -18,7 +18,9 @@ use crate::{
|
||||||
db::{backup_database, get_sql_server_version, models::*, DbConn, DbConnType},
|
db::{backup_database, get_sql_server_version, models::*, DbConn, DbConnType},
|
||||||
error::{Error, MapResult},
|
error::{Error, MapResult},
|
||||||
mail,
|
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,
|
CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -492,6 +494,7 @@ fn diagnostics(_token: AdminToken, ip_header: IpHeader, conn: DbConn) -> ApiResu
|
||||||
|
|
||||||
// Execute some environment checks
|
// Execute some environment checks
|
||||||
let running_within_docker = is_running_in_docker();
|
let running_within_docker = is_running_in_docker();
|
||||||
|
let docker_base_image = docker_base_image();
|
||||||
let has_http_access = has_http_access();
|
let has_http_access = has_http_access();
|
||||||
let uses_proxy = env::var_os("HTTP_PROXY").is_some()
|
let uses_proxy = env::var_os("HTTP_PROXY").is_some()
|
||||||
|| 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,
|
"web_vault_version": web_vault_version.version,
|
||||||
"latest_web_build": latest_web_build,
|
"latest_web_build": latest_web_build,
|
||||||
"running_within_docker": running_within_docker,
|
"running_within_docker": running_within_docker,
|
||||||
|
"docker_base_image": docker_base_image,
|
||||||
"has_http_access": has_http_access,
|
"has_http_access": has_http_access,
|
||||||
"ip_header_exists": &ip_header.0.is_some(),
|
"ip_header_exists": &ip_header.0.is_some(),
|
||||||
"ip_header_match": ip_header_name == CONFIG.ip_header(),
|
"ip_header_match": ip_header_name == CONFIG.ip_header(),
|
||||||
|
|
23
src/mail.rs
23
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
|
// Match some common errors and make them more user friendly
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.is_client() {
|
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() {
|
} 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() {
|
} 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() {
|
} 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 {
|
} else {
|
||||||
Err(e.into())
|
debug!("SMTP {:#?}", e);
|
||||||
|
err!(format!("SMTP {}", e.to_string()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,8 @@
|
||||||
headers: { "Content-Type": "application/json" }
|
headers: { "Content-Type": "application/json" }
|
||||||
}).then( resp => {
|
}).then( resp => {
|
||||||
if (resp.ok) { msg(successMsg, reload_page); return Promise.reject({error: false}); }
|
if (resp.ok) { msg(successMsg, reload_page); return Promise.reject({error: false}); }
|
||||||
respStatus = resp.status;
|
const respStatus = resp.status;
|
||||||
respStatusText = resp.statusText;
|
const respStatusText = resp.statusText;
|
||||||
return resp.text();
|
return resp.text();
|
||||||
}).then( respText => {
|
}).then( respText => {
|
||||||
try {
|
try {
|
||||||
|
@ -126,9 +126,9 @@
|
||||||
|
|
||||||
// get current URL path and assign 'active' class to the correct nav-item
|
// 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;
|
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) {
|
if (navItem.length === 1) {
|
||||||
navItem[0].className = navItem[0].className + ' active';
|
navItem[0].className = navItem[0].className + ' active';
|
||||||
navItem[0].setAttribute('aria-current', 'page');
|
navItem[0].setAttribute('aria-current', 'page');
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
<dt class="col-sm-5">Running within Docker</dt>
|
<dt class="col-sm-5">Running within Docker</dt>
|
||||||
<dd class="col-sm-7">
|
<dd class="col-sm-7">
|
||||||
{{#if page_data.running_within_docker}}
|
{{#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}}
|
{{/if}}
|
||||||
{{#unless page_data.running_within_docker}}
|
{{#unless page_data.running_within_docker}}
|
||||||
<span class="d-block"><b>No</b></span>
|
<span class="d-block"><b>No</b></span>
|
||||||
|
@ -329,7 +329,7 @@
|
||||||
|
|
||||||
supportString += "* Vaultwarden version: v{{ version }}\n";
|
supportString += "* Vaultwarden version: v{{ version }}\n";
|
||||||
supportString += "* Web-vault version: v{{ page_data.web_vault_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: ";
|
supportString += "* Environment settings overridden: ";
|
||||||
{{#if page_data.overrides}}
|
{{#if page_data.overrides}}
|
||||||
supportString += "true\n"
|
supportString += "true\n"
|
||||||
|
|
|
@ -37,8 +37,8 @@
|
||||||
<span class="d-block"><strong>Size:</strong> {{attachment_size}}</span>
|
<span class="d-block"><strong>Size:</strong> {{attachment_size}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end pe-2 small">
|
<td class="text-end px-0 small">
|
||||||
<a class="d-block" href="#" onclick='deleteOrganization({{jsesc Id}}, {{jsesc Name}}, {{jsesc BillingEmail}})'>Delete Organization</a>
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
@ -219,11 +219,10 @@
|
||||||
onChange(); // Trigger the event initially
|
onChange(); // Trigger the event initially
|
||||||
checkbox.addEventListener("change", onChange);
|
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");
|
masterCheck("input_{{grouptoggle}}", "#g_{{group}} input");
|
||||||
// {{/if}} {{/each}}
|
{{/if}} {{/each}}
|
||||||
|
|
||||||
// Two functions to help check if there were changes to the form fields
|
// 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
|
// Useful for example during the smtp test to prevent people from clicking save before testing there new settings
|
||||||
|
|
|
@ -61,16 +61,16 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end pe-2 small">
|
<td class="text-end px-0 small">
|
||||||
{{#if TwoFactorEnabled}}
|
{{#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}}
|
{{/if}}
|
||||||
<a class="d-block" href="#" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</a>
|
<button type="button" class="btn btn-sm btn-link p-0 border-0" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</button>
|
||||||
<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='deleteUser({{jsesc Id}}, {{jsesc Email}})'>Delete User</button>
|
||||||
{{#if user_enabled}}
|
{{#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}}
|
{{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}}
|
{{/if}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
12
src/util.rs
12
src/util.rs
|
@ -419,6 +419,18 @@ pub fn is_running_in_docker() -> bool {
|
||||||
Path::new("/.dockerenv").exists() || Path::new("/run/.containerenv").exists()
|
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
|
// Deserialization methods
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue