Merge pull request #35 from yaso-meth/Feature-biometrics

Feature-biometrics
This commit is contained in:
yaso-meth
2025-01-14 13:16:28 +02:00
committed by GitHub
25 changed files with 339 additions and 65 deletions

View File

@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

View File

@@ -1,6 +1,6 @@
package za.co.mzansiinnovationhub.mih package za.co.mzansiinnovationhub.mih
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterActivity() { class MainActivity: FlutterFragmentActivity() {
} }

View File

@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSFaceIDUsageDescription</key>
<string>Why is my app authenticating using face id?</string>
<key>LSSupportsOpeningDocumentsInPlace</key> <key>LSSupportsOpeningDocumentsInPlace</key>
<true/> <true/>
<key>UIFileSharingEnabled</key> <key>UIFileSharingEnabled</key>

View File

@@ -67,46 +67,48 @@ class _MIHLayoutBuilderState extends State<MIHLayoutBuilder> {
Widget getBody(double width, double height) { Widget getBody(double width, double height) {
if (widget.pullDownToRefresh == true) { if (widget.pullDownToRefresh == true) {
return LayoutBuilder(builder: (context, BoxConstraints constraints) { return SafeArea(
double newheight = constraints.maxHeight; child: LayoutBuilder(builder: (context, BoxConstraints constraints) {
//print(newheight); double newheight = constraints.maxHeight;
return RefreshIndicator( //print(newheight);
onRefresh: widget.onPullDown, return RefreshIndicator(
child: ListView.builder( onRefresh: widget.onPullDown,
itemCount: 1, child: ListView.builder(
itemBuilder: (BuildContext context, int index) { itemCount: 1,
return SafeArea( itemBuilder: (BuildContext context, int index) {
child: SizedBox( return SafeArea(
width: width, child: SizedBox(
height: newheight, width: width,
child: Column( height: newheight,
mainAxisAlignment: MainAxisAlignment.start, child: Column(
children: [ mainAxisAlignment: MainAxisAlignment.start,
const SizedBox(height: 5), children: [
getLayoutHeader(), const SizedBox(height: 5),
const SizedBox(height: 5), getLayoutHeader(),
Expanded(child: widget.body), const SizedBox(height: 5),
], Expanded(child: widget.body),
],
),
), ),
), );
); },
}, // child: SafeArea(
// child: SafeArea( // child: SizedBox(
// child: SizedBox( // width: width,
// width: width, // height: height,
// height: height, // child: Column(
// child: Column( // mainAxisAlignment: MainAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start, // children: [
// children: [ // getLayoutHeader(),
// getLayoutHeader(), // Expanded(child: widget.body),
// Expanded(child: widget.body), // ],
// ], // ),
// ), // ),
// ), // ),
// ), ),
), );
); }),
}); );
} else { } else {
return SafeArea( return SafeArea(
child: SizedBox( child: SizedBox(

View File

@@ -159,3 +159,13 @@ class ClaimStatementGenerationArguments {
this.sig_path, this.sig_path,
); );
} }
class AuthArguments {
final bool personalSelected;
final bool firstBoot;
AuthArguments(
this.personalSelected,
this.firstBoot,
);
}

View File

@@ -1,3 +1,4 @@
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../mih_components/mih_inputs_and_buttons/mih_button.dart'; import '../../mih_components/mih_inputs_and_buttons/mih_button.dart';
import '../../mih_components/mih_layout/mih_action.dart'; import '../../mih_components/mih_layout/mih_action.dart';
@@ -42,7 +43,7 @@ class _MIHAboutState extends State<MIHAbout> {
onTap: () { onTap: () {
Navigator.of(context).pushNamedAndRemoveUntil( Navigator.of(context).pushNamedAndRemoveUntil(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
(route) => false, (route) => false,
); );
}, },

View File

@@ -1,3 +1,4 @@
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../main.dart'; import '../../main.dart';
import '../../mih_apis/mih_api_calls.dart'; import '../../mih_apis/mih_api_calls.dart';
@@ -105,7 +106,7 @@ class _PatientAccessRequestState extends State<PatientAccessRequest> {
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
); );
}, },
); );

View File

@@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../main.dart'; import '../../main.dart';
import 'package:supertokens_flutter/http.dart' as http; import 'package:supertokens_flutter/http.dart' as http;
@@ -268,7 +269,7 @@ class _PatientAccessRequestState extends State<Appointments> {
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
); );
}, },
); );

View File

@@ -1,15 +1,17 @@
import 'package:Mzansi_Innovation_Hub/mih_packages/authentication/biometric_check.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:supertokens_flutter/supertokens.dart'; import 'package:supertokens_flutter/supertokens.dart';
import 'package:no_screenshot/no_screenshot.dart'; import 'package:no_screenshot/no_screenshot.dart';
import '../mih_home/mih_profile_getter.dart';
import 'signin_or_register.dart'; import 'signin_or_register.dart';
class AuthCheck extends StatefulWidget { class AuthCheck extends StatefulWidget {
final bool personalSelected; final bool personalSelected;
final bool firstBoot;
const AuthCheck({ const AuthCheck({
super.key, super.key,
required this.personalSelected, required this.personalSelected,
required this.firstBoot,
}); });
@override @override
@@ -53,8 +55,9 @@ class _AuthCheckState extends State<AuthCheck> {
builder: (context, snapshot) { builder: (context, snapshot) {
//print(snapshot.data); //print(snapshot.data);
if (snapshot.data == true) { if (snapshot.data == true) {
return MIHProfileGetter( return BiometricCheck(
personalSelected: widget.personalSelected, personalSelected: widget.personalSelected,
firstBoot: widget.firstBoot,
); );
} else if (snapshot.data == false) { } else if (snapshot.data == false) {
return const SignInOrRegister(); return const SignInOrRegister();

View File

@@ -0,0 +1,205 @@
import 'package:Mzansi_Innovation_Hub/main.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_inputs_and_buttons/mih_button.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_action.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/mih_home/mih_profile_getter.dart';
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:supertokens_flutter/supertokens.dart';
class BiometricCheck extends StatefulWidget {
final bool personalSelected;
final bool firstBoot;
const BiometricCheck({
super.key,
required this.personalSelected,
required this.firstBoot,
});
@override
State<BiometricCheck> createState() => _BiometricCheckState();
}
class _BiometricCheckState extends State<BiometricCheck> {
bool _isBioAuthenticated = false;
final LocalAuthentication _auth = LocalAuthentication();
MIHAction getActionButton() {
return MIHAction(
icon: Padding(
padding: const EdgeInsets.all(10.0),
child: SizedBox(
height: 50,
child: Image.asset('images/logo_light.png'),
),
),
iconSize: 35,
onTap: () async {
await SuperTokens.signOut(completionHandler: (error) {
print(error);
});
if (await SuperTokens.doesSessionExist() == false) {
Navigator.of(context).popAndPushNamed('/');
}
// Navigator.of(context).pushNamed(
// '/about',
// //arguments: widget.signedInUser,
// );
},
);
}
MIHHeader getHeader() {
return const MIHHeader(
headerAlignment: MainAxisAlignment.center,
headerItems: [
Text(
"",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25,
),
),
],
);
}
void authenticateUser() async {
final bool canAuthWithBio = await _auth.canCheckBiometrics;
print("Biomentric Available: $canAuthWithBio");
if (canAuthWithBio) {
try {
final bool didBioAuth = await _auth.authenticate(
localizedReason: "Authenticate to access MIH",
options: const AuthenticationOptions(
biometricOnly: false,
),
);
if (didBioAuth) {
setState(() {
_isBioAuthenticated = true;
});
}
print("Authenticated: $didBioAuth");
} catch (error) {
print(error);
}
}
}
MIHBody getBody() {
return MIHBody(
borderOn: false,
bodyItems: [
SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(25.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//logo
Icon(
Icons.fingerprint,
size: 100,
color:
MzanziInnovationHub.of(context)!.theme.secondaryColor(),
),
//spacer
const SizedBox(height: 10),
//Heading
Text(
'Biomentric Authentication',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
),
),
//spacer
const SizedBox(height: 25),
if (!_isBioAuthenticated)
Icon(
Icons.lock,
size: 200,
color: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
),
if (_isBioAuthenticated)
Icon(
Icons.lock_open,
size: 200,
color: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
),
const SizedBox(height: 30),
Container(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: 500.0,
height: 50.0,
child: MIHButton(
buttonText: "Unlock",
buttonColor: MzanziInnovationHub.of(context)!
.theme
.secondaryColor(),
textColor: MzanziInnovationHub.of(context)!
.theme
.primaryColor(),
onTap: () async {
//Check Biometrics
authenticateUser();
},
),
),
),
],
),
),
),
),
],
);
}
Widget getBiomentricAuthScreen() {
return MIHLayoutBuilder(
actionButton: getActionButton(),
header: getHeader(),
secondaryActionButton: null,
body: getBody(),
actionDrawer: null,
secondaryActionDrawer: null,
bottomNavBar: null,
pullDownToRefresh: false,
onPullDown: () async {},
);
}
@override
Widget build(BuildContext context) {
if (MzanziInnovationHub.of(context)!.theme.getPlatform() == "Web") {
return MIHProfileGetter(
personalSelected: widget.personalSelected,
);
} else if (!widget.firstBoot) {
return MIHProfileGetter(
personalSelected: widget.personalSelected,
);
} else {
if (_isBioAuthenticated) {
return MIHProfileGetter(
personalSelected: widget.personalSelected,
);
} else {
return getBiomentricAuthScreen();
}
}
}
}

View File

@@ -89,6 +89,7 @@ class _RegisterState extends State<Register> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
var userExists = jsonDecode(response.body); var userExists = jsonDecode(response.body);
if (userExists["exists"]) { if (userExists["exists"]) {
Navigator.of(context).pop();
signUpError(); signUpError();
} else { } else {
var response2 = await http.post( var response2 = await http.post(

View File

@@ -296,7 +296,7 @@ class _ManageBusinessProfileState extends State<ManageBusinessProfile> {
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: false, arguments: AuthArguments(false, false),
); );
}, },
); );

View File

@@ -2,6 +2,7 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_action.dart'
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/mih_policy_tos/policy_and_terms_text.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mih_policy_tos/policy_and_terms_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -20,7 +21,7 @@ class _MIHPrivacyPolocyState extends State<MIHPrivacyPolocy> {
onTap: () { onTap: () {
Navigator.of(context).pushNamedAndRemoveUntil( Navigator.of(context).pushNamedAndRemoveUntil(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
(route) => false, (route) => false,
); );
}, },

View File

@@ -2,6 +2,7 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_action.dart'
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/mih_policy_tos/policy_and_terms_text.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mih_policy_tos/policy_and_terms_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -18,9 +19,10 @@ class _MIHTermsOfServiceState extends State<MIHTermsOfService> {
icon: const Icon(Icons.arrow_back), icon: const Icon(Icons.arrow_back),
iconSize: 35, iconSize: 35,
onTap: () { onTap: () {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamedAndRemoveUntil(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
(route) => false,
); );
}, },
); );

View File

@@ -247,7 +247,7 @@ class _ProfileUserUpdateState extends State<ProfileUserUpdate> {
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
); );
}, },
); );

View File

@@ -3,6 +3,7 @@ import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_body.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_header.dart';
import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart'; import 'package:Mzansi_Innovation_Hub/mih_components/mih_layout/mih_layout_builder.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart'; import 'package:Mzansi_Innovation_Hub/mih_objects/app_user.dart';
import 'package:Mzansi_Innovation_Hub/mih_objects/arguments.dart';
import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/loyalty_cards.dart'; import 'package:Mzansi_Innovation_Hub/mih_packages/mzansi_wallet/loyalty_cards.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -28,7 +29,7 @@ class _MzansiWalletState extends State<MzansiWallet> {
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
); );
}, },
); );

View File

@@ -532,7 +532,7 @@ class _PatientManagerState extends State<PatientManager> {
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: false, arguments: AuthArguments(false, false),
); );
}, },
); );

View File

@@ -125,7 +125,7 @@ class _PatientViewState extends State<PatientView> {
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).popAndPushNamed( Navigator.of(context).popAndPushNamed(
'/', '/',
arguments: true, arguments: AuthArguments(true, false),
); );
}, },
); );

View File

@@ -54,21 +54,16 @@ class RouteGenerator {
switch (settings.name) { switch (settings.name) {
// Authgentication // Authgentication
case '/': case '/':
if (args is bool) { if (args is AuthArguments) {
return MaterialPageRoute( return MaterialPageRoute(
settings: settings, settings: settings,
builder: (_) => AuthCheck( builder: (_) => AuthCheck(
personalSelected: args, personalSelected: args.personalSelected,
), firstBoot: args.firstBoot,
);
} else {
return MaterialPageRoute(
settings: settings,
builder: (_) => const AuthCheck(
personalSelected: true,
), ),
); );
} }
return _errorRoute();
case '/notifications': case '/notifications':
if (args is NotificationArguments) { if (args is NotificationArguments) {
return MaterialPageRoute( return MaterialPageRoute(
@@ -284,6 +279,7 @@ Route<dynamic> _errorRoute() {
settings: const RouteSettings(name: '/'), settings: const RouteSettings(name: '/'),
builder: (_) => const AuthCheck( builder: (_) => const AuthCheck(
personalSelected: true, personalSelected: true,
firstBoot: true,
)); ));
// return MaterialPageRoute(builder: (_) { // return MaterialPageRoute(builder: (_) {
// return const Scaffold( // return const Scaffold(

View File

@@ -8,6 +8,7 @@ import Foundation
import device_info_plus import device_info_plus
import firebase_core import firebase_core
import geolocator_apple import geolocator_apple
import local_auth_darwin
import mobile_scanner import mobile_scanner
import no_screenshot import no_screenshot
import printing import printing
@@ -20,6 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
FLALocalAuthPlugin.register(with: registry.registrar(forPlugin: "FLALocalAuthPlugin"))
MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin"))
NoScreenshotPlugin.register(with: registry.registrar(forPlugin: "NoScreenshotPlugin")) NoScreenshotPlugin.register(with: registry.registrar(forPlugin: "NoScreenshotPlugin"))
PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin"))

View File

@@ -645,6 +645,46 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
local_auth:
dependency: "direct main"
description:
name: local_auth
sha256: "434d854cf478f17f12ab29a76a02b3067f86a63a6d6c4eb8fbfdcfe4879c1b7b"
url: "https://pub.dev"
source: hosted
version: "2.3.0"
local_auth_android:
dependency: transitive
description:
name: local_auth_android
sha256: "6763aaf8965f21822624cb2fd3c03d2a8b3791037b5efb0fe4b13e110f5afc92"
url: "https://pub.dev"
source: hosted
version: "1.0.46"
local_auth_darwin:
dependency: transitive
description:
name: local_auth_darwin
sha256: "5c5127061107278ab4cafa1ac51b3b6760282bf1a2abf011270908a429d1634b"
url: "https://pub.dev"
source: hosted
version: "1.4.2"
local_auth_platform_interface:
dependency: transitive
description:
name: local_auth_platform_interface
sha256: "1b842ff177a7068442eae093b64abe3592f816afd2a533c0ebcdbe40f9d2075a"
url: "https://pub.dev"
source: hosted
version: "1.0.10"
local_auth_windows:
dependency: transitive
description:
name: local_auth_windows
sha256: bc4e66a29b0fdf751aafbec923b5bed7ad6ed3614875d8151afe2578520b2ab5
url: "https://pub.dev"
source: hosted
version: "1.0.11"
logging: logging:
dependency: transitive dependency: transitive
description: description:

View File

@@ -67,6 +67,7 @@ dependencies:
barcode_widget: ^2.0.4 barcode_widget: ^2.0.4
url_launcher: ^6.3.1 url_launcher: ^6.3.1
fl_downloader: ^2.0.2 fl_downloader: ^2.0.2
local_auth: ^2.3.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@@ -9,6 +9,7 @@
#include <firebase_core/firebase_core_plugin_c_api.h> #include <firebase_core/firebase_core_plugin_c_api.h>
#include <fl_downloader/fl_downloader_plugin_c_api.h> #include <fl_downloader/fl_downloader_plugin_c_api.h>
#include <geolocator_windows/geolocator_windows.h> #include <geolocator_windows/geolocator_windows.h>
#include <local_auth_windows/local_auth_plugin.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h> #include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <printing/printing_plugin.h> #include <printing/printing_plugin.h>
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h> #include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
@@ -22,6 +23,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlDownloaderPluginCApi")); registry->GetRegistrarForPlugin("FlDownloaderPluginCApi"));
GeolocatorWindowsRegisterWithRegistrar( GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows")); registry->GetRegistrarForPlugin("GeolocatorWindows"));
LocalAuthPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("LocalAuthPlugin"));
PermissionHandlerWindowsPluginRegisterWithRegistrar( PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
PrintingPluginRegisterWithRegistrar( PrintingPluginRegisterWithRegistrar(

View File

@@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
firebase_core firebase_core
fl_downloader fl_downloader
geolocator_windows geolocator_windows
local_auth_windows
permission_handler_windows permission_handler_windows
printing printing
syncfusion_pdfviewer_windows syncfusion_pdfviewer_windows

View File

@@ -45,8 +45,8 @@ services:
ports: ports:
- 3567:3567 - 3567:3567
environment: environment:
REFRESH_TOKEN_VALIDITY: '1440' REFRESH_TOKEN_VALIDITY: '43200'
ACCESS_TOKEN_VALIDITY: '3600' ACCESS_TOKEN_VALIDITY: '43200'
PASSWORD_RESET_TOKEN_LIFETIME: '7200000' PASSWORD_RESET_TOKEN_LIFETIME: '7200000'
MYSQL_USER: ${SQL_USER} MYSQL_USER: ${SQL_USER}
MYSQL_PASSWORD: ${SQL_USER_PW} MYSQL_PASSWORD: ${SQL_USER_PW}