refreshToken method
Refresh access token
Implementation
Future<AuthResult> refreshToken() async {
try {
// Get refresh token (try all sources)
final refreshToken = await getRefreshTokenAsync();
if (refreshToken == null || refreshToken.isEmpty) {
_logger.debug('No refresh token available');
return AuthResult.failure('No refresh token available');
}
// Get device ID (try all sources, matching getRefreshTokenAsync pattern)
var deviceId = getDeviceId();
if (deviceId == null || deviceId.isEmpty) {
// Try cache
deviceId = _secureCache['com.runanywhere.sdk.deviceId'];
}
if (deviceId == null || deviceId.isEmpty) {
// Try secure storage directly
try {
const storage = FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
);
deviceId = await storage.read(key: 'com.runanywhere.sdk.deviceId');
if (deviceId != null && deviceId.isNotEmpty) {
_secureCache['com.runanywhere.sdk.deviceId'] = deviceId;
}
} catch (e) {
_logger.debug('Failed to read device ID from secure storage: $e');
}
}
if (deviceId == null || deviceId.isEmpty) {
// Fallback: get from DartBridgeDevice
deviceId = await DartBridgeDevice.instance.getDeviceId();
if (deviceId.isNotEmpty) {
_secureCache['com.runanywhere.sdk.deviceId'] = deviceId;
}
}
if (deviceId == null || deviceId.isEmpty) {
_logger.debug('No device ID available');
return AuthResult.failure('No device ID available');
}
// Build refresh request JSON
final requestJson = jsonEncode({
'device_id': deviceId,
'refresh_token': refreshToken,
});
_logger.debug('Refreshing token for device: $deviceId');
// Make HTTP request
final endpoint = _getRefreshEndpoint();
final baseURL = _baseURL ?? _getDefaultBaseURL();
final url = Uri.parse('$baseURL$endpoint');
final headers = <String, String>{
'Content-Type': 'application/json',
'Accept': 'application/json',
};
final response = await http.post(url, headers: headers, body: requestJson);
if (response.statusCode == 200 || response.statusCode == 201) {
final authData = _parseAuthResponse(response.body);
// Try C++ handler first
final cppSuccess = _handleRefreshResponse(response.body);
// Also manually store tokens in secure storage (in case C++ handler unavailable)
await _storeAuthTokens(authData);
if (cppSuccess || authData.accessToken != null) {
_logger.info('Token refresh successful');
return AuthResult.success(authData);
} else {
return AuthResult.failure('Failed to parse refresh response');
}
} else {
final errorMsg = _parseAPIError(response.body, response.statusCode);
_logger.warning('Token refresh failed: $errorMsg');
return AuthResult.failure(errorMsg);
}
} catch (e) {
_logger.error('Token refresh error', metadata: {'error': e.toString()});
return AuthResult.failure(e.toString());
}
}