Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-21 05:00:28 +01:00
Actually use Device Type for mails (#4916)
- match Bitwarden behaviour - add a different segment in mails for Device Name
Dieser Commit ist enthalten in:
Ursprung
1031c2e286
Commit
21efc0800d
17 geänderte Dateien mit 57 neuen und 21 gelöschten Zeilen
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` DROP COLUMN `device_type`;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` ADD COLUMN `device_type` INTEGER NOT NULL;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` DROP COLUMN `device_type`;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` ADD COLUMN `device_type` INTEGER NOT NULL;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` DROP COLUMN `device_type`;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `twofactor_incomplete` ADD COLUMN `device_type` INTEGER NOT NULL;
|
|
@ -269,8 +269,14 @@ pub async fn send_incomplete_2fa_notifications(pool: DbPool) {
|
||||||
"User {} did not complete a 2FA login within the configured time limit. IP: {}",
|
"User {} did not complete a 2FA login within the configured time limit. IP: {}",
|
||||||
user.email, login.ip_address
|
user.email, login.ip_address
|
||||||
);
|
);
|
||||||
match mail::send_incomplete_2fa_login(&user.email, &login.ip_address, &login.login_time, &login.device_name)
|
match mail::send_incomplete_2fa_login(
|
||||||
.await
|
&user.email,
|
||||||
|
&login.ip_address,
|
||||||
|
&login.login_time,
|
||||||
|
&login.device_name,
|
||||||
|
&DeviceType::from_i32(login.device_type).to_string(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if let Err(e) = login.delete(&mut conn).await {
|
if let Err(e) = login.delete(&mut conn).await {
|
||||||
|
|
|
@ -265,7 +265,7 @@ async fn _password_login(
|
||||||
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, conn).await?;
|
let twofactor_token = twofactor_auth(&user, &data, &mut device, ip, conn).await?;
|
||||||
|
|
||||||
if CONFIG.mail_enabled() && new_device {
|
if CONFIG.mail_enabled() && new_device {
|
||||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name).await {
|
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device).await {
|
||||||
error!("Error sending new device email: {:#?}", e);
|
error!("Error sending new device email: {:#?}", e);
|
||||||
|
|
||||||
if CONFIG.require_device_email() {
|
if CONFIG.require_device_email() {
|
||||||
|
@ -421,7 +421,7 @@ async fn _user_api_key_login(
|
||||||
|
|
||||||
if CONFIG.mail_enabled() && new_device {
|
if CONFIG.mail_enabled() && new_device {
|
||||||
let now = Utc::now().naive_utc();
|
let now = Utc::now().naive_utc();
|
||||||
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device.name).await {
|
if let Err(e) = mail::send_new_device_logged_in(&user.email, &ip.ip.to_string(), &now, &device).await {
|
||||||
error!("Error sending new device email: {:#?}", e);
|
error!("Error sending new device email: {:#?}", e);
|
||||||
|
|
||||||
if CONFIG.require_device_email() {
|
if CONFIG.require_device_email() {
|
||||||
|
@ -535,7 +535,7 @@ async fn twofactor_auth(
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
TwoFactorIncomplete::mark_incomplete(&user.uuid, &device.uuid, &device.name, ip, conn).await?;
|
TwoFactorIncomplete::mark_incomplete(&user.uuid, &device.uuid, &device.name, device.atype, ip, conn).await?;
|
||||||
|
|
||||||
let twofactor_ids: Vec<_> = twofactors.iter().map(|tf| tf.atype).collect();
|
let twofactor_ids: Vec<_> = twofactors.iter().map(|tf| tf.atype).collect();
|
||||||
let selected_id = data.two_factor_provider.unwrap_or(twofactor_ids[0]); // If we aren't given a two factor provider, assume the first one
|
let selected_id = data.two_factor_provider.unwrap_or(twofactor_ids[0]); // If we aren't given a two factor provider, assume the first one
|
||||||
|
|
|
@ -13,6 +13,7 @@ db_object! {
|
||||||
// must complete 2FA login before being added into the devices table.
|
// must complete 2FA login before being added into the devices table.
|
||||||
pub device_uuid: String,
|
pub device_uuid: String,
|
||||||
pub device_name: String,
|
pub device_name: String,
|
||||||
|
pub device_type: i32,
|
||||||
pub login_time: NaiveDateTime,
|
pub login_time: NaiveDateTime,
|
||||||
pub ip_address: String,
|
pub ip_address: String,
|
||||||
}
|
}
|
||||||
|
@ -23,6 +24,7 @@ impl TwoFactorIncomplete {
|
||||||
user_uuid: &str,
|
user_uuid: &str,
|
||||||
device_uuid: &str,
|
device_uuid: &str,
|
||||||
device_name: &str,
|
device_name: &str,
|
||||||
|
device_type: i32,
|
||||||
ip: &ClientIp,
|
ip: &ClientIp,
|
||||||
conn: &mut DbConn,
|
conn: &mut DbConn,
|
||||||
) -> EmptyResult {
|
) -> EmptyResult {
|
||||||
|
@ -44,6 +46,7 @@ impl TwoFactorIncomplete {
|
||||||
twofactor_incomplete::user_uuid.eq(user_uuid),
|
twofactor_incomplete::user_uuid.eq(user_uuid),
|
||||||
twofactor_incomplete::device_uuid.eq(device_uuid),
|
twofactor_incomplete::device_uuid.eq(device_uuid),
|
||||||
twofactor_incomplete::device_name.eq(device_name),
|
twofactor_incomplete::device_name.eq(device_name),
|
||||||
|
twofactor_incomplete::device_type.eq(device_type),
|
||||||
twofactor_incomplete::login_time.eq(Utc::now().naive_utc()),
|
twofactor_incomplete::login_time.eq(Utc::now().naive_utc()),
|
||||||
twofactor_incomplete::ip_address.eq(ip.ip.to_string()),
|
twofactor_incomplete::ip_address.eq(ip.ip.to_string()),
|
||||||
))
|
))
|
||||||
|
|
|
@ -169,6 +169,7 @@ table! {
|
||||||
user_uuid -> Text,
|
user_uuid -> Text,
|
||||||
device_uuid -> Text,
|
device_uuid -> Text,
|
||||||
device_name -> Text,
|
device_name -> Text,
|
||||||
|
device_type -> Integer,
|
||||||
login_time -> Timestamp,
|
login_time -> Timestamp,
|
||||||
ip_address -> Text,
|
ip_address -> Text,
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ table! {
|
||||||
user_uuid -> Text,
|
user_uuid -> Text,
|
||||||
device_uuid -> Text,
|
device_uuid -> Text,
|
||||||
device_name -> Text,
|
device_name -> Text,
|
||||||
|
device_type -> Integer,
|
||||||
login_time -> Timestamp,
|
login_time -> Timestamp,
|
||||||
ip_address -> Text,
|
ip_address -> Text,
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ table! {
|
||||||
user_uuid -> Text,
|
user_uuid -> Text,
|
||||||
device_uuid -> Text,
|
device_uuid -> Text,
|
||||||
device_name -> Text,
|
device_name -> Text,
|
||||||
|
device_type -> Integer,
|
||||||
login_time -> Timestamp,
|
login_time -> Timestamp,
|
||||||
ip_address -> Text,
|
ip_address -> Text,
|
||||||
}
|
}
|
||||||
|
|
20
src/mail.rs
20
src/mail.rs
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
encode_jwt, generate_delete_claims, generate_emergency_access_invite_claims, generate_invite_claims,
|
encode_jwt, generate_delete_claims, generate_emergency_access_invite_claims, generate_invite_claims,
|
||||||
generate_verify_email_claims,
|
generate_verify_email_claims,
|
||||||
},
|
},
|
||||||
db::models::User,
|
db::models::{Device, DeviceType, User},
|
||||||
error::Error,
|
error::Error,
|
||||||
CONFIG,
|
CONFIG,
|
||||||
};
|
};
|
||||||
|
@ -442,9 +442,8 @@ pub async fn send_invite_confirmed(address: &str, org_name: &str) -> EmptyResult
|
||||||
send_email(address, &subject, body_html, body_text).await
|
send_email(address, &subject, body_html, body_text).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult {
|
pub async fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTime, device: &Device) -> EmptyResult {
|
||||||
use crate::util::upcase_first;
|
use crate::util::upcase_first;
|
||||||
let device = upcase_first(device);
|
|
||||||
|
|
||||||
let fmt = "%A, %B %_d, %Y at %r %Z";
|
let fmt = "%A, %B %_d, %Y at %r %Z";
|
||||||
let (subject, body_html, body_text) = get_text(
|
let (subject, body_html, body_text) = get_text(
|
||||||
|
@ -453,7 +452,8 @@ pub async fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTi
|
||||||
"url": CONFIG.domain(),
|
"url": CONFIG.domain(),
|
||||||
"img_src": CONFIG._smtp_img_src(),
|
"img_src": CONFIG._smtp_img_src(),
|
||||||
"ip": ip,
|
"ip": ip,
|
||||||
"device": device,
|
"device_name": upcase_first(&device.name),
|
||||||
|
"device_type": DeviceType::from_i32(device.atype).to_string(),
|
||||||
"datetime": crate::util::format_naive_datetime_local(dt, fmt),
|
"datetime": crate::util::format_naive_datetime_local(dt, fmt),
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
|
@ -461,9 +461,14 @@ pub async fn send_new_device_logged_in(address: &str, ip: &str, dt: &NaiveDateTi
|
||||||
send_email(address, &subject, body_html, body_text).await
|
send_email(address, &subject, body_html, body_text).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_incomplete_2fa_login(address: &str, ip: &str, dt: &NaiveDateTime, device: &str) -> EmptyResult {
|
pub async fn send_incomplete_2fa_login(
|
||||||
|
address: &str,
|
||||||
|
ip: &str,
|
||||||
|
dt: &NaiveDateTime,
|
||||||
|
device_name: &str,
|
||||||
|
device_type: &str,
|
||||||
|
) -> EmptyResult {
|
||||||
use crate::util::upcase_first;
|
use crate::util::upcase_first;
|
||||||
let device = upcase_first(device);
|
|
||||||
|
|
||||||
let fmt = "%A, %B %_d, %Y at %r %Z";
|
let fmt = "%A, %B %_d, %Y at %r %Z";
|
||||||
let (subject, body_html, body_text) = get_text(
|
let (subject, body_html, body_text) = get_text(
|
||||||
|
@ -472,7 +477,8 @@ pub async fn send_incomplete_2fa_login(address: &str, ip: &str, dt: &NaiveDateTi
|
||||||
"url": CONFIG.domain(),
|
"url": CONFIG.domain(),
|
||||||
"img_src": CONFIG._smtp_img_src(),
|
"img_src": CONFIG._smtp_img_src(),
|
||||||
"ip": ip,
|
"ip": ip,
|
||||||
"device": device,
|
"device_name": upcase_first(device_name),
|
||||||
|
"device_type": device_type,
|
||||||
"datetime": crate::util::format_naive_datetime_local(dt, fmt),
|
"datetime": crate::util::format_naive_datetime_local(dt, fmt),
|
||||||
"time_limit": CONFIG.incomplete_2fa_time_limit(),
|
"time_limit": CONFIG.incomplete_2fa_time_limit(),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
Incomplete Two-Step Login From {{{device}}}
|
Incomplete Two-Step Login From {{{device_name}}}
|
||||||
<!---------------->
|
<!---------------->
|
||||||
Someone attempted to log into your account with the correct master password, but did not provide the correct token or action required to complete the two-step login process within {{time_limit}} minutes of the initial login attempt.
|
Someone attempted to log into your account with the correct master password, but did not provide the correct token or action required to complete the two-step login process within {{time_limit}} minutes of the initial login attempt.
|
||||||
|
|
||||||
* Date: {{datetime}}
|
* Date: {{datetime}}
|
||||||
* IP Address: {{ip}}
|
* IP Address: {{ip}}
|
||||||
* Device Type: {{device}}
|
* Device Name: {{device_name}}
|
||||||
|
* Device Type: {{device_type}}
|
||||||
|
|
||||||
If this was not you or someone you authorized, then you should change your master password as soon as possible, as it is likely to be compromised.
|
If this was not you or someone you authorized, then you should change your master password as soon as possible, as it is likely to be compromised.
|
||||||
{{> email/email_footer_text }}
|
{{> email/email_footer_text }}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Incomplete Two-Step Login From {{{device}}}
|
Incomplete Two-Step Login From {{{device_name}}}
|
||||||
<!---------------->
|
<!---------------->
|
||||||
{{> email/email_header }}
|
{{> email/email_header }}
|
||||||
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
@ -19,7 +19,12 @@ Incomplete Two-Step Login From {{{device}}}
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||||
<b>Device Type:</b> {{device}}
|
<b>Device Name:</b> {{device_name}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||||
|
<b>Device Type:</b> {{device_type}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
New Device Logged In From {{{device}}}
|
New Device Logged In From {{{device_name}}}
|
||||||
<!---------------->
|
<!---------------->
|
||||||
Your account was just logged into from a new device.
|
Your account was just logged into from a new device.
|
||||||
|
|
||||||
* Date: {{datetime}}
|
* Date: {{datetime}}
|
||||||
* IP Address: {{ip}}
|
* IP Address: {{ip}}
|
||||||
* Device Type: {{device}}
|
* Device Name: {{device_name}}
|
||||||
|
* Device Type: {{device_type}}
|
||||||
|
|
||||||
You can deauthorize all devices that have access to your account from the web vault ( {{url}} ) under Settings > My Account > Deauthorize Sessions.
|
You can deauthorize all devices that have access to your account from the web vault ( {{url}} ) under Settings > My Account > Deauthorize Sessions.
|
||||||
{{> email/email_footer_text }}
|
{{> email/email_footer_text }}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
New Device Logged In From {{{device}}}
|
New Device Logged In From {{{device_name}}}
|
||||||
<!---------------->
|
<!---------------->
|
||||||
{{> email/email_header }}
|
{{> email/email_header }}
|
||||||
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<table width="100%" cellpadding="0" cellspacing="0" style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
@ -19,7 +19,12 @@ New Device Logged In From {{{device}}}
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||||
<b>Device Type:</b> {{device}}
|
<b>Device Name:</b> {{device_name}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
|
||||||
|
<b>Device Type:</b> {{device_type}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
|
||||||
|
|
Laden …
In neuem Issue referenzieren