aboutsummaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorBlackDex <[email protected]>2022-12-28 20:05:10 +0100
committerBlackDex <[email protected]>2022-12-31 22:17:16 +0100
commit613b2519edc53dfcc7f82ea4e402ff846ab9cc04 (patch)
treedb9265109e84533fc33aeeb522634c9d7dd4ade3 /src/api
parent10dadfca068ed449fcd4a74b70ae2cd83990d3d4 (diff)
downloadvaultwarden-613b2519edc53dfcc7f82ea4e402ff846ab9cc04.tar.gz
vaultwarden-613b2519edc53dfcc7f82ea4e402ff846ab9cc04.zip
Removed unsafe-inline JS from CSP and other fixes
- Removed `unsafe-inline` for javascript from CSP. The admin interface now uses files instead of inline javascript. - Modified javascript to work not being inline. - Run eslint over javascript and fixed some items. - Added a `to_json` Handlebars helper. Used at the diagnostics page. - Changed `AdminTemplateData` struct to be smaller. The `config` was always added, but only used at one page. Same goes for `can_backup` and `version`. - Also inlined CSS. We can't remove the `unsafe-inline` from css, because that seems to break the web-vault currently. That might need some further checks. But for now the 404 page and all the admin pages are clear of inline scripts and styles.
Diffstat (limited to 'src/api')
-rw-r--r--src/api/admin.rs40
-rw-r--r--src/api/web.rs11
2 files changed, 25 insertions, 26 deletions
diff --git a/src/api/admin.rs b/src/api/admin.rs
index 6c908bfc..fd2293d6 100644
--- a/src/api/admin.rs
+++ b/src/api/admin.rs
@@ -144,7 +144,6 @@ fn render_admin_login(msg: Option<&str>, redirect: Option<String>) -> ApiResult<
let msg = msg.map(|msg| format!("Error: {msg}"));
let json = json!({
"page_content": "admin/login",
- "version": VERSION,
"error": msg,
"redirect": redirect,
"urlpath": CONFIG.domain_path()
@@ -208,34 +207,16 @@ fn _validate_token(token: &str) -> bool {
#[derive(Serialize)]
struct AdminTemplateData {
page_content: String,
- version: Option<&'static str>,
page_data: Option<Value>,
- config: Value,
- can_backup: bool,
logged_in: bool,
urlpath: String,
}
impl AdminTemplateData {
- fn new() -> Self {
- Self {
- page_content: String::from("admin/settings"),
- version: VERSION,
- config: CONFIG.prepare_json(),
- can_backup: *CAN_BACKUP,
- logged_in: true,
- urlpath: CONFIG.domain_path(),
- page_data: None,
- }
- }
-
- fn with_data(page_content: &str, page_data: Value) -> Self {
+ fn new(page_content: &str, page_data: Value) -> Self {
Self {
page_content: String::from(page_content),
- version: VERSION,
page_data: Some(page_data),
- config: CONFIG.prepare_json(),
- can_backup: *CAN_BACKUP,
logged_in: true,
urlpath: CONFIG.domain_path(),
}
@@ -247,7 +228,11 @@ impl AdminTemplateData {
}
fn render_admin_page() -> ApiResult<Html<String>> {
- let text = AdminTemplateData::new().render()?;
+ let settings_json = json!({
+ "config": CONFIG.prepare_json(),
+ "can_backup": *CAN_BACKUP,
+ });
+ let text = AdminTemplateData::new("admin/settings", settings_json).render()?;
Ok(Html(text))
}
@@ -342,7 +327,7 @@ async fn users_overview(_token: AdminToken, mut conn: DbConn) -> ApiResult<Html<
users_json.push(usr);
}
- let text = AdminTemplateData::with_data("admin/users", json!(users_json)).render()?;
+ let text = AdminTemplateData::new("admin/users", json!(users_json)).render()?;
Ok(Html(text))
}
@@ -442,7 +427,7 @@ async fn update_user_org_type(
};
if user_to_edit.atype == UserOrgType::Owner && new_type != UserOrgType::Owner {
- // Removing owner permmission, check that there is at least one other confirmed owner
+ // Removing owner permission, check that there is at least one other confirmed owner
if UserOrganization::count_confirmed_by_org_and_type(&data.org_uuid, UserOrgType::Owner, &mut conn).await <= 1 {
err!("Can't change the type of the last owner")
}
@@ -494,7 +479,7 @@ async fn organizations_overview(_token: AdminToken, mut conn: DbConn) -> ApiResu
organizations_json.push(org);
}
- let text = AdminTemplateData::with_data("admin/organizations", json!(organizations_json)).render()?;
+ let text = AdminTemplateData::new("admin/organizations", json!(organizations_json)).render()?;
Ok(Html(text))
}
@@ -617,13 +602,14 @@ async fn diagnostics(_token: AdminToken, ip_header: IpHeader, mut conn: DbConn)
let diagnostics_json = json!({
"dns_resolved": dns_resolved,
+ "current_release": VERSION,
"latest_release": latest_release,
"latest_commit": latest_commit,
"web_vault_enabled": &CONFIG.web_vault_enabled(),
"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(),
+ "docker_base_image": if running_within_docker { docker_base_image() } else { "Not applicable" },
"has_http_access": has_http_access,
"ip_header_exists": &ip_header.0.is_some(),
"ip_header_match": ip_header_name == CONFIG.ip_header(),
@@ -634,11 +620,13 @@ async fn diagnostics(_token: AdminToken, ip_header: IpHeader, mut conn: DbConn)
"db_version": get_sql_server_version(&mut conn).await,
"admin_url": format!("{}/diagnostics", admin_url()),
"overrides": &CONFIG.get_overrides().join(", "),
+ "host_arch": std::env::consts::ARCH,
+ "host_os": std::env::consts::OS,
"server_time_local": Local::now().format("%Y-%m-%d %H:%M:%S %Z").to_string(),
"server_time": Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string(), // Run the date/time check as the last item to minimize the difference
});
- let text = AdminTemplateData::with_data("admin/diagnostics", diagnostics_json).render()?;
+ let text = AdminTemplateData::new("admin/diagnostics", diagnostics_json).render()?;
Ok(Html(text))
}
diff --git a/src/api/web.rs b/src/api/web.rs
index 3742a088..b8d1bb51 100644
--- a/src/api/web.rs
+++ b/src/api/web.rs
@@ -102,6 +102,17 @@ pub fn static_files(filename: String) -> Result<(ContentType, &'static [u8]), Er
"hibp.png" => Ok((ContentType::PNG, include_bytes!("../static/images/hibp.png"))),
"vaultwarden-icon.png" => Ok((ContentType::PNG, include_bytes!("../static/images/vaultwarden-icon.png"))),
"vaultwarden-favicon.png" => Ok((ContentType::PNG, include_bytes!("../static/images/vaultwarden-favicon.png"))),
+ "404.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/404.css"))),
+ "admin.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/admin.css"))),
+ "admin.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/admin.js"))),
+ "admin_settings.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/admin_settings.js"))),
+ "admin_users.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/admin_users.js"))),
+ "admin_organizations.js" => {
+ Ok((ContentType::JavaScript, include_bytes!("../static/scripts/admin_organizations.js")))
+ }
+ "admin_diagnostics.js" => {
+ Ok((ContentType::JavaScript, include_bytes!("../static/scripts/admin_diagnostics.js")))
+ }
"bootstrap.css" => Ok((ContentType::CSS, include_bytes!("../static/scripts/bootstrap.css"))),
"bootstrap-native.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/bootstrap-native.js"))),
"jdenticon.js" => Ok((ContentType::JavaScript, include_bytes!("../static/scripts/jdenticon.js"))),