diff --git a/crates/tranquil-api/src/notification_prefs.rs b/crates/tranquil-api/src/notification_prefs.rs index dec6d39..d7cc7a8 100644 --- a/crates/tranquil-api/src/notification_prefs.rs +++ b/crates/tranquil-api/src/notification_prefs.rs @@ -19,6 +19,7 @@ pub struct NotificationPrefsOutput { pub telegram_verified: bool, pub signal_username: Option, pub signal_verified: bool, + pub legacy_login_alerts: bool, } pub async fn get_notification_prefs( @@ -32,6 +33,26 @@ pub async fn get_notification_prefs( .await .log_db_err("get notification prefs")? .ok_or(ApiError::AccountNotFound)?; + + let user_id = state + .repos + .user + .get_id_by_did(&auth.did) + .await + .log_db_err("get user by did")? + .ok_or(ApiError::AccountNotFound)?; + + let legacy_login_alerts = state + .repos + .infra + .get_account_preferences(user_id) + .await + .log_db_err("get legacy login alert prefs")? + .iter() + .find(|(name, _)| name == "legacy_login_alerts") + .and_then(|(_, value)| value.as_bool()) + .unwrap_or(true); + Ok(Json(NotificationPrefsOutput { preferred_channel: prefs.preferred_channel, email: prefs.email, @@ -41,6 +62,7 @@ pub async fn get_notification_prefs( telegram_verified: prefs.telegram_verified, signal_username: prefs.signal_username, signal_verified: prefs.signal_verified, + legacy_login_alerts, })) } @@ -121,6 +143,7 @@ pub struct UpdateNotificationPrefsInput { pub discord_username: Option, pub telegram_username: Option, pub signal_username: Option, + pub legacy_login_alerts: Option, } #[derive(Serialize)] @@ -435,6 +458,15 @@ pub async fn update_notification_prefs( .await?; } + if let Some(alerts) = input.legacy_login_alerts { + state + .repos + .infra + .upsert_account_preference(user_id, "legacy_login_alerts", json!(alerts)) + .await + .log_db_err("update legacy login alert prefs")?; + } + Ok(Json(UpdateNotificationPrefsOutput { success: true, verification_required, diff --git a/crates/tranquil-api/src/server/session.rs b/crates/tranquil-api/src/server/session.rs index 4cc2d40..5074cef 100644 --- a/crates/tranquil-api/src/server/session.rs +++ b/crates/tranquil-api/src/server/session.rs @@ -323,15 +323,31 @@ pub async fn create_session( "Legacy login on TOTP-enabled account - sending notification" ); let hostname = &tranquil_config::get().server.hostname; - if let Err(e) = tranquil_pds::comms::comms_repo::enqueue_legacy_login( - state.repos.user.as_ref(), - state.repos.infra.as_ref(), - row.id, - hostname, - client_ip, - row.preferred_comms_channel, - ) - .await + + let alerts_enabled = state + .repos + .infra + .get_account_preferences(row.id) + .await + .map(|prefs| { + prefs + .iter() + .find(|(name, _)| name == "legacy_login_alerts") + .and_then(|(_, value)| value.as_bool()) + .unwrap_or(true) + }) + .unwrap_or(true); + + if alerts_enabled + && let Err(e) = tranquil_pds::comms::comms_repo::enqueue_legacy_login( + state.repos.user.as_ref(), + state.repos.infra.as_ref(), + row.id, + hostname, + client_ip, + row.preferred_comms_channel, + ) + .await { error!("Failed to queue legacy login notification: {:?}", e); } diff --git a/frontend/src/components/dashboard/CommsContent.svelte b/frontend/src/components/dashboard/CommsContent.svelte index f287364..95d11a4 100644 --- a/frontend/src/components/dashboard/CommsContent.svelte +++ b/frontend/src/components/dashboard/CommsContent.svelte @@ -30,6 +30,7 @@ let savedDiscordUsername = $state('') let savedTelegramUsername = $state('') let savedSignalUsername = $state('') + let legacyLoginAlerts = $state(true) let verifyingChannel = $state(null) let verificationCode = $state('') let historyLoading = $state(true) @@ -62,6 +63,7 @@ telegramVerified = prefs.telegramVerified signalUsername = prefs.signalUsername ?? '' signalVerified = prefs.signalVerified + legacyLoginAlerts = prefs.legacyLoginAlerts ?? true savedDiscordUsername = discordUsername savedTelegramUsername = telegramUsername savedSignalUsername = signalUsername @@ -85,6 +87,7 @@ discordUsername: discordUsername !== savedDiscordUsername ? discordUsername : undefined, telegramUsername: telegramUsername !== savedTelegramUsername ? telegramUsername : undefined, signalUsername: signalUsername !== savedSignalUsername ? signalUsername : undefined, + legacyLoginAlerts, }) await refreshSession() toast.success($_('comms.preferencesSaved')) @@ -316,6 +319,25 @@ +
+

{$_('comms.securityAlerts')}

+
+
+ {$_('comms.legacyLoginAlerts')} + {$_('comms.legacyLoginAlertsDescription')} +
+ +
+
+