diff --git a/lib/modules/auth/auth.module.dart b/lib/modules/auth/auth.module.dart index 474c50a..2ace267 100644 --- a/lib/modules/auth/auth.module.dart +++ b/lib/modules/auth/auth.module.dart @@ -102,10 +102,6 @@ class AuthModule { AuthToken token = AuthToken.fromJson(tokenObject); - DateTime now = DateTime.now(); - - DateTime tokenCreatedAt = now.subtract(Duration(minutes: 2)); - userObject['token'] = token.accessToken; userObject['tokenType'] = token.tokenType; userObject['tokenExpiry'] = token.expiresIn; @@ -114,8 +110,9 @@ class AuthModule { userObject['dirty'] = true; userObject['baseUrl'] = instanceUrl; userObject['authType'] = "token"; - userObject['tokenCreatedAt'] = tokenCreatedAt.toIso8601String(); - + userObject['tokenExpiresAt'] = DateTime.now() + .add(Duration(seconds: token.expiresIn)) + .toIso8601String(); User user = User.fromApi(userObject); await d2Instance.userModule.user.setData(user).save(); diff --git a/lib/modules/auth/entities/user.entity.dart b/lib/modules/auth/entities/user.entity.dart index d76240e..15607de 100644 --- a/lib/modules/auth/entities/user.entity.dart +++ b/lib/modules/auth/entities/user.entity.dart @@ -36,7 +36,7 @@ class User extends IdentifiableEntity { final String? refreshToken; @Column(nullable: true) - final String? tokenCreatedAt; + final String? tokenExpiresAt; @Column(nullable: true) final int? tokenExpiry; @@ -109,7 +109,7 @@ class User extends IdentifiableEntity { this.authType, this.phoneNumber, this.userGroups, - this.tokenCreatedAt, + this.tokenExpiresAt, required this.isLoggedIn, required bool dirty}) : super( @@ -167,8 +167,10 @@ class User extends IdentifiableEntity { userGroups: (jsonData['userGroups'] ?? []) .map((group) => UserGroup.fromJson(group)) .toList(), - tokenCreatedAt: - jsonData['tokenCreatedAt'] ?? DateTime.now().toIso8601String(), + tokenExpiresAt: jsonData['tokenExpiresAt'] ?? + DateTime.now() + .add(Duration(seconds: jsonData['tokenExpiry'] ?? 3600)) + .toIso8601String(), dirty: jsonData['dirty']); } @@ -221,8 +223,10 @@ class User extends IdentifiableEntity { ? jsonData['datasets'].toString() : null, isLoggedIn: jsonData['isLoggedIn'] ?? false, - tokenCreatedAt: - jsonData['tokenCreatedAt'] ?? DateTime.now().toIso8601String(), + tokenExpiresAt: jsonData['tokenExpiresAt'] ?? + DateTime.now() + .add(Duration(seconds: jsonData['tokenExpiry'] ?? 3600)) + .toIso8601String(), dirty: jsonData['dirty'] ?? false); } @@ -284,7 +288,7 @@ class User extends IdentifiableEntity { data['baseUrl'] = this.baseUrl; data['dirty'] = this.dirty; data['userGroups'] = this.userGroups; - data['tokenCreatedAt'] = this.tokenCreatedAt; + data['tokenExpiresAt'] = this.tokenExpiresAt; return data; } diff --git a/lib/shared/queries/base.query.dart b/lib/shared/queries/base.query.dart index a519175..f917d60 100644 --- a/lib/shared/queries/base.query.dart +++ b/lib/shared/queries/base.query.dart @@ -270,24 +270,29 @@ class BaseQuery { } Future> fetchOnline({Dio? dioTestClient}) async { - final dhisUrl = await this.dhisUrl(); - final response = await HttpClient.get(dhisUrl, - database: this.database, dioTestClient: dioTestClient); + try { + final dhisUrl = await this.dhisUrl(); + final response = await HttpClient.get(dhisUrl, + database: this.database, dioTestClient: dioTestClient); - List data = response.body != null - ? response.body[this.apiResourceName]?.toList() ?? [] - : []; + List data = response.body != null + ? response.body[this.apiResourceName]?.toList() ?? [] + : []; - return data.map((dataItem) { - dataItem['dirty'] = false; - dataItem['synced'] = true; - ClassMirror classMirror = - AnnotationReflectable.reflectType(T) as ClassMirror; + return data.map((dataItem) { + dataItem['dirty'] = false; + dataItem['synced'] = true; + ClassMirror classMirror = + AnnotationReflectable.reflectType(T) as ClassMirror; - var x = classMirror.newInstance('fromJson', [dataItem]) as T; + var x = classMirror.newInstance('fromJson', [dataItem]) as T; - return x; - }).toList(); + return x; + }).toList(); + } catch (e) { + print(e); + return []; + } } Future> deleteOnline({Dio? dioTestClient}) async { diff --git a/lib/shared/utilities/http-details.util.dart b/lib/shared/utilities/http-details.util.dart index 716bf94..f6fe6e5 100644 --- a/lib/shared/utilities/http-details.util.dart +++ b/lib/shared/utilities/http-details.util.dart @@ -9,20 +9,19 @@ import 'package:sqflite/sqflite.dart'; class OAuthToken { String token; int expiresIn; - DateTime tokenCreatedAt; + DateTime tokenExpiresAt; String refreshToken; String url; OAuthToken( {required this.token, required this.expiresIn, - required this.tokenCreatedAt, + required this.tokenExpiresAt, required this.url, required this.refreshToken}); bool isTokenExpired() { - final expirationTime = tokenCreatedAt.add(Duration(seconds: expiresIn)); - return DateTime.now().isAfter(expirationTime); + return DateTime.now().isAfter(tokenExpiresAt); } Future renew() async { @@ -37,12 +36,10 @@ class OAuthToken { final dio = Dio(options); final response = await dio.get( - '/oauth/token/refresh?token=${this.refreshToken}', + '/oauth/token/refresh?token=${this.refreshToken}&isNew=true', ); return response.data; } on DioException catch (e) { - print(e.toString()); - print(e.response?.data); return e.response?.data ?? {}; } } @@ -81,22 +78,20 @@ class HttpDetails { //!TODO: Improve token refresh implementation not to use the SDK core //!TODO!: Improve token refresh implementation not to use the SDK core - if (this.token != null && this.tokenType == 'bearer') { + if (this.token != null && + (this.tokenType == 'bearer' || this.tokenType == 'ApiToken')) { final OAuthToken token = OAuthToken( token: this.token as String, expiresIn: user?.tokenExpiry as int, refreshToken: user?.refreshToken as String, url: user?.baseUrl as String, - tokenCreatedAt: DateTime.parse(user?.tokenCreatedAt as String), + tokenExpiresAt: DateTime.parse(user?.tokenExpiresAt as String), ); - if (token.isTokenExpired() && user != null) { dynamic tokenObject = await token.renew(); if (tokenObject != null && tokenObject['access_token'] != null) { dynamic userObject = user.toJson(); AuthToken authToken = AuthToken.fromJson(tokenObject); - DateTime now = DateTime.now(); - DateTime tokenCreatedAt = now.subtract(Duration(minutes: 2)); userObject['token'] = authToken.accessToken; userObject['tokenType'] = authToken.tokenType; userObject['tokenExpiry'] = token.expiresIn; @@ -104,7 +99,9 @@ class HttpDetails { userObject['isLoggedIn'] = true; userObject['dirty'] = true; userObject['authType'] = "token"; - userObject['tokenCreatedAt'] = tokenCreatedAt.toIso8601String(); + userObject['tokenExpiresAt'] = DateTime.now() + .add(Duration(seconds: token.expiresIn)) + .toIso8601String(); User userData = User.fromApi(userObject); await UserQuery(database: database).setData(userData).save(); this.token = authToken.accessToken; @@ -125,6 +122,8 @@ class HttpDetails { switch (this.tokenType) { case 'bearer': return 'Bearer'; + case 'ApiToken': + return 'ApiToken'; default: return 'Basic'; }