feat: Store accesstokenExpiresIn and call softlogout 5 minutes before

This commit is contained in:
Krille 2024-02-23 12:50:55 +01:00
parent 38b1eb75e5
commit 65c56f3630
No known key found for this signature in database
GPG Key ID: E067ECD60F1A0652
7 changed files with 86 additions and 0 deletions

View File

@ -91,6 +91,8 @@ class Client extends MatrixApi {
Future<void> Function(Client client)? onSoftLogout;
DateTime? accessTokenExpiresAt;
// For CommandsClientExtension
final Map<String, FutureOr<String?> Function(CommandArgs)> commands = {};
final Filter syncFilter;
@ -268,6 +270,7 @@ class Client extends MatrixApi {
await database?.updateClient(
homeserverUrl,
tokenResponse.accessToken,
accessTokenExpiresAt,
tokenResponse.refreshToken,
userId,
deviceId,
@ -540,8 +543,14 @@ class Client extends MatrixApi {
throw Exception(
'Registered but token, device ID, user ID or homeserver is null.');
}
final expiresInMs = response.expiresInMs;
final tokenExpiresAt = expiresInMs == null
? null
: DateTime.now().add(Duration(milliseconds: expiresInMs));
await init(
newToken: accessToken,
newTokenExpiresAt: tokenExpiresAt,
newRefreshToken: response.refreshToken,
newUserID: userId,
newHomeserver: homeserver,
@ -604,8 +613,15 @@ class Client extends MatrixApi {
if (homeserver_ == null) {
throw Exception('Registered but homerserver is null.');
}
final expiresInMs = response.expiresInMs;
final tokenExpiresAt = expiresInMs == null
? null
: DateTime.now().add(Duration(milliseconds: expiresInMs));
await init(
newToken: accessToken,
newTokenExpiresAt: tokenExpiresAt,
newRefreshToken: response.refreshToken,
newUserID: userId,
newHomeserver: homeserver_,
@ -1521,6 +1537,7 @@ class Client extends MatrixApi {
/// `userDeviceKeysLoading` where it is necessary.
Future<void> init({
String? newToken,
DateTime? newTokenExpiresAt,
String? newRefreshToken,
Uri? newHomeserver,
String? newUserID,
@ -1579,6 +1596,11 @@ class Client extends MatrixApi {
_id = account['client_id'];
homeserver = Uri.parse(account['homeserver_url']);
accessToken = this.accessToken = account['token'];
final tokenExpiresAtMs =
int.tryParse(account.tryGet<String>('token_expires_at') ?? '');
accessTokenExpiresAt = tokenExpiresAtMs == null
? null
: DateTime.fromMillisecondsSinceEpoch(tokenExpiresAtMs);
userID = _userID = account['user_id'];
_deviceID = account['device_id'];
_deviceName = account['device_name'];
@ -1588,6 +1610,7 @@ class Client extends MatrixApi {
}
if (newToken != null) {
accessToken = this.accessToken = newToken;
accessTokenExpiresAt = newTokenExpiresAt;
homeserver = newHomeserver;
userID = _userID = newUserID;
_deviceID = newDeviceID;
@ -1595,6 +1618,7 @@ class Client extends MatrixApi {
olmAccount = newOlmAccount;
} else {
accessToken = this.accessToken = newToken ?? accessToken;
accessTokenExpiresAt = newTokenExpiresAt ?? accessTokenExpiresAt;
homeserver = newHomeserver ?? homeserver;
userID = _userID = newUserID ?? userID;
_deviceID = newDeviceID ?? _deviceID;
@ -1635,6 +1659,7 @@ class Client extends MatrixApi {
await database.updateClient(
homeserver.toString(),
accessToken,
accessTokenExpiresAt,
newRefreshToken,
userID,
_deviceID,
@ -1647,6 +1672,7 @@ class Client extends MatrixApi {
clientName,
homeserver.toString(),
accessToken,
accessTokenExpiresAt,
newRefreshToken,
userID,
_deviceID,
@ -1794,6 +1820,15 @@ class Client extends MatrixApi {
Object? syncError;
await _checkSyncFilter();
// 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);
}
// 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.
@ -3169,10 +3204,15 @@ class Client extends MatrixApi {
Logs().i('Found data in the legacy database!');
onMigration?.call();
_id = migrateClient['client_id'];
final tokenExpiresAtMs =
int.tryParse(migrateClient.tryGet<String>('token_expires_at') ?? '');
await database.insertClient(
clientName,
migrateClient['homeserver_url'],
migrateClient['token'],
tokenExpiresAtMs == null
? null
: DateTime.fromMillisecondsSinceEpoch(tokenExpiresAtMs),
migrateClient['refresh_token'],
migrateClient['user_id'],
migrateClient['device_id'],

View File

@ -33,6 +33,7 @@ abstract class DatabaseApi {
Future updateClient(
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -45,6 +46,7 @@ abstract class DatabaseApi {
String name,
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,

View File

@ -785,6 +785,7 @@ class HiveCollectionsDatabase extends DatabaseApi {
String name,
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -800,6 +801,14 @@ class HiveCollectionsDatabase extends DatabaseApi {
} else {
await _clientBox.put('refresh_token', refreshToken);
}
if (tokenExpiresAt == null) {
await _clientBox.delete('token_expires_at');
} else {
await _clientBox.put(
'token_expires_at',
tokenExpiresAt.millisecondsSinceEpoch.toString(),
);
}
if (deviceId == null) {
await _clientBox.delete('device_id');
} else {
@ -1377,6 +1386,7 @@ class HiveCollectionsDatabase extends DatabaseApi {
Future<void> updateClient(
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -1387,6 +1397,12 @@ class HiveCollectionsDatabase extends DatabaseApi {
await transaction(() async {
await _clientBox.put('homeserver_url', homeserverUrl);
await _clientBox.put('token', token);
if (tokenExpiresAt == null) {
await _clientBox.delete('token_expires_at');
} else {
await _clientBox.put('token_expires_at',
tokenExpiresAt.millisecondsSinceEpoch.toString());
}
if (refreshToken == null) {
await _clientBox.delete('refresh_token');
} else {

View File

@ -750,6 +750,7 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
String name,
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -758,6 +759,8 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
String? olmAccount) async {
await _clientBox.put('homeserver_url', homeserverUrl);
await _clientBox.put('token', token);
await _clientBox.put(
'token_expires_at', tokenExpiresAt?.millisecondsSinceEpoch.toString());
await _clientBox.put('refresh_token', refreshToken);
await _clientBox.put('user_id', userId);
await _clientBox.put('device_id', deviceId);
@ -1316,6 +1319,7 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
Future<void> updateClient(
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -1325,6 +1329,8 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
) async {
await _clientBox.put('homeserver_url', homeserverUrl);
await _clientBox.put('token', token);
await _clientBox.put(
'token_expires_at', tokenExpiresAt?.millisecondsSinceEpoch.toString());
await _clientBox.put('refresh_token', refreshToken);
await _clientBox.put('user_id', userId);
await _clientBox.put('device_id', deviceId);

View File

@ -727,6 +727,7 @@ class MatrixSdkDatabase extends DatabaseApi {
String name,
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -736,6 +737,12 @@ class MatrixSdkDatabase extends DatabaseApi {
await transaction(() async {
await _clientBox.put('homeserver_url', homeserverUrl);
await _clientBox.put('token', token);
if (tokenExpiresAt == null) {
await _clientBox.delete('token_expires_at');
} else {
await _clientBox.put('token_expires_at',
tokenExpiresAt.millisecondsSinceEpoch.toString());
}
if (refreshToken == null) {
await _clientBox.delete('refresh_token');
} else {
@ -1349,6 +1356,7 @@ class MatrixSdkDatabase extends DatabaseApi {
Future<void> updateClient(
String homeserverUrl,
String token,
DateTime? tokenExpiresAt,
String? refreshToken,
String userId,
String? deviceId,
@ -1359,6 +1367,12 @@ class MatrixSdkDatabase extends DatabaseApi {
await transaction(() async {
await _clientBox.put('homeserver_url', homeserverUrl);
await _clientBox.put('token', token);
if (tokenExpiresAt == null) {
await _clientBox.delete('token_expires_at');
} else {
await _clientBox.put('token_expires_at',
tokenExpiresAt.millisecondsSinceEpoch.toString());
}
if (refreshToken == null) {
await _clientBox.delete('refresh_token');
} else {

View File

@ -129,10 +129,12 @@ void main() {
await database.getClient('name');
});
test('insertClient', () async {
final now = DateTime.now();
await database.insertClient(
'name',
'homeserverUrl',
'token',
now,
'refresh_token',
'userId',
'deviceId',
@ -143,11 +145,16 @@ void main() {
final client = await database.getClient('name');
expect(client?['token'], 'token');
expect(
client?['token_expires_at'],
now.millisecondsSinceEpoch.toString(),
);
});
test('updateClient', () async {
await database.updateClient(
'homeserverUrl',
'token_different',
DateTime.now(),
'refresh_token',
'userId',
'deviceId',

View File

@ -33,6 +33,7 @@ void main() {
'https://example.org',
'blubb',
null,
null,
'@test:example.org',
null,
null,