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:
commit
fdee8ee845
|
|
@ -43,7 +43,7 @@ import 'package:matrix/src/utils/try_get_push_rule.dart';
|
||||||
|
|
||||||
typedef RoomSorter = int Function(Room a, Room b);
|
typedef RoomSorter = int Function(Room a, Room b);
|
||||||
|
|
||||||
enum LoginState { loggedIn, loggedOut }
|
enum LoginState { loggedIn, loggedOut, softLoggedOut }
|
||||||
|
|
||||||
extension TrailingSlash on Uri {
|
extension TrailingSlash on Uri {
|
||||||
Uri stripTrailingSlash() => path.endsWith('/')
|
Uri stripTrailingSlash() => path.endsWith('/')
|
||||||
|
|
@ -267,10 +267,15 @@ class Client extends MatrixApi {
|
||||||
final tokenResponse = await refresh(refreshToken);
|
final tokenResponse = await refresh(refreshToken);
|
||||||
|
|
||||||
accessToken = tokenResponse.accessToken;
|
accessToken = tokenResponse.accessToken;
|
||||||
|
final expiresInMs = tokenResponse.expiresInMs;
|
||||||
|
final tokenExpiresAt = expiresInMs == null
|
||||||
|
? null
|
||||||
|
: DateTime.now().add(Duration(milliseconds: expiresInMs));
|
||||||
|
accessTokenExpiresAt = tokenExpiresAt;
|
||||||
await database?.updateClient(
|
await database?.updateClient(
|
||||||
homeserverUrl,
|
homeserverUrl,
|
||||||
tokenResponse.accessToken,
|
tokenResponse.accessToken,
|
||||||
accessTokenExpiresAt,
|
tokenExpiresAt,
|
||||||
tokenResponse.refreshToken,
|
tokenResponse.refreshToken,
|
||||||
userId,
|
userId,
|
||||||
deviceId,
|
deviceId,
|
||||||
|
|
@ -1574,7 +1579,7 @@ class Client extends MatrixApi {
|
||||||
String? userID;
|
String? userID;
|
||||||
try {
|
try {
|
||||||
Logs().i('Initialize client $clientName');
|
Logs().i('Initialize client $clientName');
|
||||||
if (isLogged()) {
|
if (onLoginStateChanged.value == LoginState.loggedIn) {
|
||||||
throw ClientInitPreconditionError(
|
throw ClientInitPreconditionError(
|
||||||
'User is already logged in! Call [logout()] first!',
|
'User is already logged in! Call [logout()] first!',
|
||||||
);
|
);
|
||||||
|
|
@ -1592,6 +1597,7 @@ class Client extends MatrixApi {
|
||||||
_serverConfigCache.invalidate();
|
_serverConfigCache.invalidate();
|
||||||
|
|
||||||
final account = await this.database?.getClient(clientName);
|
final account = await this.database?.getClient(clientName);
|
||||||
|
newRefreshToken ??= account?.tryGet<String>('refresh_token');
|
||||||
if (account != null) {
|
if (account != null) {
|
||||||
_id = account['client_id'];
|
_id = account['client_id'];
|
||||||
homeserver = Uri.parse(account['homeserver_url']);
|
homeserver = Uri.parse(account['homeserver_url']);
|
||||||
|
|
@ -1626,6 +1632,26 @@ class Client extends MatrixApi {
|
||||||
olmAccount = newOlmAccount ?? olmAccount;
|
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 (accessToken == null || homeserver == null || userID == null) {
|
||||||
if (legacyDatabaseBuilder != null) {
|
if (legacyDatabaseBuilder != null) {
|
||||||
await _migrateFromLegacyDatabase(onMigration: onMigration);
|
await _migrateFromLegacyDatabase(onMigration: onMigration);
|
||||||
|
|
@ -1806,6 +1832,21 @@ class Client extends MatrixApi {
|
||||||
return;
|
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.
|
/// Pass a timeout to set how long the server waits before sending an empty response.
|
||||||
/// (Corresponds to the timeout param on the /sync request.)
|
/// (Corresponds to the timeout param on the /sync request.)
|
||||||
Future<void> _innerSync({Duration? timeout}) async {
|
Future<void> _innerSync({Duration? timeout}) async {
|
||||||
|
|
@ -1820,20 +1861,20 @@ class Client extends MatrixApi {
|
||||||
Object? syncError;
|
Object? syncError;
|
||||||
await _checkSyncFilter();
|
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
|
// Call onSoftLogout 5 minutes before access token expires to prevent
|
||||||
// failing network requests.
|
// failing network requests.
|
||||||
final tokenExpiresAt = accessTokenExpiresAt;
|
final tokenExpiresAt = accessTokenExpiresAt;
|
||||||
if (onSoftLogout != null &&
|
if (onSoftLogout != null &&
|
||||||
tokenExpiresAt != null &&
|
tokenExpiresAt != null &&
|
||||||
tokenExpiresAt.difference(DateTime.now()) <= Duration(minutes: 5)) {
|
tokenExpiresAt.difference(DateTime.now()) <= timeout * 2) {
|
||||||
await onSoftLogout?.call(this);
|
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(
|
final syncRequest = sync(
|
||||||
filter: syncFilterId,
|
filter: syncFilterId,
|
||||||
since: prevBatch,
|
since: prevBatch,
|
||||||
|
|
@ -1910,12 +1951,8 @@ class Client extends MatrixApi {
|
||||||
final onSoftLogout = this.onSoftLogout;
|
final onSoftLogout = this.onSoftLogout;
|
||||||
if (e.raw.tryGet<bool>('soft_logout') == true && onSoftLogout != null) {
|
if (e.raw.tryGet<bool>('soft_logout') == true && onSoftLogout != null) {
|
||||||
Logs().w('The user has been soft logged out! Try to login again...');
|
Logs().w('The user has been soft logged out! Try to login again...');
|
||||||
try {
|
|
||||||
await onSoftLogout(this);
|
await _handleSoftLogout();
|
||||||
} catch (e, s) {
|
|
||||||
Logs().e('Unable to login again', e, s);
|
|
||||||
await clear();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Logs().w('The user has been logged out!');
|
Logs().w('The user has been logged out!');
|
||||||
await clear();
|
await clear();
|
||||||
|
|
|
||||||
|
|
@ -2034,7 +2034,7 @@ class FakeMatrixApi extends BaseClient {
|
||||||
'POST': {
|
'POST': {
|
||||||
'/client/v3/refresh': (var req) => {
|
'/client/v3/refresh': (var req) => {
|
||||||
'access_token': 'a_new_token',
|
'access_token': 'a_new_token',
|
||||||
'expires_in_ms': 60000,
|
'expires_in_ms': 1000 * 60 * 5,
|
||||||
'refresh_token': 'another_new_token'
|
'refresh_token': 'another_new_token'
|
||||||
},
|
},
|
||||||
'/client/v3/delete_devices': (var req) => {},
|
'/client/v3/delete_devices': (var req) => {},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue