this repo has no description
1pub const DEFAULT_LOCALE: &str = "en";
2pub const VALID_LOCALES: &[&str] = &["en", "zh", "ja", "ko"];
3
4pub fn validate_locale(locale: &str) -> &str {
5 if VALID_LOCALES.contains(&locale) {
6 locale
7 } else {
8 DEFAULT_LOCALE
9 }
10}
11
12pub struct NotificationStrings {
13 pub welcome_subject: &'static str,
14 pub welcome_body: &'static str,
15 pub email_verification_subject: &'static str,
16 pub email_verification_body: &'static str,
17 pub password_reset_subject: &'static str,
18 pub password_reset_body: &'static str,
19 pub email_update_subject: &'static str,
20 pub email_update_body: &'static str,
21 pub account_deletion_subject: &'static str,
22 pub account_deletion_body: &'static str,
23 pub plc_operation_subject: &'static str,
24 pub plc_operation_body: &'static str,
25 pub two_factor_code_subject: &'static str,
26 pub two_factor_code_body: &'static str,
27 pub passkey_recovery_subject: &'static str,
28 pub passkey_recovery_body: &'static str,
29 pub signup_verification_subject: &'static str,
30 pub signup_verification_body: &'static str,
31 pub legacy_login_subject: &'static str,
32 pub legacy_login_body: &'static str,
33}
34
35pub fn get_strings(locale: &str) -> &'static NotificationStrings {
36 match validate_locale(locale) {
37 "zh" => &STRINGS_ZH,
38 "ja" => &STRINGS_JA,
39 "ko" => &STRINGS_KO,
40 _ => &STRINGS_EN,
41 }
42}
43
44static STRINGS_EN: NotificationStrings = NotificationStrings {
45 welcome_subject: "Welcome to {hostname}",
46 welcome_body: "Welcome to {hostname}!\n\nYour handle is: @{handle}\n\nThank you for joining us.",
47 email_verification_subject: "Verify your email - {hostname}",
48 email_verification_body: "Hello @{handle},\n\nYour email verification code is: {code}\n\nThis code will expire in 10 minutes.\n\nIf you did not request this, please ignore this email.",
49 password_reset_subject: "Password Reset - {hostname}",
50 password_reset_body: "Hello @{handle},\n\nYour password reset code is: {code}\n\nThis code will expire in 10 minutes.\n\nIf you did not request this, please ignore this message.",
51 email_update_subject: "Confirm your new email - {hostname}",
52 email_update_body: "Hello @{handle},\n\nYour email update confirmation code is: {code}\n\nThis code will expire in 10 minutes.\n\nIf you did not request this, please ignore this email.",
53 account_deletion_subject: "Account Deletion Request - {hostname}",
54 account_deletion_body: "Hello @{handle},\n\nYour account deletion confirmation code is: {code}\n\nThis code will expire in 10 minutes.\n\nIf you did not request this, please secure your account immediately.",
55 plc_operation_subject: "{hostname} - PLC Operation Token",
56 plc_operation_body: "Hello @{handle},\n\nYou requested to sign a PLC operation for your account.\n\nYour verification token is: {token}\n\nThis token will expire in 10 minutes.\n\nIf you did not request this, you can safely ignore this message.",
57 two_factor_code_subject: "Sign-in Verification - {hostname}",
58 two_factor_code_body: "Hello @{handle},\n\nYour sign-in verification code is: {code}\n\nThis code will expire in 10 minutes.\n\nIf you did not request this, please secure your account immediately.",
59 passkey_recovery_subject: "Account Recovery - {hostname}",
60 passkey_recovery_body: "Hello @{handle},\n\nYou requested to recover your passkey-only account.\n\nClick the link below to set a temporary password and regain access:\n{url}\n\nThis link will expire in 1 hour.\n\nIf you did not request this, please ignore this message. Your account remains secure.",
61 signup_verification_subject: "Verify your account - {hostname}",
62 signup_verification_body: "Welcome! Your account verification code is: {code}\n\nThis code will expire in 30 minutes.\n\nEnter this code to complete your registration on {hostname}.",
63 legacy_login_subject: "Security Alert: Legacy Login Detected - {hostname}",
64 legacy_login_body: "Hello @{handle},\n\nA login to your account was detected using a legacy app (like Bluesky) that doesn't support TOTP verification.\n\nDetails:\n- Time: {timestamp}\n- IP Address: {ip}\n\nYour TOTP protection was bypassed for this login. The session has limited permissions for sensitive operations.\n\nIf this wasn't you, please:\n1. Change your password immediately\n2. Review your active sessions\n3. Consider disabling legacy app logins in your security settings\n\nStay safe,\n{hostname}",
65};
66
67static STRINGS_ZH: NotificationStrings = NotificationStrings {
68 welcome_subject: "欢迎加入 {hostname}",
69 welcome_body: "欢迎加入 {hostname}!\n\n您的用户名是:@{handle}\n\n感谢您的加入。",
70 email_verification_subject: "验证您的邮箱 - {hostname}",
71 email_verification_body: "您好 @{handle},\n\n您的邮箱验证码是:{code}\n\n此验证码将在10分钟后过期。\n\n如果这不是您的操作,请忽略此邮件。",
72 password_reset_subject: "密码重置 - {hostname}",
73 password_reset_body: "您好 @{handle},\n\n您的密码重置验证码是:{code}\n\n此验证码将在10分钟后过期。\n\n如果这不是您的操作,请忽略此消息。",
74 email_update_subject: "确认您的新邮箱 - {hostname}",
75 email_update_body: "您好 @{handle},\n\n您的邮箱更新确认码是:{code}\n\n此验证码将在10分钟后过期。\n\n如果这不是您的操作,请忽略此邮件。",
76 account_deletion_subject: "账户删除请求 - {hostname}",
77 account_deletion_body: "您好 @{handle},\n\n您的账户删除确认码是:{code}\n\n此验证码将在10分钟后过期。\n\n如果这不是您的操作,请立即保护您的账户。",
78 plc_operation_subject: "{hostname} - PLC 操作令牌",
79 plc_operation_body: "您好 @{handle},\n\n您请求为账户签署 PLC 操作。\n\n您的验证令牌是:{token}\n\n此令牌将在10分钟后过期。\n\n如果这不是您的操作,您可以安全地忽略此消息。",
80 two_factor_code_subject: "登录验证 - {hostname}",
81 two_factor_code_body: "您好 @{handle},\n\n您的登录验证码是:{code}\n\n此验证码将在10分钟后过期。\n\n如果这不是您的操作,请立即保护您的账户。",
82 passkey_recovery_subject: "账户恢复 - {hostname}",
83 passkey_recovery_body: "您好 @{handle},\n\n您请求恢复仅通行密钥账户的访问权限。\n\n点击以下链接设置临时密码并恢复访问:\n{url}\n\n此链接将在1小时后过期。\n\n如果这不是您的操作,请忽略此消息。您的账户仍然安全。",
84 signup_verification_subject: "验证您的账户 - {hostname}",
85 signup_verification_body: "欢迎!您的账户验证码是:{code}\n\n此验证码将在30分钟后过期。\n\n请输入此验证码完成在 {hostname} 上的注册。",
86 legacy_login_subject: "安全提醒:检测到传统应用登录 - {hostname}",
87 legacy_login_body: "您好 @{handle},\n\n检测到使用不支持 TOTP 验证的传统应用(如 Bluesky)登录您的账户。\n\n详细信息:\n- 时间:{timestamp}\n- IP 地址:{ip}\n\n此次登录绕过了 TOTP 保护。该会话对敏感操作的权限有限。\n\n如果这不是您的操作,请:\n1. 立即更改密码\n2. 检查您的活跃会话\n3. 考虑在安全设置中禁用传统应用登录\n\n请注意安全,\n{hostname}",
88};
89
90static STRINGS_JA: NotificationStrings = NotificationStrings {
91 welcome_subject: "{hostname} へようこそ",
92 welcome_body: "{hostname} へようこそ!\n\nお客様のハンドル:@{handle}\n\nご登録ありがとうございます。",
93 email_verification_subject: "メール認証 - {hostname}",
94 email_verification_body: "@{handle} 様\n\nメール認証コードは:{code}\n\nこのコードは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、このメールを無視してください。",
95 password_reset_subject: "パスワードリセット - {hostname}",
96 password_reset_body: "@{handle} 様\n\nパスワードリセットコードは:{code}\n\nこのコードは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、このメッセージを無視してください。",
97 email_update_subject: "新しいメールアドレスの確認 - {hostname}",
98 email_update_body: "@{handle} 様\n\nメールアドレス更新の確認コードは:{code}\n\nこのコードは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、このメールを無視してください。",
99 account_deletion_subject: "アカウント削除リクエスト - {hostname}",
100 account_deletion_body: "@{handle} 様\n\nアカウント削除の確認コードは:{code}\n\nこのコードは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、直ちにアカウントを保護してください。",
101 plc_operation_subject: "{hostname} - PLC 操作トークン",
102 plc_operation_body: "@{handle} 様\n\nアカウントの PLC 操作の署名をリクエストされました。\n\n認証トークンは:{token}\n\nこのトークンは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、このメッセージを無視しても問題ありません。",
103 two_factor_code_subject: "ログイン認証 - {hostname}",
104 two_factor_code_body: "@{handle} 様\n\nログイン認証コードは:{code}\n\nこのコードは10分後に期限切れとなります。\n\nこの操作に心当たりがない場合は、直ちにアカウントを保護してください。",
105 passkey_recovery_subject: "アカウント復旧 - {hostname}",
106 passkey_recovery_body: "@{handle} 様\n\nパスキー専用アカウントの復旧をリクエストされました。\n\n以下のリンクをクリックして一時パスワードを設定し、アクセスを回復してください:\n{url}\n\nこのリンクは1時間後に期限切れとなります。\n\nこの操作に心当たりがない場合は、このメッセージを無視してください。アカウントは安全なままです。",
107 signup_verification_subject: "アカウント認証 - {hostname}",
108 signup_verification_body: "ようこそ!アカウント認証コードは:{code}\n\nこのコードは30分後に期限切れとなります。\n\n{hostname} への登録を完了するには、このコードを入力してください。",
109 legacy_login_subject: "セキュリティ警告:レガシーログインを検出 - {hostname}",
110 legacy_login_body: "@{handle} 様\n\nTOTP 認証に対応していないレガシーアプリ(Bluesky など)からのログインが検出されました。\n\n詳細:\n- 時刻:{timestamp}\n- IP アドレス:{ip}\n\nこのログインでは TOTP 保護がバイパスされました。このセッションは機密操作に対する権限が制限されています。\n\n心当たりがない場合は:\n1. 直ちにパスワードを変更してください\n2. アクティブなセッションを確認してください\n3. セキュリティ設定でレガシーアプリのログインを無効にすることを検討してください\n\nご注意ください。\n{hostname}",
111};
112
113static STRINGS_KO: NotificationStrings = NotificationStrings {
114 welcome_subject: "{hostname}에 오신 것을 환영합니다",
115 welcome_body: "{hostname}에 오신 것을 환영합니다!\n\n회원님의 핸들은: @{handle}\n\n가입해 주셔서 감사합니다.",
116 email_verification_subject: "이메일 인증 - {hostname}",
117 email_verification_body: "안녕하세요 @{handle}님,\n\n이메일 인증 코드는: {code}\n\n이 코드는 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 이 이메일을 무시하세요.",
118 password_reset_subject: "비밀번호 재설정 - {hostname}",
119 password_reset_body: "안녕하세요 @{handle}님,\n\n비밀번호 재설정 코드는: {code}\n\n이 코드는 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 이 메시지를 무시하세요.",
120 email_update_subject: "새 이메일 확인 - {hostname}",
121 email_update_body: "안녕하세요 @{handle}님,\n\n이메일 업데이트 확인 코드는: {code}\n\n이 코드는 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 이 이메일을 무시하세요.",
122 account_deletion_subject: "계정 삭제 요청 - {hostname}",
123 account_deletion_body: "안녕하세요 @{handle}님,\n\n계정 삭제 확인 코드는: {code}\n\n이 코드는 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 즉시 계정을 보호하세요.",
124 plc_operation_subject: "{hostname} - PLC 작업 토큰",
125 plc_operation_body: "안녕하세요 @{handle}님,\n\n계정의 PLC 작업 서명을 요청하셨습니다.\n\n인증 토큰은: {token}\n\n이 토큰은 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 이 메시지를 안전하게 무시하셔도 됩니다.",
126 two_factor_code_subject: "로그인 인증 - {hostname}",
127 two_factor_code_body: "안녕하세요 @{handle}님,\n\n로그인 인증 코드는: {code}\n\n이 코드는 10분 후에 만료됩니다.\n\n요청하지 않으셨다면 즉시 계정을 보호하세요.",
128 passkey_recovery_subject: "계정 복구 - {hostname}",
129 passkey_recovery_body: "안녕하세요 @{handle}님,\n\n패스키 전용 계정 복구를 요청하셨습니다.\n\n아래 링크를 클릭하여 임시 비밀번호를 설정하고 액세스를 복구하세요:\n{url}\n\n이 링크는 1시간 후에 만료됩니다.\n\n요청하지 않으셨다면 이 메시지를 무시하세요. 계정은 안전하게 유지됩니다.",
130 signup_verification_subject: "계정 인증 - {hostname}",
131 signup_verification_body: "환영합니다! 계정 인증 코드는: {code}\n\n이 코드는 30분 후에 만료됩니다.\n\n{hostname}에서 등록을 완료하려면 이 코드를 입력하세요.",
132 legacy_login_subject: "보안 알림: 레거시 로그인 감지 - {hostname}",
133 legacy_login_body: "안녕하세요 @{handle}님,\n\nTOTP 인증을 지원하지 않는 레거시 앱(예: Bluesky)을 사용한 로그인이 감지되었습니다.\n\n세부 정보:\n- 시간: {timestamp}\n- IP 주소: {ip}\n\n이 로그인에서 TOTP 보호가 우회되었습니다. 이 세션은 민감한 작업에 대한 권한이 제한됩니다.\n\n본인이 아닌 경우:\n1. 즉시 비밀번호를 변경하세요\n2. 활성 세션을 검토하세요\n3. 보안 설정에서 레거시 앱 로그인 비활성화를 고려하세요\n\n{hostname} 드림",
134};
135
136pub fn format_message(template: &str, vars: &[(&str, &str)]) -> String {
137 let mut result = template.to_string();
138 for (key, value) in vars {
139 result = result.replace(&format!("{{{}}}", key), value);
140 }
141 result
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_validate_locale() {
150 assert_eq!(validate_locale("en"), "en");
151 assert_eq!(validate_locale("zh"), "zh");
152 assert_eq!(validate_locale("ja"), "ja");
153 assert_eq!(validate_locale("ko"), "ko");
154 assert_eq!(validate_locale("invalid"), DEFAULT_LOCALE);
155 assert_eq!(validate_locale(""), DEFAULT_LOCALE);
156 }
157
158 #[test]
159 fn test_format_message() {
160 let template = "Hello {name}, your code is {code}";
161 let result = format_message(template, &[("name", "Alice"), ("code", "123456")]);
162 assert_eq!(result, "Hello Alice, your code is 123456");
163 }
164
165 #[test]
166 fn test_get_strings() {
167 let en = get_strings("en");
168 assert!(en.welcome_subject.contains("{hostname}"));
169
170 let zh = get_strings("zh");
171 assert!(zh.welcome_subject.contains("{hostname}"));
172 assert!(zh.welcome_body.contains("欢迎"));
173 }
174}