From 104a04c5de01fc533760ab2bb42d2b13f1e1d0bf Mon Sep 17 00:00:00 2001 From: cc <98377878+hicccc77@users.noreply.github.com> Date: Sun, 22 Mar 2026 23:34:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DWindows=20hello=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=83=85=E5=86=B5=E4=B8=8B=E8=AE=BE=E7=BD=AE=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + src/pages/SettingsPage.tsx | 47 ++++++++++++++---------------- src/pages/WelcomePage.tsx | 58 +++++++++++++++++++------------------- 3 files changed, 51 insertions(+), 55 deletions(-) diff --git a/.gitignore b/.gitignore index dbde240..d026e51 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,4 @@ resources/wx_send 概述.md pnpm-lock.yaml /pnpm-workspace.yaml +wechat-research-site \ No newline at end of file diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index b2caa5f..d7c8899 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -32,6 +32,7 @@ const tabs: { id: SettingsTab; label: string; icon: React.ElementType }[] = [ const isMac = navigator.userAgent.toLowerCase().includes('mac') const isLinux = navigator.userAgent.toLowerCase().includes('linux') +const isWindows = !isMac && !isLinux const dbDirName = isMac ? '2.0b4.0.9 目录' : 'xwechat_files 目录' const dbPathPlaceholder = isMac @@ -193,9 +194,7 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { // 检查 Hello 可用性 useEffect(() => { - if (window.PublicKeyCredential) { - void PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then(setHelloAvailable) - } + setHelloAvailable(isWindows) }, []) // 检查 HTTP API 服务状态 @@ -2039,33 +2038,29 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) { showMessage('请输入当前密码以开启 Hello', false) return } + if (!isWindows) { + showMessage('当前系统不支持 Windows Hello', false) + return + } setIsSettingHello(true) try { - const challenge = new Uint8Array(32) - window.crypto.getRandomValues(challenge) - - const credential = await navigator.credentials.create({ - publicKey: { - challenge, - rp: { name: 'WeFlow', id: 'localhost' }, - user: { id: new Uint8Array([1]), name: 'user', displayName: 'User' }, - pubKeyCredParams: [{ alg: -7, type: 'public-key' }], - authenticatorSelection: { userVerification: 'required' }, - timeout: 60000 - } - }) - - if (credential) { - // 存储密码作为 Hello Secret,以便 Hello 解锁时能派生密钥 - await window.electronAPI.auth.setHelloSecret(helloPassword) - setAuthUseHello(true) - setHelloPassword('') - showMessage('Windows Hello 设置成功', true) + const verifyResult = await window.electronAPI.auth.hello('请验证您的身份以开启 Windows Hello') + if (!verifyResult.success) { + showMessage(verifyResult.error || 'Windows Hello 验证失败', false) + return } + + const saveResult = await window.electronAPI.auth.setHelloSecret(helloPassword) + if (!saveResult.success) { + showMessage('Windows Hello 配置保存失败', false) + return + } + + setAuthUseHello(true) + setHelloPassword('') + showMessage('Windows Hello 设置成功', true) } catch (e: any) { - if (e.name !== 'NotAllowedError') { - showMessage(`Windows Hello 设置失败: ${e.message}`, false) - } + showMessage(`Windows Hello 设置失败: ${e?.message || String(e)}`, false) } finally { setIsSettingHello(false) } diff --git a/src/pages/WelcomePage.tsx b/src/pages/WelcomePage.tsx index 8f529cc..846ce73 100644 --- a/src/pages/WelcomePage.tsx +++ b/src/pages/WelcomePage.tsx @@ -103,9 +103,7 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { // 检查 Hello 可用性 useEffect(() => { - if (window.PublicKeyCredential) { - void PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then(setHelloAvailable) - } + setHelloAvailable(isWindows) }, []) async function sha256(message: string) { @@ -117,35 +115,27 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { } const handleSetupHello = async () => { + if (!isWindows) { + setError('当前系统不支持 Windows Hello') + return + } + if (!authPassword || authPassword !== authConfirmPassword) { + setError('请先设置并确认应用密码,再开启 Windows Hello') + return + } + setIsSettingHello(true) try { - // 注册凭证 (WebAuthn) - const challenge = new Uint8Array(32) - window.crypto.getRandomValues(challenge) - - const credential = await navigator.credentials.create({ - publicKey: { - challenge, - rp: { name: 'WeFlow', id: 'localhost' }, - user: { - id: new Uint8Array([1]), - name: 'user', - displayName: 'User' - }, - pubKeyCredParams: [{ alg: -7, type: 'public-key' }], - authenticatorSelection: { userVerification: 'required' }, - timeout: 60000 - } - }) - - if (credential) { - setEnableHello(true) - // 成功提示? + const result = await window.electronAPI.auth.hello('请验证您的身份以开启 Windows Hello') + if (!result.success) { + setError(`Windows Hello 设置失败: ${result.error || '验证失败'}`) + return } + + setEnableHello(true) + setError('') } catch (e: any) { - if (e.name !== 'NotAllowedError') { - setError('Windows Hello 设置失败: ' + e.message) - } + setError(`Windows Hello 设置失败: ${e?.message || String(e)}`) } finally { setIsSettingHello(false) } @@ -502,7 +492,17 @@ function WelcomePage({ standalone = false }: WelcomePageProps) { const hash = await sha256(authPassword) await configService.setAuthEnabled(true) await configService.setAuthPassword(hash) - await configService.setAuthUseHello(enableHello) + if (enableHello) { + const helloResult = await window.electronAPI.auth.setHelloSecret(authPassword) + if (!helloResult.success) { + setError('Windows Hello 配置保存失败') + setLoading(false) + return + } + } else { + await window.electronAPI.auth.clearHelloSecret() + await configService.setAuthUseHello(false) + } } await configService.setOnboardingDone(true)