Skip to content

Commit 0c51965

Browse files
Merge pull request #13 from geeksesi/master
#12 feat: kerio auto login
2 parents e0c2b8d + 1fc4d78 commit 0c51965

6 files changed

Lines changed: 253 additions & 8 deletions

File tree

assets/kerio.png

12.4 KB
Loading

lib/data/leak_item.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ class LeakItem {
66

77
static List<String> prePopulatedUrls() {
88
return [
9-
'https://console.firebase.google.com',
109
'https://developer.android.com',
11-
'https://storage.googleapis.com/dartlang-pub-public-packages/packages/live_event-0.0.1.tar.gz',
1210
'https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/4.1.3/gradle-4.1.3.pom',
11+
'https://storage.googleapis.com/dartlang-pub-public-packages/packages/live_event-0.0.1.tar.gz'
1312
];
1413
}
1514
}

lib/data/shared_preferences.dart

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
11
import 'package:shared_preferences/shared_preferences.dart';
22

33
class AppSharedPreferences {
4-
static SharedPreferences? __instance;
4+
static Future<String?> get kerioIP async {
5+
return (await _preference).getString(_keyKerioIP);
6+
}
57

6-
static Future<SharedPreferences> get _preference async {
7-
__instance ??= await SharedPreferences.getInstance();
8-
return __instance!;
8+
static Future<void> setKerioIP(String value) async {
9+
(await _preference).setString(_keyKerioIP, value);
10+
}
11+
12+
static Future<String?> get kerioUsername async {
13+
return (await _preference).getString(_keyKerioUsername);
14+
}
15+
16+
static Future<void> setKerioUsername(String value) async {
17+
(await _preference).setString(_keyKerioUsername, value);
18+
}
19+
20+
static Future<String?> get kerioPassword async {
21+
return (await _preference).getString(_keyKerioPassword);
22+
}
23+
24+
static Future<void> setKerioPassword(String value) async {
25+
(await _preference).setString(_keyKerioPassword, value);
26+
}
27+
28+
static Future<bool> get kerioAutoLogin async {
29+
return (await _preference).getBool(_keyKerioAutoLogin) ?? true;
30+
}
31+
32+
static Future<void> setKerioAutoLogin(bool value) async {
33+
(await _preference).setBool(_keyKerioAutoLogin, value);
934
}
1035

1136
static Future<bool> get showLeakInSysTray async {
12-
return (await _preference).getBool(_keyShowLeakInSysTray) ?? false;
37+
return (await _preference).getBool(_keyShowLeakInSysTray) ?? true;
1338
}
1439

1540
static Future<void> setShowLeakInSysTray(bool value) async {
@@ -44,7 +69,17 @@ class AppSharedPreferences {
4469
(await _preference).setString(_keyLeakCheckList, previousChecklist.join(';'));
4570
}
4671

72+
static SharedPreferences? __instance;
73+
static Future<SharedPreferences> get _preference async {
74+
__instance ??= await SharedPreferences.getInstance();
75+
return __instance!;
76+
}
77+
4778
static const _keyIsLeakPrePopulated = 'isLeakPrePopulated';
4879
static const _keyShowLeakInSysTray = 'showLeakInSysTray';
4980
static const _keyLeakCheckList = 'leakChecklist';
81+
static const _keyKerioIP = 'kerioIP';
82+
static const _keyKerioUsername = 'kerioUsername';
83+
static const _keyKerioPassword = 'kerioPassword';
84+
static const _keyKerioAutoLogin = 'kerioAutoLogin';
5085
}

lib/main.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ Future<void> initSharedPreferences() async {
5454
}
5555
await AppSharedPreferences.setIsLeakPrePopulated(true);
5656
}
57+
if ((await AppSharedPreferences.kerioIP) == null) {
58+
await AppSharedPreferences.setKerioIP('172.18.18.1:4080');
59+
}
5760
}
5861

5962
Future<void> initLaunchAtStartup() async {

lib/views/kerio_login.dart

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:http/http.dart' as http;
3+
import 'package:ir_net/data/shared_preferences.dart';
4+
5+
class KerioLoginView extends StatefulWidget {
6+
const KerioLoginView({super.key});
7+
8+
@override
9+
State<KerioLoginView> createState() => _KerioLoginViewState();
10+
}
11+
12+
class _KerioLoginViewState extends State<KerioLoginView> {
13+
final TextEditingController _ipController = TextEditingController();
14+
final TextEditingController _usernameController = TextEditingController();
15+
final TextEditingController _passwordController = TextEditingController();
16+
17+
@override
18+
void initState() {
19+
super.initState();
20+
_attemptAutoLogin();
21+
}
22+
23+
Future<void> _attemptAutoLogin() async {
24+
final ip = await AppSharedPreferences.kerioIP;
25+
final username = await AppSharedPreferences.kerioUsername;
26+
final password = await AppSharedPreferences.kerioPassword;
27+
final enabled = await AppSharedPreferences.kerioAutoLogin;
28+
29+
_ipController.text = ip ?? '';
30+
if (ip != null && username != null && password != null && enabled == true) {
31+
_ipController.text = ip;
32+
_usernameController.text = username;
33+
_passwordController.text = password;
34+
_login(true);
35+
}
36+
}
37+
38+
void _login(bool auto) async {
39+
final ip = _ipController.text;
40+
final username = _usernameController.text;
41+
final password = _passwordController.text;
42+
43+
if (ip.isEmpty || username.isEmpty || password.isEmpty) {
44+
_showMessage('Please fill in all fields');
45+
return;
46+
}
47+
48+
// Save credentials for auto-login
49+
await AppSharedPreferences.setKerioIP(ip);
50+
await AppSharedPreferences.setKerioUsername(username);
51+
await AppSharedPreferences.setKerioPassword(password);
52+
53+
final url = 'http://$ip/internal/dologin.php';
54+
final response = await http.post(
55+
Uri.parse(url),
56+
body: {
57+
'kerio_username': username,
58+
'kerio_password': password,
59+
},
60+
);
61+
62+
if (auto) {
63+
return;
64+
}
65+
66+
_showMessage('Login request sent'); // todo: handle failure case
67+
}
68+
69+
void _showMessage(String message) {
70+
showDialog(
71+
context: context,
72+
builder: (context) => AlertDialog(
73+
content: Text(message),
74+
actions: [
75+
TextButton(
76+
onPressed: () => Navigator.of(context).pop(),
77+
child: const Text('OK'),
78+
),
79+
],
80+
),
81+
);
82+
}
83+
84+
@override
85+
Widget build(BuildContext context) {
86+
return SizedBox(
87+
width: 400,
88+
child: Column(
89+
crossAxisAlignment: CrossAxisAlignment.center,
90+
children: [
91+
ipInput(),
92+
const SizedBox(height: 4),
93+
Row(
94+
children: [
95+
Expanded(
96+
child: username(),
97+
),
98+
const SizedBox(width: 4),
99+
Expanded(
100+
child: password(),
101+
),
102+
],
103+
),
104+
const SizedBox(height: 8),
105+
loginRow()
106+
],
107+
),
108+
);
109+
}
110+
111+
Widget ipInput() {
112+
return TextField(
113+
controller: _ipController,
114+
decoration: InputDecoration(
115+
focusedBorder: const OutlineInputBorder(
116+
borderSide: BorderSide(color: Colors.green),
117+
),
118+
enabledBorder: const OutlineInputBorder(
119+
borderSide: BorderSide(color: Colors.blue),
120+
),
121+
hintText: 'Kerio login page IP',
122+
hintStyle: const TextStyle(color: Colors.black38),
123+
suffixIcon: IconButton(
124+
onPressed: null,
125+
icon: Image.asset('assets/kerio.png', width: 24, height: 24),
126+
),
127+
),
128+
keyboardType: TextInputType.url,
129+
);
130+
}
131+
132+
Widget username() {
133+
return TextField(
134+
controller: _usernameController,
135+
decoration: const InputDecoration(
136+
focusedBorder: OutlineInputBorder(
137+
borderSide: BorderSide(color: Colors.green),
138+
),
139+
enabledBorder: OutlineInputBorder(
140+
borderSide: BorderSide(color: Colors.blue),
141+
),
142+
hintText: 'Username',
143+
hintStyle: TextStyle(color: Colors.black38),
144+
),
145+
);
146+
}
147+
148+
Widget password() {
149+
return TextField(
150+
controller: _passwordController,
151+
decoration: const InputDecoration(
152+
focusedBorder: OutlineInputBorder(
153+
borderSide: BorderSide(color: Colors.green),
154+
),
155+
enabledBorder: OutlineInputBorder(
156+
borderSide: BorderSide(color: Colors.blue),
157+
),
158+
hintText: 'Password',
159+
hintStyle: TextStyle(color: Colors.black38),
160+
),
161+
obscureText: true,
162+
);
163+
}
164+
165+
Widget loginRow() {
166+
return Row(
167+
children: [
168+
Expanded(
169+
flex: 2,
170+
child: ElevatedButton(
171+
onPressed: () => _login(false),
172+
style: ElevatedButton.styleFrom(
173+
shape: const RoundedRectangleBorder(
174+
borderRadius: BorderRadius.all(Radius.circular(8)),
175+
),
176+
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
177+
backgroundColor: Colors.blue,
178+
),
179+
child: const Text('Login', style: TextStyle(color: Colors.white)),
180+
),
181+
),
182+
const SizedBox(width: 10),
183+
Expanded(
184+
child: autoLoginOption(),
185+
)
186+
],
187+
);
188+
}
189+
190+
Widget autoLoginOption() {
191+
return FutureBuilder<bool>(
192+
future: AppSharedPreferences.kerioAutoLogin,
193+
builder: (context, snapshot) {
194+
final value = snapshot.data ?? false;
195+
return CheckboxListTile(
196+
title: const Text('Auto?'),
197+
value: value,
198+
onChanged: (enabled) async {
199+
await AppSharedPreferences.setKerioAutoLogin(enabled ?? false);
200+
setState(() {});
201+
},
202+
);
203+
},
204+
);
205+
}
206+
}

lib/views/leak.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'package:flutter/material.dart';
22
import 'package:ir_net/data/leak_item.dart';
33
import 'package:ir_net/main.dart';
4+
import 'package:ir_net/views/kerio_login.dart';
45
import 'package:touch_mouse_behavior/touch_mouse_behavior.dart';
56
import 'package:url_launcher/url_launcher.dart';
67

@@ -41,6 +42,7 @@ class _LeakViewState extends State<LeakView> {
4142
),
4243
const SizedBox(height: 16),
4344
items(),
45+
const KerioLoginView()
4446
],
4547
);
4648
}
@@ -55,7 +57,7 @@ class _LeakViewState extends State<LeakView> {
5557
}
5658
return SizedBox(
5759
width: 400,
58-
height: 400,
60+
height: 250,
5961
child: TouchMouseScrollable(
6062
child: ListView.builder(
6163
itemCount: data.length,

0 commit comments

Comments
 (0)