feat: Store accesstokenExpiresIn and call softlogout 5 minutes before
This commit is contained in:
parent
38b1eb75e5
commit
65c56f3630
|
|
@ -91,6 +91,8 @@ class Client extends MatrixApi {
|
||||||
|
|
||||||
Future<void> Function(Client client)? onSoftLogout;
|
Future<void> Function(Client client)? onSoftLogout;
|
||||||
|
|
||||||
|
DateTime? accessTokenExpiresAt;
|
||||||
|
|
||||||
// For CommandsClientExtension
|
// For CommandsClientExtension
|
||||||
final Map<String, FutureOr<String?> Function(CommandArgs)> commands = {};
|
final Map<String, FutureOr<String?> Function(CommandArgs)> commands = {};
|
||||||
final Filter syncFilter;
|
final Filter syncFilter;
|
||||||
|
|
@ -268,6 +270,7 @@ class Client extends MatrixApi {
|
||||||
await database?.updateClient(
|
await database?.updateClient(
|
||||||
homeserverUrl,
|
homeserverUrl,
|
||||||
tokenResponse.accessToken,
|
tokenResponse.accessToken,
|
||||||
|
accessTokenExpiresAt,
|
||||||
tokenResponse.refreshToken,
|
tokenResponse.refreshToken,
|
||||||
userId,
|
userId,
|
||||||
deviceId,
|
deviceId,
|
||||||
|
|
@ -540,8 +543,14 @@ class Client extends MatrixApi {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
'Registered but token, device ID, user ID or homeserver is null.');
|
'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(
|
await init(
|
||||||
newToken: accessToken,
|
newToken: accessToken,
|
||||||
|
newTokenExpiresAt: tokenExpiresAt,
|
||||||
newRefreshToken: response.refreshToken,
|
newRefreshToken: response.refreshToken,
|
||||||
newUserID: userId,
|
newUserID: userId,
|
||||||
newHomeserver: homeserver,
|
newHomeserver: homeserver,
|
||||||
|
|
@ -604,8 +613,15 @@ class Client extends MatrixApi {
|
||||||
if (homeserver_ == null) {
|
if (homeserver_ == null) {
|
||||||
throw Exception('Registered but homerserver is 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(
|
await init(
|
||||||
newToken: accessToken,
|
newToken: accessToken,
|
||||||
|
newTokenExpiresAt: tokenExpiresAt,
|
||||||
newRefreshToken: response.refreshToken,
|
newRefreshToken: response.refreshToken,
|
||||||
newUserID: userId,
|
newUserID: userId,
|
||||||
newHomeserver: homeserver_,
|
newHomeserver: homeserver_,
|
||||||
|
|
@ -1521,6 +1537,7 @@ class Client extends MatrixApi {
|
||||||
/// `userDeviceKeysLoading` where it is necessary.
|
/// `userDeviceKeysLoading` where it is necessary.
|
||||||
Future<void> init({
|
Future<void> init({
|
||||||
String? newToken,
|
String? newToken,
|
||||||
|
DateTime? newTokenExpiresAt,
|
||||||
String? newRefreshToken,
|
String? newRefreshToken,
|
||||||
Uri? newHomeserver,
|
Uri? newHomeserver,
|
||||||
String? newUserID,
|
String? newUserID,
|
||||||
|
|
@ -1579,6 +1596,11 @@ class Client extends MatrixApi {
|
||||||
_id = account['client_id'];
|
_id = account['client_id'];
|
||||||
homeserver = Uri.parse(account['homeserver_url']);
|
homeserver = Uri.parse(account['homeserver_url']);
|
||||||
accessToken = this.accessToken = account['token'];
|
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'];
|
userID = _userID = account['user_id'];
|
||||||
_deviceID = account['device_id'];
|
_deviceID = account['device_id'];
|
||||||
_deviceName = account['device_name'];
|
_deviceName = account['device_name'];
|
||||||
|
|
@ -1588,6 +1610,7 @@ class Client extends MatrixApi {
|
||||||
}
|
}
|
||||||
if (newToken != null) {
|
if (newToken != null) {
|
||||||
accessToken = this.accessToken = newToken;
|
accessToken = this.accessToken = newToken;
|
||||||
|
accessTokenExpiresAt = newTokenExpiresAt;
|
||||||
homeserver = newHomeserver;
|
homeserver = newHomeserver;
|
||||||
userID = _userID = newUserID;
|
userID = _userID = newUserID;
|
||||||
_deviceID = newDeviceID;
|
_deviceID = newDeviceID;
|
||||||
|
|
@ -1595,6 +1618,7 @@ class Client extends MatrixApi {
|
||||||
olmAccount = newOlmAccount;
|
olmAccount = newOlmAccount;
|
||||||
} else {
|
} else {
|
||||||
accessToken = this.accessToken = newToken ?? accessToken;
|
accessToken = this.accessToken = newToken ?? accessToken;
|
||||||
|
accessTokenExpiresAt = newTokenExpiresAt ?? accessTokenExpiresAt;
|
||||||
homeserver = newHomeserver ?? homeserver;
|
homeserver = newHomeserver ?? homeserver;
|
||||||
userID = _userID = newUserID ?? userID;
|
userID = _userID = newUserID ?? userID;
|
||||||
_deviceID = newDeviceID ?? _deviceID;
|
_deviceID = newDeviceID ?? _deviceID;
|
||||||
|
|
@ -1635,6 +1659,7 @@ class Client extends MatrixApi {
|
||||||
await database.updateClient(
|
await database.updateClient(
|
||||||
homeserver.toString(),
|
homeserver.toString(),
|
||||||
accessToken,
|
accessToken,
|
||||||
|
accessTokenExpiresAt,
|
||||||
newRefreshToken,
|
newRefreshToken,
|
||||||
userID,
|
userID,
|
||||||
_deviceID,
|
_deviceID,
|
||||||
|
|
@ -1647,6 +1672,7 @@ class Client extends MatrixApi {
|
||||||
clientName,
|
clientName,
|
||||||
homeserver.toString(),
|
homeserver.toString(),
|
||||||
accessToken,
|
accessToken,
|
||||||
|
accessTokenExpiresAt,
|
||||||
newRefreshToken,
|
newRefreshToken,
|
||||||
userID,
|
userID,
|
||||||
_deviceID,
|
_deviceID,
|
||||||
|
|
@ -1794,6 +1820,15 @@ class Client extends MatrixApi {
|
||||||
Object? syncError;
|
Object? syncError;
|
||||||
await _checkSyncFilter();
|
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
|
// 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
|
// server that we want to receive an empty sync response after this
|
||||||
// amount of time if nothing happens.
|
// amount of time if nothing happens.
|
||||||
|
|
@ -3169,10 +3204,15 @@ class Client extends MatrixApi {
|
||||||
Logs().i('Found data in the legacy database!');
|
Logs().i('Found data in the legacy database!');
|
||||||
onMigration?.call();
|
onMigration?.call();
|
||||||
_id = migrateClient['client_id'];
|
_id = migrateClient['client_id'];
|
||||||
|
final tokenExpiresAtMs =
|
||||||
|
int.tryParse(migrateClient.tryGet<String>('token_expires_at') ?? '');
|
||||||
await database.insertClient(
|
await database.insertClient(
|
||||||
clientName,
|
clientName,
|
||||||
migrateClient['homeserver_url'],
|
migrateClient['homeserver_url'],
|
||||||
migrateClient['token'],
|
migrateClient['token'],
|
||||||
|
tokenExpiresAtMs == null
|
||||||
|
? null
|
||||||
|
: DateTime.fromMillisecondsSinceEpoch(tokenExpiresAtMs),
|
||||||
migrateClient['refresh_token'],
|
migrateClient['refresh_token'],
|
||||||
migrateClient['user_id'],
|
migrateClient['user_id'],
|
||||||
migrateClient['device_id'],
|
migrateClient['device_id'],
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ abstract class DatabaseApi {
|
||||||
Future updateClient(
|
Future updateClient(
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -45,6 +46,7 @@ abstract class DatabaseApi {
|
||||||
String name,
|
String name,
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
|
||||||
|
|
@ -785,6 +785,7 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
||||||
String name,
|
String name,
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -800,6 +801,14 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
||||||
} else {
|
} else {
|
||||||
await _clientBox.put('refresh_token', refreshToken);
|
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) {
|
if (deviceId == null) {
|
||||||
await _clientBox.delete('device_id');
|
await _clientBox.delete('device_id');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1377,6 +1386,7 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
||||||
Future<void> updateClient(
|
Future<void> updateClient(
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -1387,6 +1397,12 @@ class HiveCollectionsDatabase extends DatabaseApi {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
await _clientBox.put('homeserver_url', homeserverUrl);
|
await _clientBox.put('homeserver_url', homeserverUrl);
|
||||||
await _clientBox.put('token', token);
|
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) {
|
if (refreshToken == null) {
|
||||||
await _clientBox.delete('refresh_token');
|
await _clientBox.delete('refresh_token');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -750,6 +750,7 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
|
||||||
String name,
|
String name,
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -758,6 +759,8 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
|
||||||
String? olmAccount) async {
|
String? olmAccount) async {
|
||||||
await _clientBox.put('homeserver_url', homeserverUrl);
|
await _clientBox.put('homeserver_url', homeserverUrl);
|
||||||
await _clientBox.put('token', token);
|
await _clientBox.put('token', token);
|
||||||
|
await _clientBox.put(
|
||||||
|
'token_expires_at', tokenExpiresAt?.millisecondsSinceEpoch.toString());
|
||||||
await _clientBox.put('refresh_token', refreshToken);
|
await _clientBox.put('refresh_token', refreshToken);
|
||||||
await _clientBox.put('user_id', userId);
|
await _clientBox.put('user_id', userId);
|
||||||
await _clientBox.put('device_id', deviceId);
|
await _clientBox.put('device_id', deviceId);
|
||||||
|
|
@ -1316,6 +1319,7 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
|
||||||
Future<void> updateClient(
|
Future<void> updateClient(
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -1325,6 +1329,8 @@ class FamedlySdkHiveDatabase extends DatabaseApi with ZoneTransactionMixin {
|
||||||
) async {
|
) async {
|
||||||
await _clientBox.put('homeserver_url', homeserverUrl);
|
await _clientBox.put('homeserver_url', homeserverUrl);
|
||||||
await _clientBox.put('token', token);
|
await _clientBox.put('token', token);
|
||||||
|
await _clientBox.put(
|
||||||
|
'token_expires_at', tokenExpiresAt?.millisecondsSinceEpoch.toString());
|
||||||
await _clientBox.put('refresh_token', refreshToken);
|
await _clientBox.put('refresh_token', refreshToken);
|
||||||
await _clientBox.put('user_id', userId);
|
await _clientBox.put('user_id', userId);
|
||||||
await _clientBox.put('device_id', deviceId);
|
await _clientBox.put('device_id', deviceId);
|
||||||
|
|
|
||||||
|
|
@ -727,6 +727,7 @@ class MatrixSdkDatabase extends DatabaseApi {
|
||||||
String name,
|
String name,
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -736,6 +737,12 @@ class MatrixSdkDatabase extends DatabaseApi {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
await _clientBox.put('homeserver_url', homeserverUrl);
|
await _clientBox.put('homeserver_url', homeserverUrl);
|
||||||
await _clientBox.put('token', token);
|
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) {
|
if (refreshToken == null) {
|
||||||
await _clientBox.delete('refresh_token');
|
await _clientBox.delete('refresh_token');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1349,6 +1356,7 @@ class MatrixSdkDatabase extends DatabaseApi {
|
||||||
Future<void> updateClient(
|
Future<void> updateClient(
|
||||||
String homeserverUrl,
|
String homeserverUrl,
|
||||||
String token,
|
String token,
|
||||||
|
DateTime? tokenExpiresAt,
|
||||||
String? refreshToken,
|
String? refreshToken,
|
||||||
String userId,
|
String userId,
|
||||||
String? deviceId,
|
String? deviceId,
|
||||||
|
|
@ -1359,6 +1367,12 @@ class MatrixSdkDatabase extends DatabaseApi {
|
||||||
await transaction(() async {
|
await transaction(() async {
|
||||||
await _clientBox.put('homeserver_url', homeserverUrl);
|
await _clientBox.put('homeserver_url', homeserverUrl);
|
||||||
await _clientBox.put('token', token);
|
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) {
|
if (refreshToken == null) {
|
||||||
await _clientBox.delete('refresh_token');
|
await _clientBox.delete('refresh_token');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -129,10 +129,12 @@ void main() {
|
||||||
await database.getClient('name');
|
await database.getClient('name');
|
||||||
});
|
});
|
||||||
test('insertClient', () async {
|
test('insertClient', () async {
|
||||||
|
final now = DateTime.now();
|
||||||
await database.insertClient(
|
await database.insertClient(
|
||||||
'name',
|
'name',
|
||||||
'homeserverUrl',
|
'homeserverUrl',
|
||||||
'token',
|
'token',
|
||||||
|
now,
|
||||||
'refresh_token',
|
'refresh_token',
|
||||||
'userId',
|
'userId',
|
||||||
'deviceId',
|
'deviceId',
|
||||||
|
|
@ -143,11 +145,16 @@ void main() {
|
||||||
|
|
||||||
final client = await database.getClient('name');
|
final client = await database.getClient('name');
|
||||||
expect(client?['token'], 'token');
|
expect(client?['token'], 'token');
|
||||||
|
expect(
|
||||||
|
client?['token_expires_at'],
|
||||||
|
now.millisecondsSinceEpoch.toString(),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
test('updateClient', () async {
|
test('updateClient', () async {
|
||||||
await database.updateClient(
|
await database.updateClient(
|
||||||
'homeserverUrl',
|
'homeserverUrl',
|
||||||
'token_different',
|
'token_different',
|
||||||
|
DateTime.now(),
|
||||||
'refresh_token',
|
'refresh_token',
|
||||||
'userId',
|
'userId',
|
||||||
'deviceId',
|
'deviceId',
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ void main() {
|
||||||
'https://example.org',
|
'https://example.org',
|
||||||
'blubb',
|
'blubb',
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
'@test:example.org',
|
'@test:example.org',
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue