Fix password login profile handling
This commit is contained in:
@@ -228,7 +228,9 @@ class AccountModule {
|
|||||||
throw Exception('completeRegistration: отсутствует id аккаунта');
|
throw Exception('completeRegistration: отсутствует id аккаунта');
|
||||||
}
|
}
|
||||||
|
|
||||||
final profile = ProfileData.fromServerMap(contact.cast<dynamic, dynamic>());
|
final profile = ProfileData.fromServerProfile(
|
||||||
|
profileMap.cast<dynamic, dynamic>(),
|
||||||
|
);
|
||||||
await AppDatabase.saveProfile(profile, isActive: true);
|
await AppDatabase.saveProfile(profile, isActive: true);
|
||||||
await TokenStorage.setActiveAccount(accountId);
|
await TokenStorage.setActiveAccount(accountId);
|
||||||
await SpoofingService.commitPendingSpoof(accountId);
|
await SpoofingService.commitPendingSpoof(accountId);
|
||||||
@@ -446,8 +448,25 @@ class AccountModule {
|
|||||||
throw Exception('checkPassword: отсутствует токен в ответе');
|
throw Exception('checkPassword: отсутствует токен в ответе');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final accountId = extractAccountId(data);
|
||||||
|
if (accountId == null) {
|
||||||
|
throw Exception('checkPassword: отсутствует accountId в ответе');
|
||||||
|
}
|
||||||
|
|
||||||
|
final profileMap = data['profile'];
|
||||||
|
if (profileMap is Map) {
|
||||||
|
final profile = ProfileData.fromServerProfile(
|
||||||
|
profileMap.cast<dynamic, dynamic>(),
|
||||||
|
);
|
||||||
|
await AppDatabase.saveProfile(profile, isActive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
await TokenStorage.saveToken(loginToken, accountId);
|
||||||
|
await TokenStorage.setActiveAccount(accountId);
|
||||||
|
await SpoofingService.commitPendingSpoof(accountId);
|
||||||
|
|
||||||
logger.i('2FA пройдена, получен login-токен');
|
logger.i('2FA пройдена, получен login-токен');
|
||||||
return TwoFactorResult(loginToken: loginToken);
|
return TwoFactorResult(loginToken: loginToken, accountId: accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<dynamic, dynamic> buildLoginPayload(
|
Map<dynamic, dynamic> buildLoginPayload(
|
||||||
@@ -500,16 +519,24 @@ class AccountModule {
|
|||||||
await TokenStorage.saveToken(updatedToken, accountId);
|
await TokenStorage.saveToken(updatedToken, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfileData profile;
|
||||||
final profileMap = data['profile'];
|
final profileMap = data['profile'];
|
||||||
if (profileMap is! Map) {
|
if (profileMap is Map) {
|
||||||
throw Exception('login: отсутствует profile в ответе');
|
final contact = profileMap['contact'];
|
||||||
|
if (contact is! Map) {
|
||||||
|
throw Exception('login: отсутствует profile.contact в ответе');
|
||||||
|
}
|
||||||
|
profile = ProfileData.fromServerProfile(
|
||||||
|
profileMap.cast<dynamic, dynamic>(),
|
||||||
|
);
|
||||||
|
await AppDatabase.saveProfile(profile, isActive: true);
|
||||||
|
} else {
|
||||||
|
final cachedProfile = await AppDatabase.loadProfile(accountId);
|
||||||
|
if (cachedProfile == null) {
|
||||||
|
throw Exception('login: отсутствует profile в ответе');
|
||||||
|
}
|
||||||
|
profile = cachedProfile;
|
||||||
}
|
}
|
||||||
final contact = profileMap['contact'];
|
|
||||||
if (contact is! Map) {
|
|
||||||
throw Exception('login: отсутствует profile.contact в ответе');
|
|
||||||
}
|
|
||||||
final profile = ProfileData.fromServerMap(contact.cast<dynamic, dynamic>());
|
|
||||||
await AppDatabase.saveProfile(profile, isActive: true);
|
|
||||||
await AppDatabase.setActiveAccount(profile.id);
|
await AppDatabase.setActiveAccount(profile.id);
|
||||||
|
|
||||||
await _saveSyncState(data, serverTime, profile.id);
|
await _saveSyncState(data, serverTime, profile.id);
|
||||||
|
|||||||
@@ -372,8 +372,9 @@ class VerifyCodeResult {
|
|||||||
|
|
||||||
class TwoFactorResult {
|
class TwoFactorResult {
|
||||||
final String loginToken;
|
final String loginToken;
|
||||||
|
final int accountId;
|
||||||
|
|
||||||
const TwoFactorResult({required this.loginToken});
|
const TwoFactorResult({required this.loginToken, required this.accountId});
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginSyncParams {
|
class LoginSyncParams {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class ProfileModule extends AccountApiBase {
|
|||||||
if (profile == null) throw Exception('No profile in response');
|
if (profile == null) throw Exception('No profile in response');
|
||||||
final contact = profile['contact'] as Map?;
|
final contact = profile['contact'] as Map?;
|
||||||
if (contact == null) throw Exception('No contact in response');
|
if (contact == null) throw Exception('No contact in response');
|
||||||
final newProfile = ProfileData.fromServerMap(
|
final newProfile = ProfileData.fromServerProfile(
|
||||||
contact.cast<dynamic, dynamic>(),
|
profile.cast<dynamic, dynamic>(),
|
||||||
);
|
);
|
||||||
await AppDatabase.saveProfile(newProfile, isActive: true);
|
await AppDatabase.saveProfile(newProfile, isActive: true);
|
||||||
return newProfile;
|
return newProfile;
|
||||||
@@ -88,7 +88,7 @@ class ProfileModule extends AccountApiBase {
|
|||||||
final contact = profile['contact'];
|
final contact = profile['contact'];
|
||||||
if (contact is! Map) return;
|
if (contact is! Map) return;
|
||||||
completer.complete(
|
completer.complete(
|
||||||
ProfileData.fromServerMap(contact.cast<dynamic, dynamic>()),
|
ProfileData.fromServerProfile(profile.cast<dynamic, dynamic>()),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
final timer = Timer(const Duration(seconds: 15), () {
|
final timer = Timer(const Duration(seconds: 15), () {
|
||||||
|
|||||||
@@ -36,7 +36,21 @@ class ProfileData {
|
|||||||
this.profileOptions,
|
this.profileOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory ProfileData.fromServerMap(Map<dynamic, dynamic> contact) {
|
factory ProfileData.fromServerProfile(Map<dynamic, dynamic> profile) {
|
||||||
|
final contact = profile['contact'];
|
||||||
|
if (contact is! Map) {
|
||||||
|
throw const FormatException('No contact in profile');
|
||||||
|
}
|
||||||
|
return ProfileData.fromServerMap(
|
||||||
|
contact.cast<dynamic, dynamic>(),
|
||||||
|
profileOptions: _parseProfileOptions(profile['profileOptions']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory ProfileData.fromServerMap(
|
||||||
|
Map<dynamic, dynamic> contact, {
|
||||||
|
List<int>? profileOptions,
|
||||||
|
}) {
|
||||||
final names = contact['names'];
|
final names = contact['names'];
|
||||||
String firstName = '';
|
String firstName = '';
|
||||||
String? lastName;
|
String? lastName;
|
||||||
@@ -52,12 +66,6 @@ class ProfileData {
|
|||||||
lastName = name['lastName'] as String?;
|
lastName = name['lastName'] as String?;
|
||||||
}
|
}
|
||||||
|
|
||||||
final profileOptionsRaw = contact['profileOptions'];
|
|
||||||
List<int>? profileOptions;
|
|
||||||
if (profileOptionsRaw is List) {
|
|
||||||
profileOptions = profileOptionsRaw.map((e) => e as int).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ProfileData(
|
return ProfileData(
|
||||||
id: contact['id'] as int,
|
id: contact['id'] as int,
|
||||||
firstName: firstName,
|
firstName: firstName,
|
||||||
@@ -69,10 +77,20 @@ class ProfileData {
|
|||||||
country: (contact['country'] as String?) ?? '',
|
country: (contact['country'] as String?) ?? '',
|
||||||
accountStatus: (contact['accountStatus'] as int?) ?? 0,
|
accountStatus: (contact['accountStatus'] as int?) ?? 0,
|
||||||
updateTime: (contact['updateTime'] as int?) ?? 0,
|
updateTime: (contact['updateTime'] as int?) ?? 0,
|
||||||
profileOptions: profileOptions,
|
profileOptions:
|
||||||
|
profileOptions ?? _parseProfileOptions(contact['profileOptions']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<int>? _parseProfileOptions(dynamic raw) {
|
||||||
|
if (raw is! List) return null;
|
||||||
|
final options = raw
|
||||||
|
.map((e) => e is int ? e : int.tryParse(e.toString()))
|
||||||
|
.whereType<int>()
|
||||||
|
.toList();
|
||||||
|
return options.isEmpty ? null : options;
|
||||||
|
}
|
||||||
|
|
||||||
factory ProfileData.fromDbRow(Map<String, dynamic> row) {
|
factory ProfileData.fromDbRow(Map<String, dynamic> row) {
|
||||||
final profileOptionsStr = row['profile_options'] as String?;
|
final profileOptionsStr = row['profile_options'] as String?;
|
||||||
List<int>? profileOptions;
|
List<int>? profileOptions;
|
||||||
|
|||||||
@@ -67,7 +67,10 @@ class _Password2FAScreenState extends State<Password2FAScreen>
|
|||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
final loginResult = await accountModule.login(token: result.loginToken);
|
final loginResult = await accountModule.login(
|
||||||
|
accountId: result.accountId,
|
||||||
|
token: result.loginToken,
|
||||||
|
);
|
||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 0.5.0+13
|
version: 0.5.0+14
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.10.4
|
sdk: ^3.10.4
|
||||||
|
|||||||
Reference in New Issue
Block a user