diff --git a/apps/style/login.css b/apps/style/login.css index b04ee0b2..238460f7 100755 --- a/apps/style/login.css +++ b/apps/style/login.css @@ -45,6 +45,37 @@ transition: 80ms; } +#login-password { + display: none; + width: 220px; + margin-bottom: 10px; + padding: 7px 10px; + color: #fff; + background-color: #eeeeee40; + border: 2px solid #ffffff50; + border-radius: 6px; + outline: none; + text-align: center; +} + +#login-password::placeholder { + color: #ffffffaa; +} + +#login-error { + display: none; + min-height: 18px; + margin-bottom: 8px; + color: #fff; + font-size: 14px; + text-shadow: 0 1px 3px #000; +} + +#loginback.tauri-password #login-password, +#loginback.tauri-password #login-error { + display: block; +} + :root.corner_squ #login { corner-shape: squircle; border-radius: 15px; diff --git a/apps/style/setting.css b/apps/style/setting.css index 61e111bb..1e6ad0f7 100755 --- a/apps/style/setting.css +++ b/apps/style/setting.css @@ -283,6 +283,29 @@ box-shadow: 0 1px 2px 1px var(--s3d); } +.setting-password { + display: grid; + gap: 10px; +} + +.setting-password>div>p:first-child { + font-size: 18px; +} + +.setting-password>div>p:last-child { + color: var(--text2); +} + +.setting-password>.button { + width: max-content; + padding: 5px 18px; +} + +.setting-password>.button.disabled { + pointer-events: none; + opacity: 0.6; +} + .checkbox { width: 40px; height: 20px; diff --git a/desktop.html b/desktop.html index 7f0611aa..82796224 100755 --- a/desktop.html +++ b/desktop.html @@ -188,19 +188,9 @@
Administrator
-
+ +
+
登录
@@ -1558,7 +1548,18 @@

请求记录

您的微软账户

订阅、账单等

您的账户信息

电子邮件、日历和联系人使用的帐户

-

登录选项

Windows Hello、安全密钥、密码、动态锁

+ +

电子邮件和账户

电子邮件、日历和联系人使用的帐户

家庭

管理您的家庭群组、编辑帐户类型和设备权限

Windows 备份

备份您的文件、应用程序、首选项以跨设备恢复它们

diff --git a/desktop.js b/desktop.js index 86b5b229..7165fd99 100755 --- a/desktop.js +++ b/desktop.js @@ -189,6 +189,151 @@ function stop(e) { e.stopPropagation(); return false; } + +let loginPasswordHasPassword = false; + +function win12FinishLogin() { + $('#login').css('opacity', '0'); + $('#login-password').css('opacity', '0'); + $('#login-error').css('opacity', '0'); + $('#login-welc').css('opacity', '1'); + setTimeout(() => { + $('#loginback').addClass('close'); + setTimeout(() => { + $('#loginback').css('opacity', '0'); + }, 500); + setTimeout(() => { + $('#loginback').css('display', 'none'); + }, 2000); + if (use_music) { + document.querySelector('audio#startup-music').play(); + } + }, 2000); +} + +function setLoginError(text) { + $('#login-error').text(text); +} + +async function initLoginPassword() { + if (window.win12Native && window.win12Native.isTauri() && (new URL(location.href)).searchParams.get('skip_login') !== '1') { + try { + const status = await window.win12Native.getLoginPasswordStatus(); + loginPasswordHasPassword = !!(status && status.has_password); + if (loginPasswordHasPassword) { + $('#loginback').addClass('tauri-password'); + $('#login-password').attr('placeholder', '密码'); + $('#login-password').focus(); + } + else { + $('#loginback').removeClass('tauri-password'); + } + } + catch (e) { + setLoginError('无法读取本地密码状态'); + } + } +} + +async function win12LoginSubmit() { + if (!(window.win12Native && window.win12Native.isTauri())) { + win12FinishLogin(); + return; + } + + if (!loginPasswordHasPassword) { + win12FinishLogin(); + return; + } + + const password = $('#login-password').val(); + if (!password) { + setLoginError('请输入密码'); + $('#login-password').focus(); + return; + } + + $('#login').css('pointer-events', 'none'); + setLoginError('正在验证'); + + try { + const result = await window.win12Native.verifyLoginPassword(password); + if (result && result.ok) { + $('#login-password').val(''); + win12FinishLogin(); + return; + } + setLoginError('密码错误'); + $('#login-password').val('').focus(); + } + catch (e) { + setLoginError(String(e)); + } + finally { + $('#login').css('pointer-events', 'auto'); + } +} + +async function win12RefreshPasswordSettingStatus() { + if (!(window.win12Native && window.win12Native.isTauri())) { + $('#setting-password-status').text('仅 Tauri App 可用'); + $('#setting-password-current').hide(); + $('#setting-password-new').prop('disabled', true); + $('#setting-password-submit').addClass('disabled'); + return; + } + + try { + const status = await window.win12Native.getLoginPasswordStatus(); + loginPasswordHasPassword = !!(status && status.has_password); + $('#setting-password-status').text(loginPasswordHasPassword ? '已设置密码' : '未设置密码'); + $('#setting-password-current')[loginPasswordHasPassword ? 'show' : 'hide'](); + $('#setting-password-current').val(''); + $('#setting-password-new').val('').prop('disabled', false); + $('#setting-password-new').attr('placeholder', loginPasswordHasPassword ? '新密码(留空清除密码)' : '新密码'); + $('#setting-password-submit').removeClass('disabled'); + } + catch (e) { + $('#setting-password-status').text(String(e)); + } +} + +async function win12SetLoginPassword() { + if (!(window.win12Native && window.win12Native.isTauri())) { + $('#setting-password-status').text('仅 Tauri App 可用'); + return; + } + + const currentPassword = $('#setting-password-current').val(); + const newPassword = $('#setting-password-new').val(); + if (!loginPasswordHasPassword && !newPassword) { + $('#setting-password-status').text('请输入新密码'); + $('#setting-password-new').focus(); + return; + } + if (loginPasswordHasPassword && !currentPassword) { + $('#setting-password-status').text('请输入当前密码'); + $('#setting-password-current').focus(); + return; + } + + $('#setting-password-submit').addClass('disabled'); + const clearingPassword = loginPasswordHasPassword && !newPassword; + $('#setting-password-status').text(clearingPassword ? '正在清除' : '正在保存'); + + try { + await window.win12Native.setLoginPassword(loginPasswordHasPassword ? currentPassword : null, newPassword); + await win12RefreshPasswordSettingStatus(); + $('#setting-password-status').text(clearingPassword ? '密码已清空' : '密码已保存'); + } + catch (e) { + $('#setting-password-status').text(String(e)); + } + finally { + $('#setting-password-submit').removeClass('disabled'); + } +} + $('input,textarea,*[contenteditable=true]').on('contextmenu', (e) => { stop(e); return true; @@ -2413,6 +2558,7 @@ document.getElementsByTagName('body')[0].onload = () => { $('#loadback').css('display', 'none'); }, 1000); apps.webapps.init(); + initLoginPassword(); //getdata if (localStorage.getItem('theme') == 'dark') { $(':root').addClass('dark'); @@ -2506,10 +2652,14 @@ else { autoUpdate = (autoUpdate == 'true'); } -// PWA 应用 -if (!location.href.match(/((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))/) && !location.href.match('localhost') && !(new URL(location.href)).searchParams.get('develop')) { +const urlParams = new URL(location.href).searchParams; +if (urlParams.get('skip_login') !== '1') { $('#loginback').css('opacity', '1'); $('#loginback').css('display', 'flex'); +} + +// PWA 应用 +if (!location.href.match(/((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))/) && !location.href.match('localhost') && !urlParams.get('develop')) { shownotice('about'); navigator.serviceWorker.register('sw.js', { updateViaCache: 'none', scope: './' }).then(reg => { diff --git a/tauri/tauri_api.js b/tauri/tauri_api.js index d3aa6810..1c1f0739 100644 --- a/tauri/tauri_api.js +++ b/tauri/tauri_api.js @@ -6,4 +6,16 @@ window.win12Native = { if (!this.isTauri()) return null; return await window.__TAURI__.core.invoke("get_battery_info"); }, + async getLoginPasswordStatus() { + if (!this.isTauri()) return null; + return await window.__TAURI__.core.invoke("get_login_password_status"); + }, + async verifyLoginPassword(password) { + if (!this.isTauri()) return { ok: true }; + return await window.__TAURI__.core.invoke("verify_login_password", { password }); + }, + async setLoginPassword(currentPassword, newPassword) { + if (!this.isTauri()) return null; + return await window.__TAURI__.core.invoke("set_login_password", { currentPassword, newPassword }); + }, };