refreshTokens method
Gets user information using automatic token management Returns null if token is invalid and refresh fails Gets user information with automatic re-authentication This version requires BuildContext for UI navigation if needed
Implementation
// Future<UserInfo?> getUser() async {
// final accessToken = await getAccessToken();
// if (accessToken == null) {
// debugPrint('[WARNING] No valid access token for getUser - authentication required');
// return null;
// }
//
// try {
// final response =
// Uri.parse('${Remit2AnyEnvironmentConfig.authUrl}/oauth2/userInfo');
// final res = await http.get(
// response,
// headers: {'Authorization': 'Bearer $accessToken'},
// );
// if (res.statusCode == 200) {
// return UserInfo.fromJson(jsonDecode(res.body));
// } else {
// debugPrint('[ERROR] Failed to fetch user info: ${res.statusCode}');
// }
// } catch (e) {
// debugPrint('[ERROR] Error fetching user info: $e');
// }
// return null;
// }
/// Gets user information with automatic re-authentication
/// This version requires BuildContext for UI navigation if needed
// Future<UserInfo?> getUserWithAuth(BuildContext context) async {
// // First try without UI
// final user = await getUser();
// if (user != null) return user;
//
// // If failed, try to get a valid token with auth
// final accessToken = await getAccessTokenWithAuth(context);
// if (accessToken == null) return null;
//
// // Retry with new token
// return await getUser();
// }
Future<void> refreshTokens() async {
final refreshToken = await TokenStorage.getRefreshToken();
final deviceKey = await TokenStorage.getDeviceKey();
final currentAccessToken = await TokenStorage.getAccessToken();
if (refreshToken == null) {
debugPrint('[WARNING] No refresh token available for refresh');
await _handleRefreshFailure();
return;
}
try {
final clientId = Remit2AnyEnvironmentConfig.userPoolClientId;
final url = Uri.parse('https://cognito-idp.us-east-1.amazonaws.com/');
debugPrint('[INFO] Refreshing tokens using Cognito API...');
final requestBody = {
'ClientId': clientId,
'AuthFlow': 'REFRESH_TOKEN_AUTH',
'AuthParameters': {
'REFRESH_TOKEN': refreshToken,
'DEVICE_KEY': deviceKey,
}
};
final response = await http.post(
url,
headers: {
'Content-Type': 'application/x-amz-json-1.1',
'X-Amz-Target': 'AWSCognitoIdentityProviderService.InitiateAuth',
},
body: jsonEncode(requestBody),
);
debugPrint('[DEBUG] Cognito API Response Status: ${response.statusCode}');
debugPrint('[DEBUG] Cognito API Response Body: ${response.body}');
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
// Check if we got a valid response with AuthenticationResult
if (data['AuthenticationResult'] != null) {
final authResult = data['AuthenticationResult'];
final newAccessToken = authResult['AccessToken'];
final newIdToken = authResult['IdToken'];
// Check if access token is present
if (newAccessToken == null || newAccessToken.isEmpty) {
debugPrint(
'[ERROR] No access token in refresh response, calling signIn');
await _handleRefreshFailure();
return;
}
// Check if the new access token is the same as current one
if (newAccessToken == currentAccessToken) {
debugPrint(
'[WARNING] New access token is same as current one, calling signIn');
await _handleRefreshFailure();
return;
}
// Save the new tokens
await TokenStorage.saveTokens(
accessToken: newAccessToken,
refreshToken: refreshToken, // Keep the same refresh token
deviceKey: deviceKey, // Keep the same device key
idToken: newIdToken,
);
debugPrint('[INFO] Tokens refreshed successfully');
} else {
debugPrint(
'[ERROR] No AuthenticationResult in response, calling signIn');
await _handleRefreshFailure();
}
} else {
debugPrint('[ERROR] Token refresh failed: ${response.statusCode}');
debugPrint('[ERROR] Response body: ${response.body}');
await _handleRefreshFailure();
}
} catch (e) {
debugPrint('[ERROR] Token refresh exception: $e, calling signIn');
await _handleRefreshFailure();
}
}