mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-18 18:13:31 +00:00
Fix multiple accounts from same server not working
Fixes Issue #72 - Refactor the initial profile loading - Add a clear all profiles button (and service support) to the Profile Manager screen since once profiles are corrupted need to start from scratch - Fix the short term cache response to key on headers and body as well as URL/QP - Fix ID handling in Basic Credentials copy method
This commit is contained in:
parent
8ee7b3eec1
commit
d5f4196435
6 changed files with 52 additions and 17 deletions
|
@ -779,18 +779,21 @@ class ProfileClient extends FriendicaClient {
|
||||||
|
|
||||||
ProfileClient(super.credentials) : super();
|
ProfileClient(super.credentials) : super();
|
||||||
|
|
||||||
FutureResult<Connection, ExecError> getMyProfile() async {
|
FutureResult<(Connection, Profile), ExecError> getMyProfile() async {
|
||||||
_logger.finest(() => 'Getting logged in user profile');
|
_logger.finest(() => 'Getting logged in user profile');
|
||||||
final request =
|
final request =
|
||||||
Uri.parse('https://$serverName/api/v1/accounts/verify_credentials');
|
Uri.parse('https://$serverName/api/v1/accounts/verify_credentials');
|
||||||
return (await _getApiRequest(request, timeout: oauthTimeout))
|
return (await _getApiRequest(request, timeout: oauthTimeout))
|
||||||
.mapValue((json) => ConnectionMastodonExtensions.fromJson(
|
.mapValue((json) {
|
||||||
|
final connection = ConnectionMastodonExtensions.fromJson(
|
||||||
json,
|
json,
|
||||||
defaultServerName: serverName,
|
defaultServerName: serverName,
|
||||||
).copy(
|
).copy(
|
||||||
status: ConnectionStatus.you,
|
status: ConnectionStatus.you,
|
||||||
network: 'friendica',
|
network: 'friendica',
|
||||||
));
|
);
|
||||||
|
return (connection, profile);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ class BasicCredentials implements ICredentials {
|
||||||
String? serverName,
|
String? serverName,
|
||||||
}) {
|
}) {
|
||||||
return BasicCredentials(
|
return BasicCredentials(
|
||||||
|
id: id,
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
password: password ?? this.password,
|
password: password ?? this.password,
|
||||||
serverName: serverName ?? this.serverName,
|
serverName: serverName ?? this.serverName,
|
||||||
|
|
|
@ -373,6 +373,20 @@ class _SignInScreenState extends State<SignInScreen> {
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const VerticalPadding(),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
final confirm = await showYesNoDialog(context,
|
||||||
|
'Are you sure you want to logout and delete *all* accounts? This cannot be undone.') ??
|
||||||
|
false;
|
||||||
|
print(confirm);
|
||||||
|
if (!confirm) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await getIt<AccountsService>().clearAllProfiles();
|
||||||
|
},
|
||||||
|
child: Text('Clear All')),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -395,8 +409,9 @@ class _SignInScreenState extends State<SignInScreen> {
|
||||||
} else {
|
} else {
|
||||||
switch (authType) {
|
switch (authType) {
|
||||||
case usernamePasswordType:
|
case usernamePasswordType:
|
||||||
|
final username = usernameController.text.split('@').first;
|
||||||
creds = BasicCredentials(
|
creds = BasicCredentials(
|
||||||
username: usernameController.text,
|
username: username,
|
||||||
password: passwordController.text,
|
password: passwordController.text,
|
||||||
serverName: serverNameController.text);
|
serverName: serverNameController.text);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -78,20 +78,20 @@ class AccountsService extends ChangeNotifier {
|
||||||
|
|
||||||
FutureResult<Profile, ExecError> signIn(ICredentials credentials,
|
FutureResult<Profile, ExecError> signIn(ICredentials credentials,
|
||||||
{bool withNotification = true}) async {
|
{bool withNotification = true}) async {
|
||||||
ICredentials? credentialsCache;
|
|
||||||
final result =
|
final result =
|
||||||
await credentials.signIn().andThenAsync((signedInCredentials) async {
|
await credentials.signIn().andThenAsync((signedInCredentials) async {
|
||||||
final client =
|
final client =
|
||||||
ProfileClient(Profile.credentialsOnly(signedInCredentials));
|
ProfileClient(Profile.credentialsOnly(signedInCredentials));
|
||||||
credentialsCache = signedInCredentials;
|
|
||||||
getIt<StatusService>().setStatus(
|
getIt<StatusService>().setStatus(
|
||||||
'Getting user profile from ${signedInCredentials.serverName}');
|
'Getting user profile from ${signedInCredentials.serverName}');
|
||||||
return await client.getMyProfile();
|
return await client.getMyProfile();
|
||||||
}).andThenAsync((profileData) async {
|
}).andThenAsync((profileResult) async {
|
||||||
|
final profileData = profileResult.$1;
|
||||||
|
final profile = profileResult.$2;
|
||||||
final loginProfile = Profile(
|
final loginProfile = Profile(
|
||||||
credentials: credentialsCache!,
|
credentials: profile.credentials,
|
||||||
username: profileData.name,
|
username: profileData.name,
|
||||||
serverName: credentialsCache!.serverName,
|
serverName: profile.credentials.serverName,
|
||||||
avatar: profileData.avatarUrl,
|
avatar: profileData.avatarUrl,
|
||||||
userId: profileData.id,
|
userId: profileData.id,
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
|
@ -178,6 +178,14 @@ class AccountsService extends ChangeNotifier {
|
||||||
await _saveStoredLoginState();
|
await _saveStoredLoginState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> clearAllProfiles() async {
|
||||||
|
_loggedInProfiles.clear();
|
||||||
|
_loggedOutProfiles.clear();
|
||||||
|
_currentProfile = null;
|
||||||
|
await secretsService.clearCredentials();
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _saveStoredLoginState() async {
|
Future<void> _saveStoredLoginState() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
await prefs.setString('active_profile_id', _currentProfile?.id ?? '');
|
await prefs.setString('active_profile_id', _currentProfile?.id ?? '');
|
||||||
|
|
|
@ -41,6 +41,7 @@ class SecretsService {
|
||||||
try {
|
try {
|
||||||
await _secureStorage.delete(key: _basicProfilesKey);
|
await _secureStorage.delete(key: _basicProfilesKey);
|
||||||
await _secureStorage.delete(key: _oauthProfilesKey);
|
await _secureStorage.delete(key: _oauthProfilesKey);
|
||||||
|
profiles.clear();
|
||||||
return Result.ok(profiles);
|
return Result.ok(profiles);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return Result.error(ExecError(
|
return Result.error(ExecError(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:result_monad/result_monad.dart';
|
import 'package:result_monad/result_monad.dart';
|
||||||
|
@ -80,10 +81,16 @@ class _CachedResponse {
|
||||||
other is _CachedResponse &&
|
other is _CachedResponse &&
|
||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
requestType == other.requestType &&
|
requestType == other.requestType &&
|
||||||
requestUri == other.requestUri;
|
requestUri == other.requestUri &&
|
||||||
|
const MapEquality().equals(requestBody, other.requestBody) &&
|
||||||
|
const MapEquality().equals(headers, other.headers);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => requestType.hashCode ^ requestUri.hashCode;
|
int get hashCode =>
|
||||||
|
requestType.hashCode ^
|
||||||
|
requestUri.hashCode ^
|
||||||
|
const MapEquality().hash(requestBody) ^
|
||||||
|
const MapEquality().hash(headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExpiringRequestCache {
|
class _ExpiringRequestCache {
|
||||||
|
@ -121,7 +128,7 @@ class _ExpiringRequestCache {
|
||||||
|
|
||||||
late final http.Response response;
|
late final http.Response response;
|
||||||
if (_responses.containsKey(requestStub)) {
|
if (_responses.containsKey(requestStub)) {
|
||||||
print('Returning cached response for $type => $url');
|
_logger.fine('Returning cached response for $type => $url');
|
||||||
response = _responses[requestStub]?.response ?? http.Response('', 555);
|
response = _responses[requestStub]?.response ?? http.Response('', 555);
|
||||||
} else {
|
} else {
|
||||||
final request = RelaticaUserAgentHttpClient().get(
|
final request = RelaticaUserAgentHttpClient().get(
|
||||||
|
|
Loading…
Reference in a new issue