优化自动登录

This commit is contained in:
xkeyC 2023-11-07 20:47:28 +08:00
parent c92078b931
commit 183864054e
6 changed files with 121 additions and 28 deletions

View File

@ -246,6 +246,8 @@ async function getRSILauncherToken(channelId) {
return; return;
} }
SCTShowToast("登录游戏中...");
// get claims // get claims
let claimsR = await fetch("api/launcher/v3/games/claims", { let claimsR = await fetch("api/launcher/v3/games/claims", {
method: 'POST', headers: { method: 'POST', headers: {
@ -311,9 +313,9 @@ function RSIAutoLogin(email, pwd) {
if (pwd !== "") { if (pwd !== "") {
$('#password').val(pwd) $('#password').val(pwd)
} }
sessionStorage.setItem('inputEmail', '');
sessionStorage.setItem('inputPassword', ''); sessionStorage.setItem('inputPassword', '');
if (email !== "" && pwd !== "") { if (email !== "" && pwd !== "") {
$("#remember").prop("checked", true);
$('.c-form__submit-button-label').click(); $('.c-form__submit-button-label').click();
} }
}); });

View File

@ -209,7 +209,7 @@ class HomeUI extends BaseUI<HomeUIModel> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
shadowConfig: const ShadowConfig(disable: true), shadowConfig: const ShadowConfig(disable: true),
child: GestureDetector( child: GestureDetector(
onTap: ()=> model.onTapFestival(), onTap: () => model.onTapFestival(),
child: Container( child: Container(
width: width + 24, width: width + 24,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -234,8 +234,9 @@ class HomeUI extends BaseUI<HomeUIModel> {
autoplay: true, autoplay: true,
autoplayDelay: 5000, autoplayDelay: 5000,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = model final item =
.countdownFestivalListData![index]; model.countdownFestivalListData![
index];
return Row( return Row(
mainAxisAlignment: mainAxisAlignment:
MainAxisAlignment.spaceEvenly, MainAxisAlignment.spaceEvenly,
@ -244,11 +245,13 @@ class HomeUI extends BaseUI<HomeUIModel> {
item.icon != "") ...[ item.icon != "") ...[
ClipRRect( ClipRRect(
borderRadius: borderRadius:
BorderRadius.circular(1000), BorderRadius.circular(
1000),
child: Image.asset( child: Image.asset(
"assets/countdown/${item.icon}", "assets/countdown/${item.icon}",
width: 48, width: 48,
height: 48, height: 48,
fit: BoxFit.cover,
), ),
), ),
], ],

View File

@ -25,7 +25,8 @@ class LoginDialog extends BaseUI<LoginDialogModel> {
const Text("登录中..."), const Text("登录中..."),
const SizedBox(height: 12), const SizedBox(height: 12),
const ProgressRing(), const ProgressRing(),
const SizedBox(height: 24), if (model.isDeviceSupportWinHello)
const SizedBox(height: 24),
Text( Text(
"* 若开启了自动填充,请留意弹出的 Windows Hello 窗口", "* 若开启了自动填充,请留意弹出的 Windows Hello 窗口",
style: TextStyle( style: TextStyle(

View File

@ -32,17 +32,21 @@ class LoginDialogModel extends BaseUIModel {
final LocalAuthentication localAuth = LocalAuthentication(); final LocalAuthentication localAuth = LocalAuthentication();
var isDeviceSupportWinHello = false;
@override @override
void initModel() { void initModel() {
_launchWebLogin(); _launchWebLogin();
super.initModel(); super.initModel();
} }
void _launchWebLogin() { Future<void> _launchWebLogin() async {
isDeviceSupportWinHello = await localAuth.isDeviceSupported();
notifyListeners();
goWebView("登录 RSI 账户", "https://robertsspaceindustries.com/connect", goWebView("登录 RSI 账户", "https://robertsspaceindustries.com/connect",
loginMode: true, 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;
@ -62,25 +66,28 @@ class LoginDialogModel extends BaseUIModel {
final inputEmail = data["inputEmail"]; final inputEmail = data["inputEmail"];
final inputPassword = data["inputPassword"]; final inputPassword = data["inputPassword"];
final userBox = await Hive.openBox("rsi_account_data");
if (inputEmail != null && inputEmail != "") { if (inputEmail != null && inputEmail != "") {
final userBox = await Hive.openBox("rsi_account_data");
await userBox.put("account_email", inputEmail); await userBox.put("account_email", inputEmail);
} }
if (isDeviceSupportWinHello) {
if (await localAuth.isDeviceSupported()) { if (await userBox.get("enable", defaultValue: true)) {
if (inputEmail != null && if (inputEmail != null &&
inputEmail != "" && inputEmail != "" &&
inputPassword != null && inputPassword != null &&
inputPassword != "") { inputPassword != "") {
final ok = await showConfirmDialogs( final ok = await showConfirmDialogs(
context!, context!,
"是否开启自动密码填充?", "是否开启自动密码填充?",
const Text( const Text(
"盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时您只需授权PIN即可自动填充登录。")); "盒子将使用 PIN 与 Windows 凭据加密保存您的密码,密码只存储在您的设备中。\n\n当下次登录需要输入密码时您只需授权PIN即可自动填充登录。"));
if (ok == true) { if (ok == true) {
if (await localAuth.authenticate(localizedReason: "输入PIN以启用加密") == if (await localAuth.authenticate(localizedReason: "输入PIN以启用加密") ==
true) { true) {
await _savePwd(inputEmail, inputPassword); await _savePwd(inputEmail, inputPassword);
}
} else {
await userBox.put("enable", false);
} }
} }
} }

View File

@ -4,8 +4,56 @@ import 'package:starcitizen_doctor/ui/settings/settings_ui_model.dart';
class SettingUI extends BaseUI<SettingUIModel> { class SettingUI extends BaseUI<SettingUIModel> {
@override @override
Widget? buildBody(BuildContext context, SettingUIModel model) { Widget? buildBody(BuildContext context, SettingUIModel model) {
return const Center( return Container(
child: Text("暂时没啥好设置的。"), width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
margin: const EdgeInsets.all(16),
child: Column(
children: [
makeSettingsItem(const Icon(FluentIcons.reset_device), "重置自动密码填充",
subTitle:
"启用:${model.isEnableAutoLogin ? "已启用" : "已禁用"} 设备支持:${model.isDeviceSupportWinHello ? "支持" : "不支持"} 邮箱:${model.autoLoginEmail} 密码:${model.isEnableAutoLoginPwd ? "已加密保存" : "未保存"}",
onTap: model.onResetAutoLogin),
],
),
);
}
Widget makeSettingsItem(Widget icon, String title,
{String? subTitle, VoidCallback? onTap}) {
return Button(
onPressed: onTap,
child: Padding(
padding: const EdgeInsets.only(top: 12, bottom: 12),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
icon,
const SizedBox(width: 12),
Text(title),
const Spacer(),
],
),
if (subTitle != null) ...[
const SizedBox(height: 3),
Text(
subTitle,
style: TextStyle(
fontSize: 12, color: Colors.white.withOpacity(.6)),
)
],
],
),
),
const Icon(FluentIcons.chevron_right),
],
),
),
); );
} }

View File

@ -1,5 +1,37 @@
import 'package:hive/hive.dart';
import 'package:local_auth/local_auth.dart';
import 'package:starcitizen_doctor/base/ui_model.dart'; import 'package:starcitizen_doctor/base/ui_model.dart';
import 'package:starcitizen_doctor/common/win32/credentials.dart';
class SettingUIModel extends BaseUIModel { class SettingUIModel extends BaseUIModel {
var isDeviceSupportWinHello = false;
String autoLoginEmail = "-";
bool isEnableAutoLogin = false;
bool isEnableAutoLoginPwd = false;
@override
loadData() async {
final LocalAuthentication localAuth = LocalAuthentication();
isDeviceSupportWinHello = await localAuth.isDeviceSupported();
notifyListeners();
_updateAutoLoginAccount();
}
Future<void> onResetAutoLogin() async {
final userBox = await Hive.openBox("rsi_account_data");
await userBox.deleteFromDisk();
Win32Credentials.delete("SCToolbox_RSI_Account_secret");
showToast(context!, "已清理自动填充数据");
reloadData();
}
Future _updateAutoLoginAccount() async {
final userBox = await Hive.openBox("rsi_account_data");
autoLoginEmail = userBox.get("account_email", defaultValue: "-");
isEnableAutoLogin = userBox.get("enable", defaultValue: true);
isEnableAutoLoginPwd =
userBox.get("account_pwd_encrypted", defaultValue: "") != "";
notifyListeners();
}
} }