修复登录失败显示英文原文的问题(第1章复测发现)

Tinode 原生 WS 登录走 {ctrl} 协议,不经过 im-api.js 的 REASON_MESSAGES 翻译表(那张表只在
REST 请求里生效)。ctrl.text 是服务端 datamodel.go 里固定的英文串("authentication failed"
等),ctrl.params 也没有 REST 层那种稳定的 reason 字段(已实测确认)。原来 doLogin 的 catch
直接把 err.message 原样传给 handleError,密码打错时用户看到的是英文 "authentication failed",
不是参考图要求的"账号或密码错误"。

新增 loginErrorMessage():已知的几个固定英文串映射成中文,未知文案按状态码兜底
(401/403 → 账号或密码错误)。

已用真实账号验证:错误密码显示"账号或密码错误",正确密码登录正常进入工作台。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-04 12:21:44 +08:00
co-authored by Claude Sonnet 5
parent 5bc3fee20b
commit 02a565b8e5
3 changed files with 35 additions and 3 deletions
+21 -1
View File
@@ -154,6 +154,26 @@ const SIDE_PANEL_VIEWS = ['acc_general','archive','blocked','contacts','cred','c
const AUTH_FLOW_VIEWS = ['tenant', 'login', 'register', 'reset', 'cred',
'enterprise-register', 'enterprise-feedback'];
// Tinode 原生 WS 登录失败走的是 {ctrl} 协议,不是 REST 层——im-api.js 里那张
// REASON_MESSAGES 翻译表只在 REST 请求里生效,这条路径完全绕开它。ctrl.text 是服务端
// datamodel.go 里固定的英文串(authentication failed / unknown authentication scheme 等),
// ctrl.params 里也没有像 REST 层那样稳定的 reason 字段可用(已实测确认)。
// 原来这里直接把 err.message 原样显示,登录密码打错用户看到的是英文 "authentication failed",
// 不是参考图要求的"账号或密码错误"。
const LOGIN_ERROR_TEXT_CN = {
'authentication failed': '账号或密码错误',
'authentication required': '请先登录',
'unknown authentication scheme': '登录方式不受支持,请刷新页面重试',
'policy violation': '当前操作不符合安全策略要求'
};
function loginErrorMessage(err) {
const known = err && err.message && LOGIN_ERROR_TEXT_CN[err.message.trim().toLowerCase()];
if (known) return known;
// 未知文案时按状态码兜底,401/403 绝大多数场景就是账号或密码错误
if (err && (err.code === 401 || err.code === 403)) return '账号或密码错误';
return (err && err.message) || '登录失败,请重试';
}
class TinodeWeb extends React.Component {
constructor(props) {
super(props);
@@ -953,7 +973,7 @@ class TinodeWeb extends React.Component {
loadSpinnerVisible: false,
autoLogin: autoLogin
});
this.handleError(err.message, 'err');
this.handleError(loginErrorMessage(err), 'err');
console.warn("Login failed", err);
if (!autoLogin) {
if (token) {
+13 -1
View File
@@ -17227,6 +17227,18 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
});
const SIDE_PANEL_VIEWS = ['acc_general', 'archive', 'blocked', 'contacts', 'cred', 'crop', 'edit', 'general', 'newtpk', 'notif', 'register', 'reset', 'security', 'settings', 'support', 'wallpapers', 'tenant', 'login', 'enterprise-register', 'enterprise-feedback', 'identity-check', 'realname', 'realname-verified', 'realname-reminder', 'independent-password', 'messages-home', 'messages-offline', 'messages-menu', 'message-actions', 'system-messages', 'chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card', 'compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle', 'address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm', 'group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload', 'favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos', 'call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized', 'workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-list', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice', 'personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info', 'fraud-risk-warning', 'fraud-risk-confirmation', 'abuse-report-reasons', 'abuse-report-details', 'user-feedback', ''];
const AUTH_FLOW_VIEWS = ['tenant', 'login', 'register', 'reset', 'cred', 'enterprise-register', 'enterprise-feedback'];
const LOGIN_ERROR_TEXT_CN = {
'authentication failed': '账号或密码错误',
'authentication required': '请先登录',
'unknown authentication scheme': '登录方式不受支持,请刷新页面重试',
'policy violation': '当前操作不符合安全策略要求'
};
function loginErrorMessage(err) {
const known = err && err.message && LOGIN_ERROR_TEXT_CN[err.message.trim().toLowerCase()];
if (known) return known;
if (err && (err.code === 401 || err.code === 403)) return '账号或密码错误';
return err && err.message || '登录失败,请重试';
}
class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
constructor(props) {
super(props);
@@ -17909,7 +17921,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
loadSpinnerVisible: false,
autoLogin: autoLogin
});
this.handleError(err.message, 'err');
this.handleError(loginErrorMessage(err), 'err');
console.warn("Login failed", err);
if (!autoLogin) {
if (token) {
+1 -1
View File
File diff suppressed because one or more lines are too long