feat: Phase 1 WinAuth Go 移植完整实现

将原 C#/.NET WinAuth 移植为 Go + Gio GUI,覆盖 Phase 1 全部功能。

核心模块:
- internal/authenticator: TOTP (Google/Microsoft/Okta) + HOTP + BattleNet + Steam,含
  enroll/sync/code 生成、Steam 交易确认轮询
- internal/config: YAML 配置 + 老版 WinAuth XML 导入(DPAPI + Password + Blowfish/PBKDF2 解密链)
- internal/crypto: 现代加密 (WAGO1) + DPAPI 跨平台封装 + 老版 Blowfish ECB
- internal/win32: 单实例 Mutex 锁 + 全局热键管理器 (RegisterHotKey + PeekMessage 泵) +
  SendInput Unicode 注入 + 剪贴板文本/CF_DIB 图像读写 + AttachThreadInput 焦点切换
- internal/hotkey: "Ctrl+Alt+G" 风格快捷键字符串解析/格式化
- internal/qr: gozxing 二维码解码 + otpauth:// URI 解析
- internal/i18n: en/zh-CN/de 三语 TOML

UI 模块 (Gio):
- 主窗口:圆环倒计时进度条、复制按钮 + Toast 反馈、空列表占位、行分隔线
- 添加流程:vendor 菜单 + 各 vendor 独立对话框 + 二维码扫描入口(文件 / 剪贴板)
- 设置:密码加密、老版 XML 导入、每条目热键配置
- Steam:注册向导(含 captcha/email/SMS 多步)+ 交易确认窗

构建:Windows 主目标,非 Windows 平台所有 Win32 功能走 build-tag 桩实现。
This commit is contained in:
2026-06-12 03:10:37 +08:00
commit c671f2115e
165 changed files with 10102 additions and 0 deletions
+369
View File
@@ -0,0 +1,369 @@
# Simplified Chinese locale file for winauth-go.
[app_title]
other = "WinAuth"
[menu_file]
other = "文件"
[menu_help]
other = "帮助"
[menu_add_authenticator]
other = "添加身份验证器"
[menu_choose_vendor]
other = "选择身份验证器类型"
[btn_ok]
other = "确定"
[btn_cancel]
other = "取消"
[btn_add]
other = "添加"
[btn_remove]
other = "删除"
[btn_close]
other = "关闭"
[btn_enroll]
other = "注册"
[vendor_google]
other = "Google"
[vendor_microsoft]
other = "Microsoft"
[vendor_okta]
other = "Okta Verify"
[vendor_hotp]
other = "HOTP(基于计数器)"
[vendor_battlenet]
other = "战网"
[vendor_steam]
other = "Steam"
[vendor_battlenet_restore]
other = "战网(纸质恢复码恢复)"
[dialog_add_google_title]
other = "添加 Google 身份验证器"
[dialog_add_microsoft_title]
other = "添加 Microsoft 身份验证器"
[dialog_add_okta_title]
other = "添加 Okta Verify"
[dialog_add_hotp_title]
other = "添加 HOTP 身份验证器"
[dialog_add_battlenet_title]
other = "添加战网身份验证器"
[dialog_add_steam_title]
other = "添加 Steam 身份验证器"
[label_secret_key]
other = "密钥"
[label_name]
other = "名称"
[label_counter]
other = "计数器"
[label_serial]
other = "序列号"
[label_device_id]
other = "设备 ID"
[label_steam_data]
other = "Steam 数据(JSON,可选)"
[label_region]
other = "区域"
[label_show_secret]
other = "显示密钥"
[region_auto]
other = "自动检测"
[msg_empty_secret]
other = "请输入密钥。"
[msg_invalid_secret]
other = "密钥不是有效的 Base32 字符串。"
[msg_empty_serial]
other = "请输入序列号。"
[msg_invalid_counter]
other = "计数器必须是非负整数。"
[msg_enrolling]
other = "正在连接服务器……"
[msg_enroll_failed]
other = "注册失败:%s"
[menu_settings]
other = "设置"
[menu_set_password]
other = "设置密码…"
[menu_about]
other = "关于"
[dialog_password_title]
other = "输入密码"
[dialog_set_password_title]
other = "设置密码"
[label_password]
other = "密码"
[label_password_confirm]
other = "确认密码"
[hint_password_empty_disables]
other = "两个字段均留空可关闭加密。"
[msg_password_required]
other = "配置已加密,请输入密码。"
[msg_password_wrong]
other = "密码错误。"
[msg_password_mismatch]
other = "两次输入的密码不一致。"
[msg_save_failed]
other = "保存配置失败:%s"
[msg_load_failed]
other = "加载配置失败:%s"
# --- Steam 注册向导 ---
[steam_step_credentials]
other = "请输入 Steam 账号凭证。密码会使用 Steam 公钥 RSA 加密后发送,不会在本地保存。"
[steam_step_captcha]
other = "Steam 需要图形验证码,请输入下面图片中的字符。"
[steam_step_email]
other = "Steam 已将验证码发送到 %s,请在下方输入。"
[steam_step_activation]
other = "Steam 已将短信验证码发送至您的手机,请在下方输入以完成注册。"
[steam_step_done]
other = "注册完成。请立即记录吊销码 —— 若丢失将无法再从 Steam 账号上移除该验证器。"
[label_username]
other = "用户名"
[label_captcha_text]
other = "图形验证码"
[label_email_code]
other = "邮件验证码"
[label_activation_code]
other = "激活码(短信)"
[label_revocation_code]
other = "吊销码"
[hint_captcha_loading]
other = "正在加载验证码图片……"
[hint_captcha_failed]
other = "无法加载验证码图片:%s"
[btn_login]
other = "登录"
[btn_continue]
other = "继续"
[btn_activate]
other = "激活"
[btn_finish]
other = "完成"
[btn_trades]
other = "交易确认"
[btn_refresh]
other = "刷新"
[btn_accept]
other = "接受"
[btn_reject]
other = "拒绝"
[msg_empty_username]
other = "请输入用户名。"
[msg_empty_password]
other = "请输入密码。"
[msg_empty_captcha]
other = "请输入图形验证码。"
[msg_empty_email_code]
other = "请输入邮件中的验证码。"
[msg_empty_activation_code]
other = "请输入短信中的激活码。"
[msg_busy]
other = "正在处理,请稍候……"
# --- Steam 交易确认窗 ---
[dialog_steam_trades_title]
other = "Steam 交易确认"
[steam_trades_empty]
other = "暂无待确认交易。"
[steam_trades_loading]
other = "正在加载交易……"
[steam_trades_session_missing]
other = "该 Steam 验证器没有可用的登录会话。请通过注册向导重新添加,才能管理交易确认。"
[steam_trades_error]
other = "加载交易失败:%s"
# --- 战网纸质恢复码 ---
[dialog_restore_battlenet_title]
other = "恢复战网身份验证器"
[battlenet_restore_intro]
other = "请输入您在初次注册验证器时记录的序列号与 10 字符恢复码。任何同时持有二者的人都能恢复完整账号控制权 —— 请妥善保管恢复码。"
[label_restore_code]
other = "恢复码"
[label_show_restore_code]
other = "显示恢复码"
[btn_restore]
other = "恢复"
[msg_empty_restore_code]
other = "请输入 10 字符恢复码。"
[msg_restoring]
other = "正在从战网服务器恢复……"
[msg_restore_failed]
other = "恢复失败:%s"
# --- 老 WinAuth XML 导入 ---
[menu_import_legacy]
other = "导入旧版 WinAuth XML..."
[dialog_import_legacy_title]
other = "导入旧版 WinAuth 配置"
[import_legacy_intro]
other = "请定位原 WinAuth 的 winauth.xml(通常位于 %APPDATA%\\WinAuth)。DPAPI 加密条目只能在加密时使用的 Windows 用户/电脑上解密。导入的条目会追加到当前列表后面。"
[label_import_path]
other = "winauth.xml 路径"
[btn_import]
other = "导入"
[msg_empty_import_path]
other = "请输入 winauth.xml 的路径。"
[msg_legacy_password_required]
other = "该文件包含密码加密的条目 —— 请输入原 WinAuth 的密码。"
[msg_legacy_password_wrong]
other = "旧版 WinAuth 文件密码错误。"
[msg_import_failed]
other = "导入失败:%s"
# --- 热键配置 ---
[btn_hotkey]
other = "热键..."
[btn_clear_hotkey]
other = "清除热键"
[dialog_hotkey_title]
other = "编辑热键"
[label_hotkey]
other = "热键"
[hotkey_intro]
other = "为该条目设置一个全局快捷键,例如 \"Ctrl+Alt+G\"。至少需要一个修饰键(Ctrl、Alt、Shift 或 Win)。在桌面任意位置按下该快捷键后,OTP 会被复制到剪贴板并直接输入到当前前台窗口。"
# --- 其他 UX ---
[btn_copy]
other = "复制"
[msg_copied]
other = "验证码已复制到剪贴板"
[msg_copy_failed]
other = "复制到剪贴板失败"
[msg_empty_list]
other = "还没有验证器,点击\"添加\"开始。"
# --- 二维码扫描 ---
[vendor_scan_qr]
other = "扫描二维码 (otpauth://)"
[dialog_scan_qr_title]
other = "扫描 otpauth 二维码"
[qr_intro]
other = "输入包含二维码的 PNG/JPG 文件路径后点击\"从文件\"。或者将二维码图片复制到剪贴板(Win+Shift+S 截图即可)后点击\"从剪贴板\"。"
[label_qr_path]
other = "图片文件路径"
[btn_qr_from_file]
other = "从文件"
[btn_qr_from_clipboard]
other = "从剪贴板"
[msg_empty_qr_path]
other = "请输入图片文件路径,或使用\"从剪贴板\"。"
[msg_qr_failed]
other = "二维码扫描失败:%s"
[msg_clipboard_no_image]
other = "剪贴板中没有图片"