auto_login.dart 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import 'dart:convert';
  2. import 'package:auto_route/auto_route.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  5. import 'package:telnow_mobile_new/src/api/jwt_token.dart';
  6. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  7. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  8. import 'package:telnow_mobile_new/src/injector/injector.dart';
  9. import 'package:telnow_mobile_new/src/model/login/login_body.dart';
  10. import 'package:telnow_mobile_new/src/api/api_auth_repository.dart';
  11. import 'package:telnow_mobile_new/src/model/token/token.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:easy_localization/easy_localization.dart';
  14. import 'package:telnow_mobile_new/src/utils/U.dart';
  15. @RoutePage()
  16. class AutoLoginPage extends StatefulWidget {
  17. @override
  18. State<AutoLoginPage> createState() => _AutoLoginPageState();
  19. }
  20. class _AutoLoginPageState extends State<AutoLoginPage> {
  21. final ApiAuthProvider apiAuthProvider = ApiAuthProvider();
  22. final ApiAuthRepository apiAuthRepository = ApiAuthRepository();
  23. final SharedPreferencesManager sharedPreferencesManager = locator<SharedPreferencesManager>();
  24. Map<String, dynamic>? tokenData;
  25. String companyName = '';
  26. String guestName = '';
  27. bool loading = false;
  28. bool invalidUserLogin = false;
  29. bool onProgress = false;
  30. bool redirectToLoginPage = false;
  31. String progressMsg = 'initializing'.tr();
  32. String newPassword = '';
  33. String cfrmPassword = '';
  34. Map <String, String> Ddata = {};
  35. @override
  36. void initState() {
  37. WidgetsBinding.instance.addPostFrameCallback((_) {
  38. getQueryParam();
  39. getCompanyName();
  40. });
  41. // TODO: implement initState
  42. super.initState();
  43. }
  44. getQueryParam() async {
  45. String url = kIsWeb ? Uri.base.toString() : U.getUrl();
  46. Uri uri = Uri.dataFromString(url);
  47. String prmJson = '';
  48. try {
  49. uri.queryParameters.forEach((k,v) {
  50. switch (k) {
  51. case 'prm':prmJson = U.decodeBase64Url(Uri.decodeComponent(v));
  52. }
  53. });
  54. Ddata = {
  55. "username": jsonDecode(prmJson)["username"],
  56. "password": jsonDecode(prmJson)["password"]
  57. };
  58. U.clearUrl();
  59. getTokenData();
  60. } catch(e) {
  61. U.showDebugToast(e.toString());
  62. print("invalid param: " + e.toString());
  63. redirectToLoginPage = true;
  64. Future.delayed(Duration.zero, (){
  65. context.router.removeLast();
  66. context.navigateNamedTo("/app/${U.getAccessCode()}");
  67. });
  68. }
  69. }
  70. getTokenData({int n = 0}) async {
  71. JwtToken jwtToken = JwtToken();
  72. // if (n > 2){
  73. //
  74. // }
  75. showLoading(context);
  76. try {
  77. Token token = await apiAuthRepository.postLoginUser(LoginBody(Ddata["username"]!.trim(), Ddata["password"]!.trim(), "password"));
  78. if (token.error != null) {
  79. closeLoading(context);
  80. showError(context, token.error);
  81. setState(() {
  82. loading = false;
  83. invalidUserLogin = true;
  84. });
  85. return;
  86. }
  87. // var pid = U.getPidFromUrl(context.router.currentUrl);
  88. await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!);
  89. await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!);
  90. String accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!;
  91. var jwt = jwtToken.parseJwtPayLoad(accessToken);
  92. // print(jwt);
  93. var user = await apiAuthProvider.getData('/api/informants/'+jwt['userId'].toString(), null, context);
  94. if(user != null){
  95. closeLoading(context);
  96. setState((){
  97. tokenData = jwt;
  98. context.setLocale(Locale(tokenData!['language'].toLowerCase()));
  99. guestName = user['guestName'];
  100. });
  101. }
  102. } catch(e){
  103. closeLoading(context);
  104. print(e.toString());
  105. U.showDebugToast(e.toString());
  106. getTokenData(n: n + 1);
  107. }
  108. }
  109. getCompanyName() async {
  110. var lics = await U.getLicense();
  111. if (lics != null && lics['companyName'] != null && mounted) {
  112. setState(() {
  113. companyName = lics['companyName'];
  114. });
  115. }
  116. }
  117. backToQr() async {
  118. try {
  119. // U.clearAccessCode();
  120. U.clearPreferences().then((value) {
  121. context.router.removeLast();
  122. context.navigateNamedTo('/qr?new=true');
  123. });
  124. } catch(e) {
  125. print(e.toString());
  126. U.showDebugToast(e.toString());
  127. }
  128. }
  129. @override
  130. Widget build(BuildContext context) {
  131. return WillPopScope(
  132. onWillPop: (){
  133. return Future.value(true);
  134. },
  135. child: Scaffold(
  136. resizeToAvoidBottomInset: false,
  137. body: redirectToLoginPage ? Container() : Stack(
  138. children: [
  139. Container(
  140. decoration: BoxDecoration(
  141. image: DecorationImage(
  142. image: AssetImage("assets/image/background/background.jpg"),
  143. fit: BoxFit.cover,
  144. )
  145. ),
  146. ),
  147. Container(
  148. width: MediaQuery.of(context).size.width,
  149. height: MediaQuery.of(context).size.height,
  150. decoration: BoxDecoration(
  151. gradient: LinearGradient(
  152. begin: Alignment.topCenter, end: Alignment.bottomCenter,
  153. colors: [
  154. primaryColor.withValues(alpha: 0.50), Colors.black.withValues(alpha: 0.91)
  155. ]
  156. )
  157. ),
  158. child: SingleChildScrollView(
  159. padding: EdgeInsets.fromLTRB(16, 50, 16, 16),
  160. child: Column(
  161. crossAxisAlignment: CrossAxisAlignment.center,
  162. children: [
  163. Container(
  164. margin: EdgeInsets.only(bottom: 100),
  165. child: Row(
  166. children: [
  167. GestureDetector(
  168. child: U.iconsax('arrow-left', color: Colors.white),
  169. onTap: (){
  170. context.router.removeLast();
  171. context.navigateNamedTo('/qr?new=true');
  172. },
  173. ),
  174. SizedBox(width: 15),
  175. Expanded(
  176. child: GestureDetector(
  177. child: Column(
  178. crossAxisAlignment: CrossAxisAlignment.start,
  179. children: [
  180. Text('buttonBack'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  181. Text('buttonScan'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)),
  182. ],
  183. ),
  184. onTap: () => backToQr(),
  185. ),
  186. ),
  187. Image.asset('assets/image/logo/logo.png', width: 120)
  188. ],
  189. )
  190. ),
  191. !invalidUserLogin ? Column(
  192. children: [
  193. Text('welcome'.tr()+' $guestName', style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center),
  194. SizedBox(height: 16),
  195. Text('createNewPassText'.tr(), style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center),
  196. ],
  197. ) : Container(),
  198. !invalidUserLogin ? Column(
  199. children: [
  200. SizedBox(height: 80),
  201. loginFieldTemplate(placeholder: 'newPassword'.tr(), value: newPassword, action: (val)=>newPassword = val, isPassword: true, submit: (val)=>loginAction()),
  202. SizedBox(height: 12),
  203. loginFieldTemplate(placeholder: 'confirmPassword'.tr(), value: cfrmPassword, action: (val)=>cfrmPassword = val, isPassword: true, submit: (val)=>loginAction()),
  204. GestureDetector(
  205. child: Container(
  206. width: double.infinity,
  207. margin: EdgeInsets.only(top: 40, bottom: 60),
  208. padding: EdgeInsets.symmetric(vertical: 16),
  209. decoration: BoxDecoration(
  210. color: primaryColor.withValues(alpha: 0.50),
  211. border: Border.all(color: Colors.white),
  212. borderRadius: BorderRadius.all(Radius.circular(12))
  213. ),
  214. child: !loading ? Text('buttonLogin'.tr(), style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center) : Center(
  215. child: Row(
  216. mainAxisAlignment: MainAxisAlignment.center,
  217. children: [
  218. SizedBox(
  219. width: 22, height: 22, child: CircularProgressIndicator(color: Colors.white),
  220. ),
  221. SizedBox(width: 10,),
  222. onProgress ? Text(progressMsg, style: TextStyle(color: Colors.white, fontSize: 15), textAlign: TextAlign.center) : Container()
  223. ],
  224. ),
  225. ),
  226. ),
  227. onTap: () => loginAction(),
  228. ),
  229. ],
  230. ) : Column(
  231. children: [
  232. Text("Sorry, user login is not valid.", style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center),
  233. Text("Please try again with another QR code.", style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center)
  234. ],
  235. ),
  236. Text(companyName, style: TextStyle(fontSize: 16, color: Colors.white), textAlign: TextAlign.center),
  237. Container(
  238. margin: const EdgeInsets.only(top: 118),
  239. alignment: Alignment.bottomCenter,
  240. child: Text('${'version'.tr()} ${ApiAuthProvider().displayVersion}', style: TextStyle(color: Colors.white, fontSize: 14))
  241. ),
  242. ],
  243. ),
  244. ),
  245. ),
  246. ],
  247. ),
  248. ),
  249. );
  250. }
  251. loginAction() async{
  252. if(!loading && tokenData != null){
  253. if(newPassword.isNotEmpty && cfrmPassword.isNotEmpty){
  254. if(newPassword.trim() == cfrmPassword.trim()){
  255. setState(() {
  256. loading = true;
  257. onProgress = true;
  258. });
  259. var data = {'oldPassword': Ddata['password'], 'password': newPassword.trim()};
  260. try {
  261. var res = await apiAuthProvider.patchData('/api/informants/${tokenData!['userId']}/changePassword', data, context);
  262. if (res != null) {
  263. // setState(() => progressMsg = "Initializing...");
  264. String password = tokenData!['related'] && tokenData!['tenantCode'] != null && tokenData!['tenantCode'] != '' ? tokenData!['tenantCode'] + ' ' + data['password'] : data['password'];
  265. LoginBody loginBody = LoginBody(Ddata['username']!, password, 'password');
  266. Token token = await apiAuthRepository.postLoginUser(loginBody);
  267. if (token.error != null) {
  268. setState(() => loading = false);
  269. showError(context, token.error);
  270. } else {
  271. setState(() => progressMsg = "redirecting".tr());
  272. await U.setChangedPassword(true);
  273. var parsedToken = U.token.parseJwtPayLoad(token.accessToken!);
  274. await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!);
  275. await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!);
  276. await sharedPreferencesManager.putString(SharedPreferencesManager.keyUsername, tokenData!['related'] ? parsedToken['user_name'].split("-").last : Ddata['username']);
  277. await sharedPreferencesManager.putBool(SharedPreferencesManager.keyIsLogin, true);
  278. await sharedPreferencesManager.putString(SharedPreferencesManager.keyScoope, 'INSIDE');
  279. await sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
  280. U.setHidePayload(true);
  281. var pid = U.getAccessCode();
  282. context.router.removeLast();
  283. context.navigateNamedTo("/app/$pid/menu");
  284. }
  285. }
  286. else{
  287. setState(() => loading = false);
  288. }
  289. } catch(e) {
  290. print(e.toString());
  291. setState(() => loading = false);
  292. }
  293. }
  294. else{
  295. showError(context, 'checkNewPass'.tr());
  296. }
  297. }
  298. else{
  299. showError(context, 'cannotEmpty'.tr());
  300. }
  301. }
  302. }
  303. }