-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
request an example that locks down an app #98
Comments
How about using |
I think it would be a useful test if your plugin to build such a sample, yes. |
I will try to find time to try, but I work full time and don't know when that will be. |
I haven't tried it yet, but here's what Bing chat says about how to use local_auth to secure an app the way I'm interested in: import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
final LocalAuthentication auth = LocalAuthentication();
bool _isAuthenticated = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_authenticate(); // authenticate when app starts
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print(state);
if (state == AppLifecycleState.resumed) {
// authenticate when app resumes
_authenticate();
}
}
Future<void> _authenticate() async {
bool authenticated = false;
try {
authenticated = await auth.authenticate(
localizedReason: 'Please authenticate to continue using this app',
biometricOnly: true,
useErrorDialogs: true,
stickyAuth: true,
);
} on Exception catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_isAuthenticated = authenticated;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: _isAuthenticated ? Text('Hello World') : Text('Please authenticate'),
),
),
);
}
}```
I assume that's close to how to do it with your plugin. |
I asked ChatGPT to update the code to use flutter_screen_lock and this is what it said: import 'package:flutter/material.dart';
import 'package:flutter_screen_lock/flutter_screen_lock.dart';
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
bool _isAuthenticated = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_authenticate(); // authenticate when app starts
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
print(state);
if (state == AppLifecycleState.resumed) {
// authenticate when app resumes
_authenticate();
}
}
Future<void> _authenticate() async {
bool isAuthenticated = false;
try {
isAuthenticated = await showFlutterLockScreen(
context: context,
title: 'Please authenticate to continue using this app',
cancelButton: 'Cancel',
canAuthenticate: true,
canCreatePassword: true,
biometricAuthConfig: BiometricAuthConfig(
android: AndroidAuthConfig(
useBioMetric: true,
androidAuthType: AndroidAuthType.BIOMETRIC_WEAK,
),
iOS: IOSAuthConfig(
useBioMetric: true,
),
),
);
} catch (e) {
print(e);
}
if (!mounted) return;
setState(() {
_isAuthenticated = isAuthenticated;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: _isAuthenticated ? Text('Hello World') : Text('Please authenticate'),
),
),
);
}
} I have no idea if this is true or not, however. |
The result is the same as my idea. |
Nothing that ChatGPT suggests above actually works, although as you say, the hint about // ignore_for_file: library_private_types_in_public_api
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screen_lock/flutter_screen_lock.dart';
import 'package:shared_preferences/shared_preferences.dart';
late final SharedPreferences prefs;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
prefs = await SharedPreferences.getInstance();
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) => const MaterialApp(
home: HomeScreen(),
);
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with WidgetsBindingObserver {
bool _isAuthenticated = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
// authenticate when app starts
scheduleMicrotask(_authenticate);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.inactive:
// "logout" when app becomes inactive
setState(() => _isAuthenticated = false);
break;
case AppLifecycleState.resumed:
// authenticate when app resumes
_authenticate();
break;
case AppLifecycleState.paused:
case AppLifecycleState.detached:
break;
}
}
Future<void> _authenticate() async {
final passcode = prefs.getString('passcode');
if (passcode == null) {
// let use create passcode
screenLockCreate(
context: context,
canCancel: false,
onConfirmed: _onLockCreate,
);
} else {
// match passcode to user input
screenLock(
context: context,
correctString: passcode,
canCancel: false,
onUnlocked: _onUnlock,
);
}
}
void _onLockCreate(String value) {
unawaited(prefs.setString('passcode', value));
setState(() => _isAuthenticated = true);
Navigator.pop(context);
}
void _onUnlock() {
setState(() => _isAuthenticated = true);
Navigator.pop(context);
}
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: _isAuthenticated
? const Text('Hello World')
: const Text('Please authenticate'),
),
);
} You need to update the package com.example.total_screen_lock_example
import android.os.Bundle
import android.view.WindowManager
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE)
}
} I don't know if there's something equivalent to do for an iOS app. None of this works for a Flutter desktop app, however, since |
I'd love an example of an app that blocks the user till they login and makes them login again if they switch back to the app. The current example just shows dialogs when buttons are pushed and don't really show how the plugin works in a real-world situation.
The text was updated successfully, but these errors were encountered: