-
登录选项
Windows Hello、安全密钥、密码、动态锁
+
登录选项
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 });
+ },
};