fix: 因 RSI 官网变更,移除自动填充功能 (不再支持)

This commit is contained in:
xkeyC 2024-04-26 22:55:38 +08:00
parent 2c71f3baba
commit d2694a1e25
24 changed files with 12 additions and 515 deletions

View File

@ -221,19 +221,8 @@ InitWebLocalization();
async function getRSILauncherToken(channelId) { async function getRSILauncherToken(channelId) {
if (!window.location.href.includes("robertsspaceindustries.com")) return; if (!window.location.href.includes("robertsspaceindustries.com")) return;
if (window.location.href.startsWith("https://robertsspaceindustries.com/connect")) { let loginBodyElement = $(".c-form.c-signIn");
$(function () { loginBodyElement.hide();
$('#email').on('input', function () {
let inputEmail = $('#email').val()
sessionStorage.setItem('inputEmail', inputEmail);
});
$('#password').on('input', function () {
let inputPassword = $('#password').val()
sessionStorage.setItem('inputPassword', inputPassword);
});
});
}
// check login // check login
let r = await fetch("api/launcher/v3/account/check", { let r = await fetch("api/launcher/v3/account/check", {
method: 'POST', headers: { method: 'POST', headers: {
@ -241,6 +230,7 @@ async function getRSILauncherToken(channelId) {
}, },
}); });
if (r.status !== 200) { if (r.status !== 200) {
loginBodyElement.show();
// wait login // wait login
window.chrome.webview.postMessage({action: 'webview_rsi_login_show_window'}); window.chrome.webview.postMessage({action: 'webview_rsi_login_show_window'});
return; return;
@ -309,25 +299,6 @@ async function getRSILauncherToken(channelId) {
'releaseInfo': releaseDataJson, 'releaseInfo': releaseDataJson,
"avatar": avatarUrl, "avatar": avatarUrl,
'libraryData': libraryData, 'libraryData': libraryData,
"inputEmail": sessionStorage.getItem("inputEmail"),
"inputPassword": sessionStorage.getItem("inputPassword")
}
});
}
function RSIAutoLogin(email, pwd) {
if (!window.location.href.includes("robertsspaceindustries.com")) return;
$(function () {
if (email !== "") {
$('#email').val(email)
}
if (pwd !== "") {
$('#password').val(pwd)
}
sessionStorage.setItem('inputPassword', '');
if (email !== "" && pwd !== "") {
$("#remember").prop("checked", true);
$('.c-formLegacyEnlist__submit-button-label').click();
} }
}); });
} }
@ -345,5 +316,4 @@ function SCTShowToast(message) {
document.body.removeChild(m) document.body.removeChild(m)
}, d * 1000); }, d * 1000);
}, 3500); }, 3500);
} }

View File

@ -1,76 +0,0 @@
// Copyright (c) 2020, Dart | Windows. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Reads and writes credentials
import 'dart:convert';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:win32/win32.dart';
class Win32Credentials {
static void write(
{required String credentialName,
required String userName,
required String password}) {
final examplePassword = utf8.encode(password);
final blob = examplePassword.allocatePointer();
final credential = calloc<CREDENTIAL>()
..ref.Type = CRED_TYPE.CRED_TYPE_GENERIC
..ref.TargetName = credentialName.toNativeUtf16()
..ref.Persist = CRED_PERSIST.CRED_PERSIST_LOCAL_MACHINE
..ref.UserName = userName.toNativeUtf16()
..ref.CredentialBlob = blob
..ref.CredentialBlobSize = examplePassword.length;
final result = CredWrite(credential, 0);
if (result != TRUE) {
final errorCode = GetLastError();
dPrint('Error ($result): $errorCode');
return;
}
dPrint('Success (blob size: ${credential.ref.CredentialBlobSize})');
free(blob);
free(credential);
}
static MapEntry<String, String>? read(String credentialName) {
dPrint('Reading $credentialName ...');
final credPointer = calloc<Pointer<CREDENTIAL>>();
final result = CredRead(credentialName.toNativeUtf16(),
CRED_TYPE.CRED_TYPE_GENERIC, 0, credPointer);
if (result != TRUE) {
final errorCode = GetLastError();
var errorText = '$errorCode';
if (errorCode == WIN32_ERROR.ERROR_NOT_FOUND) {
errorText += ' Not found.';
}
dPrint('Error ($result): $errorText');
return null;
}
final cred = credPointer.value.ref;
final blob = cred.CredentialBlob.asTypedList(cred.CredentialBlobSize);
final password = utf8.decode(blob);
CredFree(credPointer.value);
free(credPointer);
return MapEntry(cred.UserName.toDartString(), password);
}
static void delete(String credentialName) {
dPrint('Deleting $credentialName');
final result = CredDelete(
credentialName.toNativeUtf16(), CRED_TYPE.CRED_TYPE_GENERIC, 0);
if (result != TRUE) {
final errorCode = GetLastError();
dPrint('Error ($result): $errorCode');
return;
}
dPrint('Successfully deleted credential.');
}
}

View File

@ -504,9 +504,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("One-click launch"), MessageLookupByLibrary.simpleMessage("One-click launch"),
"home_action_performance_optimization": "home_action_performance_optimization":
MessageLookupByLibrary.simpleMessage("Performance optimization"), MessageLookupByLibrary.simpleMessage("Performance optimization"),
"home_action_q_auto_password_fill_prompt":
MessageLookupByLibrary.simpleMessage(
"Turn on the automatic password filling?"),
"home_action_rsi_status_arena_commander": "home_action_rsi_status_arena_commander":
MessageLookupByLibrary.simpleMessage("AC"), MessageLookupByLibrary.simpleMessage("AC"),
"home_action_rsi_status_electronic_access": "home_action_rsi_status_electronic_access":
@ -537,8 +534,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("In progress"), MessageLookupByLibrary.simpleMessage("In progress"),
"home_info_account_security_warning": MessageLookupByLibrary.simpleMessage( "home_info_account_security_warning": MessageLookupByLibrary.simpleMessage(
"In order to ensure the security of the account, the one -click startup function has been disabled in the development version, and we will provide this feature in the Microsoft store version.\n\nThe Microsoft Store Edition is provided with a reliable distribution download and digital signature by Microsoft, which can effectively prevent software from being maliciously tampered with.\n\nTip: You can use Localization without using a box to start the game."), "In order to ensure the security of the account, the one -click startup function has been disabled in the development version, and we will provide this feature in the Microsoft store version.\n\nThe Microsoft Store Edition is provided with a reliable distribution download and digital signature by Microsoft, which can effectively prevent software from being maliciously tampered with.\n\nTip: You can use Localization without using a box to start the game."),
"home_info_auto_fill_notice": MessageLookupByLibrary.simpleMessage(
"* If the automatic filling is turned on, please pay attention to the Windows Hello pop-up"),
"home_info_one_click_launch_warning": "home_info_one_click_launch_warning":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"One -click start -up function prompt"), "One -click start -up function prompt"),
@ -558,17 +553,11 @@ class MessageLookup extends MessageLookupByLibrary {
"Need to install WebView2 Runtime"), "Need to install WebView2 Runtime"),
"home_login_info_action_ignore": "home_login_info_action_ignore":
MessageLookupByLibrary.simpleMessage("Neglect"), MessageLookupByLibrary.simpleMessage("Neglect"),
"home_login_info_enter_pin_to_encrypt":
MessageLookupByLibrary.simpleMessage(
"Enter PIN to enable encryption"),
"home_login_info_game_version_outdated": "home_login_info_game_version_outdated":
MessageLookupByLibrary.simpleMessage("Outdated game version"), MessageLookupByLibrary.simpleMessage("Outdated game version"),
"home_login_info_one_click_launch_description": "home_login_info_one_click_launch_description":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"This feature can help you start the game more conveniently.\n\nTo ensure the security of the account, this function uses the Localization browser to retain the login status and will not save your password information (unless you enable the automatic filling function).\n\nWhen logging in to the account, please make sure your SCToolBox is downloaded from a trusted source."), "This feature can help you start the game more conveniently.\n\nTo ensure the security of the account, this function uses the Localization browser to retain the login status and will not save your password information (unless you enable the automatic filling function).\n\nWhen logging in to the account, please make sure your SCToolBox is downloaded from a trusted source."),
"home_login_info_password_encryption_notice":
MessageLookupByLibrary.simpleMessage(
"The box will use the PIN and Windows credentials to save your password encryption, and the password is only stored in your device.\n\nWhen you need to enter a password for the next login, you only need to authorize PIN to automatically fill in the login."),
"home_login_info_rsi_server_report": m31, "home_login_info_rsi_server_report": m31,
"home_login_title_launching_game": "home_login_title_launching_game":
MessageLookupByLibrary.simpleMessage("Launching game for you ..."), MessageLookupByLibrary.simpleMessage("Launching game for you ..."),
@ -917,12 +906,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("RSI starter position:"), MessageLookupByLibrary.simpleMessage("RSI starter position:"),
"tools_info_scanning": "tools_info_scanning":
MessageLookupByLibrary.simpleMessage("Scanning..."), MessageLookupByLibrary.simpleMessage("Scanning..."),
"webview_localization_device_windows_hello_toast":
MessageLookupByLibrary.simpleMessage(
"Please complete the Windows Hello verification to fill in the password"),
"webview_localization_enter_device_pin":
MessageLookupByLibrary.simpleMessage(
"Please enter the device PIN to automatically log in to the RSI account"),
"webview_localization_finished_invitations": "webview_localization_finished_invitations":
MessageLookupByLibrary.simpleMessage("Completed invitations"), MessageLookupByLibrary.simpleMessage("Completed invitations"),
"webview_localization_name_member": "webview_localization_name_member":

View File

@ -117,31 +117,22 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("RSI アカウントログイン"), MessageLookupByLibrary.simpleMessage("RSI アカウントログイン"),
"home_action_one_click_launch": "home_action_one_click_launch":
MessageLookupByLibrary.simpleMessage("ワンクリック起動"), MessageLookupByLibrary.simpleMessage("ワンクリック起動"),
"home_action_q_auto_password_fill_prompt":
MessageLookupByLibrary.simpleMessage("パスワードの自動入力はオンになっていますか?"),
"home_holiday_countdown": "home_holiday_countdown":
MessageLookupByLibrary.simpleMessage("祝日カウントダウン"), MessageLookupByLibrary.simpleMessage("祝日カウントダウン"),
"home_holiday_countdown_disclaimer": "home_holiday_countdown_disclaimer":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"* 上記の祝日は手作業で収集・管理されているため、誤りがある可能性があります、フィードバックは歓迎する!!"), "* 上記の祝日は手作業で収集・管理されているため、誤りがある可能性があります、フィードバックは歓迎する!!"),
"home_info_auto_fill_notice": MessageLookupByLibrary.simpleMessage(
"* 自動入力がオンになっている場合は、Windows Hello のポップアップに注意してください"),
"home_login_action_title_box_one_click_launch": "home_login_action_title_box_one_click_launch":
MessageLookupByLibrary.simpleMessage("ボックスワンクリック起動"), MessageLookupByLibrary.simpleMessage("ボックスワンクリック起動"),
"home_login_action_title_need_webview2_runtime": "home_login_action_title_need_webview2_runtime":
MessageLookupByLibrary.simpleMessage("WebView2 Runtime のインストールが必要"), MessageLookupByLibrary.simpleMessage("WebView2 Runtime のインストールが必要"),
"home_login_info_action_ignore": "home_login_info_action_ignore":
MessageLookupByLibrary.simpleMessage("無視する"), MessageLookupByLibrary.simpleMessage("無視する"),
"home_login_info_enter_pin_to_encrypt":
MessageLookupByLibrary.simpleMessage("PINを入力して暗号化を有効にする"),
"home_login_info_game_version_outdated": "home_login_info_game_version_outdated":
MessageLookupByLibrary.simpleMessage("ゲームバージョンが古すぎる"), MessageLookupByLibrary.simpleMessage("ゲームバージョンが古すぎる"),
"home_login_info_one_click_launch_description": "home_login_info_one_click_launch_description":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"この機能は、ゲームをより便利に起動するのに役立ちます。\n\nアカウントのセキュリティを確保するため、この機能はローカライズブラウザを使用してログイン状態を保持し、パスワード情報を保存しません(自動入力オンの場合を除く)。\n\nこの機能を使用してアカウントにログインする際は、SCToolBox が信頼できるソースからダウンロードされていることを確認してください。"), "この機能は、ゲームをより便利に起動するのに役立ちます。\n\nアカウントのセキュリティを確保するため、この機能はローカライズブラウザを使用してログイン状態を保持し、パスワード情報を保存しません(自動入力オンの場合を除く)。\n\nこの機能を使用してアカウントにログインする際は、SCToolBox が信頼できるソースからダウンロードされていることを確認してください。"),
"home_login_info_password_encryption_notice":
MessageLookupByLibrary.simpleMessage(
"このツールには PIN と Windows 認証を使用して暗号化のパスワードが保存され、パスワードはローカルのみ保存されます。\n\n次回のログインでパスワードが必要になった場合、PIN だけてを許可する後、パスワードは自動的に入力して、ログインできます。"),
"home_login_info_rsi_server_report": m31, "home_login_info_rsi_server_report": m31,
"home_login_title_launching_game": "home_login_title_launching_game":
MessageLookupByLibrary.simpleMessage("ゲーム起動中..."), MessageLookupByLibrary.simpleMessage("ゲーム起動中..."),

View File

@ -451,8 +451,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("一键启动"), MessageLookupByLibrary.simpleMessage("一键启动"),
"home_action_performance_optimization": "home_action_performance_optimization":
MessageLookupByLibrary.simpleMessage("性能优化"), MessageLookupByLibrary.simpleMessage("性能优化"),
"home_action_q_auto_password_fill_prompt":
MessageLookupByLibrary.simpleMessage("是否开启自动密码填充?"),
"home_action_rsi_status_arena_commander": "home_action_rsi_status_arena_commander":
MessageLookupByLibrary.simpleMessage("竞技场指挥官"), MessageLookupByLibrary.simpleMessage("竞技场指挥官"),
"home_action_rsi_status_electronic_access": "home_action_rsi_status_electronic_access":
@ -482,8 +480,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("正在进行中"), MessageLookupByLibrary.simpleMessage("正在进行中"),
"home_info_account_security_warning": MessageLookupByLibrary.simpleMessage( "home_info_account_security_warning": MessageLookupByLibrary.simpleMessage(
"为确保账户安全,一键启动功能已在开发版中禁用,我们将在微软商店版本中提供此功能。\n\n微软商店版由微软提供可靠的分发下载与数字签名,可有效防止软件被恶意篡改。\n\n提示:您无需使用盒子启动游戏也可使用汉化。"), "为确保账户安全,一键启动功能已在开发版中禁用,我们将在微软商店版本中提供此功能。\n\n微软商店版由微软提供可靠的分发下载与数字签名,可有效防止软件被恶意篡改。\n\n提示:您无需使用盒子启动游戏也可使用汉化。"),
"home_info_auto_fill_notice": MessageLookupByLibrary.simpleMessage(
"* 若开启了自动填充,请留意弹出的 Windows Hello 窗口"),
"home_info_one_click_launch_warning": "home_info_one_click_launch_warning":
MessageLookupByLibrary.simpleMessage("一键启动功能提示"), MessageLookupByLibrary.simpleMessage("一键启动功能提示"),
"home_info_valid_installation_required": "home_info_valid_installation_required":
@ -498,16 +494,11 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("需要安装 WebView2 Runtime"), MessageLookupByLibrary.simpleMessage("需要安装 WebView2 Runtime"),
"home_login_info_action_ignore": "home_login_info_action_ignore":
MessageLookupByLibrary.simpleMessage("忽略"), MessageLookupByLibrary.simpleMessage("忽略"),
"home_login_info_enter_pin_to_encrypt":
MessageLookupByLibrary.simpleMessage("输入PIN以启用加密"),
"home_login_info_game_version_outdated": "home_login_info_game_version_outdated":
MessageLookupByLibrary.simpleMessage("游戏版本过期"), MessageLookupByLibrary.simpleMessage("游戏版本过期"),
"home_login_info_one_click_launch_description": "home_login_info_one_click_launch_description":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"本功能可以帮您更加便利的启动游戏。\n\n为确保账户安全 ,本功能使用汉化浏览器保留登录状态,且不会保存您的密码信息(除非你启用了自动填充功能)。\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。"), "本功能可以帮您更加便利的启动游戏。\n\n为确保账户安全 ,本功能使用汉化浏览器保留登录状态,且不会保存您的密码信息(除非你启用了自动填充功能)。\n\n使用此功能登录账号时请确保您的 SC汉化盒子 是从可信任的来源下载。"),
"home_login_info_password_encryption_notice":
MessageLookupByLibrary.simpleMessage(
"盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时您只需授权PIN即可自动填充登录。"),
"home_login_info_rsi_server_report": m31, "home_login_info_rsi_server_report": m31,
"home_login_title_launching_game": "home_login_title_launching_game":
MessageLookupByLibrary.simpleMessage("正在为您启动游戏..."), MessageLookupByLibrary.simpleMessage("正在为您启动游戏..."),
@ -808,10 +799,6 @@ class MessageLookup extends MessageLookupByLibrary {
"tools_info_rsi_launcher_location": "tools_info_rsi_launcher_location":
MessageLookupByLibrary.simpleMessage("RSI启动器位置"), MessageLookupByLibrary.simpleMessage("RSI启动器位置"),
"tools_info_scanning": MessageLookupByLibrary.simpleMessage("正在扫描..."), "tools_info_scanning": MessageLookupByLibrary.simpleMessage("正在扫描..."),
"webview_localization_device_windows_hello_toast":
MessageLookupByLibrary.simpleMessage("请完成 Windows Hello 验证以填充密码"),
"webview_localization_enter_device_pin":
MessageLookupByLibrary.simpleMessage("请输入设备PIN以自动登录RSI账户"),
"webview_localization_finished_invitations": "webview_localization_finished_invitations":
MessageLookupByLibrary.simpleMessage("已完成的邀请"), MessageLookupByLibrary.simpleMessage("已完成的邀请"),
"webview_localization_name_member": "webview_localization_name_member":

View File

@ -451,8 +451,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("快速啟動"), MessageLookupByLibrary.simpleMessage("快速啟動"),
"home_action_performance_optimization": "home_action_performance_optimization":
MessageLookupByLibrary.simpleMessage("性能調整"), MessageLookupByLibrary.simpleMessage("性能調整"),
"home_action_q_auto_password_fill_prompt":
MessageLookupByLibrary.simpleMessage("是否開啟自動密碼輸入?"),
"home_action_rsi_status_arena_commander": "home_action_rsi_status_arena_commander":
MessageLookupByLibrary.simpleMessage("競技場指揮官"), MessageLookupByLibrary.simpleMessage("競技場指揮官"),
"home_action_rsi_status_electronic_access": "home_action_rsi_status_electronic_access":
@ -482,8 +480,6 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("正在進行中"), MessageLookupByLibrary.simpleMessage("正在進行中"),
"home_info_account_security_warning": MessageLookupByLibrary.simpleMessage( "home_info_account_security_warning": MessageLookupByLibrary.simpleMessage(
"為確保帳戶安全,快速啟動功能已在開發版中禁用,我們將在 Microsoft Store 版本中提供此功能。\n\nMicrosoft Store 版由微軟提供可靠的分發下載與數字簽名,可有效防止軟件被惡意篡改。\n\n提示:您無需使用盒子啟動遊戲也可使用翻譯。"), "為確保帳戶安全,快速啟動功能已在開發版中禁用,我們將在 Microsoft Store 版本中提供此功能。\n\nMicrosoft Store 版由微軟提供可靠的分發下載與數字簽名,可有效防止軟件被惡意篡改。\n\n提示:您無需使用盒子啟動遊戲也可使用翻譯。"),
"home_info_auto_fill_notice": MessageLookupByLibrary.simpleMessage(
"* 若開啟了自動輸入,請留意彈出的 Windows Hello 窗口"),
"home_info_one_click_launch_warning": "home_info_one_click_launch_warning":
MessageLookupByLibrary.simpleMessage("一鍵啟動功能提示"), MessageLookupByLibrary.simpleMessage("一鍵啟動功能提示"),
"home_info_valid_installation_required": "home_info_valid_installation_required":
@ -498,16 +494,11 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("需要安裝 WebView2 Runtime"), MessageLookupByLibrary.simpleMessage("需要安裝 WebView2 Runtime"),
"home_login_info_action_ignore": "home_login_info_action_ignore":
MessageLookupByLibrary.simpleMessage("忽略"), MessageLookupByLibrary.simpleMessage("忽略"),
"home_login_info_enter_pin_to_encrypt":
MessageLookupByLibrary.simpleMessage("輸入PIN以啟用加密"),
"home_login_info_game_version_outdated": "home_login_info_game_version_outdated":
MessageLookupByLibrary.simpleMessage("遊戲版本過期"), MessageLookupByLibrary.simpleMessage("遊戲版本過期"),
"home_login_info_one_click_launch_description": "home_login_info_one_click_launch_description":
MessageLookupByLibrary.simpleMessage( MessageLookupByLibrary.simpleMessage(
"此功能可以幫您更加便利的啟動遊戲。\n\n為確保帳戶安全 ,此功能使用漢化瀏覽器保留登入狀態,且不會保存您的密碼資訊(除非你啟用了自動輸入功能)。\n\n使用此功能登入帳號時請確保您的 SC漢化盒子 是從可信任的來源下載。"), "此功能可以幫您更加便利的啟動遊戲。\n\n為確保帳戶安全 ,此功能使用漢化瀏覽器保留登入狀態,且不會保存您的密碼資訊(除非你啟用了自動輸入功能)。\n\n使用此功能登入帳號時請確保您的 SC漢化盒子 是從可信任的來源下載。"),
"home_login_info_password_encryption_notice":
MessageLookupByLibrary.simpleMessage(
"盒子將使用 PIN 與 Windows 憑據加密保存您的密碼,密碼只儲存在您的裝置中。\n\n當下次登入需要輸入密碼時您只需授權PIN即可自動輸入登入。"),
"home_login_info_rsi_server_report": m31, "home_login_info_rsi_server_report": m31,
"home_login_title_launching_game": "home_login_title_launching_game":
MessageLookupByLibrary.simpleMessage("正在為您啟動遊戲..."), MessageLookupByLibrary.simpleMessage("正在為您啟動遊戲..."),
@ -806,10 +797,6 @@ class MessageLookup extends MessageLookupByLibrary {
"tools_info_rsi_launcher_location": "tools_info_rsi_launcher_location":
MessageLookupByLibrary.simpleMessage("RSI啟動器位置"), MessageLookupByLibrary.simpleMessage("RSI啟動器位置"),
"tools_info_scanning": MessageLookupByLibrary.simpleMessage("正在掃描..."), "tools_info_scanning": MessageLookupByLibrary.simpleMessage("正在掃描..."),
"webview_localization_device_windows_hello_toast":
MessageLookupByLibrary.simpleMessage("請完成 Windows Hello 驗證以輸入密碼"),
"webview_localization_enter_device_pin":
MessageLookupByLibrary.simpleMessage("請輸入裝置PIN以自動登入RSI帳戶"),
"webview_localization_finished_invitations": "webview_localization_finished_invitations":
MessageLookupByLibrary.simpleMessage("已完成的邀請"), MessageLookupByLibrary.simpleMessage("已完成的邀請"),
"webview_localization_name_member": "webview_localization_name_member":

View File

@ -290,16 +290,6 @@ class S {
); );
} }
/// `* If the automatic filling is turned on, please pay attention to the Windows Hello pop-up`
String get home_info_auto_fill_notice {
return Intl.message(
'* If the automatic filling is turned on, please pay attention to the Windows Hello pop-up',
name: 'home_info_auto_fill_notice',
desc: '',
args: [],
);
}
/// `Welcome back!` /// `Welcome back!`
String get home_login_title_welcome_back { String get home_login_title_welcome_back {
return Intl.message( return Intl.message(
@ -330,36 +320,6 @@ class S {
); );
} }
/// `Turn on the automatic password filling?`
String get home_action_q_auto_password_fill_prompt {
return Intl.message(
'Turn on the automatic password filling?',
name: 'home_action_q_auto_password_fill_prompt',
desc: '',
args: [],
);
}
/// `The box will use the PIN and Windows credentials to save your password encryption, and the password is only stored in your device.\n\nWhen you need to enter a password for the next login, you only need to authorize PIN to automatically fill in the login.`
String get home_login_info_password_encryption_notice {
return Intl.message(
'The box will use the PIN and Windows credentials to save your password encryption, and the password is only stored in your device.\n\nWhen you need to enter a password for the next login, you only need to authorize PIN to automatically fill in the login.',
name: 'home_login_info_password_encryption_notice',
desc: '',
args: [],
);
}
/// `Enter PIN to enable encryption`
String get home_login_info_enter_pin_to_encrypt {
return Intl.message(
'Enter PIN to enable encryption',
name: 'home_login_info_enter_pin_to_encrypt',
desc: '',
args: [],
);
}
/// `Outdated game version` /// `Outdated game version`
String get home_login_info_game_version_outdated { String get home_login_info_game_version_outdated {
return Intl.message( return Intl.message(
@ -3383,26 +3343,6 @@ class S {
); );
} }
/// `Please enter the device PIN to automatically log in to the RSI account`
String get webview_localization_enter_device_pin {
return Intl.message(
'Please enter the device PIN to automatically log in to the RSI account',
name: 'webview_localization_enter_device_pin',
desc: '',
args: [],
);
}
/// `Please complete the Windows Hello verification to fill in the password`
String get webview_localization_device_windows_hello_toast {
return Intl.message(
'Please complete the Windows Hello verification to fill in the password',
name: 'webview_localization_device_windows_hello_toast',
desc: '',
args: [],
);
}
/// `Language` /// `Language`
String get settings_app_language { String get settings_app_language {
return Intl.message( return Intl.message(

View File

@ -48,19 +48,12 @@
"@home_action_one_click_launch": {}, "@home_action_one_click_launch": {},
"home_title_logging_in": "Logging in...", "home_title_logging_in": "Logging in...",
"@home_title_logging_in": {}, "@home_title_logging_in": {},
"home_info_auto_fill_notice": "* If the automatic filling is turned on, please pay attention to the Windows Hello pop-up",
"@home_info_auto_fill_notice": {},
"home_login_title_welcome_back": "Welcome back!", "home_login_title_welcome_back": "Welcome back!",
"@home_login_title_welcome_back": {}, "@home_login_title_welcome_back": {},
"home_login_title_launching_game": "Launching game for you ...", "home_login_title_launching_game": "Launching game for you ...",
"@home_login_title_launching_game": {}, "@home_login_title_launching_game": {},
"home_action_login_rsi_account": "Log in to RSI account", "home_action_login_rsi_account": "Log in to RSI account",
"@home_action_login_rsi_account": {}, "@home_action_login_rsi_account": {},
"home_action_q_auto_password_fill_prompt": "Turn on the automatic password filling?",
"@home_action_q_auto_password_fill_prompt": {},
"home_login_info_password_encryption_notice": "The box will use the PIN and Windows credentials to save your password encryption, and the password is only stored in your device.\n\nWhen you need to enter a password for the next login, you only need to authorize PIN to automatically fill in the login.",
"@home_login_info_password_encryption_notice": {},
"home_login_info_enter_pin_to_encrypt": "Enter PIN to enable encryption",
"@home_login_info_enter_pin_to_encrypt": {}, "@home_login_info_enter_pin_to_encrypt": {},
"home_login_info_game_version_outdated": "Outdated game version", "home_login_info_game_version_outdated": "Outdated game version",
"@home_login_info_game_version_outdated": {}, "@home_login_info_game_version_outdated": {},
@ -666,10 +659,6 @@
"@webview_localization_finished_invitations": {}, "@webview_localization_finished_invitations": {},
"app_init_failed_with_reason": "Initialization failure: {v0}", "app_init_failed_with_reason": "Initialization failure: {v0}",
"@app_init_failed_with_reason": {}, "@app_init_failed_with_reason": {},
"webview_localization_enter_device_pin": "Please enter the device PIN to automatically log in to the RSI account",
"@webview_localization_enter_device_pin": {},
"webview_localization_device_windows_hello_toast": "Please complete the Windows Hello verification to fill in the password",
"@webview_localization_device_windows_hello_toast": {},
"settings_app_language": "Language", "settings_app_language": "Language",
"@settings_app_language": {}, "@settings_app_language": {},
"settings_app_language_auto": "Automatic", "settings_app_language_auto": "Automatic",

View File

@ -40,18 +40,12 @@
"@home_action_one_click_launch": {}, "@home_action_one_click_launch": {},
"home_title_logging_in": "ログイン中...", "home_title_logging_in": "ログイン中...",
"@home_title_logging_in": {}, "@home_title_logging_in": {},
"home_info_auto_fill_notice": "* 自動入力がオンになっている場合は、Windows Hello のポップアップに注意してください",
"@home_info_auto_fill_notice": {},
"home_login_title_welcome_back": "お帰りなさい!", "home_login_title_welcome_back": "お帰りなさい!",
"@home_login_title_welcome_back": {}, "@home_login_title_welcome_back": {},
"home_login_title_launching_game": "ゲーム起動中...", "home_login_title_launching_game": "ゲーム起動中...",
"@home_login_title_launching_game": {}, "@home_login_title_launching_game": {},
"home_action_login_rsi_account": "RSI アカウントログイン", "home_action_login_rsi_account": "RSI アカウントログイン",
"@home_action_login_rsi_account": {}, "@home_action_login_rsi_account": {},
"home_action_q_auto_password_fill_prompt": "パスワードの自動入力はオンになっていますか?",
"@home_action_q_auto_password_fill_prompt": {},
"home_login_info_enter_pin_to_encrypt": "PINを入力して暗号化を有効にする",
"@home_login_info_enter_pin_to_encrypt": {},
"home_login_info_game_version_outdated": "ゲームバージョンが古すぎる", "home_login_info_game_version_outdated": "ゲームバージョンが古すぎる",
"@home_login_info_game_version_outdated": {}, "@home_login_info_game_version_outdated": {},
"home_login_info_rsi_server_report": "RSI サーバレポートのバージョン:{v1} \n\nローカルのバージョン{v2} \n\nRSI Launcher を使ってゲームをアップデートしてください!", "home_login_info_rsi_server_report": "RSI サーバレポートのバージョン:{v1} \n\nローカルのバージョン{v2} \n\nRSI Launcher を使ってゲームをアップデートしてください!",
@ -118,8 +112,6 @@
"@downloader_action_confirm_cancel_all_tasks": {}, "@downloader_action_confirm_cancel_all_tasks": {},
"downloader_action_confirm_cancel_download": "ダウンロードのキャンセルを確認しますか?", "downloader_action_confirm_cancel_download": "ダウンロードのキャンセルを確認しますか?",
"@downloader_action_confirm_cancel_download": {}, "@downloader_action_confirm_cancel_download": {},
"home_login_info_password_encryption_notice": "このツールには PIN と Windows 認証を使用して暗号化のパスワードが保存され、パスワードはローカルのみ保存されます。\n\n次回のログインでパスワードが必要になった場合、PIN だけてを許可する後、パスワードは自動的に入力して、ログインできます。",
"@home_login_info_password_encryption_notice": {},
"home_login_info_one_click_launch_description": "この機能は、ゲームをより便利に起動するのに役立ちます。\n\nアカウントのセキュリティを確保するため、この機能はローカライズブラウザを使用してログイン状態を保持し、パスワード情報を保存しません自動入力オンの場合を除く。\n\nこの機能を使用してアカウントにログインする際は、SCToolBox が信頼できるソースからダウンロードされていることを確認してください。", "home_login_info_one_click_launch_description": "この機能は、ゲームをより便利に起動するのに役立ちます。\n\nアカウントのセキュリティを確保するため、この機能はローカライズブラウザを使用してログイン状態を保持し、パスワード情報を保存しません自動入力オンの場合を除く。\n\nこの機能を使用してアカウントにログインする際は、SCToolBox が信頼できるソースからダウンロードされていることを確認してください。",
"@home_login_info_one_click_launch_description": {}, "@home_login_info_one_click_launch_description": {},
"downloader_info_manual_file_deletion_note": "ダウンロードしたファイルが不要になった場合は、手動で削除する必要があります。", "downloader_info_manual_file_deletion_note": "ダウンロードしたファイルが不要になった場合は、手動で削除する必要があります。",

View File

@ -48,20 +48,12 @@
"@home_action_one_click_launch": {}, "@home_action_one_click_launch": {},
"home_title_logging_in": "登录中...", "home_title_logging_in": "登录中...",
"@home_title_logging_in": {}, "@home_title_logging_in": {},
"home_info_auto_fill_notice": "* 若开启了自动填充,请留意弹出的 Windows Hello 窗口",
"@home_info_auto_fill_notice": {},
"home_login_title_welcome_back": "欢迎回来!", "home_login_title_welcome_back": "欢迎回来!",
"@home_login_title_welcome_back": {}, "@home_login_title_welcome_back": {},
"home_login_title_launching_game": "正在为您启动游戏...", "home_login_title_launching_game": "正在为您启动游戏...",
"@home_login_title_launching_game": {}, "@home_login_title_launching_game": {},
"home_action_login_rsi_account": "登录 RSI 账户", "home_action_login_rsi_account": "登录 RSI 账户",
"@home_action_login_rsi_account": {}, "@home_action_login_rsi_account": {},
"home_action_q_auto_password_fill_prompt": "是否开启自动密码填充?",
"@home_action_q_auto_password_fill_prompt": {},
"home_login_info_password_encryption_notice": "盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时您只需授权PIN即可自动填充登录。",
"@home_login_info_password_encryption_notice": {},
"home_login_info_enter_pin_to_encrypt": "输入PIN以启用加密",
"@home_login_info_enter_pin_to_encrypt": {},
"home_login_info_game_version_outdated": "游戏版本过期", "home_login_info_game_version_outdated": "游戏版本过期",
"@home_login_info_game_version_outdated": {}, "@home_login_info_game_version_outdated": {},
"home_login_info_rsi_server_report": "RSI 服务器报告版本号:{v1} \n\n本地版本号{v2} \n\n建议使用 RSI Launcher 更新游戏!", "home_login_info_rsi_server_report": "RSI 服务器报告版本号:{v1} \n\n本地版本号{v2} \n\n建议使用 RSI Launcher 更新游戏!",

View File

@ -49,20 +49,12 @@
"@home_action_one_click_launch": {}, "@home_action_one_click_launch": {},
"home_title_logging_in": "登入中...", "home_title_logging_in": "登入中...",
"@home_title_logging_in": {}, "@home_title_logging_in": {},
"home_info_auto_fill_notice": "* 若開啟了自動輸入,請留意彈出的 Windows Hello 窗口",
"@home_info_auto_fill_notice": {},
"home_login_title_welcome_back": "歡迎回來!", "home_login_title_welcome_back": "歡迎回來!",
"@home_login_title_welcome_back": {}, "@home_login_title_welcome_back": {},
"home_login_title_launching_game": "正在為您啟動遊戲...", "home_login_title_launching_game": "正在為您啟動遊戲...",
"@home_login_title_launching_game": {}, "@home_login_title_launching_game": {},
"home_action_login_rsi_account": "登入 RSI 帳戶", "home_action_login_rsi_account": "登入 RSI 帳戶",
"@home_action_login_rsi_account": {}, "@home_action_login_rsi_account": {},
"home_action_q_auto_password_fill_prompt": "是否開啟自動密碼輸入?",
"@home_action_q_auto_password_fill_prompt": {},
"home_login_info_password_encryption_notice": "盒子將使用 PIN 與 Windows 憑據加密保存您的密碼,密碼只儲存在您的裝置中。\n\n當下次登入需要輸入密碼時您只需授權PIN即可自動輸入登入。",
"@home_login_info_password_encryption_notice": {},
"home_login_info_enter_pin_to_encrypt": "輸入PIN以啟用加密",
"@home_login_info_enter_pin_to_encrypt": {},
"home_login_info_game_version_outdated": "遊戲版本過期", "home_login_info_game_version_outdated": "遊戲版本過期",
"@home_login_info_game_version_outdated": {}, "@home_login_info_game_version_outdated": {},
"home_login_info_rsi_server_report": "RSI 伺服器報告版本號:{v1} \n\n本地版本號{v2} \n\n建議使用 RSI Launcher 更新遊戲!", "home_login_info_rsi_server_report": "RSI 伺服器報告版本號:{v1} \n\n本地版本號{v2} \n\n建議使用 RSI Launcher 更新遊戲!",

View File

@ -6,7 +6,7 @@ part of 'aria2c.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$aria2cModelHash() => r'5431c2d9667f17ff03d0794711af22b015feda0d'; String _$aria2cModelHash() => r'8efef4661876de219510cf3e7e2d86c02405eb26';
/// See also [Aria2cModel]. /// See also [Aria2cModel].
@ProviderFor(Aria2cModel) @ProviderFor(Aria2cModel)

View File

@ -6,7 +6,7 @@ part of 'unp4kc.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$unp4kCModelHash() => r'46b6ac12670a6ff6ffb9d5bc8a8d04c07c570a8c'; String _$unp4kCModelHash() => r'0f1bff187bbc4e043405f60e95c08af6e1159b57';
/// See also [Unp4kCModel]. /// See also [Unp4kCModel].
@ProviderFor(Unp4kCModel) @ProviderFor(Unp4kCModel)

View File

@ -42,13 +42,6 @@ class HomeGameLoginDialogUI extends HookConsumerWidget {
Text(S.current.home_title_logging_in), Text(S.current.home_title_logging_in),
const SizedBox(height: 12), const SizedBox(height: 12),
const ProgressRing(), const ProgressRing(),
if (loginState.isDeviceSupportWinHello ?? false)
const SizedBox(height: 24),
Text(
S.current.home_info_auto_fill_notice,
style: TextStyle(
fontSize: 13, color: Colors.white.withOpacity(.6)),
)
], ],
), ),
), ),

View File

@ -4,16 +4,13 @@ import 'dart:io';
import 'package:fluent_ui/fluent_ui.dart'; import 'package:fluent_ui/fluent_ui.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:local_auth/local_auth.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:cryptography/cryptography.dart';
import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:jwt_decode/jwt_decode.dart'; import 'package:jwt_decode/jwt_decode.dart';
import 'package:starcitizen_doctor/common/helper/system_helper.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart';
import 'package:starcitizen_doctor/common/utils/base_utils.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart';
import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/utils/provider.dart'; import 'package:starcitizen_doctor/common/utils/provider.dart';
import 'package:starcitizen_doctor/common/win32/credentials.dart';
import 'package:starcitizen_doctor/data/rsi_game_library_data.dart'; import 'package:starcitizen_doctor/data/rsi_game_library_data.dart';
import 'package:starcitizen_doctor/ui/home/home_ui_model.dart'; import 'package:starcitizen_doctor/ui/home/home_ui_model.dart';
import 'package:starcitizen_doctor/ui/webview/webview.dart'; import 'package:starcitizen_doctor/ui/webview/webview.dart';
@ -46,25 +43,20 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
return HomeGameLoginState(loginStatus: 0); return HomeGameLoginState(loginStatus: 0);
} }
final LocalAuthentication _localAuth = LocalAuthentication();
// ignore: avoid_build_context_in_providers // ignore: avoid_build_context_in_providers
Future<void> launchWebLogin(BuildContext context) async { Future<void> launchWebLogin(BuildContext context) async {
final homeState = ref.read(homeUIModelProvider); final homeState = ref.read(homeUIModelProvider);
final isDeviceSupportWinHello = await _localAuth.isDeviceSupported();
state = state.copyWith(isDeviceSupportWinHello: isDeviceSupportWinHello);
if (!context.mounted) return; if (!context.mounted) return;
goWebView(context, S.current.home_action_login_rsi_account, goWebView(context, S.current.home_action_login_rsi_account,
"https://robertsspaceindustries.com/connect", loginMode: true, "https://robertsspaceindustries.com/connect?jumpto=/connect",
rsiLoginCallback: (message, ok) async { loginMode: true, rsiLoginCallback: (message, ok) async {
// dPrint( // dPrint(
// "======rsiLoginCallback=== $ok ===== data==\n${json.encode(message)}"); // "======rsiLoginCallback=== $ok ===== data==\n${json.encode(message)}");
if (message == null || !ok) { if (message == null || !ok) {
Navigator.pop(context); Navigator.pop(context);
return; return;
} }
dPrint("web message == $message");
// final emailBox = await Hive.openBox("quick_login_email"); // final emailBox = await Hive.openBox("quick_login_email");
final data = message["data"]; final data = message["data"];
final authToken = data["authToken"]; final authToken = data["authToken"];
@ -78,13 +70,6 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
final Map<String, dynamic> payload = Jwt.parseJwt(authToken!); final Map<String, dynamic> payload = Jwt.parseJwt(authToken!);
final nickname = payload["nickname"] ?? ""; final nickname = payload["nickname"] ?? "";
final inputEmail = data["inputEmail"];
final inputPassword = data["inputPassword"];
final userBox = await Hive.openBox("rsi_account_data");
if (inputEmail != null && inputEmail != "") {
await userBox.put("account_email", inputEmail);
}
state = state.copyWith( state = state.copyWith(
nickname: nickname, nickname: nickname,
avatarUrl: avatarUrl, avatarUrl: avatarUrl,
@ -94,37 +79,11 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
libraryData: libraryData, libraryData: libraryData,
); );
if (isDeviceSupportWinHello) {
if (await userBox.get("enable", defaultValue: true)) {
if (inputEmail != null &&
inputEmail != "" &&
inputPassword != null &&
inputPassword != "") {
if (!context.mounted) return;
final ok = await showConfirmDialogs(
context,
S.current.home_action_q_auto_password_fill_prompt,
Text(S.current.home_login_info_password_encryption_notice));
if (ok == true) {
if (await _localAuth.authenticate(
localizedReason:
S.current.home_login_info_enter_pin_to_encrypt) ==
true) {
await _savePwd(inputEmail, inputPassword);
}
} else {
await userBox.put("enable", false);
}
}
}
}
final buildInfoFile = final buildInfoFile =
File("${homeState.scInstalledPath}\\build_manifest.id"); File("${homeState.scInstalledPath}\\build_manifest.id");
if (await buildInfoFile.exists()) { if (await buildInfoFile.exists()) {
final buildInfo = final buildInfo =
json.decode(await buildInfoFile.readAsString())["Data"]; json.decode(await buildInfoFile.readAsString())["Data"];
dPrint("buildInfo ======= $buildInfo");
if (releaseInfo?["versionLabel"] != null && if (releaseInfo?["versionLabel"] != null &&
buildInfo["RequestedP4ChangeNum"] != null) { buildInfo["RequestedP4ChangeNum"] != null) {
@ -265,33 +224,4 @@ class HomeGameLoginUIModel extends _$HomeGameLoginUIModel {
} }
return "PTU"; return "PTU";
} }
_savePwd(String inputEmail, String inputPassword) async {
final algorithm = AesGcm.with256bits();
final secretKey = await algorithm.newSecretKey();
final nonce = algorithm.newNonce();
final secretBox = await algorithm.encrypt(utf8.encode(inputPassword),
secretKey: secretKey, nonce: nonce);
await algorithm.decrypt(
SecretBox(secretBox.cipherText,
nonce: secretBox.nonce, mac: secretBox.mac),
secretKey: secretKey);
final pwdEncrypted = base64.encode(secretBox.cipherText);
final userBox = await Hive.openBox("rsi_account_data");
await userBox.put("account_email", inputEmail);
await userBox.put("account_pwd_encrypted", pwdEncrypted);
await userBox.put("nonce", base64.encode(secretBox.nonce));
await userBox.put("mac", base64.encode(secretBox.mac.bytes));
final secretKeyStr = base64.encode((await secretKey.extractBytes()));
Win32Credentials.write(
credentialName: "SCToolbox_RSI_Account_secret",
userName: inputEmail,
password: secretKeyStr);
}
} }

View File

@ -7,7 +7,7 @@ part of 'home_game_login_dialog_ui_model.dart';
// ************************************************************************** // **************************************************************************
String _$homeGameLoginUIModelHash() => String _$homeGameLoginUIModelHash() =>
r'55ae072fdc222a015661e50f2d8d60e95911ce14'; r'862fac9e29e55937e1246542feac75cf55062182';
/// See also [HomeGameLoginUIModel]. /// See also [HomeGameLoginUIModel].
@ProviderFor(HomeGameLoginUIModel) @ProviderFor(HomeGameLoginUIModel)

View File

@ -2,7 +2,6 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:starcitizen_doctor/app.dart'; import 'package:starcitizen_doctor/app.dart';
import 'package:starcitizen_doctor/common/conf/const_conf.dart';
import 'package:starcitizen_doctor/generated/l10n.dart'; import 'package:starcitizen_doctor/generated/l10n.dart';
import 'package:starcitizen_doctor/ui/settings/settings_ui_model.dart'; import 'package:starcitizen_doctor/ui/settings/settings_ui_model.dart';
@ -31,23 +30,6 @@ class SettingsUI extends HookConsumerWidget {
S.current.setting_action_create_settings_shortcut, S.current.setting_action_create_settings_shortcut,
subTitle: S.current.setting_action_create_desktop_shortcut, subTitle: S.current.setting_action_create_desktop_shortcut,
onTap: () => model.addShortCut(context)), onTap: () => model.addShortCut(context)),
if (ConstConf.isMSE) ...[
const SizedBox(height: 12),
makeSettingsItem(const Icon(FluentIcons.reset_device, size: 20),
S.current.setting_action_reset_auto_password_fill,
subTitle: S.current.setting_action_info_device_support_info(
sate.isEnableAutoLogin
? S.current.setting_action_info_enabled
: S.current.setting_action_info_disabled,
sate.isDeviceSupportWinHello
? S.current.setting_action_info_support
: S.current.setting_action_info_not_support,
sate.autoLoginEmail,
sate.isEnableAutoLoginPwd
? S.current.setting_action_info_encrypted_saved
: S.current.setting_action_info_not_saved),
onTap: () => model.onResetAutoLogin(context)),
],
const SizedBox(height: 12), const SizedBox(height: 12),
makeSettingsItem(const Icon(FontAwesomeIcons.microchip, size: 20), makeSettingsItem(const Icon(FontAwesomeIcons.microchip, size: 20),
S.current.setting_action_ignore_efficiency_cores_on_launch, S.current.setting_action_ignore_efficiency_cores_on_launch,

View File

@ -6,13 +6,11 @@ import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:local_auth/local_auth.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:starcitizen_doctor/common/conf/const_conf.dart'; import 'package:starcitizen_doctor/common/conf/const_conf.dart';
import 'package:starcitizen_doctor/common/helper/system_helper.dart'; import 'package:starcitizen_doctor/common/helper/system_helper.dart';
import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/utils/provider.dart'; import 'package:starcitizen_doctor/common/utils/provider.dart';
import 'package:starcitizen_doctor/common/win32/credentials.dart';
import 'package:starcitizen_doctor/widgets/widgets.dart'; import 'package:starcitizen_doctor/widgets/widgets.dart';
part 'settings_ui_model.g.dart'; part 'settings_ui_model.g.dart';
@ -22,10 +20,6 @@ part 'settings_ui_model.freezed.dart';
@freezed @freezed
class SettingsUIState with _$SettingsUIState { class SettingsUIState with _$SettingsUIState {
factory SettingsUIState({ factory SettingsUIState({
@Default(false) isDeviceSupportWinHello,
@Default("-") String autoLoginEmail,
@Default(false) bool isEnableAutoLogin,
@Default(false) bool isEnableAutoLoginPwd,
@Default(false) bool isEnableToolSiteMirrors, @Default(false) bool isEnableToolSiteMirrors,
@Default("0") String inputGameLaunchECore, @Default("0") String inputGameLaunchECore,
String? customLauncherPath, String? customLauncherPath,
@ -44,47 +38,12 @@ class SettingsUIModel extends _$SettingsUIModel {
} }
void _initState() async { void _initState() async {
final LocalAuthentication localAuth = LocalAuthentication();
final isDeviceSupportWinHello = await localAuth.isDeviceSupported();
state = state.copyWith(isDeviceSupportWinHello: isDeviceSupportWinHello);
_updateGameLaunchECore(); _updateGameLaunchECore();
if (ConstConf.isMSE) {
_updateAutoLoginAccount();
}
_loadCustomPath(); _loadCustomPath();
_loadLocationCacheSize(); _loadLocationCacheSize();
_loadToolSiteMirrorState(); _loadToolSiteMirrorState();
} }
Future<void> onResetAutoLogin(BuildContext context) async {
final ok = await showConfirmDialogs(
context,
S.current.setting_action_info_confirm_reset_autofill,
Text(S.current.setting_action_info_delete_local_account_warning));
if (ok) {
final userBox = await Hive.openBox("rsi_account_data");
await userBox.deleteFromDisk();
Win32Credentials.delete("SCToolbox_RSI_Account_secret");
if (!context.mounted) return;
showToast(context, S.current.setting_action_info_autofill_data_cleared);
_initState();
}
}
Future _updateAutoLoginAccount() async {
final userBox = await Hive.openBox("rsi_account_data");
final autoLoginEmail = userBox.get("account_email", defaultValue: "-");
final isEnableAutoLogin = userBox.get("enable", defaultValue: true);
final isEnableAutoLoginPwd =
userBox.get("account_pwd_encrypted", defaultValue: "") != "";
state = state.copyWith(
autoLoginEmail: autoLoginEmail,
isEnableAutoLogin: isEnableAutoLogin,
isEnableAutoLoginPwd: isEnableAutoLoginPwd);
}
Future<void> setGameLaunchECore(BuildContext context) async { Future<void> setGameLaunchECore(BuildContext context) async {
final userBox = await Hive.openBox("app_conf"); final userBox = await Hive.openBox("app_conf");
final defaultInput = final defaultInput =

View File

@ -17,9 +17,6 @@ final _privateConstructorUsedError = UnsupportedError(
/// @nodoc /// @nodoc
mixin _$SettingsUIState { mixin _$SettingsUIState {
dynamic get isDeviceSupportWinHello => throw _privateConstructorUsedError; dynamic get isDeviceSupportWinHello => throw _privateConstructorUsedError;
String get autoLoginEmail => throw _privateConstructorUsedError;
bool get isEnableAutoLogin => throw _privateConstructorUsedError;
bool get isEnableAutoLoginPwd => throw _privateConstructorUsedError;
bool get isEnableToolSiteMirrors => throw _privateConstructorUsedError; bool get isEnableToolSiteMirrors => throw _privateConstructorUsedError;
String get inputGameLaunchECore => throw _privateConstructorUsedError; String get inputGameLaunchECore => throw _privateConstructorUsedError;
String? get customLauncherPath => throw _privateConstructorUsedError; String? get customLauncherPath => throw _privateConstructorUsedError;
@ -39,9 +36,6 @@ abstract class $SettingsUIStateCopyWith<$Res> {
@useResult @useResult
$Res call( $Res call(
{dynamic isDeviceSupportWinHello, {dynamic isDeviceSupportWinHello,
String autoLoginEmail,
bool isEnableAutoLogin,
bool isEnableAutoLoginPwd,
bool isEnableToolSiteMirrors, bool isEnableToolSiteMirrors,
String inputGameLaunchECore, String inputGameLaunchECore,
String? customLauncherPath, String? customLauncherPath,
@ -63,9 +57,6 @@ class _$SettingsUIStateCopyWithImpl<$Res, $Val extends SettingsUIState>
@override @override
$Res call({ $Res call({
Object? isDeviceSupportWinHello = freezed, Object? isDeviceSupportWinHello = freezed,
Object? autoLoginEmail = null,
Object? isEnableAutoLogin = null,
Object? isEnableAutoLoginPwd = null,
Object? isEnableToolSiteMirrors = null, Object? isEnableToolSiteMirrors = null,
Object? inputGameLaunchECore = null, Object? inputGameLaunchECore = null,
Object? customLauncherPath = freezed, Object? customLauncherPath = freezed,
@ -77,18 +68,6 @@ class _$SettingsUIStateCopyWithImpl<$Res, $Val extends SettingsUIState>
? _value.isDeviceSupportWinHello ? _value.isDeviceSupportWinHello
: isDeviceSupportWinHello // ignore: cast_nullable_to_non_nullable : isDeviceSupportWinHello // ignore: cast_nullable_to_non_nullable
as dynamic, as dynamic,
autoLoginEmail: null == autoLoginEmail
? _value.autoLoginEmail
: autoLoginEmail // ignore: cast_nullable_to_non_nullable
as String,
isEnableAutoLogin: null == isEnableAutoLogin
? _value.isEnableAutoLogin
: isEnableAutoLogin // ignore: cast_nullable_to_non_nullable
as bool,
isEnableAutoLoginPwd: null == isEnableAutoLoginPwd
? _value.isEnableAutoLoginPwd
: isEnableAutoLoginPwd // ignore: cast_nullable_to_non_nullable
as bool,
isEnableToolSiteMirrors: null == isEnableToolSiteMirrors isEnableToolSiteMirrors: null == isEnableToolSiteMirrors
? _value.isEnableToolSiteMirrors ? _value.isEnableToolSiteMirrors
: isEnableToolSiteMirrors // ignore: cast_nullable_to_non_nullable : isEnableToolSiteMirrors // ignore: cast_nullable_to_non_nullable
@ -123,9 +102,6 @@ abstract class _$$SettingsUIStateImplCopyWith<$Res>
@useResult @useResult
$Res call( $Res call(
{dynamic isDeviceSupportWinHello, {dynamic isDeviceSupportWinHello,
String autoLoginEmail,
bool isEnableAutoLogin,
bool isEnableAutoLoginPwd,
bool isEnableToolSiteMirrors, bool isEnableToolSiteMirrors,
String inputGameLaunchECore, String inputGameLaunchECore,
String? customLauncherPath, String? customLauncherPath,
@ -145,9 +121,6 @@ class __$$SettingsUIStateImplCopyWithImpl<$Res>
@override @override
$Res call({ $Res call({
Object? isDeviceSupportWinHello = freezed, Object? isDeviceSupportWinHello = freezed,
Object? autoLoginEmail = null,
Object? isEnableAutoLogin = null,
Object? isEnableAutoLoginPwd = null,
Object? isEnableToolSiteMirrors = null, Object? isEnableToolSiteMirrors = null,
Object? inputGameLaunchECore = null, Object? inputGameLaunchECore = null,
Object? customLauncherPath = freezed, Object? customLauncherPath = freezed,
@ -158,18 +131,6 @@ class __$$SettingsUIStateImplCopyWithImpl<$Res>
isDeviceSupportWinHello: freezed == isDeviceSupportWinHello isDeviceSupportWinHello: freezed == isDeviceSupportWinHello
? _value.isDeviceSupportWinHello! ? _value.isDeviceSupportWinHello!
: isDeviceSupportWinHello, : isDeviceSupportWinHello,
autoLoginEmail: null == autoLoginEmail
? _value.autoLoginEmail
: autoLoginEmail // ignore: cast_nullable_to_non_nullable
as String,
isEnableAutoLogin: null == isEnableAutoLogin
? _value.isEnableAutoLogin
: isEnableAutoLogin // ignore: cast_nullable_to_non_nullable
as bool,
isEnableAutoLoginPwd: null == isEnableAutoLoginPwd
? _value.isEnableAutoLoginPwd
: isEnableAutoLoginPwd // ignore: cast_nullable_to_non_nullable
as bool,
isEnableToolSiteMirrors: null == isEnableToolSiteMirrors isEnableToolSiteMirrors: null == isEnableToolSiteMirrors
? _value.isEnableToolSiteMirrors ? _value.isEnableToolSiteMirrors
: isEnableToolSiteMirrors // ignore: cast_nullable_to_non_nullable : isEnableToolSiteMirrors // ignore: cast_nullable_to_non_nullable
@ -199,9 +160,6 @@ class __$$SettingsUIStateImplCopyWithImpl<$Res>
class _$SettingsUIStateImpl implements _SettingsUIState { class _$SettingsUIStateImpl implements _SettingsUIState {
_$SettingsUIStateImpl( _$SettingsUIStateImpl(
{this.isDeviceSupportWinHello = false, {this.isDeviceSupportWinHello = false,
this.autoLoginEmail = "-",
this.isEnableAutoLogin = false,
this.isEnableAutoLoginPwd = false,
this.isEnableToolSiteMirrors = false, this.isEnableToolSiteMirrors = false,
this.inputGameLaunchECore = "0", this.inputGameLaunchECore = "0",
this.customLauncherPath, this.customLauncherPath,
@ -213,15 +171,6 @@ class _$SettingsUIStateImpl implements _SettingsUIState {
final dynamic isDeviceSupportWinHello; final dynamic isDeviceSupportWinHello;
@override @override
@JsonKey() @JsonKey()
final String autoLoginEmail;
@override
@JsonKey()
final bool isEnableAutoLogin;
@override
@JsonKey()
final bool isEnableAutoLoginPwd;
@override
@JsonKey()
final bool isEnableToolSiteMirrors; final bool isEnableToolSiteMirrors;
@override @override
@JsonKey() @JsonKey()
@ -236,7 +185,7 @@ class _$SettingsUIStateImpl implements _SettingsUIState {
@override @override
String toString() { String toString() {
return 'SettingsUIState(isDeviceSupportWinHello: $isDeviceSupportWinHello, autoLoginEmail: $autoLoginEmail, isEnableAutoLogin: $isEnableAutoLogin, isEnableAutoLoginPwd: $isEnableAutoLoginPwd, isEnableToolSiteMirrors: $isEnableToolSiteMirrors, inputGameLaunchECore: $inputGameLaunchECore, customLauncherPath: $customLauncherPath, customGamePath: $customGamePath, locationCacheSize: $locationCacheSize)'; return 'SettingsUIState(isDeviceSupportWinHello: $isDeviceSupportWinHello, isEnableToolSiteMirrors: $isEnableToolSiteMirrors, inputGameLaunchECore: $inputGameLaunchECore, customLauncherPath: $customLauncherPath, customGamePath: $customGamePath, locationCacheSize: $locationCacheSize)';
} }
@override @override
@ -246,12 +195,6 @@ class _$SettingsUIStateImpl implements _SettingsUIState {
other is _$SettingsUIStateImpl && other is _$SettingsUIStateImpl &&
const DeepCollectionEquality().equals( const DeepCollectionEquality().equals(
other.isDeviceSupportWinHello, isDeviceSupportWinHello) && other.isDeviceSupportWinHello, isDeviceSupportWinHello) &&
(identical(other.autoLoginEmail, autoLoginEmail) ||
other.autoLoginEmail == autoLoginEmail) &&
(identical(other.isEnableAutoLogin, isEnableAutoLogin) ||
other.isEnableAutoLogin == isEnableAutoLogin) &&
(identical(other.isEnableAutoLoginPwd, isEnableAutoLoginPwd) ||
other.isEnableAutoLoginPwd == isEnableAutoLoginPwd) &&
(identical( (identical(
other.isEnableToolSiteMirrors, isEnableToolSiteMirrors) || other.isEnableToolSiteMirrors, isEnableToolSiteMirrors) ||
other.isEnableToolSiteMirrors == isEnableToolSiteMirrors) && other.isEnableToolSiteMirrors == isEnableToolSiteMirrors) &&
@ -269,9 +212,6 @@ class _$SettingsUIStateImpl implements _SettingsUIState {
int get hashCode => Object.hash( int get hashCode => Object.hash(
runtimeType, runtimeType,
const DeepCollectionEquality().hash(isDeviceSupportWinHello), const DeepCollectionEquality().hash(isDeviceSupportWinHello),
autoLoginEmail,
isEnableAutoLogin,
isEnableAutoLoginPwd,
isEnableToolSiteMirrors, isEnableToolSiteMirrors,
inputGameLaunchECore, inputGameLaunchECore,
customLauncherPath, customLauncherPath,
@ -289,9 +229,6 @@ class _$SettingsUIStateImpl implements _SettingsUIState {
abstract class _SettingsUIState implements SettingsUIState { abstract class _SettingsUIState implements SettingsUIState {
factory _SettingsUIState( factory _SettingsUIState(
{final dynamic isDeviceSupportWinHello, {final dynamic isDeviceSupportWinHello,
final String autoLoginEmail,
final bool isEnableAutoLogin,
final bool isEnableAutoLoginPwd,
final bool isEnableToolSiteMirrors, final bool isEnableToolSiteMirrors,
final String inputGameLaunchECore, final String inputGameLaunchECore,
final String? customLauncherPath, final String? customLauncherPath,
@ -301,12 +238,6 @@ abstract class _SettingsUIState implements SettingsUIState {
@override @override
dynamic get isDeviceSupportWinHello; dynamic get isDeviceSupportWinHello;
@override @override
String get autoLoginEmail;
@override
bool get isEnableAutoLogin;
@override
bool get isEnableAutoLoginPwd;
@override
bool get isEnableToolSiteMirrors; bool get isEnableToolSiteMirrors;
@override @override
String get inputGameLaunchECore; String get inputGameLaunchECore;

View File

@ -6,7 +6,7 @@ part of 'settings_ui_model.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$settingsUIModelHash() => r'aab08176293b380f09c89e006f373fbfd7a7ba16'; String _$settingsUIModelHash() => r'897176bc24ec5397cce0dd1ceea58338ac7841e0';
/// See also [SettingsUIModel]. /// See also [SettingsUIModel].
@ProviderFor(SettingsUIModel) @ProviderFor(SettingsUIModel)

View File

@ -3,17 +3,14 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:cryptography/cryptography.dart';
import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:local_auth/local_auth.dart';
import 'package:starcitizen_doctor/common/conf/url_conf.dart'; import 'package:starcitizen_doctor/common/conf/url_conf.dart';
import 'package:starcitizen_doctor/common/io/rs_http.dart'; import 'package:starcitizen_doctor/common/io/rs_http.dart';
import 'package:starcitizen_doctor/common/utils/base_utils.dart'; import 'package:starcitizen_doctor/common/utils/base_utils.dart';
import 'package:starcitizen_doctor/common/utils/log.dart'; import 'package:starcitizen_doctor/common/utils/log.dart';
import 'package:starcitizen_doctor/common/win32/credentials.dart';
import 'package:starcitizen_doctor/data/app_version_data.dart'; import 'package:starcitizen_doctor/data/app_version_data.dart';
import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart'; import 'package:starcitizen_doctor/data/app_web_localization_versions_data.dart';
@ -188,7 +185,6 @@ class WebViewModel {
final message = json.decode(messageString); final message = json.decode(messageString);
if (message["action"] == "webview_rsi_login_show_window") { if (message["action"] == "webview_rsi_login_show_window") {
webview.setWebviewWindowVisibility(true); webview.setWebviewWindowVisibility(true);
_checkAutoLogin(webview);
} else if (message["action"] == "webview_rsi_login_success") { } else if (message["action"] == "webview_rsi_login_success") {
_loginModeSuccess = true; _loginModeSuccess = true;
loginCallback?.call(message, true); loginCallback?.call(message, true);
@ -302,39 +298,4 @@ class WebViewModel {
} }
_isClosed = true; _isClosed = true;
} }
Future<void> _checkAutoLogin(Webview webview) async {
final LocalAuthentication localAuth = LocalAuthentication();
if (!await localAuth.isDeviceSupported()) return;
final userBox = await Hive.openBox("rsi_account_data");
final email = await userBox.get("account_email", defaultValue: "");
final pwdE = await userBox.get("account_pwd_encrypted", defaultValue: "");
final nonceStr = await userBox.get("nonce", defaultValue: "");
final macStr = await userBox.get("mac", defaultValue: "");
if (email == "") return;
webview.evaluateJavaScript("RSIAutoLogin(\"$email\",\"\")");
if (pwdE != "" && nonceStr != "" && macStr != "") {
// send toast
final toastMsg =
S.current.webview_localization_device_windows_hello_toast;
webview.evaluateJavaScript("SCTShowToast(\"$toastMsg\")");
// decrypt
if (await localAuth.authenticate(
localizedReason:
S.current.webview_localization_enter_device_pin) !=
true) return;
final kv = Win32Credentials.read("SCToolbox_RSI_Account_secret");
if (kv == null || kv.key != email) return;
final algorithm = AesGcm.with256bits();
final r = await algorithm.decrypt(
SecretBox(base64.decode(pwdE),
nonce: base64.decode(nonceStr), mac: Mac(base64.decode(macStr))),
secretKey: SecretKey(base64.decode(kv.value)));
final decryptedPwd = utf8.decode(r);
webview.evaluateJavaScript("RSIAutoLogin(\"$email\",\"$decryptedPwd\")");
}
}
} }

View File

@ -65,9 +65,7 @@ dependencies:
flutter_rust_bridge: ^2.0.0-dev.32 flutter_rust_bridge: ^2.0.0-dev.32
freezed_annotation: ^2.4.1 freezed_annotation: ^2.4.1
meta: ^1.9.1 meta: ^1.9.1
win32: ^5.0.9
windows_ui: ^0.2.0 windows_ui: ^0.2.0
local_auth: ^2.1.7
cryptography: ^2.7.0 cryptography: ^2.7.0
cryptography_flutter: ^2.3.2 cryptography_flutter: ^2.3.2
hexcolor: ^3.0.1 hexcolor: ^3.0.1

View File

@ -8,7 +8,6 @@
#include <desktop_webview_window/desktop_webview_window_plugin.h> #include <desktop_webview_window/desktop_webview_window_plugin.h>
#include <flutter_acrylic/flutter_acrylic_plugin.h> #include <flutter_acrylic/flutter_acrylic_plugin.h>
#include <local_auth_windows/local_auth_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h> #include <screen_retriever/screen_retriever_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
#include <window_manager/window_manager_plugin.h> #include <window_manager/window_manager_plugin.h>
@ -18,8 +17,6 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin")); registry->GetRegistrarForPlugin("DesktopWebviewWindowPlugin"));
FlutterAcrylicPluginRegisterWithRegistrar( FlutterAcrylicPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterAcrylicPlugin")); registry->GetRegistrarForPlugin("FlutterAcrylicPlugin"));
LocalAuthPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
ScreenRetrieverPluginRegisterWithRegistrar( ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@ -5,7 +5,6 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
desktop_webview_window desktop_webview_window
flutter_acrylic flutter_acrylic
local_auth_windows
screen_retriever screen_retriever
url_launcher_windows url_launcher_windows
window_manager window_manager