Ver Fonte

feat: mask password in telegram notification on 2FA failure (#3884)

Aleksei Sidorenko há 1 dia atrás
pai
commit
a2097ad062

+ 11 - 2
web/controller/index.go

@@ -4,6 +4,7 @@ import (
 	"net/http"
 	"text/template"
 	"time"
+	"fmt"
 
 	"github.com/mhsanaei/3x-ui/v2/logger"
 	"github.com/mhsanaei/3x-ui/v2/web/service"
@@ -71,14 +72,22 @@ func (a *IndexController) login(c *gin.Context) {
 		return
 	}
 
-	user := a.userService.CheckUser(form.Username, form.Password, form.TwoFactorCode)
+	user, checkErr := a.userService.CheckUser(form.Username, form.Password, form.TwoFactorCode)
 	timeStr := time.Now().Format("2006-01-02 15:04:05")
 	safeUser := template.HTMLEscapeString(form.Username)
 	safePass := template.HTMLEscapeString(form.Password)
 
 	if user == nil {
 		logger.Warningf("wrong username: \"%s\", password: \"%s\", IP: \"%s\"", safeUser, safePass, getRemoteIp(c))
-		a.tgbot.UserLoginNotify(safeUser, safePass, getRemoteIp(c), timeStr, 0)
+		
+		notifyPass := safePass 
+		
+		if checkErr != nil && checkErr.Error() == "invalid 2fa code" {
+			translatedError := a.tgbot.I18nBot("tgbot.messages.2faFailed")
+			notifyPass = fmt.Sprintf("*** (%s)", translatedError) 
+		}
+
+		a.tgbot.UserLoginNotify(safeUser, notifyPass, getRemoteIp(c), timeStr, 0)
 		pureJsonMsg(c, http.StatusOK, false, I18nWeb(c, "pages.login.toasts.wrongUsernameOrPassword"))
 		return
 	}

+ 9 - 11
web/service/user.go

@@ -33,7 +33,7 @@ func (s *UserService) GetFirstUser() (*model.User, error) {
 	return user, nil
 }
 
-func (s *UserService) CheckUser(username string, password string, twoFactorCode string) *model.User {
+func (s *UserService) CheckUser(username string, password string, twoFactorCode string) (*model.User, error) {
 	db := database.GetDB()
 
 	user := &model.User{}
@@ -43,17 +43,16 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode
 		First(user).
 		Error
 	if err == gorm.ErrRecordNotFound {
-		return nil
+		return nil, errors.New("invalid credentials")
 	} else if err != nil {
 		logger.Warning("check user err:", err)
-		return nil
+		return nil, err
 	}
 
-	// If LDAP enabled and local password check fails, attempt LDAP auth
 	if !crypto.CheckPasswordHash(user.Password, password) {
 		ldapEnabled, _ := s.settingService.GetLdapEnable()
 		if !ldapEnabled {
-			return nil
+			return nil, errors.New("invalid credentials")
 		}
 
 		host, _ := s.settingService.GetLdapHost()
@@ -77,15 +76,14 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode
 		}
 		ok, err := ldaputil.AuthenticateUser(cfg, username, password)
 		if err != nil || !ok {
-			return nil
+			return nil, errors.New("invalid credentials")
 		}
-		// On successful LDAP auth, continue 2FA checks below
 	}
 
 	twoFactorEnable, err := s.settingService.GetTwoFactorEnable()
 	if err != nil {
 		logger.Warning("check two factor err:", err)
-		return nil
+		return nil, err
 	}
 
 	if twoFactorEnable {
@@ -93,15 +91,15 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode
 
 		if err != nil {
 			logger.Warning("check two factor token err:", err)
-			return nil
+			return nil, err
 		}
 
 		if gotp.NewDefaultTOTP(twoFactorToken).Now() != twoFactorCode {
-			return nil
+			return nil, errors.New("invalid 2fa code") 
 		}
 	}
 
-	return user
+	return user, nil
 }
 
 func (s *UserService) UpdateUser(id int, username string, password string) error {

+ 1 - 0
web/translation/translate.ar_EG.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ حفظت بيانات مستخدم Telegram."
 "loginSuccess" = "✅ تسجيل الدخول للبانل تم بنجاح.\r\n"
 "loginFailed" = "❗️فشل محاولة تسجيل الدخول للبانل.\r\n"
+"2faFailed" = "فشل 2FA"
 "report" = "🕰 التقارير المجدولة: {{ .RunTime }}\r\n"
 "datetime" = "⏰ التاريخ والوقت: {{ .DateTime }}\r\n"
 "hostname" = "💻 السيرفر: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.en_US.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Telegram User saved."
 "loginSuccess" = "✅ Logged in to the panel successfully.\r\n"
 "loginFailed" = "❗️Login attempt to the panel failed.\r\n"
+"2faFailed" = "2FA Failed"
 "report" = "🕰 Scheduled Reports: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Date&Time: {{ .DateTime }}\r\n"
 "hostname" = "💻 Host: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.es_ES.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Usuario de Telegram guardado."
 "loginSuccess" = "✅ Has iniciado sesión en el panel con éxito.\r\n"
 "loginFailed" = "❗️ Falló el inicio de sesión en el panel.\r\n"
+"2faFailed" = "Error de 2FA"
 "report" = "🕰 Informes programados: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Fecha y Hora: {{ .DateTime }}\r\n"
 "hostname" = "💻 Nombre del Host: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.fa_IR.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ کاربر تلگرام ذخیره شد."
 "loginSuccess" = "✅ با موفقیت به پنل وارد شدید.\r\n"
 "loginFailed" = "❗️ ورود به پنل ناموفق‌بود \r\n"
+"2faFailed" = "خطای 2FA"
 "report" = "🕰 گزارشات‌زمان‌بندی‌شده: {{ .RunTime }}\r\n"
 "datetime" = "⏰ تاریخ‌وزمان: {{ .DateTime }}\r\n"
 "hostname" = "💻 نام‌میزبان: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.id_ID.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Pengguna Telegram tersimpan."
 "loginSuccess" = "✅ Berhasil masuk ke panel.\r\n"
 "loginFailed" = "❗️ Gagal masuk ke panel.\r\n"
+"2faFailed" = "2FA Gagal"
 "report" = "🕰 Laporan Terjadwal: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Tanggal & Waktu: {{ .DateTime }}\r\n"
 "hostname" = "💻 Host: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.ja_JP.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Telegramユーザーが保存されました。"
 "loginSuccess" = "✅ パネルに正常にログインしました。\r\n"
 "loginFailed" = "❗️ パネルのログインに失敗しました。\r\n"
+"2faFailed" = "2FAエラー"
 "report" = "🕰 定期報告:{{ .RunTime }}\r\n"
 "datetime" = "⏰ 日時:{{ .DateTime }}\r\n"
 "hostname" = "💻 ホスト名:{{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.pt_BR.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Usuário do Telegram salvo."
 "loginSuccess" = "✅ Conectado ao painel com sucesso.\r\n"
 "loginFailed" = "❗️Tentativa de login no painel falhou.\r\n"
+"2faFailed" = "Falha no 2FA"
 "report" = "🕰 Relatórios agendados: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Data&Hora: {{ .DateTime }}\r\n"
 "hostname" = "💻 Host: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.ru_RU.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Пользователь Telegram сохранен."
 "loginSuccess" = "✅ Успешный вход в панель.\r\n"
 "loginFailed" = "❗️ Ошибка входа в панель.\r\n"
+"2faFailed" = "Ошибка 2FA"
 "report" = "🕰 Запланированные отчеты: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Дата и время: {{ .DateTime }}\r\n"
 "hostname" = "💻 Имя хоста: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.tr_TR.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Telegram Kullanıcısı kaydedildi."
 "loginSuccess" = "✅ Panele başarıyla giriş yapıldı.\r\n"
 "loginFailed" = "❗️Panele giriş denemesi başarısız oldu.\r\n"
+"2faFailed" = "2FA Hatası"
 "report" = "🕰 Planlanmış Raporlar: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Tarih&Zaman: {{ .DateTime }}\r\n"
 "hostname" = "💻 Sunucu: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.uk_UA.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Користувача Telegram збережено."
 "loginSuccess" = "✅ Успішно ввійшли в панель\r\n"
 "loginFailed" = "❗️ Помилка входу в панель.\r\n"
+"2faFailed" = "Помилка 2FA"
 "report" = "🕰 Заплановані звіти: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Дата й час: {{ .DateTime }}\r\n"
 "hostname" = "💻 Хост: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.vi_VN.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ Người dùng Telegram đã được lưu."
 "loginSuccess" = "✅ Đăng nhập thành công vào bảng điều khiển.\r\n"
 "loginFailed" = "❗️ Đăng nhập vào bảng điều khiển thất bại.\r\n"
+"2faFailed" = "Lỗi 2FA"
 "report" = "🕰 Báo cáo định kỳ: {{ .RunTime }}\r\n"
 "datetime" = "⏰ Ngày-Giờ: {{ .DateTime }}\r\n"
 "hostname" = "💻 Tên máy chủ: {{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.zh_CN.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ 电报用户已保存。"
 "loginSuccess" = "✅ 成功登录到面板。\r\n"
 "loginFailed" = "❗️ 面板登录失败。\r\n"
+"2faFailed" = "2FA 失败"
 "report" = "🕰 定时报告:{{ .RunTime }}\r\n"
 "datetime" = "⏰ 日期时间:{{ .DateTime }}\r\n"
 "hostname" = "💻 主机名:{{ .Hostname }}\r\n"

+ 1 - 0
web/translation/translate.zh_TW.toml

@@ -663,6 +663,7 @@
 "userSaved" = "✅ 電報使用者已儲存。"
 "loginSuccess" = "✅ 成功登入到面板。\r\n"
 "loginFailed" = "❗️ 面板登入失敗。\r\n"
+"2faFailed" = "2FA 失敗"
 "report" = "🕰 定時報告:{{ .RunTime }}\r\n"
 "datetime" = "⏰ 日期時間:{{ .DateTime }}\r\n"
 "hostname" = "💻 主機名:{{ .Hostname }}\r\n"