android screensht no test

This commit is contained in:
2024-09-11 13:31:45 +02:00
parent 438163a91e
commit f1f39889b7
9 changed files with 219 additions and 109 deletions

View File

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:patient_manager/env/env.dart'; import 'package:patient_manager/env/env.dart';
import 'package:patient_manager/router/routeGenerator.dart'; import 'package:patient_manager/router/routeGenerator.dart';
import 'package:patient_manager/theme/mihTheme.dart'; import 'package:patient_manager/theme/mihTheme.dart';
import 'package:no_screenshot/no_screenshot.dart'; import 'package:flutter_windowmanager/flutter_windowmanager.dart';
class MzanziInnovationHub extends StatefulWidget { class MzanziInnovationHub extends StatefulWidget {
const MzanziInnovationHub({ const MzanziInnovationHub({
@@ -21,8 +21,6 @@ class _MzanziInnovationHubState extends State<MzanziInnovationHub> {
late ThemeMode _themeMode; late ThemeMode _themeMode;
late MyTheme theme; late MyTheme theme;
final _noScreenshot = NoScreenshot.instance;
Color getPrimany() { Color getPrimany() {
return theme.primaryColor(); return theme.primaryColor();
} }
@@ -50,32 +48,23 @@ class _MzanziInnovationHubState extends State<MzanziInnovationHub> {
}); });
} }
void disableScreenshot() async {
await _noScreenshot.startScreenshotListening();
bool result = await _noScreenshot.screenshotOff();
debugPrint('Screenshot Off: $result');
}
void setPlatformSpecificPlugins() {
print("is PWA: ${theme.isPwa()}");
if (theme.isPwa()) {
disableScreenshot();
//print(object)
}
}
@override @override
void initState() { void initState() {
_themeMode = ThemeMode.dark; _themeMode = ThemeMode.dark;
theme = MyTheme(); theme = MyTheme();
theme.platform = Theme.of(context).platform;
theme.mode = "Dark"; theme.mode = "Dark";
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
setPlatformSpecificPlugins(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
if (theme.getPlatform() == "Android") {
await FlutterWindowManager.addFlags(FlutterWindowManager.FLAG_SECURE);
}
});
double width = MediaQuery.sizeOf(context).width; double width = MediaQuery.sizeOf(context).width;
theme.setScreenType(width); theme.setScreenType(width);
precacheImage(theme.loadingImage(), context); precacheImage(theme.loadingImage(), context);

View File

@@ -304,7 +304,7 @@ class _SignInState extends State<SignIn> {
const SizedBox(height: 10), const SizedBox(height: 10),
//Heading //Heading
Text( Text(
'Sign In (PWA: ${MzanziInnovationHub.of(context)!.theme.isPwa()})', 'Sign In (${MzanziInnovationHub.of(context)!.theme.getPlatform()})',
style: TextStyle( style: TextStyle(
fontSize: 25, fontSize: 25,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@@ -1,96 +1,192 @@
import 'package:flutter/material.dart'; import 'dart:async';
import 'package:no_screenshot/no_screenshot.dart';
import 'package:no_screenshot/screenshot_snapshot.dart';
void main() { import 'package:flutter/material.dart';
runApp(const MyApp()); import 'package:secure_application/secure_application.dart';
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({super.key});
@override @override
State<MyApp> createState() => _MyAppState(); _MyAppState createState() => _MyAppState();
} }
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
final _noScreenshot = NoScreenshot.instance; bool failedAuth = false;
bool _isListeningToScreenshotSnapshot = false; double blurr = 20;
ScreenshotSnapshot _latestValue = ScreenshotSnapshot( double opacity = 0.6;
isScreenshotProtectionOn: false, StreamSubscription<bool>? subLock;
wasScreenshotTaken: false, List<String> history = [];
screenshotPath: '',
);
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_noScreenshot.screenshotStream.listen((value) { }
setState(() {
_latestValue = value; @override
}); void dispose() {
}); subLock?.cancel();
super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var width = MediaQuery.of(context).size.width * 0.8;
return MaterialApp( return MaterialApp(
home: Scaffold( home: SecureApplication(
appBar: AppBar( nativeRemoveDelay: 1000,
title: const Text('No Screenshot Plugin Example'), onNeedUnlock: (secure) async {
), print(
body: Center( 'need unlock maybe use biometric to confirm and then sercure.unlock() or you can use the lockedBuilder');
child: Column( // var authResult = authMyUser();
mainAxisAlignment: MainAxisAlignment.spaceBetween, // if (authResul) {
children: <Widget>[ // secure.unlock();
ElevatedButton( // return SecureApplicationAuthenticationStatus.SUCCESS;
onPressed: () async { //}
await _noScreenshot.startScreenshotListening(); // else {
setState(() { // return SecureApplicationAuthenticationStatus.FAILED;
_isListeningToScreenshotSnapshot = true; //}
}); return null;
}, },
child: const Text('Start Listening'), onAuthenticationFailed: () async {
// clean you data
setState(() {
failedAuth = true;
});
print('auth failed');
},
onAuthenticationSucceed: () async {
// clean you data
setState(() {
failedAuth = false;
});
print('auth success');
},
child: Builder(builder: (context) {
if (subLock == null)
subLock = SecureApplicationProvider.of(context, listen: false)
?.lockEvents
.listen((s) => history.add(
'${DateTime.now().toIso8601String()} - ${s ? 'locked' : 'unlocked'}'));
return SecureGate(
blurr: blurr,
opacity: opacity,
lockedBuilder: (context, secureNotifier) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
child: Text('UNLOCK'),
onPressed: () => secureNotifier?.authSuccess(unlock: true),
),
ElevatedButton(
child: Text('FAIL AUTHENTICATION'),
onPressed: () => secureNotifier?.authFailed(unlock: true),
),
],
)),
child: Scaffold(
appBar: AppBar(
title: const Text('Secure Window Example'),
), ),
ElevatedButton( body: Center(
onPressed: () async { child: Builder(builder: (context) {
await _noScreenshot.stopScreenshotListening(); var valueNotifier = SecureApplicationProvider.of(context);
setState(() { if (valueNotifier == null)
_isListeningToScreenshotSnapshot = false; throw new Exception(
}); 'Unable to find secure application context');
}, return ListView(
child: const Text('Stop Listening'), children: <Widget>[
Text('This is secure content'),
ValueListenableBuilder<SecureApplicationState>(
valueListenable: valueNotifier,
builder: (context, state, _) => state.secured
? Column(
children: <Widget>[
ElevatedButton(
onPressed: () => valueNotifier.open(),
child: Text('Open app'),
),
state.paused
? ElevatedButton(
onPressed: () =>
valueNotifier.unpause(),
child: Text('resume security'),
)
: ElevatedButton(
onPressed: () =>
valueNotifier.pause(),
child: Text('pause security'),
),
],
)
: ElevatedButton(
onPressed: () => valueNotifier.secure(),
child: Text('Secure app'),
),
),
failedAuth
? Text(
'Auth failed we cleaned sensitive data',
style: TextStyle(color: Colors.red),
)
: Text(
'Auth success',
style: TextStyle(color: Colors.green),
),
FlutterLogo(
size: width,
),
StreamBuilder(
stream: valueNotifier.authenticationEvents,
builder: (context, snapshot) =>
Text('Last auth status is: ${snapshot.data}'),
),
ElevatedButton(
onPressed: () => valueNotifier.lock(),
child: Text('manually lock'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text('Blurr:'),
Expanded(
child: Slider(
value: blurr,
min: 0,
max: 100,
onChanged: (v) => setState(() => blurr = v)),
),
Text(blurr.floor().toString()),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Text('opacity:'),
Expanded(
child: Slider(
value: opacity,
min: 0,
max: 1,
onChanged: (v) =>
setState(() => opacity = v)),
),
Text((opacity * 100).floor().toString() + "%"),
],
),
),
...history.map<Widget>((h) => Text(h)).toList(),
],
);
}),
), ),
Padding( ),
padding: const EdgeInsets.symmetric(horizontal: 10), );
child: Text( }),
"Screenshot Streaming is ${_isListeningToScreenshotSnapshot ? 'ON' : 'OFF'}\n\nIsScreenshotProtectionOn: ${_latestValue.isScreenshotProtectionOn}\nwasScreenshotTaken: ${_latestValue.wasScreenshotTaken}\nScreenshot Path: ${_latestValue.screenshotPath}"),
),
ElevatedButton(
onPressed: () async {
bool result = await _noScreenshot.screenshotOff();
debugPrint('Screenshot Off: $result');
},
child: const Text('Disable Screenshot'),
),
ElevatedButton(
onPressed: () async {
bool result = await _noScreenshot.screenshotOn();
debugPrint('Enable Screenshot: $result');
},
child: const Text('Enable Screenshot'),
),
ElevatedButton(
onPressed: () async {
bool result = await _noScreenshot.toggleScreenshot();
debugPrint('Toggle Screenshot: $result');
},
child: const Text('Toggle Screenshot'),
),
const SizedBox(height: 20),
],
),
),
), ),
); );
} }

View File

@@ -10,6 +10,7 @@ class MyTheme {
late String mode; late String mode;
late String screenType; late String screenType;
late AssetImage loading; late AssetImage loading;
late TargetPlatform platform;
bool kIsWeb = const bool.fromEnvironment('dart.library.js_util'); bool kIsWeb = const bool.fromEnvironment('dart.library.js_util');
// Options:- // Options:-
// f3f9d2 = Cream // f3f9d2 = Cream
@@ -74,6 +75,19 @@ class MyTheme {
)); ));
} }
String getPlatform() {
if (kIsWeb) {
return "Web";
} else if (isPwa()) {
if (platform == TargetPlatform.android) {
return "Android";
} else if (platform == TargetPlatform.iOS) {
return "iOS";
}
}
return "Other";
}
bool isPwa() { bool isPwa() {
return html.window.matchMedia('(display-mode: standalone)').matches; return html.window.matchMedia('(display-mode: standalone)').matches;
} }

View File

@@ -8,7 +8,6 @@ import Foundation
import app_links import app_links
import device_info_plus import device_info_plus
import google_sign_in_ios import google_sign_in_ios
import no_screenshot
import path_provider_foundation import path_provider_foundation
import shared_preferences_foundation import shared_preferences_foundation
import sign_in_with_apple import sign_in_with_apple
@@ -19,7 +18,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin"))
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin"))
NoScreenshotPlugin.register(with: registry.registrar(forPlugin: "NoScreenshotPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin")) SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin"))

View File

@@ -400,6 +400,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_windowmanager:
dependency: "direct main"
description:
name: flutter_windowmanager
sha256: b4d0bc06f6777952b729c0cdb7ce9ad1ecabd8b8b1cb0acb57a36621457dab1b
url: "https://pub.dev"
source: hosted
version: "0.2.0"
font_awesome_flutter: font_awesome_flutter:
dependency: transitive dependency: transitive
description: description:
@@ -688,14 +696,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.0.27" version: "0.0.27"
no_screenshot:
dependency: "direct main"
description:
name: no_screenshot
sha256: ec3d86d7ee89a09c3a3939c1003012536ba4b3fcb4f8cbd23d87ada595c99258
url: "https://pub.dev"
source: hosted
version: "0.3.1"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
@@ -844,10 +844,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: rxdart name: rxdart
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.28.0" version: "0.27.7"
scratch_space: scratch_space:
dependency: transitive dependency: transitive
description: description:
@@ -856,6 +856,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
secure_application:
dependency: "direct main"
description:
name: secure_application
sha256: b8e34b4bc2467a3a3c0a649e46ae6a442df7ca27aeaddebb8a53c40656da0385
url: "https://pub.dev"
source: hosted
version: "4.0.1"
shared_preferences: shared_preferences:
dependency: transitive dependency: transitive
description: description:

View File

@@ -50,9 +50,10 @@ dependencies:
gif: ^2.3.0 gif: ^2.3.0
intl: ^0.19.0 intl: ^0.19.0
flutter_native_splash: ^2.4.1 flutter_native_splash: ^2.4.1
no_screenshot: ^0.3.1
#google_maps_flutter_web: ^0.5.10 #google_maps_flutter_web: ^0.5.10
url_strategy: ^0.3.0 url_strategy: ^0.3.0
secure_application: ^4.0.1
flutter_windowmanager: ^0.2.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@@ -7,12 +7,15 @@
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <app_links/app_links_plugin_c_api.h> #include <app_links/app_links_plugin_c_api.h>
#include <secure_application/secure_application_plugin.h>
#include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h> #include <syncfusion_pdfviewer_windows/syncfusion_pdfviewer_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h> #include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) { void RegisterPlugins(flutter::PluginRegistry* registry) {
AppLinksPluginCApiRegisterWithRegistrar( AppLinksPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AppLinksPluginCApi")); registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
SecureApplicationPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SecureApplicationPlugin"));
SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar( SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin")); registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin"));
UrlLauncherWindowsRegisterWithRegistrar( UrlLauncherWindowsRegisterWithRegistrar(

View File

@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST list(APPEND FLUTTER_PLUGIN_LIST
app_links app_links
secure_application
syncfusion_pdfviewer_windows syncfusion_pdfviewer_windows
url_launcher_windows url_launcher_windows
) )