api_auth_provider.dart 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'package:dio/dio.dart';
  5. import 'package:flutter/cupertino.dart';
  6. import 'package:telnow_mobile_new/src/injector/injector.dart';
  7. import 'package:telnow_mobile_new/src/model/login/login_body.dart';
  8. import 'package:telnow_mobile_new/src/model/refreshtoken/refresh_token_body.dart';
  9. import 'package:telnow_mobile_new/src/model/token/token.dart';
  10. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  11. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  12. import 'package:telnow_mobile_new/src/utils/ui_service.dart';
  13. import 'package:telnow_mobile_new/src/utils/dio_logging_interceptors.dart';
  14. import 'package:telnow_mobile_new/src/utils/U.dart';
  15. import 'package:easy_localization/easy_localization.dart';
  16. import 'package:http/http.dart' as http;
  17. const String host = '';
  18. // const String host = 'bridge3.telmessenger.com';
  19. // const String host = '192.168.100.19:8080';
  20. // const String host = '192.168.100.18:8080';
  21. class ApiAuthProvider {
  22. final Dio _dio = Dio();
  23. final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
  24. final String displayVersion = '4.0.17'; //versi aplikasi untuk di tampilkan
  25. final int currentVersion = 40; //versi aplikasi yang digunakan untuk pengecekan versi
  26. final String buildNumber = '2617.01';
  27. // final String companyName = '999';
  28. // final String _baseUrl = 'http://139.162.7.140:9090/';
  29. // final String _baseUrl = 'http://192.168.100.14:8080/'; //irma
  30. // final String _baseUrl = 'http://192.168.100.68:8080/'; //mita
  31. // final String _baseUrl = 'http://192.168.100.121:8080/'; //abi
  32. // String companyCode = '001';
  33. late String baseUrl = 'https://$host/';
  34. // final String baseUrl = 'http://$host/';
  35. final String clientId = 'inf-G52G4op8N8';
  36. final String clientSecret = '3JskYu5zxlXRDv6g';
  37. // final String clientIdWeb = 'web-apHca0ncOX';
  38. // final String clientSecretWeb = '1qeIwW8Wu9AF4DRF';
  39. bool isDebug = false;
  40. ApiAuthProvider() {
  41. // print('ApiAuthProvider called');
  42. // print(U.getAccessCode());
  43. // isDebug = _sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsDebug);
  44. // if (_sharedPreferencesManager
  45. // .isKeyExists(SharedPreferencesManager.keyAccessCode)) {
  46. // _dio.options.baseUrl = baseUrl + U.decryptAESCryptoJS(U.getAccessCode(), U.passphrase);
  47. // // _dio.options.baseUrl = baseUrl + U.getAccessCode();
  48. // _dio.interceptors.add(DioLoggingInterceptors(_dio));
  49. // }
  50. init();
  51. }
  52. init(){
  53. // print('ApiAuthProvider called');
  54. // print("U.getAccessCode() ==> ${U.getAccessCode()}");
  55. isDebug = _sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsDebug)??false;
  56. if (_sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyAccessCode)! && _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyBaseUrl)!) {
  57. baseUrl = U.decodeBase64Url(U.getBaseUrl()!);
  58. _dio.options.baseUrl = baseUrl + U.decodeBase64Url(Uri.decodeComponent(U.getAccessCode()!));
  59. // _dio.options.baseUrl = baseUrl + U.getAccessCode();
  60. _dio.interceptors.add(DioLoggingInterceptors(_dio));
  61. }
  62. }
  63. Future<Token> loginUser(LoginBody loginBody) async {
  64. try {
  65. // print("======base url==========");
  66. // print(baseUrl + U.decryptAESCryptoJS(U.getAccessCode(), U.passphrase));
  67. var loginData = loginBody.toJson();
  68. var strData = "";
  69. var i = 0;
  70. loginData.forEach((key, value) {
  71. strData = '$strData${i == 0 ? '' : '&'}$key=${Uri.encodeComponent(value)}';
  72. i++;
  73. });
  74. // print(strData);
  75. final response = await _dio.post('/oauth/token?$strData',
  76. options: Options(
  77. headers: {
  78. 'Accept': 'application/json',
  79. 'Authorization': 'Basic ${base64Encode(
  80. utf8.encode('$clientId:$clientSecret'),
  81. )}'
  82. },
  83. ));
  84. return Token.fromJson(response.data);
  85. } on DioException catch (error) {
  86. // print(error.response);
  87. if (error.response == null) {
  88. try {
  89. final result = await InternetAddress.lookup('google.com');
  90. if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
  91. return Token.withError('errorConnection'.tr());
  92. }
  93. } on SocketException catch (_) {
  94. return Token.withError('noInternet'.tr());
  95. }
  96. } else if (error.response?.statusCode == 400) {
  97. if (error.response?.data['error_description'] == 'User account has expired') return Token.withError('expAccount'.tr());
  98. return Token.withError('invalidLogin'.tr());
  99. } else if (error.response?.statusCode == 401) {
  100. if (error.response?.data['error_description'] ==
  101. 'Invalid phone number') {
  102. return Token.withError('invalidPhone'.tr());
  103. }
  104. return Token.withError('expAccount'.tr());
  105. } else if (error.response!.statusCode! >= 500) {
  106. return Token.withError('errorConnection'.tr());
  107. } else {
  108. return Token.withError('errorServer'.tr());
  109. }
  110. return Token.withError('$error');
  111. }
  112. }
  113. Future<Token> refreshAuth(RefreshTokenBody refreshTokenBody) async {
  114. try {
  115. // print(refreshTokenBody.toJson());
  116. var refreshData = refreshTokenBody.toJson();
  117. var strData = "";
  118. var i = 0;
  119. refreshData.forEach((key, value) {
  120. strData = '$strData${i == 0 ? '' : '&'}$key=${Uri.encodeComponent(value)}';
  121. i++;
  122. });
  123. // print(strData);
  124. final response = await _dio.post(
  125. '/oauth/token?$strData',
  126. options: Options(
  127. headers: {
  128. 'Accept': 'application/json',
  129. 'Authorization': 'Basic ${base64Encode(
  130. utf8.encode('$clientId:$clientSecret'),
  131. )}',
  132. },
  133. ),
  134. );
  135. return Token.fromJson(response.data);
  136. } on DioException catch (error) {
  137. // print(error.response.statusCode);
  138. return Token.withError('$error');
  139. } catch(error){
  140. return Token.withError('$error');
  141. }
  142. }
  143. Future<dynamic> getJsonData(String path, var params, context,
  144. {bool secondCheck = false}) async {
  145. try {
  146. Response<String> response = await _dio.getUri(
  147. Uri(path: path, queryParameters: params),
  148. options: Options(
  149. headers: {
  150. 'Accept': 'application/json',
  151. 'requirestoken': true,
  152. },
  153. ),
  154. );
  155. return json.decode(response.data!);
  156. } on DioException catch (error) {
  157. debugPrint(error.response.toString());
  158. if (error.response == null) {
  159. try {
  160. final result = await InternetAddress.lookup('google.com');
  161. if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
  162. handlingError(context, 1); //error server
  163. }
  164. } on SocketException catch (_) {
  165. // handlingError(context, ApiError.NO_INTERNET); //no internet
  166. }
  167. } else if (error.response!.statusCode! >= 500) {
  168. if (secondCheck) {
  169. // print('secondCheck');
  170. handlingError(context, 2); //error connection
  171. } else {
  172. await Future.delayed(Duration(milliseconds: 200));
  173. return getData(path, params, secondCheck: true);
  174. }
  175. //error server
  176. } else if (error.response?.statusCode == 401) {
  177. handlingError(context, 3); //error auth
  178. } else {
  179. if (secondCheck) {
  180. // print('secondCheck');
  181. handlingError(context, 2); //error connection
  182. } else {
  183. await Future.delayed(Duration(milliseconds: 200));
  184. return getData(path, params, secondCheck: true);
  185. }
  186. }
  187. return Future.error(error);
  188. } catch (error) {
  189. debugPrint(error.toString());
  190. handlingError(context, 1);
  191. return Future.error(error);
  192. }
  193. }
  194. Future getData(String path, var params, {bool secondCheck = false}) async {
  195. try {
  196. Response<String> response = await _dio.getUri(
  197. Uri(path: path, queryParameters: params),
  198. options: Options(
  199. headers: {
  200. 'requirestoken': true,
  201. },
  202. ),
  203. );
  204. return json.decode(response.data!);
  205. } on DioException catch (error) {
  206. debugPrint("Error DIO: ${error.toString()}");
  207. bool isOpen = UIService.isCurrentRouteInactive;
  208. if (error.response == null) {
  209. try {
  210. final result = await InternetAddress.lookup('google.com');
  211. if (!isOpen && result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
  212. UIService.handlingError(ErrorType.noInternet); //error server
  213. }
  214. } on SocketException catch (_) {
  215. }
  216. } else if (!isOpen && error.response!.statusCode! >= 500) {
  217. UIService.handlingError(ErrorType.serverError); //error server
  218. } else if (!isOpen && error.response?.statusCode == 401) {
  219. UIService.handlingError(ErrorType.invalidAccount); //error auth
  220. } else {
  221. if(!isOpen){
  222. if (secondCheck) {
  223. UIService.handlingError(ErrorType.connectionError); //error connection
  224. } else {
  225. return getData(path, params, secondCheck: true);
  226. }
  227. }
  228. }
  229. return null;
  230. }
  231. }
  232. Future postData(String path, var params, var data) async {
  233. try {
  234. Response response = await _dio.postUri(
  235. Uri(path: path, queryParameters: params),
  236. data: data,
  237. options: Options(
  238. headers: {
  239. 'Accept': 'application/json',
  240. 'requirestoken': true,
  241. },
  242. ),
  243. );
  244. return response.data;
  245. } on DioException catch (error) {
  246. debugPrint('Error post: ${error.toString()}');
  247. if (error.response == null) {
  248. try {
  249. final result = await InternetAddress.lookup('google.com');
  250. if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
  251. UIService.showError('errorConnection'.tr());
  252. // showError(context, 'errorConnection'.tr());
  253. }
  254. } on SocketException catch (_) {
  255. UIService.showError('noInternet'.tr());
  256. // showError(context, 'noInternet'.tr());
  257. }
  258. } else if (error.response!.statusCode! >= 500) {
  259. UIService.showError('errorConnection'.tr());
  260. // showError(context, 'errorConnection'.tr());
  261. } else if (error.response?.statusCode == 401) {
  262. UIService.handlingError(ErrorType.invalidAccount);
  263. // handlingError(context, 3); //error auth
  264. } else if (error.response?.statusCode == 422) {
  265. if(error.response?.data['message'] == 'Worktime did not found'){
  266. UIService.showError('notFoundWorktime'.tr());
  267. // showError(context, 'notFoundWorktime'.tr());
  268. } else if(error.response?.data['message'] == 'Cant send broadcast message, you have not permission.'){
  269. UIService.showError('broadcastPermission'.tr());
  270. // showError(context, 'broadcastPermission'.tr());
  271. } else if(error.response?.data['message'] == 'Cant send broadcast message, you have not permission.'){
  272. UIService.showError('broadcastPermission'.tr());
  273. // showError(context, 'broadcastPermission'.tr());
  274. } else if(error.response?.data['message'] == 'request did not match informant rights'){
  275. UIService.showError('idNotMatch'.tr().replaceAll("#ID", data['user_id']));
  276. // showError(context, 'idNotMatch'.tr().replaceAll("#ID", data['user_id']));
  277. } else if(error.response?.data['message'] == 'Informant user id not found.' ||
  278. error.response?.data['message'] == 'invalid user informant requested'
  279. ){
  280. UIService.showError('idNotFound'.tr());
  281. // showError(context, 'idNotFound'.tr());
  282. } else if(error.response?.data['message'] == 'You are not registered as receptionist or room attendant.'){
  283. UIService.showError('informantNotRegistered'.tr());
  284. // showError(context, 'informantNotRegistered'.tr());
  285. } else if(error.response?.data['message'] == 'invalid parent ticket'){
  286. UIService.showError('invalidParentTicket'.tr());
  287. // showError(context, 'invalidParentTicket'.tr());
  288. } else {
  289. UIService.showError(error.response?.data['message']);
  290. // showError(context, error.response?.data['message']);
  291. }
  292. } else {
  293. UIService.showError('errorServer'.tr());
  294. // showError(context, 'errorServer'.tr());
  295. }
  296. return null;
  297. }
  298. }
  299. Future postDataNoAuth(String path) async {
  300. try {
  301. // print(path);
  302. Response response = await _dio.postUri(Uri(path: path));
  303. return response.data;
  304. } on DioException catch (error) {
  305. debugPrint(error.response.toString());
  306. return null;
  307. }
  308. }
  309. Future patchData(String path, var data, {var params}) async {
  310. try {
  311. Response response = await _dio.patchUri(
  312. Uri(path: path, queryParameters: params),
  313. data: data,
  314. options: Options(
  315. headers: {
  316. 'Accept': 'application/json',
  317. 'requirestoken': true,
  318. },
  319. ),
  320. );
  321. return response.data;
  322. } on DioException catch (error) {
  323. if (error.response == null) {
  324. try {
  325. final result = await InternetAddress.lookup('google.com');
  326. if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
  327. UIService.showError('errorConnection'.tr());
  328. }
  329. } on SocketException catch (_) {
  330. UIService.showError('noInternet'.tr());
  331. }
  332. } else if (error.response!.statusCode! >= 500) {
  333. UIService.showError('errorConnection'.tr());
  334. } else if (error.response?.statusCode == 401) {
  335. UIService.handlingError(ErrorType.invalidAccount); //error auth
  336. } else if (error.response?.statusCode == 422) {
  337. if (error.response?.data['message'] == 'Old Password Not Match.') {
  338. UIService.showError('wrongOldPass'.tr());
  339. } else if (error.response?.data['message'] == 'New password already in used.') {
  340. UIService.showError('alreadyUsePass'.tr());
  341. } else {
  342. UIService.showError(error.response?.data['message']);
  343. }
  344. } else {
  345. UIService.showError('errorServer'.tr());
  346. }
  347. return null;
  348. }
  349. }
  350. Future<dynamic> getJsonDataNoAuth(String path, {int n = 0}) async {
  351. // print('sini');
  352. var thisUrl = U.decodeBase64Url(U.getBaseUrl()!) + U.decodeBase64Url(Uri.decodeComponent(U.getAccessCode()!));
  353. // print("url : ${thisUrl + path}");
  354. try{
  355. var response = await http.get(Uri.parse(thisUrl + path)).timeout(Duration(seconds: 5));
  356. // print("data: ${response.body}");
  357. if(response.statusCode == 200){
  358. return Future.value(json.decode(response.body));
  359. }
  360. else{
  361. return Future.error(json.decode(response.body));
  362. }
  363. } on TimeoutException catch (error) {
  364. // print("err timeout men");
  365. // Fluttertoast.showToast(msg: 'invalid_bridge'.tr());
  366. return Future.error(error);
  367. } catch (error) {
  368. // print("err catch: $error");
  369. if (n < 3) {
  370. return getJsonDataNoAuth(path, n: n+1);
  371. } else {
  372. return Future.error(error);
  373. }
  374. }
  375. // try {
  376. // Response<String> response = await _dio.getUri(Uri(path: path));
  377. // return json.decode(response.data!);
  378. // } catch (error) {
  379. // if (n < 3) {
  380. // print("retry $n");
  381. // return getJsonDataNoAuth(path, n: n+1);
  382. // } else {
  383. // print("return error: after $n trial");
  384. // if (path.contains("/api/license")) {
  385. // U.clearAccessCode();
  386. // }
  387. // return Future.error(error);
  388. // }
  389. // }
  390. }
  391. Future getDataNoAuth(String path, {int n = 0}) async {
  392. try {
  393. Response<String> response = await _dio.getUri(Uri(path: path));
  394. return json.decode(response.data!);
  395. } catch (error) {
  396. // print('trien $n times!');
  397. if (n < 3) {
  398. getDataNoAuth(path, n: n+1);
  399. } else {
  400. // print("error after trial $n times: ${error.response}");
  401. return isDebug ? Future.error(error) : null;
  402. }
  403. }
  404. }
  405. Future downloadImage(String path, String savePath) async {
  406. try {
  407. var response = _dio.download(path, savePath);
  408. return response;
  409. } catch (e) {
  410. return e;
  411. }
  412. }
  413. String getServiceAsset(String key){
  414. return '${_dio.options.baseUrl}/assets/lotties/$key';
  415. }
  416. }