multi auth added, token verification added, multi time added on ppm.

main_design2.0
Sikander Saleem 1 year ago
parent e212cf75b1
commit b508e839c5

@ -31,6 +31,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:showWhenLocked="true"
android:turnScreenOn="true"
android:enableOnBackInvokedCallback="true"
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"

@ -1,6 +1,7 @@
package com.example.test_sa;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.android.FlutterFragmentActivity;
public class MainActivity extends FlutterActivity {
public class MainActivity extends FlutterFragmentActivity {
}

File diff suppressed because one or more lines are too long

@ -16,7 +16,7 @@ class URLs {
// API Routes
static get login => "$_baseUrl/MobileAuth/Login"; // web login
static get checkLoginValidation => "$_baseUrl/Account/Authenticate "; // web login
static get checkLoginValidation => "$_baseUrl/Account/Authenticate"; // web login
// static get login => "$_baseUrl/MobileAuth/LoginIntegration"; // mobile login
static get register => "$_baseUrl/handle/create/user"; // post
static get updateProfile => "$_baseUrl/update/user/profile"; // post

@ -4,6 +4,7 @@ class ASettings {
static final String host = "host";
static final String language = "language";
static final String theme = "theme";
static final String localAuth = "local_auth";
static final String speechToText = "speech_to_text";
static final String rememberMe = "remember_me";
static final String userName = "username";

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:local_auth/local_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
@ -94,10 +95,21 @@ class SettingProvider extends ChangeNotifier {
notifyListeners();
}
bool isLocalAuthEnable = false;
Future<void> setAuth(bool status) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
isLocalAuthEnable = status;
prefs.setBool(ASettings.localAuth, isLocalAuthEnable);
notifyListeners();
}
String _theme;
String get theme => _theme;
bool get localAuth => isLocalAuthEnable;
Future<void> setDarkTheme(bool value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
_theme = value ? "dark" : "light";
@ -139,6 +151,12 @@ class SettingProvider extends ChangeNotifier {
_theme = 'light';
}
if (prefs.containsKey(ASettings.localAuth)) {
isLocalAuthEnable = prefs.getBool(ASettings.localAuth);
} else {
isLocalAuthEnable = false;
}
if (prefs.containsKey(ASettings.speechToText)) {
_speechToText = prefs.getString(ASettings.speechToText);
} else {
@ -169,4 +187,20 @@ class SettingProvider extends ChangeNotifier {
isLoaded = true;
notifyListeners();
}
Future<bool> checkUserTokenValidation(String token) async {
Response response;
bool isValid = false;
try {
Map<String, dynamic> body = {};
response = await ApiManager.instance.post(URLs.checkLoginValidation + "?token=$token", body: body);
if (response.statusCode >= 200 && response.statusCode < 300) {
isValid = true;
}
return isValid;
} catch (error) {
return isValid;
}
}
}

@ -1,10 +1,18 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/app_settings.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/pages/land_page/calendar_page.dart';
import 'package:test_sa/new_views/pages/land_page/my_request/my_requests_page.dart';
import 'package:test_sa/new_views/pages/settings_page.dart';
import 'package:test_sa/views/widgets/equipment/single_device_picker.dart';
import '../../../controllers/providers/settings/setting_provider.dart';
@ -36,6 +44,55 @@ class _LandPageState extends State<LandPage> {
super.initState();
}
void checkLocalAuth() async {
if (await Provider.of<SettingProvider>(context, listen: false).auth.isDeviceSupported()) {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (!prefs.containsKey(ASettings.localAuth)) {
showModalBottomSheet(
context: context,
useSafeArea: true,
backgroundColor: Colors.transparent,
builder: (context) => Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: const BorderRadius.only(topRight: Radius.circular(20), topLeft: Radius.circular(20)),
),
padding: EdgeInsets.symmetric(horizontal: 24.toScreenWidth, vertical: 24.toScreenHeight),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40.toScreenWidth,
height: 5.toScreenHeight,
decoration: BoxDecoration(color: AppColor.neutral40, borderRadius: BorderRadius.circular(30)),
),
16.height,
Align(
alignment: AlignmentDirectional.centerStart,
child: "Fingerprint/Face ID".addTranslation.heading3(context).custom(fontWeight: FontWeight.w600),
),
16.height,
"fingerprint".toLottieAsset(height: 180),
16.height,
Align(
alignment: AlignmentDirectional.centerStart,
child: "Let's set up Face ID/Fingerprint for quick and secure logins in the future".bodyText(context).custom(fontWeight: FontWeight.w500),
),
24.height,
AppFilledButton(
onPressed: () {
Navigator.pop(context);
Navigator.of(context).pushNamed(SettingsPage.id);
},
label: "Enable".addTranslation),
],
)),
);
}
}
}
@override
Widget build(BuildContext context) {
if (_userProvider == null) {
@ -49,6 +106,7 @@ class _LandPageState extends State<LandPage> {
const MyAssetsPage(fromBottomBar: true),
if (_userProvider.user.type == UsersTypes.engineer) const CalendarPage(),
];
checkLocalAuth();
}
return WillPopScope(

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
import 'package:local_auth/local_auth.dart';
@ -24,16 +26,44 @@ class _SettingsPageState extends State<SettingsPage> {
ValueNotifier<bool> langController, themeController;
SettingProvider _settingProvider;
bool localAuth = false;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
void dispose() {
super.dispose();
langController.dispose();
themeController.dispose();
// authController.dispose();
}
void checkForLocalAuth(bool buttonState) async {
bool authStatus = await _settingProvider.auth.authenticate(
localizedReason: Platform.isAndroid ? "Scan your fingerprint to authenticate" : "",
options: AuthenticationOptions(biometricOnly: Platform.isAndroid),
);
if (authStatus) {
localAuth = !localAuth;
await _settingProvider.setAuth(localAuth);
// authController.value = _settingProvider.localAuth == buttonState.toString();
setState(() {});
} else {
// authController.value = !buttonState;
}
}
@override
Widget build(BuildContext context) {
_settingProvider ??= Provider.of<SettingProvider>(context, listen: false);
if (_settingProvider == null) {
_settingProvider = Provider.of<SettingProvider>(context, listen: false);
localAuth = _settingProvider.localAuth;
}
langController ??= ValueNotifier<bool>(_settingProvider.language == "ar")
..addListener(() async {
/// TODO : uncomment the below lines to support the another language
@ -45,17 +75,18 @@ class _SettingsPageState extends State<SettingsPage> {
await _settingProvider.setDarkTheme(_settingProvider.theme == "light");
themeController.value = _settingProvider.theme == "light";
});
// authController ??= ValueNotifier<bool>(_settingProvider.localAuth == "false")
// ..addListener(() async {
// print("authController.value:${authController.value}");
//
// _settingProvider.auth.getAvailableBiometrics().then((value) {
// value.forEach((element) => print(element.name));
// print("face:${value.contains(BiometricType.face)}");
// print("bio:${value.contains(BiometricType.fingerprint)}");
// print("iris:${value.contains(BiometricType.iris)}");
// print("weak:${value.contains(BiometricType.weak)}");
// print("strong:${value.contains(BiometricType.strong)}");
//
// _settingProvider.auth.canCheckBiometrics.then((value) => print(value));
// });
// // if (authController.value) {
// // checkForLocalAuth();
// // } else {
// // await _settingProvider.setAuth(_settingProvider.localAuth == "false");
// // authController.value = _settingProvider.localAuth == "false";
// // }
// });
return Scaffold(
appBar: DefaultAppBar(title: context.translation.settings),
@ -100,40 +131,50 @@ class _SettingsPageState extends State<SettingsPage> {
),
],
),
// 16.height,
// const Divider().defaultStyle(context),
// 16.height,
// FutureBuilder(
// future: _settingProvider.auth.isDeviceSupported(),
// builder: (cxt, snapshot) {
// bool isDeviceSupported = false;
// if (snapshot.hasData) {
// isDeviceSupported = snapshot.data;
// }
//
// if (!isDeviceSupported) {
// return Text("Your device did not support Fingerprint/Face ID.", style: AppTextStyles.tinyFont.copyWith(fontSize: 11, color: Colors.red));
// }
//
// return Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// context.translation.lightTheme.heading5(context),
// AdvancedSwitch(
// controller: themeController,
// activeColor: AppColor.green50.withOpacity(0.5),
// inactiveColor: AppColor.neutral10,
// thumb: CircleAvatar(backgroundColor: _settingProvider.theme == "light" ? AppColor.green50 : AppColor.neutral20),
// borderRadius: const BorderRadius.all(Radius.circular(30)),
// width: 42.toScreenWidth,
// height: 24.toScreenHeight,
// disabledOpacity: 1,
// ),
// ],
// );
// }),
16.height,
const Divider().defaultStyle(context),
16.height,
FutureBuilder(
future: _settingProvider.auth.isDeviceSupported(),
builder: (cxt, snapshot) {
bool isDeviceSupported = false;
if (snapshot.hasData) {
isDeviceSupported = snapshot.data;
}
if (!isDeviceSupported) {
return Text("Your device did not support Fingerprint/Face ID.", style: AppTextStyles.tinyFont.copyWith(fontSize: 11, color: Colors.red));
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"Fingerprint/Face ID".heading5(context),
customSwitch(localAuth).onPress(() {
checkForLocalAuth(localAuth);
}),
],
);
}),
],
).toShadowContainer(context).paddingAll(16),
);
}
Widget customSwitch(bool enable) {
return Container(
width: 42.toScreenWidth,
height: 24.toScreenHeight,
alignment: enable ? Alignment.centerRight : Alignment.centerLeft,
decoration: BoxDecoration(
color: enable ? AppColor.green50.withOpacity(0.5) : AppColor.neutral10,
borderRadius: const BorderRadius.all(Radius.circular(30)),
),
padding: const EdgeInsets.all(2),
child: Container(
height: 20.toScreenHeight,
width: 20.toScreenWidth,
decoration: BoxDecoration(shape: BoxShape.circle, color: enable ? AppColor.green50 : AppColor.neutral20),
));
}
}

@ -1,16 +1,15 @@
import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/notification/notification_manger.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/service_request/service_request.dart';
import 'package:test_sa/new_views/pages/land_page/land_page.dart';
import 'package:test_sa/new_views/pages/login_page.dart';
import 'package:test_sa/views/pages/user/requests/service_request_details.dart';
import '../../models/size_config.dart';
@ -27,7 +26,7 @@ class _SplashPageState extends State<SplashPage> {
SettingProvider _settingProvider;
UserProvider _userProvider;
bool isnotificationCame=false;
bool loading = false;
@override
void initState() {
@ -50,34 +49,84 @@ class _SplashPageState extends State<SplashPage> {
super.initState();
}
void checkTokenValidity(String token) async {
setState(() {
loading = true;
});
bool isValid = await _settingProvider.checkUserTokenValidation(token);
setState(() {
loading = false;
});
if (isValid && _settingProvider.isLocalAuthEnable) {
bool isSuccess = await checkDualAuthentication();
if (isSuccess) {
_userProvider.user = _settingProvider.user;
Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
}
} else {
Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
}
}
Future<bool> checkDualAuthentication() async {
return await _settingProvider.auth.authenticate(
localizedReason: Platform.isAndroid ? "Scan your fingerprint to authenticate" : "",
options: AuthenticationOptions(biometricOnly: Platform.isAndroid),
);
}
@override
Widget build(BuildContext context) {
SizeConfig.init(context);
_settingProvider = Provider.of<SettingProvider>(context, listen: false);
_userProvider = Provider.of<UserProvider>(context, listen: false);
return Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width / 1.1,
child: FlareActor(
"assets/rives/atoms_splash.flr",
fit: BoxFit.contain,
animation: "splash",
callback: (animation) async {
Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
if (_settingProvider.isLoaded && (_settingProvider.user?.isLiveToken ?? false)) {
_userProvider.user = _settingProvider.user;
Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
// if(isnotificationCame)
// Navigator.of(context).push(MaterialPageRoute(
// builder: (_) => ServiceRequestDetailsPage(
// serviceRequest: ServiceRequest(id: "72348"),
// )));
/// The below line for the new design
// Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
}
},
),
).center,
body: Stack(
alignment: Alignment.center,
children: [
if (loading)
const Positioned(
bottom: 100,
child: SizedBox(
width: 36,
height: 36,
child: CircularProgressIndicator(
color: Color(0xff4A8DB7),
strokeWidth: 3,
),
)),
SizedBox(
width: MediaQuery.of(context).size.width / 1.1,
child: FlareActor(
"assets/rives/atoms_splash.flr",
fit: BoxFit.contain,
animation: "splash",
callback: (animation) async {
if (_settingProvider.isLoaded && (_settingProvider.user != null)) {
checkTokenValidity(_settingProvider.user.token);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
}
// if (_settingProvider.isLoaded && (_settingProvider.user?.isLiveToken ?? false)) {
// _userProvider.user = _settingProvider.user;
// Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
// // if(isnotificationCame)
// // Navigator.of(context).push(MaterialPageRoute(
// // builder: (_) => ServiceRequestDetailsPage(
// // serviceRequest: ServiceRequest(id: "72348"),
// // )));
// /// The below line for the new design
// // Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
// }
},
),
).center,
],
),
);
}
}

Loading…
Cancel
Save