|
1 | | -import 'dart:async'; |
2 | | - |
3 | 1 | import 'package:flutter/material.dart'; |
4 | | -import 'package:flutter/services.dart'; |
5 | | -import 'package:flutter_security_toolkit/flutter_security_toolkit.dart'; |
| 2 | +import 'package:flutter_security_toolkit_example/app/app.dart'; |
6 | 3 |
|
7 | 4 | void main() { |
8 | | - runApp(const MyApp()); |
9 | | -} |
10 | | - |
11 | | -class MyApp extends StatefulWidget { |
12 | | - const MyApp({super.key}); |
13 | | - |
14 | | - @override |
15 | | - State<MyApp> createState() => _MyAppState(); |
16 | | -} |
17 | | - |
18 | | -class _MyAppState extends State<MyApp> { |
19 | | - bool _jailbroken = false; |
20 | | - bool _hooks = false; |
21 | | - bool _simulator = false; |
22 | | - |
23 | | - @override |
24 | | - void initState() { |
25 | | - super.initState(); |
26 | | - initPlatformState(); |
27 | | - } |
28 | | - |
29 | | - // Platform messages are asynchronous, so we initialize in an async method. |
30 | | - Future<void> initPlatformState() async { |
31 | | - // Platform messages may fail, so we use a try/catch PlatformException. |
32 | | - // We also handle the message potentially returning null. |
33 | | - try { |
34 | | - final (jailbroken, hooks, simulator) = await ( |
35 | | - ThreatDetectionCenter.areRootPrivilegesDetected(), |
36 | | - ThreatDetectionCenter.areHooksDetected(), |
37 | | - ThreatDetectionCenter.isSimulatorDetected(), |
38 | | - ).wait; |
39 | | - |
40 | | - if (!mounted) return; |
41 | | - |
42 | | - setState(() { |
43 | | - _jailbroken = jailbroken ?? _jailbroken; |
44 | | - _hooks = hooks ?? _hooks; |
45 | | - _simulator = simulator ?? _simulator; |
46 | | - }); |
47 | | - } on PlatformException { |
48 | | - // Do nothing |
49 | | - } |
50 | | - } |
51 | | - |
52 | | - @override |
53 | | - Widget build(BuildContext context) { |
54 | | - return MaterialApp( |
55 | | - debugShowCheckedModeBanner: false, |
56 | | - home: Scaffold( |
57 | | - body: SafeArea( |
58 | | - child: Center( |
59 | | - child: Builder(builder: (context) { |
60 | | - final textTheme = Theme.of(context).textTheme; |
61 | | - return SingleChildScrollView( |
62 | | - child: Column( |
63 | | - crossAxisAlignment: CrossAxisAlignment.center, |
64 | | - mainAxisAlignment: MainAxisAlignment.center, |
65 | | - children: [ |
66 | | - Icon( |
67 | | - _jailbroken || _hooks ? Icons.lock_open : Icons.lock, |
68 | | - size: 80, |
69 | | - ).padding(bottom: 24), |
70 | | - Text( |
71 | | - 'Protection', |
72 | | - style: textTheme.headlineLarge, |
73 | | - ).padding(bottom: 8), |
74 | | - Text( |
75 | | - 'Here is a list of the threats that could put you at risk', |
76 | | - style: |
77 | | - textTheme.titleMedium?.copyWith(color: Colors.grey), |
78 | | - textAlign: TextAlign.center, |
79 | | - ).padding(bottom: 16), |
80 | | - ThreatCard( |
81 | | - title: 'Jailbreak / Root', |
82 | | - description: |
83 | | - 'Is a way of acquiring privileged control over the operating system of a device. Tools such as Magisk or Shadow can hide the privileged access', |
84 | | - status: _jailbroken, |
85 | | - ), |
86 | | - ThreatCard( |
87 | | - title: 'Hooks', |
88 | | - description: |
89 | | - 'Intercept system or application calls and then modify them (modify the return value of a function call for example)', |
90 | | - status: _hooks, |
91 | | - ), |
92 | | - ThreatCard( |
93 | | - title: 'Simulator', |
94 | | - description: 'Running the application in an Simulator', |
95 | | - status: _simulator, |
96 | | - ), |
97 | | - ], |
98 | | - ), |
99 | | - ); |
100 | | - }), |
101 | | - ).padding(left: 20, right: 20), |
102 | | - ), |
103 | | - ), |
104 | | - ); |
105 | | - } |
106 | | -} |
107 | | - |
108 | | -class ThreatCard extends StatelessWidget { |
109 | | - final String title; |
110 | | - final String description; |
111 | | - final bool status; |
112 | | - |
113 | | - const ThreatCard({ |
114 | | - required this.title, |
115 | | - required this.description, |
116 | | - required this.status, |
117 | | - super.key, |
118 | | - }); |
119 | | - |
120 | | - @override |
121 | | - Widget build(BuildContext context) { |
122 | | - final textTheme = Theme.of(context).textTheme; |
123 | | - return Card( |
124 | | - shape: RoundedRectangleBorder( |
125 | | - borderRadius: BorderRadius.circular(8), |
126 | | - ), |
127 | | - color: Colors.white, |
128 | | - child: Column( |
129 | | - crossAxisAlignment: CrossAxisAlignment.start, |
130 | | - children: [ |
131 | | - Row( |
132 | | - mainAxisAlignment: MainAxisAlignment.spaceBetween, |
133 | | - children: [ |
134 | | - Text( |
135 | | - title, |
136 | | - style: textTheme.titleLarge?.copyWith(color: Colors.black), |
137 | | - ), |
138 | | - Card( |
139 | | - shape: RoundedRectangleBorder( |
140 | | - borderRadius: BorderRadius.circular(8), |
141 | | - ), |
142 | | - color: !status ? Colors.green : Colors.red, |
143 | | - child: Column( |
144 | | - children: [ |
145 | | - Text( |
146 | | - !status ? 'SAFE' : 'DETECTED', |
147 | | - style: textTheme.bodySmall?.copyWith(color: Colors.white), |
148 | | - ), |
149 | | - ], |
150 | | - ).paddingAll(8), |
151 | | - ) |
152 | | - ], |
153 | | - ).padding(bottom: 8), |
154 | | - Text( |
155 | | - description, |
156 | | - style: textTheme.titleMedium?.copyWith(color: Colors.grey), |
157 | | - textAlign: TextAlign.start, |
158 | | - ), |
159 | | - ], |
160 | | - ).paddingAll(16), |
161 | | - ).paddingAll(8); |
162 | | - } |
163 | | -} |
164 | | - |
165 | | -extension PaddedWidget on Widget { |
166 | | - Widget padding({ |
167 | | - double left = 0.0, |
168 | | - double top = 0.0, |
169 | | - double right = 0.0, |
170 | | - double bottom = 0.0, |
171 | | - }) => |
172 | | - Padding( |
173 | | - padding: EdgeInsets.only( |
174 | | - left: left, |
175 | | - top: top, |
176 | | - right: right, |
177 | | - bottom: bottom, |
178 | | - ), |
179 | | - child: this, |
180 | | - ); |
181 | | - |
182 | | - Widget paddingAll(double all) => |
183 | | - padding(left: all, top: all, right: all, bottom: all); |
| 5 | + runApp(const App()); |
184 | 6 | } |
0 commit comments