Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-06 02:38:00 +01:00
f4a9645b54
Squashed commit of the following: commit 1bdf1c7954e0731c95703d10118f3874ab5155d3 Merge:8ba6e61
7257251
Author: Daniel García <dani-garcia@users.noreply.github.com> Date: Sun Jan 23 23:40:17 2022 +0100 Merge branch 'remove-bwrs' of https://github.com/RealOrangeOne/vaultwarden into RealOrangeOne-remove-bwrs commit7257251ecf
Author: Jake Howard <git@theorangeone.net> Date: Thu Jan 6 17:48:18 2022 +0000 Use `or_else` to save potentially unnecessary function call commit40ae81dd3c
Author: Jake Howard <git@theorangeone.net> Date: Wed Jan 5 21:18:24 2022 +0000 Move $BWRS_VERSION fallback into build.rs commit743ef74b30
Author: Jake Howard <git@theorangeone.net> Date: Sat Jan 1 23:08:27 2022 +0000 Revert "Add feature to enable use of `Option::or` in const context" This reverts commitfe8e043b8a
. We want to run on stable soon, where these features are not supported commita1f0da638c
Author: Jake Howard <git@theorangeone.net> Date: Sat Jan 1 13:04:47 2022 +0000 Rename web vault version file https://github.com/dani-garcia/bw_web_builds/pull/58 commitfe8e043b8a
Author: Jake Howard <git@theorangeone.net> Date: Sat Jan 1 12:56:44 2022 +0000 Add feature to enable use of `Option::or` in const context commit687435c8b2
Author: Jake Howard <git@theorangeone.net> Date: Sat Jan 1 12:27:28 2022 +0000 Continue to allow using `$BWRS_VERSION` commit8e2f708e50
Author: Jake Howard <git@theorangeone.net> Date: Fri Dec 31 11:41:34 2021 +0000 Remove references to "bwrs" The only remaining one is getting the version of the web vault, which requires coordinating with the web vault patching.
180 Zeilen
5,8 KiB
Rust
180 Zeilen
5,8 KiB
Rust
mod accounts;
|
|
mod ciphers;
|
|
mod emergency_access;
|
|
mod folders;
|
|
mod organizations;
|
|
mod sends;
|
|
pub mod two_factor;
|
|
|
|
pub use ciphers::purge_trashed_ciphers;
|
|
pub use emergency_access::{emergency_notification_reminder_job, emergency_request_timeout_job};
|
|
pub use sends::purge_sends;
|
|
pub use two_factor::send_incomplete_2fa_notifications;
|
|
|
|
pub fn routes() -> Vec<Route> {
|
|
let mut mod_routes =
|
|
routes![clear_device_token, put_device_token, get_eq_domains, post_eq_domains, put_eq_domains, hibp_breach,];
|
|
|
|
let mut routes = Vec::new();
|
|
routes.append(&mut accounts::routes());
|
|
routes.append(&mut ciphers::routes());
|
|
routes.append(&mut emergency_access::routes());
|
|
routes.append(&mut folders::routes());
|
|
routes.append(&mut organizations::routes());
|
|
routes.append(&mut two_factor::routes());
|
|
routes.append(&mut sends::routes());
|
|
routes.append(&mut mod_routes);
|
|
|
|
routes
|
|
}
|
|
|
|
//
|
|
// Move this somewhere else
|
|
//
|
|
use rocket::Route;
|
|
use rocket_contrib::json::Json;
|
|
use serde_json::Value;
|
|
|
|
use crate::{
|
|
api::{JsonResult, JsonUpcase},
|
|
auth::Headers,
|
|
db::DbConn,
|
|
error::Error,
|
|
util::get_reqwest_client,
|
|
};
|
|
|
|
#[put("/devices/identifier/<uuid>/clear-token")]
|
|
fn clear_device_token(uuid: String) -> &'static str {
|
|
// This endpoint doesn't have auth header
|
|
|
|
let _ = uuid;
|
|
// uuid is not related to deviceId
|
|
|
|
// This only clears push token
|
|
// https://github.com/bitwarden/core/blob/master/src/Api/Controllers/DevicesController.cs#L109
|
|
// https://github.com/bitwarden/core/blob/master/src/Core/Services/Implementations/DeviceService.cs#L37
|
|
""
|
|
}
|
|
|
|
#[put("/devices/identifier/<uuid>/token", data = "<data>")]
|
|
fn put_device_token(uuid: String, data: JsonUpcase<Value>, headers: Headers) -> Json<Value> {
|
|
let _data: Value = data.into_inner().data;
|
|
// Data has a single string value "PushToken"
|
|
let _ = uuid;
|
|
// uuid is not related to deviceId
|
|
|
|
// TODO: This should save the push token, but we don't have push functionality
|
|
|
|
Json(json!({
|
|
"Id": headers.device.uuid,
|
|
"Name": headers.device.name,
|
|
"Type": headers.device.atype,
|
|
"Identifier": headers.device.uuid,
|
|
"CreationDate": crate::util::format_date(&headers.device.created_at),
|
|
}))
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
#[allow(non_snake_case)]
|
|
struct GlobalDomain {
|
|
Type: i32,
|
|
Domains: Vec<String>,
|
|
Excluded: bool,
|
|
}
|
|
|
|
const GLOBAL_DOMAINS: &str = include_str!("../../static/global_domains.json");
|
|
|
|
#[get("/settings/domains")]
|
|
fn get_eq_domains(headers: Headers) -> Json<Value> {
|
|
_get_eq_domains(headers, false)
|
|
}
|
|
|
|
fn _get_eq_domains(headers: Headers, no_excluded: bool) -> Json<Value> {
|
|
let user = headers.user;
|
|
use serde_json::from_str;
|
|
|
|
let equivalent_domains: Vec<Vec<String>> = from_str(&user.equivalent_domains).unwrap();
|
|
let excluded_globals: Vec<i32> = from_str(&user.excluded_globals).unwrap();
|
|
|
|
let mut globals: Vec<GlobalDomain> = from_str(GLOBAL_DOMAINS).unwrap();
|
|
|
|
for global in &mut globals {
|
|
global.Excluded = excluded_globals.contains(&global.Type);
|
|
}
|
|
|
|
if no_excluded {
|
|
globals.retain(|g| !g.Excluded);
|
|
}
|
|
|
|
Json(json!({
|
|
"EquivalentDomains": equivalent_domains,
|
|
"GlobalEquivalentDomains": globals,
|
|
"Object": "domains",
|
|
}))
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
#[allow(non_snake_case)]
|
|
struct EquivDomainData {
|
|
ExcludedGlobalEquivalentDomains: Option<Vec<i32>>,
|
|
EquivalentDomains: Option<Vec<Vec<String>>>,
|
|
}
|
|
|
|
#[post("/settings/domains", data = "<data>")]
|
|
fn post_eq_domains(data: JsonUpcase<EquivDomainData>, headers: Headers, conn: DbConn) -> JsonResult {
|
|
let data: EquivDomainData = data.into_inner().data;
|
|
|
|
let excluded_globals = data.ExcludedGlobalEquivalentDomains.unwrap_or_default();
|
|
let equivalent_domains = data.EquivalentDomains.unwrap_or_default();
|
|
|
|
let mut user = headers.user;
|
|
use serde_json::to_string;
|
|
|
|
user.excluded_globals = to_string(&excluded_globals).unwrap_or_else(|_| "[]".to_string());
|
|
user.equivalent_domains = to_string(&equivalent_domains).unwrap_or_else(|_| "[]".to_string());
|
|
|
|
user.save(&conn)?;
|
|
|
|
Ok(Json(json!({})))
|
|
}
|
|
|
|
#[put("/settings/domains", data = "<data>")]
|
|
fn put_eq_domains(data: JsonUpcase<EquivDomainData>, headers: Headers, conn: DbConn) -> JsonResult {
|
|
post_eq_domains(data, headers, conn)
|
|
}
|
|
|
|
#[get("/hibp/breach?<username>")]
|
|
fn hibp_breach(username: String) -> JsonResult {
|
|
let url = format!(
|
|
"https://haveibeenpwned.com/api/v3/breachedaccount/{}?truncateResponse=false&includeUnverified=false",
|
|
username
|
|
);
|
|
|
|
if let Some(api_key) = crate::CONFIG.hibp_api_key() {
|
|
let hibp_client = get_reqwest_client();
|
|
|
|
let res = hibp_client.get(&url).header("hibp-api-key", api_key).send()?;
|
|
|
|
// If we get a 404, return a 404, it means no breached accounts
|
|
if res.status() == 404 {
|
|
return Err(Error::empty().with_code(404));
|
|
}
|
|
|
|
let value: Value = res.error_for_status()?.json()?;
|
|
Ok(Json(value))
|
|
} else {
|
|
Ok(Json(json!([{
|
|
"Name": "HaveIBeenPwned",
|
|
"Title": "Manual HIBP Check",
|
|
"Domain": "haveibeenpwned.com",
|
|
"BreachDate": "2019-08-18T00:00:00Z",
|
|
"AddedDate": "2019-08-18T00:00:00Z",
|
|
"Description": format!("Go to: <a href=\"https://haveibeenpwned.com/account/{account}\" target=\"_blank\" rel=\"noreferrer\">https://haveibeenpwned.com/account/{account}</a> for a manual check.<br/><br/>HaveIBeenPwned API key not set!<br/>Go to <a href=\"https://haveibeenpwned.com/API/Key\" target=\"_blank\" rel=\"noreferrer\">https://haveibeenpwned.com/API/Key</a> to purchase an API key from HaveIBeenPwned.<br/><br/>", account=username),
|
|
"LogoPath": "vw_static/hibp.png",
|
|
"PwnCount": 0,
|
|
"DataClasses": [
|
|
"Error - No API key set!"
|
|
]
|
|
}])))
|
|
}
|
|
}
|