import 'dart:convert'; import 'dart:io'; import 'package:aitrainer_app/service/logging.dart'; import 'package:aitrainer_app/util/common.dart'; import 'package:aitrainer_app/util/not_found_exception.dart'; import 'package:flutter/services.dart'; import 'package:aitrainer_app/model/cache.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; class APIClient with Common, Logging { static final APIClient _singleton = APIClient._internal(); late bool cert; factory APIClient() { return _singleton; } APIClient._internal() { cert = false; } dynamic authenticateUser(String email, String password) async { var url = Cache().getBaseUrl() + "authenticate"; try { ByteData data = await rootBundle.load('asset/data/aitrainer_server.crt.pem'); SecurityContext context = SecurityContext.defaultContext; if (cert == false) { print("Set CERT $cert"); context.setTrustedCertificatesBytes(data.buffer.asUint8List(), password: "[xxxx]"); cert = true; } HttpClient client = new HttpClient(); //context: context Todo provide the right certificate client.badCertificateCallback = ((X509Certificate cert, String host, int port) { print("Host: $host Port: $port"); return true; }); var uri = Uri.parse(url); final HttpClientRequest request = await client.postUrl(uri); request.headers.set('Content-Type', 'application/json'); request.headers.set('Authorization', '1'); final body = '{"username":"$email", "password":"$password"}'; request.write(body); HttpClientResponse result = await request.close(); client.close(); if (result.statusCode != 200) { trace("authentication response: ${result.statusCode} with URL: $url"); throw Exception("Authentication error: ${result.statusCode}"); } return jsonDecode(await result.transform(utf8.decoder).join()); } catch (exception) { print(exception.toString()); try { await Sentry.captureException(exception); } on Exception catch (e) { print(e); } throw Exception("Network error, try again later!"); } } Future post(String endPoint, String body) async { final url = Cache().getBaseUrl() + endPoint; trace(" ------------ http/post body $body - url: $url "); try { String authToken = Cache().getAuthToken(); if (authToken.length == 0) { var responseJson = await this.authenticateUser(Cache.username, Cache.password); authToken = responseJson['token']; Cache().authToken = authToken; } var uri = Uri.parse(url); HttpClient client = new HttpClient(); client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true); final HttpClientRequest request = await client.postUrl(uri); request.headers.contentType = new ContentType("application", "json", charset: "utf-8"); request.headers.set('Authorization', 'Bearer $authToken'); //request.contentLength = body.length; request.write(body); HttpClientResponse result = await request.close(); client.close(); trace(" ------------post response code: " + result.statusCode.toString()); if (result.statusCode == 200) { return await result.transform(utf8.decoder).join(); } else if (result.statusCode == 404) { throw NotFoundException(message: "Not Found"); } else { throw Exception("Network Error, please try again later"); } } on NotFoundException catch(e) { throw NotFoundException(message: "Not Found"); } on Exception catch (e) { print("Post Exception: $e"); await Sentry.captureException(e); throw Exception("Network Error, please try again later"); } } Future get(String endPoint, String param) async { final url = Cache().getBaseUrl() + endPoint + param; try { trace("-------- API get " + url); String authToken = Cache().getAuthToken(); if (authToken.length == 0) { var responseJson = await this.authenticateUser(Cache.username, Cache.password); authToken = responseJson['token']; Cache().authToken = authToken; } var uri = Uri.parse(url); HttpClient client = new HttpClient(); client.badCertificateCallback = ((X509Certificate cert, String host, int port) => true); final HttpClientRequest request = await client.getUrl(uri); request.headers.set('Content-Type', 'application/json'); request.headers.set('Authorization', 'Bearer $authToken'); HttpClientResponse result = await request.close(); client.close(); trace(" ------------get response code: " + result.statusCode.toString()); if (result.statusCode == 200) { return await result.transform(utf8.decoder).join(); } else if (result.statusCode == 404) { throw NotFoundException(message: "Not Found"); } else { throw Exception("Network Error, please try again later"); } } on NotFoundException catch(e) { throw NotFoundException(message: "Not Found"); } on Exception catch (e) { print("Post Exception: $e"); await Sentry.captureException(e); throw Exception("Network Error, please try again later"); } } }