新增游客模式

This commit is contained in:
2025-10-17 15:28:40 +08:00
parent f5bc239b6a
commit 2333ad52a9
15 changed files with 1434 additions and 53 deletions
+4
View File
@@ -19,6 +19,10 @@ abstract class Api {
/// 登录接口
static const String kr_login = "/v1/app/auth/login";
/// 设备登录(游客登录)
/// 参考 OmnOem 项目 ppanel.json 配置
static const String kr_deviceLogin = "/v1/auth/login/device";
/// 删除账号
static const String kr_deleteAccount = "/v1/app/user/account";
@@ -1,5 +1,6 @@
import 'dart:io';
import 'dart:math';
import 'dart:convert';
import 'package:fpdart/fpdart.dart';
import 'package:get/get.dart';
@@ -15,6 +16,11 @@ import 'package:kaer_with_panels/app/utils/kr_device_util.dart';
import '../../utils/kr_common_util.dart';
import '../../utils/kr_log_util.dart';
import '../../utils/kr_aes_util.dart';
import '../kr_device_info_service.dart';
import '../kr_site_config_service.dart';
import '../../common/app_config.dart';
import 'package:dio/dio.dart' as dio;
class KRAuthApi {
/// 是否开启了审核开关
@@ -221,6 +227,145 @@ class KRAuthApi {
return right(baseResponse.model.kr_token.toString());
}
/// 设备登录(游客登录)
Future<Either<HttpError, String>> kr_deviceLogin() async {
try {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('🔐 开始设备登录(游客模式)');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('🔐 开始设备登录(游客模式)', tag: 'KRAuthApi');
// 获取设备信息
final deviceInfoService = KRDeviceInfoService();
final deviceId = deviceInfoService.deviceId;
final userAgent = deviceInfoService.getUserAgent();
if (deviceId == null) {
print('❌ 设备ID为空,无法登录');
return left(HttpError(msg: '设备ID获取失败', code: -1));
}
print('📱 设备ID: $deviceId');
print('📱 User-Agent: $userAgent');
KRLogUtil.kr_i('📱 设备ID: $deviceId', tag: 'KRAuthApi');
KRLogUtil.kr_i('📱 User-Agent: $userAgent', tag: 'KRAuthApi');
// 构建请求数据
Map<String, dynamic> data = {
'identifier': deviceId,
'user_agent': userAgent,
};
print('📤 原始请求数据: $data');
// 检查是否需要加密
final siteConfigService = KRSiteConfigService();
final needEncryption = siteConfigService.isDeviceSecurityEnabled();
print('🔒 是否需要加密: $needEncryption');
KRLogUtil.kr_i('🔒 是否需要加密: $needEncryption', tag: 'KRAuthApi');
String? requestBody;
if (needEncryption) {
// 加密请求数据
print('🔐 加密请求数据...');
final encrypted = KRAesUtil.encryptJson(data, AppConfig.kr_encryptionKey);
requestBody = '{"data":"${encrypted['data']}","time":"${encrypted['time']}"}';
print('🔐 加密后请求体: $requestBody');
KRLogUtil.kr_i('🔐 加密后请求体', tag: 'KRAuthApi');
} else {
// 使用明文
requestBody = jsonEncode(data);
print('📝 明文请求体: $requestBody');
}
// 使用 Dio 直接发送请求(因为需要特殊的加密处理)
final dioInstance = dio.Dio();
final baseUrl = AppConfig.getInstance().baseUrl;
final url = '$baseUrl${Api.kr_deviceLogin}';
print('📤 请求URL: $url');
KRLogUtil.kr_i('📤 请求URL: $url', tag: 'KRAuthApi');
// 设置请求头
final headers = <String, String>{
'Content-Type': 'application/json',
};
if (needEncryption) {
headers['Login-Type'] = 'device';
}
print('📤 请求头: $headers');
// 配置Dio实例的超时设置
dioInstance.options.connectTimeout = const Duration(seconds: 10);
dioInstance.options.sendTimeout = const Duration(seconds: 10);
dioInstance.options.receiveTimeout = const Duration(seconds: 10);
final response = await dioInstance.post(
url,
data: requestBody,
options: dio.Options(
headers: headers,
),
);
print('📥 响应状态码: ${response.statusCode}');
print('📥 响应数据: ${response.data}');
KRLogUtil.kr_i('📥 响应状态码: ${response.statusCode}', tag: 'KRAuthApi');
KRLogUtil.kr_i('📥 响应数据: ${response.data}', tag: 'KRAuthApi');
if (response.statusCode == 200) {
Map<String, dynamic> responseData = response.data as Map<String, dynamic>;
// 检查是否需要解密响应
if (needEncryption && responseData.containsKey('data')) {
final dataField = responseData['data'];
if (dataField is Map<String, dynamic> &&
dataField.containsKey('data') &&
dataField.containsKey('time')) {
print('🔓 解密响应数据...');
final decrypted = KRAesUtil.decryptJson(
dataField['data'] as String,
dataField['time'] as String,
AppConfig.kr_encryptionKey,
);
responseData['data'] = decrypted;
print('🔓 解密后数据: ${responseData['data']}');
KRLogUtil.kr_i('🔓 解密成功', tag: 'KRAuthApi');
}
}
if (responseData['code'] == 200) {
final token = responseData['data']['token'] as String;
print('✅ 设备登录成功');
print('🎫 Token: ${token.substring(0, min(20, token.length))}...');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('✅ 设备登录成功', tag: 'KRAuthApi');
return right(token);
} else {
final msg = responseData['msg'] ?? '登录失败';
print('❌ 登录失败: $msg');
return left(HttpError(msg: msg, code: responseData['code']));
}
} else {
print('❌ HTTP错误: ${response.statusCode}');
return left(HttpError(msg: 'HTTP错误', code: response.statusCode ?? -1));
}
} on dio.DioException catch (e) {
print('❌ Dio异常: ${e.type}');
print('❌ 错误信息: ${e.message}');
KRLogUtil.kr_e('❌ 设备登录Dio异常: ${e.message}', tag: 'KRAuthApi');
return left(HttpError(msg: '网络请求失败: ${e.message}', code: -1));
} catch (e, stackTrace) {
print('❌ 设备登录异常: $e');
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ 设备登录异常: $e', tag: 'KRAuthApi');
return left(HttpError(msg: '设备登录失败: $e', code: -1));
}
}
String _kr_getUserAgent() {
if (Platform.isAndroid) {
return 'android';
@@ -0,0 +1,260 @@
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import '../utils/kr_secure_storage.dart';
import '../utils/kr_log_util.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';
/// 设备信息服务
/// 用于获取设备唯一标识和其他设备信息
class KRDeviceInfoService {
static final KRDeviceInfoService _instance = KRDeviceInfoService._internal();
factory KRDeviceInfoService() => _instance;
KRDeviceInfoService._internal();
final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();
String? _deviceId;
Map<String, dynamic>? _deviceDetails;
// 获取设备唯一标识
String? get deviceId => _deviceId;
// 获取设备详细信息
Map<String, dynamic>? get deviceDetails => _deviceDetails;
/// 初始化设备信息
Future<void> initialize() async {
try {
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
print('📱 开始初始化设备信息服务');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('📱 开始初始化设备信息', tag: 'KRDeviceInfoService');
_deviceId = await _getDeviceId();
_deviceDetails = await _getDeviceDetails();
print('✅ 设备信息初始化成功');
print('📱 设备ID: $_deviceId');
print('📱 设备平台: ${getPlatformName()}');
print('📱 设备型号: ${getDeviceModel()}');
print('📱 系统版本: ${getOSVersion()}');
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
KRLogUtil.kr_i('✅ 设备信息初始化成功', tag: 'KRDeviceInfoService');
KRLogUtil.kr_i('📱 设备ID - $_deviceId', tag: 'KRDeviceInfoService');
KRLogUtil.kr_i('📱 设备详情 - $_deviceDetails', tag: 'KRDeviceInfoService');
} catch (e) {
print('❌ 设备信息初始化失败: $e');
KRLogUtil.kr_e('❌ 设备信息初始化失败 - $e', tag: 'KRDeviceInfoService');
}
}
/// 获取设备唯一标识
Future<String> _getDeviceId() async {
try {
String? identifier;
if (Platform.isAndroid) {
final androidInfo = await _deviceInfo.androidInfo;
// Android使用androidId作为唯一标识
identifier = androidInfo.id;
} else if (Platform.isIOS) {
final iosInfo = await _deviceInfo.iosInfo;
// iOS使用identifierForVendor作为唯一标识
identifier = iosInfo.identifierForVendor;
} else if (Platform.isMacOS) {
final macInfo = await _deviceInfo.macOsInfo;
// macOS使用systemGUID
identifier = macInfo.systemGUID;
} else if (Platform.isWindows) {
final windowsInfo = await _deviceInfo.windowsInfo;
// Windows使用计算机名作为唯一标识
identifier = windowsInfo.computerName;
} else if (Platform.isLinux) {
final linuxInfo = await _deviceInfo.linuxInfo;
// Linux使用machineId
identifier = linuxInfo.machineId;
} else {
// Web或其他平台,使用生成的UUID
identifier = await _getOrCreateStoredDeviceId();
}
// 如果获取失败,使用存储的或生成新的ID
if (identifier == null || identifier.isEmpty) {
identifier = await _getOrCreateStoredDeviceId();
}
return identifier;
} catch (e) {
print('❌ 获取设备ID失败: $e');
KRLogUtil.kr_e('❌ 获取设备ID失败 - $e', tag: 'KRDeviceInfoService');
// 如果获取失败,返回存储的或生成新的ID
return await _getOrCreateStoredDeviceId();
}
}
/// 获取或创建存储的设备ID
Future<String> _getOrCreateStoredDeviceId() async {
try {
const key = 'kr_device_unique_id';
final storage = KRSecureStorage();
String? storedId = await storage.kr_readData(key: key);
if (storedId == null || storedId.isEmpty) {
// 生成新的UUID
storedId = _generateUniqueId();
await storage.kr_saveData(key: key, value: storedId);
print('📱 生成新的设备ID: $storedId');
KRLogUtil.kr_i('📱 生成新的设备ID - $storedId', tag: 'KRDeviceInfoService');
} else {
print('📱 使用存储的设备ID: $storedId');
KRLogUtil.kr_i('📱 使用存储的设备ID - $storedId', tag: 'KRDeviceInfoService');
}
return storedId;
} catch (e) {
print('❌ 获取存储的设备ID失败: $e');
KRLogUtil.kr_e('❌ 获取存储的设备ID失败 - $e', tag: 'KRDeviceInfoService');
return _generateUniqueId();
}
}
/// 生成唯一ID
String _generateUniqueId() {
final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
final random = DateTime.now().microsecondsSinceEpoch.toString();
final combined = '$timestamp-$random';
// 使用MD5生成唯一标识
final bytes = utf8.encode(combined);
final digest = md5.convert(bytes);
return digest.toString();
}
/// 获取设备详细信息
Future<Map<String, dynamic>> _getDeviceDetails() async {
try {
if (Platform.isAndroid) {
final androidInfo = await _deviceInfo.androidInfo;
return {
'platform': 'android',
'device': androidInfo.device,
'model': androidInfo.model,
'brand': androidInfo.brand,
'manufacturer': androidInfo.manufacturer,
'androidId': androidInfo.id,
'version': androidInfo.version.release,
'sdkInt': androidInfo.version.sdkInt,
};
} else if (Platform.isIOS) {
final iosInfo = await _deviceInfo.iosInfo;
return {
'platform': 'ios',
'name': iosInfo.name,
'model': iosInfo.model,
'systemName': iosInfo.systemName,
'systemVersion': iosInfo.systemVersion,
'identifierForVendor': iosInfo.identifierForVendor,
'isPhysicalDevice': iosInfo.isPhysicalDevice,
};
} else if (Platform.isMacOS) {
final macInfo = await _deviceInfo.macOsInfo;
return {
'platform': 'macos',
'computerName': macInfo.computerName,
'model': macInfo.model,
'hostName': macInfo.hostName,
'arch': macInfo.arch,
'systemGUID': macInfo.systemGUID,
};
} else if (Platform.isWindows) {
final windowsInfo = await _deviceInfo.windowsInfo;
return {
'platform': 'windows',
'computerName': windowsInfo.computerName,
'numberOfCores': windowsInfo.numberOfCores,
'systemMemoryInMegabytes': windowsInfo.systemMemoryInMegabytes,
};
} else if (Platform.isLinux) {
final linuxInfo = await _deviceInfo.linuxInfo;
return {
'platform': 'linux',
'name': linuxInfo.name,
'version': linuxInfo.version,
'id': linuxInfo.id,
'machineId': linuxInfo.machineId,
};
} else if (kIsWeb) {
final webInfo = await _deviceInfo.webBrowserInfo;
return {
'platform': 'web',
'browserName': webInfo.browserName.toString(),
'userAgent': webInfo.userAgent,
'vendor': webInfo.vendor,
};
}
return {
'platform': 'unknown',
};
} catch (e) {
print('❌ 获取设备详情失败: $e');
KRLogUtil.kr_e('❌ 获取设备详情失败 - $e', tag: 'KRDeviceInfoService');
return {
'platform': 'unknown',
'error': e.toString(),
};
}
}
/// 获取平台名称
String getPlatformName() {
if (Platform.isAndroid) return 'Android';
if (Platform.isIOS) return 'iOS';
if (Platform.isMacOS) return 'macOS';
if (Platform.isWindows) return 'Windows';
if (Platform.isLinux) return 'Linux';
if (kIsWeb) return 'Web';
return 'Unknown';
}
/// 获取设备型号
String getDeviceModel() {
if (_deviceDetails == null) return 'Unknown';
if (Platform.isAndroid) {
return '${_deviceDetails!['brand']} ${_deviceDetails!['model']}';
} else if (Platform.isIOS) {
return _deviceDetails!['model'] ?? 'Unknown';
} else if (Platform.isMacOS) {
return _deviceDetails!['model'] ?? 'Unknown';
}
return 'Unknown';
}
/// 获取操作系统版本
String getOSVersion() {
if (_deviceDetails == null) return 'Unknown';
if (Platform.isAndroid) {
return _deviceDetails!['version'] ?? 'Unknown';
} else if (Platform.isIOS) {
return _deviceDetails!['systemVersion'] ?? 'Unknown';
}
return 'Unknown';
}
/// 获取User-Agent信息
String getUserAgent() {
final platform = getPlatformName();
final model = getDeviceModel();
final osVersion = getOSVersion();
return 'BearVPN/1.0.0 ($platform; $model; $osVersion) Flutter';
}
}
@@ -0,0 +1,292 @@
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../model/response/kr_site_config.dart';
import '../common/app_config.dart';
import '../utils/kr_log_util.dart';
/// 网站配置服务
class KRSiteConfigService extends ChangeNotifier {
static final KRSiteConfigService _instance = KRSiteConfigService._internal();
factory KRSiteConfigService() => _instance;
KRSiteConfigService._internal() {
// 配置 Dio 默认超时设置
_dio.options.connectTimeout = const Duration(seconds: 10);
_dio.options.sendTimeout = const Duration(seconds: 10);
_dio.options.receiveTimeout = const Duration(seconds: 10);
}
KRSiteConfig? _siteConfig;
bool _isInitialized = false;
final Dio _dio = Dio();
/// 获取站点配置
KRSiteConfig? get siteConfig => _siteConfig;
/// 是否已初始化
bool get isInitialized => _isInitialized;
/// 初始化站点配置
Future<bool> initialize() async {
try {
print('🔧 KRSiteConfigService.initialize() 开始执行');
KRLogUtil.kr_i('🔧 开始初始化网站配置', tag: 'KRSiteConfigService');
// Debug 模式下使用固定地址
final baseUrl = AppConfig().baseUrl;
print('📍 baseUrl = $baseUrl');
final url = '$baseUrl/v1/common/site/config';
print('📍 完整URL = $url');
KRLogUtil.kr_i('📤 请求网站配置 - $url', tag: 'KRSiteConfigService');
print('📤 准备发送 GET 请求到: $url');
print('⏱️ 超时配置: connectTimeout=10s, sendTimeout=10s, receiveTimeout=10s');
print('⏳ 开始发送请求...');
final startTime = DateTime.now();
final response = await _dio.get(url);
final endTime = DateTime.now();
final duration = endTime.difference(startTime).inMilliseconds;
print('⏱️ 请求耗时: ${duration}ms');
print('✅ 请求完成,状态码: ${response.statusCode}');
KRLogUtil.kr_i('📥 响应状态码 - ${response.statusCode}', tag: 'KRSiteConfigService');
if (response.statusCode == 200) {
final responseData = response.data;
print('📥 响应数据类型: ${responseData.runtimeType}');
print('📥 响应数据: $responseData');
KRLogUtil.kr_i('📥 响应数据 - $responseData', tag: 'KRSiteConfigService');
if (responseData['code'] == 200) {
_siteConfig = KRSiteConfig.fromJson(responseData['data']);
_isInitialized = true;
// 打印配置信息
_printConfigInfo();
// 通知监听者配置已更新
notifyListeners();
return true;
} else {
KRLogUtil.kr_e('❌ API返回错误 - ${responseData['msg']}', tag: 'KRSiteConfigService');
return false;
}
} else {
KRLogUtil.kr_e('❌ HTTP错误 - ${response.statusCode}', tag: 'KRSiteConfigService');
return false;
}
} on DioException catch (e, stackTrace) {
print('❌ Dio请求异常: ${e.type}');
print('❌ 错误信息: ${e.message}');
print('❌ 请求URL: ${e.requestOptions.uri}');
print('❌ 连接超时: ${e.requestOptions.connectTimeout}');
print('❌ 发送超时: ${e.requestOptions.sendTimeout}');
print('❌ 接收超时: ${e.requestOptions.receiveTimeout}');
if (e.response != null) {
print('❌ 响应状态码: ${e.response?.statusCode}');
print('❌ 响应数据: ${e.response?.data}');
}
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ Dio异常 - ${e.type}: ${e.message}', tag: 'KRSiteConfigService');
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
} catch (e, stackTrace) {
print('❌ 未知异常: $e');
print('📚 堆栈跟踪: $stackTrace');
KRLogUtil.kr_e('❌ 初始化失败 - $e', tag: 'KRSiteConfigService');
KRLogUtil.kr_e('📚 堆栈: $stackTrace', tag: 'KRSiteConfigService');
return false;
}
}
/// 打印配置信息
void _printConfigInfo() {
if (_siteConfig == null) return;
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('📊 网站配置信息:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
// 站点信息
KRLogUtil.kr_i('🏠 站点名称: ${_siteConfig!.site.siteName}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点描述: ${_siteConfig!.site.siteDesc}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🏠 站点域名: ${_siteConfig!.site.host}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('💬 Crisp ID: ${_siteConfig!.site.crispId}', tag: 'KRSiteConfigService');
// 注册相关
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('📝 注册配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 开放注册: ${isRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机号注册: ${isMobileRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱注册: ${isEmailRegisterEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 设备登录: ${isDeviceLoginEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
// 验证相关
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔐 验证配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 邮箱验证: ${isEmailVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 手机验证: ${isMobileVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 登录验证: ${isLoginVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 注册验证: ${isRegisterVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 重置密码验证: ${isResetPasswordVerificationEnabled() ? "" : ""}', tag: 'KRSiteConfigService');
// 邀请相关
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🎁 邀请配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 强制邀请码: ${isForcedInvite() ? "" : ""}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 推荐比例: ${_siteConfig!.invite.referralPercentage}%', tag: 'KRSiteConfigService');
// 货币相关
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('💰 货币配置:', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币单位: ${_siteConfig!.currency.currencyUnit}', tag: 'KRSiteConfigService');
KRLogUtil.kr_i(' ✓ 货币符号: ${_siteConfig!.currency.currencySymbol}', tag: 'KRSiteConfigService');
// OAuth 方法
if (_siteConfig!.oauthMethods.isNotEmpty) {
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('🔑 OAuth 方法: ${_siteConfig!.oauthMethods.join(", ")}', tag: 'KRSiteConfigService');
}
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('✅ 网站配置初始化成功', tag: 'KRSiteConfigService');
KRLogUtil.kr_i('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━', tag: 'KRSiteConfigService');
}
/// 是否开启手机号注册
bool isMobileRegisterEnabled() {
return _siteConfig?.auth.mobile.enable ?? false;
}
/// 是否开启邮箱注册
bool isEmailRegisterEnabled() {
return _siteConfig?.auth.email.enable ?? false;
}
/// 是否开放注册(未停止注册)
bool isRegisterEnabled() {
return !(_siteConfig?.auth.register.stopRegister ?? true);
}
/// 是否开启邮箱验证
bool isEmailVerificationEnabled() {
return _siteConfig?.auth.email.enableVerify ?? false;
}
/// 是否开启手机验证
bool isMobileVerificationEnabled() {
return _siteConfig?.auth.mobile.enable ?? false;
}
/// 是否开启登录验证
bool isLoginVerificationEnabled() {
return _siteConfig?.verify.enableLoginVerify ?? false;
}
/// 是否开启注册验证
bool isRegisterVerificationEnabled() {
return _siteConfig?.verify.enableRegisterVerify ?? false;
}
/// 是否开启重置密码验证
bool isResetPasswordVerificationEnabled() {
return _siteConfig?.verify.enableResetPasswordVerify ?? false;
}
/// 是否强制邀请码
bool isForcedInvite() {
return _siteConfig?.invite.forcedInvite ?? false;
}
/// 获取验证码间隔时间(秒)
int getVerifyCodeInterval() {
return _siteConfig?.verifyCode.verifyCodeInterval ?? 60;
}
/// 获取OAuth方法列表
List<String> getOAuthMethods() {
return _siteConfig?.oauthMethods ?? [];
}
/// 检查是否支持设备模式(匿名游客模式)
bool isDeviceModeSupported() {
final oauthMethods = getOAuthMethods();
return oauthMethods.contains('device');
}
/// 检查是否启用设备登录
bool isDeviceLoginEnabled() {
return _siteConfig?.auth.device.enable ?? false;
}
/// 检查是否需要设备安全加密
bool isDeviceSecurityEnabled() {
return _siteConfig?.auth.device.enableSecurity ?? false;
}
/// 检查是否显示广告
bool isDeviceShowAds() {
return _siteConfig?.auth.device.showAds ?? false;
}
/// 检查是否只允许真实设备
bool isOnlyRealDevice() {
return _siteConfig?.auth.device.onlyRealDevice ?? false;
}
/// 获取站点信息
KRSiteInfo? getSiteInfo() {
return _siteConfig?.site;
}
/// 获取货币配置
KRCurrencyConfig? getCurrencyConfig() {
return _siteConfig?.currency;
}
/// 获取订阅配置
KRSubscribeConfig? getSubscribeConfig() {
return _siteConfig?.subscribe;
}
/// 检查手机号是否在白名单中
bool isMobileInWhitelist(String mobile) {
if (!(_siteConfig?.auth.mobile.enableWhitelist ?? false)) {
return true; // 如果未开启白名单,则允许所有手机号
}
final whitelist = _siteConfig?.auth.mobile.whitelist ?? [];
return whitelist.contains(mobile);
}
/// 检查邮箱域名是否被允许
bool isEmailDomainAllowed(String email) {
if (!(_siteConfig?.auth.email.enableDomainSuffix ?? false)) {
return true; // 如果未开启域名限制,则允许所有域名
}
final domainSuffixList = _siteConfig?.auth.email.domainSuffixList ?? '';
if (domainSuffixList.isEmpty) {
return true;
}
final allowedDomains = domainSuffixList.split(',').map((d) => d.trim()).toList();
final emailDomain = email.split('@').last.toLowerCase();
return allowedDomains.any((domain) => emailDomain.endsWith(domain.toLowerCase()));
}
/// 获取Crisp客服系统ID
String getCrispId() {
return _siteConfig?.site.crispId ?? '0';
}
/// 重置配置
void reset() {
_siteConfig = null;
_isInitialized = false;
notifyListeners();
}
}