Fix Login with device (#4878)

Fixed an issue with login with device for the new Bitwrden Beta clients.
They seem to not support ISO8601 milli date/time, only micro.

Also updated the device display names to match Upstream and added the
CLI devices which were missing.

Signed-off-by: BlackDex <black.dex@gmail.com>
This commit is contained in:
Mathijs van Veluw 2024-08-21 21:57:52 +02:00 committed by GitHub
parent aaab7f9640
commit c722006385
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 21 deletions

View file

@ -1,5 +1,5 @@
use crate::db::DbPool; use crate::db::DbPool;
use chrono::Utc; use chrono::{SecondsFormat, Utc};
use rocket::serde::json::Json; use rocket::serde::json::Json;
use serde_json::Value; use serde_json::Value;
@ -1123,7 +1123,7 @@ async fn post_auth_request(
"requestIpAddress": auth_request.request_ip, "requestIpAddress": auth_request.request_ip,
"key": null, "key": null,
"masterPasswordHash": null, "masterPasswordHash": null,
"creationDate": auth_request.creation_date.and_utc(), "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
"responseDate": null, "responseDate": null,
"requestApproved": false, "requestApproved": false,
"origin": CONFIG.domain_origin(), "origin": CONFIG.domain_origin(),
@ -1140,7 +1140,9 @@ async fn get_auth_request(uuid: &str, mut conn: DbConn) -> JsonResult {
} }
}; };
let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); let response_date_utc = auth_request
.response_date
.map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
Ok(Json(json!( Ok(Json(json!(
{ {
@ -1150,7 +1152,7 @@ async fn get_auth_request(uuid: &str, mut conn: DbConn) -> JsonResult {
"requestIpAddress": auth_request.request_ip, "requestIpAddress": auth_request.request_ip,
"key": auth_request.enc_key, "key": auth_request.enc_key,
"masterPasswordHash": auth_request.master_password_hash, "masterPasswordHash": auth_request.master_password_hash,
"creationDate": auth_request.creation_date.and_utc(), "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
"responseDate": response_date_utc, "responseDate": response_date_utc,
"requestApproved": auth_request.approved, "requestApproved": auth_request.approved,
"origin": CONFIG.domain_origin(), "origin": CONFIG.domain_origin(),
@ -1195,7 +1197,9 @@ async fn put_auth_request(
nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, data.device_identifier, &mut conn).await; nt.send_auth_response(&auth_request.user_uuid, &auth_request.uuid, data.device_identifier, &mut conn).await;
} }
let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); let response_date_utc = auth_request
.response_date
.map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
Ok(Json(json!( Ok(Json(json!(
{ {
@ -1205,7 +1209,7 @@ async fn put_auth_request(
"requestIpAddress": auth_request.request_ip, "requestIpAddress": auth_request.request_ip,
"key": auth_request.enc_key, "key": auth_request.enc_key,
"masterPasswordHash": auth_request.master_password_hash, "masterPasswordHash": auth_request.master_password_hash,
"creationDate": auth_request.creation_date.and_utc(), "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
"responseDate": response_date_utc, "responseDate": response_date_utc,
"requestApproved": auth_request.approved, "requestApproved": auth_request.approved,
"origin": CONFIG.domain_origin(), "origin": CONFIG.domain_origin(),
@ -1227,7 +1231,9 @@ async fn get_auth_request_response(uuid: &str, code: &str, mut conn: DbConn) ->
err!("Access code invalid doesn't exist") err!("Access code invalid doesn't exist")
} }
let response_date_utc = auth_request.response_date.map(|response_date| response_date.and_utc()); let response_date_utc = auth_request
.response_date
.map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
Ok(Json(json!( Ok(Json(json!(
{ {
@ -1237,7 +1243,7 @@ async fn get_auth_request_response(uuid: &str, code: &str, mut conn: DbConn) ->
"requestIpAddress": auth_request.request_ip, "requestIpAddress": auth_request.request_ip,
"key": auth_request.enc_key, "key": auth_request.enc_key,
"masterPasswordHash": auth_request.master_password_hash, "masterPasswordHash": auth_request.master_password_hash,
"creationDate": auth_request.creation_date.and_utc(), "creationDate": auth_request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
"responseDate": response_date_utc, "responseDate": response_date_utc,
"requestApproved": auth_request.approved, "requestApproved": auth_request.approved,
"origin": CONFIG.domain_origin(), "origin": CONFIG.domain_origin(),
@ -1255,7 +1261,7 @@ async fn get_auth_requests(headers: Headers, mut conn: DbConn) -> JsonResult {
.iter() .iter()
.filter(|request| request.approved.is_none()) .filter(|request| request.approved.is_none())
.map(|request| { .map(|request| {
let response_date_utc = request.response_date.map(|response_date| response_date.and_utc()); let response_date_utc = request.response_date.map(|response_date| response_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true));
json!({ json!({
"id": request.uuid, "id": request.uuid,
@ -1264,7 +1270,7 @@ async fn get_auth_requests(headers: Headers, mut conn: DbConn) -> JsonResult {
"requestIpAddress": request.request_ip, "requestIpAddress": request.request_ip,
"key": request.enc_key, "key": request.enc_key,
"masterPasswordHash": request.master_password_hash, "masterPasswordHash": request.master_password_hash,
"creationDate": request.creation_date.and_utc(), "creationDate": request.creation_date.and_utc().to_rfc3339_opts(SecondsFormat::Micros, true),
"responseDate": response_date_utc, "responseDate": response_date_utc,
"requestApproved": request.approved, "requestApproved": request.approved,
"origin": CONFIG.domain_origin(), "origin": CONFIG.domain_origin(),

View file

@ -16,7 +16,7 @@ db_object! {
pub user_uuid: String, pub user_uuid: String,
pub name: String, pub name: String,
pub atype: i32, // https://github.com/bitwarden/server/blob/master/src/Core/Enums/DeviceType.cs pub atype: i32, // https://github.com/bitwarden/server/blob/dcc199bcce4aa2d5621f6fab80f1b49d8b143418/src/Core/Enums/DeviceType.cs
pub push_uuid: Option<String>, pub push_uuid: Option<String>,
pub push_token: Option<String>, pub push_token: Option<String>,
@ -267,6 +267,9 @@ pub enum DeviceType {
SafariExtension = 20, SafariExtension = 20,
Sdk = 21, Sdk = 21,
Server = 22, Server = 22,
WindowsCLI = 23,
MacOsCLI = 24,
LinuxCLI = 25,
} }
impl fmt::Display for DeviceType { impl fmt::Display for DeviceType {
@ -278,23 +281,26 @@ impl fmt::Display for DeviceType {
DeviceType::FirefoxExtension => write!(f, "Firefox Extension"), DeviceType::FirefoxExtension => write!(f, "Firefox Extension"),
DeviceType::OperaExtension => write!(f, "Opera Extension"), DeviceType::OperaExtension => write!(f, "Opera Extension"),
DeviceType::EdgeExtension => write!(f, "Edge Extension"), DeviceType::EdgeExtension => write!(f, "Edge Extension"),
DeviceType::WindowsDesktop => write!(f, "Windows Desktop"), DeviceType::WindowsDesktop => write!(f, "Windows"),
DeviceType::MacOsDesktop => write!(f, "MacOS Desktop"), DeviceType::MacOsDesktop => write!(f, "macOS"),
DeviceType::LinuxDesktop => write!(f, "Linux Desktop"), DeviceType::LinuxDesktop => write!(f, "Linux"),
DeviceType::ChromeBrowser => write!(f, "Chrome Browser"), DeviceType::ChromeBrowser => write!(f, "Chrome"),
DeviceType::FirefoxBrowser => write!(f, "Firefox Browser"), DeviceType::FirefoxBrowser => write!(f, "Firefox"),
DeviceType::OperaBrowser => write!(f, "Opera Browser"), DeviceType::OperaBrowser => write!(f, "Opera"),
DeviceType::EdgeBrowser => write!(f, "Edge Browser"), DeviceType::EdgeBrowser => write!(f, "Edge"),
DeviceType::IEBrowser => write!(f, "Internet Explorer"), DeviceType::IEBrowser => write!(f, "Internet Explorer"),
DeviceType::UnknownBrowser => write!(f, "Unknown Browser"), DeviceType::UnknownBrowser => write!(f, "Unknown Browser"),
DeviceType::AndroidAmazon => write!(f, "Android Amazon"), DeviceType::AndroidAmazon => write!(f, "Android"),
DeviceType::Uwp => write!(f, "UWP"), DeviceType::Uwp => write!(f, "UWP"),
DeviceType::SafariBrowser => write!(f, "Safari Browser"), DeviceType::SafariBrowser => write!(f, "Safari"),
DeviceType::VivaldiBrowser => write!(f, "Vivaldi Browser"), DeviceType::VivaldiBrowser => write!(f, "Vivaldi"),
DeviceType::VivaldiExtension => write!(f, "Vivaldi Extension"), DeviceType::VivaldiExtension => write!(f, "Vivaldi Extension"),
DeviceType::SafariExtension => write!(f, "Safari Extension"), DeviceType::SafariExtension => write!(f, "Safari Extension"),
DeviceType::Sdk => write!(f, "SDK"), DeviceType::Sdk => write!(f, "SDK"),
DeviceType::Server => write!(f, "Server"), DeviceType::Server => write!(f, "Server"),
DeviceType::WindowsCLI => write!(f, "Windows CLI"),
DeviceType::MacOsCLI => write!(f, "macOS CLI"),
DeviceType::LinuxCLI => write!(f, "Linux CLI"),
} }
} }
} }
@ -325,6 +331,9 @@ impl DeviceType {
20 => DeviceType::SafariExtension, 20 => DeviceType::SafariExtension,
21 => DeviceType::Sdk, 21 => DeviceType::Sdk,
22 => DeviceType::Server, 22 => DeviceType::Server,
23 => DeviceType::WindowsCLI,
24 => DeviceType::MacOsCLI,
25 => DeviceType::LinuxCLI,
_ => DeviceType::UnknownBrowser, _ => DeviceType::UnknownBrowser,
} }
} }