import 'dart:convert'; import 'package:auto_route/auto_route.dart'; import 'package:flutter/foundation.dart'; import 'package:telnow_mobile_new/src/api/api_auth_provider.dart'; import 'package:telnow_mobile_new/src/api/jwt_token.dart'; import 'package:telnow_mobile_new/src/layouts/components/template.dart'; import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart'; import 'package:telnow_mobile_new/src/injector/injector.dart'; import 'package:telnow_mobile_new/src/model/login/login_body.dart'; import 'package:telnow_mobile_new/src/api/api_auth_repository.dart'; import 'package:telnow_mobile_new/src/model/token/token.dart'; import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:telnow_mobile_new/src/utils/U.dart'; @RoutePage() class AutoLoginPage extends StatefulWidget { @override State createState() => _AutoLoginPageState(); } class _AutoLoginPageState extends State { final ApiAuthProvider apiAuthProvider = ApiAuthProvider(); final ApiAuthRepository apiAuthRepository = ApiAuthRepository(); final SharedPreferencesManager sharedPreferencesManager = locator(); Map? tokenData; String companyName = ''; String guestName = ''; bool loading = false; bool invalidUserLogin = false; bool onProgress = false; bool redirectToLoginPage = false; String progressMsg = 'initializing'.tr(); String newPassword = ''; String cfrmPassword = ''; Map Ddata = {}; @override void initState() { WidgetsBinding.instance.addPostFrameCallback((_) { getQueryParam(); getCompanyName(); }); // TODO: implement initState super.initState(); } getQueryParam() async { String url = kIsWeb ? Uri.base.toString() : U.getUrl(); Uri uri = Uri.dataFromString(url); String prmJson = ''; try { uri.queryParameters.forEach((k,v) { switch (k) { case 'prm':prmJson = U.decodeBase64Url(Uri.decodeComponent(v)); } }); Ddata = { "username": jsonDecode(prmJson)["username"], "password": jsonDecode(prmJson)["password"] }; U.clearUrl(); getTokenData(); } catch(e) { U.showDebugToast(e.toString()); print("invalid param: " + e.toString()); redirectToLoginPage = true; Future.delayed(Duration.zero, (){ context.router.removeLast(); context.navigateToPath("/app/${U.getAccessCode()}"); }); } } getTokenData({int n = 0}) async { JwtToken jwtToken = JwtToken(); // if (n > 2){ // // } showLoading(context); try { Token token = await apiAuthRepository.postLoginUser(LoginBody(Ddata["username"]!.trim(), Ddata["password"]!.trim(), "password")); if (token.error != null) { closeLoading(context); showError(context, token.error); setState(() { loading = false; invalidUserLogin = true; }); return; } // var pid = U.getPidFromUrl(context.router.currentUrl); await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!); await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!); String accessToken = sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessToken)!; var jwt = jwtToken.parseJwtPayLoad(accessToken); // print(jwt); var user = await apiAuthProvider.getData('/api/informants/'+jwt['userId'].toString(), null, context); if(user != null){ closeLoading(context); setState((){ tokenData = jwt; context.setLocale(Locale(tokenData!['language'].toLowerCase())); guestName = user['guestName']; }); } } catch(e){ closeLoading(context); print(e.toString()); U.showDebugToast(e.toString()); getTokenData(n: n + 1); } } getCompanyName() async { var lics = await U.getLicense(); if (lics != null && lics['companyName'] != null && mounted) { setState(() { companyName = lics['companyName']; }); } } backToQr() async { try { // U.clearAccessCode(); U.clearPreferences().then((value) { context.router.removeLast(); context.navigateToPath('/qr?new=true'); }); } catch(e) { print(e.toString()); U.showDebugToast(e.toString()); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: (){ return Future.value(true); }, child: Scaffold( resizeToAvoidBottomInset: false, body: redirectToLoginPage ? Container() : Stack( children: [ Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage("assets/image/background/background.jpg"), fit: BoxFit.cover, ) ), ), Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ primaryColor.withValues(alpha: 0.50), Colors.black.withValues(alpha: 0.91) ] ) ), child: SingleChildScrollView( padding: EdgeInsets.fromLTRB(16, 50, 16, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( margin: EdgeInsets.only(bottom: 100), child: Row( children: [ GestureDetector( child: U.iconsax('arrow-left', color: Colors.white), onTap: (){ context.router.removeLast(); context.navigateToPath('/qr?new=true'); }, ), SizedBox(width: 15), Expanded( child: GestureDetector( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('buttonBack'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)), Text('buttonScan'.tr(), style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500)), ], ), onTap: () => backToQr(), ), ), Image.asset('assets/image/logo/logo.png', width: 120) ], ) ), !invalidUserLogin ? Column( children: [ Text('welcome'.tr()+' $guestName', style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center), SizedBox(height: 16), Text('createNewPassText'.tr(), style: TextStyle(color: Colors.white, fontSize: 16), textAlign: TextAlign.center), ], ) : Container(), !invalidUserLogin ? Column( children: [ SizedBox(height: 80), loginFieldTemplate(placeholder: 'newPassword'.tr(), value: newPassword, action: (val)=>newPassword = val, isPassword: true, submit: (val)=>loginAction()), SizedBox(height: 12), loginFieldTemplate(placeholder: 'confirmPassword'.tr(), value: cfrmPassword, action: (val)=>cfrmPassword = val, isPassword: true, submit: (val)=>loginAction()), GestureDetector( child: Container( width: double.infinity, margin: EdgeInsets.only(top: 40, bottom: 60), padding: EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( color: primaryColor.withValues(alpha: 0.50), border: Border.all(color: Colors.white), borderRadius: BorderRadius.all(Radius.circular(12)) ), child: !loading ? Text('buttonLogin'.tr(), style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center) : Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox( width: 22, height: 22, child: CircularProgressIndicator(color: Colors.white), ), SizedBox(width: 10,), onProgress ? Text(progressMsg, style: TextStyle(color: Colors.white, fontSize: 15), textAlign: TextAlign.center) : Container() ], ), ), ), onTap: () => loginAction(), ), ], ) : Column( children: [ Text("Sorry, user login is not valid.", style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center), Text("Please try again with another QR code.", style: TextStyle(color: Colors.white, fontSize: 17), textAlign: TextAlign.center) ], ), Text(companyName, style: TextStyle(fontSize: 16, color: Colors.white), textAlign: TextAlign.center), Container( margin: const EdgeInsets.only(top: 118), alignment: Alignment.bottomCenter, child: Text('${'version'.tr()} ${ApiAuthProvider().displayVersion}', style: TextStyle(color: Colors.white, fontSize: 14)) ), ], ), ), ), ], ), ), ); } loginAction() async{ if(!loading && tokenData != null){ if(newPassword.isNotEmpty && cfrmPassword.isNotEmpty){ if(newPassword.trim() == cfrmPassword.trim()){ setState(() { loading = true; onProgress = true; }); var data = {'oldPassword': Ddata['password'], 'password': newPassword.trim()}; try { var res = await apiAuthProvider.patchData('/api/informants/${tokenData!['userId']}/changePassword', data, context); if (res != null) { // setState(() => progressMsg = "Initializing..."); String password = tokenData!['related'] && tokenData!['tenantCode'] != null && tokenData!['tenantCode'] != '' ? tokenData!['tenantCode'] + ' ' + data['password'] : data['password']; LoginBody loginBody = LoginBody(Ddata['username']!, password, 'password'); Token token = await apiAuthRepository.postLoginUser(loginBody); if (token.error != null) { setState(() => loading = false); showError(context, token.error); } else { setState(() => progressMsg = "redirecting".tr()); await U.setChangedPassword(true); var parsedToken = U.token.parseJwtPayLoad(token.accessToken!); await sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken!); await sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken!); await sharedPreferencesManager.putString(SharedPreferencesManager.keyUsername, tokenData!['related'] ? parsedToken['user_name'].split("-").last : Ddata['username']); await sharedPreferencesManager.putBool(SharedPreferencesManager.keyIsLogin, true); await sharedPreferencesManager.putString(SharedPreferencesManager.keyScoope, 'INSIDE'); await sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0); U.setHidePayload(true); var pid = U.getAccessCode(); context.router.removeLast(); context.navigateToPath("/app/$pid/menu"); } } else{ setState(() => loading = false); } } catch(e) { print(e.toString()); setState(() => loading = false); } } else{ showError(context, 'checkNewPass'.tr()); } } else{ showError(context, 'cannotEmpty'.tr()); } } } }