Merge pull request #1720 from famedly/krille/allow-init-on-soft-logout

refactor: Allow calling init when in soft logout state
This commit is contained in:
Krille-chan 2024-03-08 11:03:49 +01:00 committed by GitHub
commit fdee8ee845
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 17 deletions

View File

@ -43,7 +43,7 @@ import 'package:matrix/src/utils/try_get_push_rule.dart';
typedef RoomSorter = int Function(Room a, Room b);
enum LoginState { loggedIn, loggedOut }
enum LoginState { loggedIn, loggedOut, softLoggedOut }
extension TrailingSlash on Uri {
Uri stripTrailingSlash() => path.endsWith('/')
@ -267,10 +267,15 @@ class Client extends MatrixApi {
final tokenResponse = await refresh(refreshToken);
accessToken = tokenResponse.accessToken;
final expiresInMs = tokenResponse.expiresInMs;
final tokenExpiresAt = expiresInMs == null
? null
: DateTime.now().add(Duration(milliseconds: expiresInMs));
accessTokenExpiresAt = tokenExpiresAt;
await database?.updateClient(
homeserverUrl,
tokenResponse.accessToken,
accessTokenExpiresAt,
tokenExpiresAt,
tokenResponse.refreshToken,
userId,
deviceId,
@ -1574,7 +1579,7 @@ class Client extends MatrixApi {
String? userID;
try {
Logs().i('Initialize client $clientName');
if (isLogged()) {
if (onLoginStateChanged.value == LoginState.loggedIn) {
throw ClientInitPreconditionError(
'User is already logged in! Call [logout()] first!',
);
@ -1592,6 +1597,7 @@ class Client extends MatrixApi {
_serverConfigCache.invalidate();
final account = await this.database?.getClient(clientName);
newRefreshToken ??= account?.tryGet<String>('refresh_token');
if (account != null) {
_id = account['client_id'];
homeserver = Uri.parse(account['homeserver_url']);
@ -1626,6 +1632,26 @@ class Client extends MatrixApi {
olmAccount = newOlmAccount ?? olmAccount;
}
// If we are refreshing the session, we are done here:
if (onLoginStateChanged.value == LoginState.softLoggedOut) {
if (newRefreshToken != null && accessToken != null && userID != null) {
// Store the new tokens:
await _database?.updateClient(
homeserver.toString(),
accessToken,
accessTokenExpiresAt,
newRefreshToken,
userID,
_deviceID,
_deviceName,
prevBatch,
encryption?.pickledOlmAccount,
);
}
onLoginStateChanged.add(LoginState.loggedIn);
return;
}
if (accessToken == null || homeserver == null || userID == null) {
if (legacyDatabaseBuilder != null) {
await _migrateFromLegacyDatabase(onMigration: onMigration);
@ -1806,6 +1832,21 @@ class Client extends MatrixApi {
return;
}
Future<void> _handleSoftLogout() async {
final onSoftLogout = this.onSoftLogout;
if (onSoftLogout == null) return;
onLoginStateChanged.add(LoginState.softLoggedOut);
try {
await onSoftLogout(this);
onLoginStateChanged.add(LoginState.loggedIn);
} catch (e, s) {
Logs().w('Unable to refresh session after soft logout', e, s);
await clear();
rethrow;
}
}
/// Pass a timeout to set how long the server waits before sending an empty response.
/// (Corresponds to the timeout param on the /sync request.)
Future<void> _innerSync({Duration? timeout}) async {
@ -1820,20 +1861,20 @@ class Client extends MatrixApi {
Object? syncError;
await _checkSyncFilter();
// The timeout we send to the server for the sync loop. It says to the
// server that we want to receive an empty sync response after this
// amount of time if nothing happens.
timeout ??= const Duration(seconds: 30);
// Call onSoftLogout 5 minutes before access token expires to prevent
// failing network requests.
final tokenExpiresAt = accessTokenExpiresAt;
if (onSoftLogout != null &&
tokenExpiresAt != null &&
tokenExpiresAt.difference(DateTime.now()) <= Duration(minutes: 5)) {
await onSoftLogout?.call(this);
tokenExpiresAt.difference(DateTime.now()) <= timeout * 2) {
await _handleSoftLogout();
}
// The timeout we send to the server for the sync loop. It says to the
// server that we want to receive an empty sync response after this
// amount of time if nothing happens.
timeout ??= const Duration(seconds: 30);
final syncRequest = sync(
filter: syncFilterId,
since: prevBatch,
@ -1910,12 +1951,8 @@ class Client extends MatrixApi {
final onSoftLogout = this.onSoftLogout;
if (e.raw.tryGet<bool>('soft_logout') == true && onSoftLogout != null) {
Logs().w('The user has been soft logged out! Try to login again...');
try {
await onSoftLogout(this);
} catch (e, s) {
Logs().e('Unable to login again', e, s);
await clear();
}
await _handleSoftLogout();
} else {
Logs().w('The user has been logged out!');
await clear();

View File

@ -2034,7 +2034,7 @@ class FakeMatrixApi extends BaseClient {
'POST': {
'/client/v3/refresh': (var req) => {
'access_token': 'a_new_token',
'expires_in_ms': 60000,
'expires_in_ms': 1000 * 60 * 5,
'refresh_token': 'another_new_token'
},
'/client/v3/delete_devices': (var req) => {},