mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-09-21 09:44:14 +00:00
Make legacy login alerts configurable
This adds security alerts section to the communication settings, with one new item: a toggle for enabling/disabling legacy login alerts. It's enabled by default. Disabling it means that you no longer get emails when logging in through a non-2FA enabled login flow, like createSession. The reason I tackled this is that I have a bot account that automatically refreshes its session, using username and app password, and I'm close to having 100 of these emails in my inbox. I also tried to just disable TOTP but I wasn't allowed (I fixed that in a different PR). English and Swedish translations were me, the rest were MyMemory. I imagine someone can improve on them after this is merged!
This commit is contained in:
@@ -19,6 +19,7 @@ pub struct NotificationPrefsOutput {
|
||||
pub telegram_verified: bool,
|
||||
pub signal_username: Option<String>,
|
||||
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<String>,
|
||||
pub telegram_username: Option<String>,
|
||||
pub signal_username: Option<String>,
|
||||
pub legacy_login_alerts: Option<bool>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
let savedDiscordUsername = $state('')
|
||||
let savedTelegramUsername = $state('')
|
||||
let savedSignalUsername = $state('')
|
||||
let legacyLoginAlerts = $state(true)
|
||||
let verifyingChannel = $state<string | null>(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 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h3>{$_('comms.securityAlerts')}</h3>
|
||||
<div class="toggle-row">
|
||||
<div class="toggle-info">
|
||||
<span class="toggle-label">{$_('comms.legacyLoginAlerts')}</span>
|
||||
<span class="toggle-description">{$_('comms.legacyLoginAlertsDescription')}</span>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="toggle-button {legacyLoginAlerts ? 'on' : 'off'}"
|
||||
onclick={() => legacyLoginAlerts = !legacyLoginAlerts}
|
||||
disabled={saving}
|
||||
aria-label={legacyLoginAlerts ? $_('comms.disableLegacyLoginAlerts') : $_('comms.enableLegacyLoginAlerts')}
|
||||
>
|
||||
<span class="toggle-slider"></span>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="actions">
|
||||
<button type="submit" disabled={saving}>
|
||||
{saving ? $_('common.saving') : $_('comms.savePreferences')}
|
||||
|
||||
@@ -680,6 +680,7 @@ export const api = {
|
||||
discordUsername?: string;
|
||||
telegramUsername?: string;
|
||||
signalUsername?: string;
|
||||
legacyLoginAlerts?: boolean;
|
||||
}): Promise<UpdateNotificationPrefsResponse> {
|
||||
return xrpc("_account.updateNotificationPrefs", {
|
||||
method: "POST",
|
||||
|
||||
@@ -232,6 +232,7 @@ export interface NotificationPrefs {
|
||||
telegramVerified: boolean;
|
||||
signalUsername: string | null;
|
||||
signalVerified: boolean;
|
||||
legacyLoginAlerts: boolean;
|
||||
}
|
||||
|
||||
export interface NotificationHistoryItem {
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"telegramStartBot": "Or send /start {handle} to @{botUsername} manually",
|
||||
"telegramOpenLink": "Open Telegram to verify",
|
||||
"discordStartBot": "DM @{botUsername} on Discord and send /start {handle}",
|
||||
"discordOpenLink": "Open Discord to verify"
|
||||
"discordOpenLink": "Open Discord to verify",
|
||||
"securityAlerts": "Security alerts",
|
||||
"legacyLoginAlerts": "Legacy login alerts",
|
||||
"legacyLoginAlertsDescription": "Get notified when someone signs in to your TOTP enabled account without using legacy login methods.",
|
||||
"enableLegacyLoginAlerts": "Enable legacy login alerts",
|
||||
"disableLegacyLoginAlerts": "Disable legacy login alerts"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "Collections",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"failedToLoad": "Asetusten lataus epäonnistui",
|
||||
"failedToSave": "Asetusten tallennus epäonnistui",
|
||||
"failedToVerify": "Vahvistus epäonnistui",
|
||||
"failedToLoadHistory": "Viestihistorian lataus epäonnistui"
|
||||
"failedToLoadHistory": "Viestihistorian lataus epäonnistui",
|
||||
"securityAlerts": "Turvallisuushälytykset",
|
||||
"legacyLoginAlerts": "Vanhat kirjautumisilmoitukset",
|
||||
"legacyLoginAlertsDescription": "Saat ilmoituksen, kun joku kirjautuu TOTP-yhteensopivalle tilillesi käyttämällä vanhoja kirjautumistapoja.",
|
||||
"enableLegacyLoginAlerts": "Ota käyttöön vanhat kirjautumisilmoitukset",
|
||||
"disableLegacyLoginAlerts": "Poista käytöstä vanhat kirjautumisilmoitukset"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "Kokoelmat",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"telegramStartBot": "Ou envoyez /start {handle} à @{botUsername} manuellement",
|
||||
"telegramOpenLink": "Ouvrir Telegram pour vérifier",
|
||||
"discordStartBot": "Envoyez un DM à @{botUsername} sur Discord avec /start {handle}",
|
||||
"discordOpenLink": "Ouvrir Discord pour vérifier"
|
||||
"discordOpenLink": "Ouvrir Discord pour vérifier",
|
||||
"securityAlerts": "Alertes de sécurité",
|
||||
"legacyLoginAlerts": "Anciennes alertes de connexion",
|
||||
"legacyLoginAlertsDescription": "Recevez une notification lorsque quelqu'un se connecte à votre compte TOTP à l'aide de méthodes de connexion héritées.",
|
||||
"enableLegacyLoginAlerts": "Activer les alertes de connexion héritées",
|
||||
"disableLegacyLoginAlerts": "Désactiver les alertes de connexion héritées"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "Collections",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"failedToLoad": "設定の読み込みに失敗しました",
|
||||
"failedToSave": "設定の保存に失敗しました",
|
||||
"failedToVerify": "確認に失敗しました",
|
||||
"failedToLoadHistory": "メッセージ履歴の読み込みに失敗しました"
|
||||
"failedToLoadHistory": "メッセージ履歴の読み込みに失敗しました",
|
||||
"securityAlerts": "セキュリティ警告",
|
||||
"legacyLoginAlerts": "レガシーログインアラート",
|
||||
"legacyLoginAlertsDescription": "誰かが従来のログイン方法を使用してTOTP対応アカウントにサインインしたときに通知を受け取ります。",
|
||||
"enableLegacyLoginAlerts": "レガシーログインアラートを有効にする",
|
||||
"disableLegacyLoginAlerts": "レガシーログインアラートを無効にする"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "コレクション",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"failedToLoad": "설정 로딩 실패",
|
||||
"failedToSave": "설정 저장 실패",
|
||||
"failedToVerify": "인증 실패",
|
||||
"failedToLoadHistory": "메시지 기록 로딩 실패"
|
||||
"failedToLoadHistory": "메시지 기록 로딩 실패",
|
||||
"securityAlerts": "보안 경고",
|
||||
"legacyLoginAlerts": "레거시 로그인 알림",
|
||||
"legacyLoginAlertsDescription": "레거시 로그인 방법을 사용하여 누군가가 TOTP 지원 계정에 로그인하면 알림을 받습니다.",
|
||||
"enableLegacyLoginAlerts": "레거시 로그인 알림 활성화",
|
||||
"disableLegacyLoginAlerts": "레거시 로그인 알림 비활성화"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "컬렉션",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"failedToLoad": "Kunde inte ladda inställningar",
|
||||
"failedToSave": "Kunde inte spara inställningar",
|
||||
"failedToVerify": "Verifiering misslyckades",
|
||||
"failedToLoadHistory": "Kunde inte ladda meddelandehistorik"
|
||||
"failedToLoadHistory": "Kunde inte ladda meddelandehistorik",
|
||||
"securityAlerts": "Säkerhetsvarningar",
|
||||
"legacyLoginAlerts": "Varningar för föråldrade inloggningsmetoder",
|
||||
"legacyLoginAlertsDescription": "Bli notifierad när en inloggning sker med föråldrade inloggningsmetoder, när du har TOTP aktiverat.",
|
||||
"enableLegacyLoginAlerts": "Aktivera föråldrad inloggningsmetodsvarning",
|
||||
"disableLegacyLoginAlerts": "Avaktivera föråldrad inloggningsmetodsvarning"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "Samlingar",
|
||||
|
||||
@@ -458,7 +458,12 @@
|
||||
"failedToLoad": "加载偏好设置失败",
|
||||
"failedToSave": "保存偏好设置失败",
|
||||
"failedToVerify": "验证失败",
|
||||
"failedToLoadHistory": "加载消息历史失败"
|
||||
"failedToLoadHistory": "加载消息历史失败",
|
||||
"securityAlerts": "安全警报",
|
||||
"legacyLoginAlerts": "旧版登录提醒",
|
||||
"legacyLoginAlertsDescription": "当有人使用传统登录方式登录您的启用了TOTP的帐户时,会收到通知。",
|
||||
"enableLegacyLoginAlerts": "启用旧版登录警报",
|
||||
"disableLegacyLoginAlerts": "禁用旧版登录警报"
|
||||
},
|
||||
"repoExplorer": {
|
||||
"collections": "集合",
|
||||
|
||||
@@ -260,6 +260,7 @@ export const mockData = {
|
||||
telegramVerified: false,
|
||||
signalUsername: null,
|
||||
signalVerified: false,
|
||||
legacyLoginAlerts: true,
|
||||
...overrides,
|
||||
}),
|
||||
describeServer: (overrides?: Record<string, unknown>) => ({
|
||||
|
||||
Reference in New Issue
Block a user