mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-06-14 22:55:12 +10:00
Merge pull request #365 from zjs81/rpt-guest
enh: make repeater admin guest aware
This commit is contained in:
@@ -14,7 +14,7 @@ import 'path_management_dialog.dart';
|
||||
|
||||
class RepeaterLoginDialog extends StatefulWidget {
|
||||
final Contact repeater;
|
||||
final Function(String password) onLogin;
|
||||
final Function(String password, bool isAdmin) onLogin;
|
||||
|
||||
const RepeaterLoginDialog({
|
||||
super.key,
|
||||
@@ -119,6 +119,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
: '${selection.hopCount} hops';
|
||||
appLogger.info('Login routing: $selectionLabel', tag: 'RepeaterLogin');
|
||||
bool? loginResult;
|
||||
bool isAdmin = false;
|
||||
for (int attempt = 0; attempt < _maxAttempts; attempt++) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
@@ -131,7 +132,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
);
|
||||
await _connector.sendFrame(loginFrame);
|
||||
|
||||
loginResult = await _awaitLoginResponse(timeout);
|
||||
(loginResult, isAdmin) = await _awaitLoginResponse(timeout);
|
||||
if (loginResult == true) {
|
||||
appLogger.info(
|
||||
'Login succeeded for ${repeater.name}',
|
||||
@@ -212,7 +213,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
|
||||
if (mounted) {
|
||||
Navigator.pop(context, password);
|
||||
Future.microtask(() => widget.onLogin(password));
|
||||
Future.microtask(() => widget.onLogin(password, isAdmin));
|
||||
}
|
||||
} catch (e) {
|
||||
final repeater = _resolveRepeater(_connector);
|
||||
@@ -229,17 +230,21 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool?> _awaitLoginResponse(Duration timeout) async {
|
||||
// _awaitLoginResponse returns a record of bool, for success and if the client is an admin
|
||||
Future<(bool?, bool)> _awaitLoginResponse(Duration timeout) async {
|
||||
final completer = Completer<bool?>();
|
||||
Timer? timer;
|
||||
StreamSubscription<Uint8List>? subscription;
|
||||
final targetPrefix = widget.repeater.publicKey.sublist(0, 6);
|
||||
|
||||
bool isAdmin = false;
|
||||
subscription = _connector.receivedFrames.listen((frame) {
|
||||
if (frame.isEmpty) return;
|
||||
final code = frame[0];
|
||||
if (code != pushCodeLoginSuccess && code != pushCodeLoginFail) return;
|
||||
if (frame.length < 8) return;
|
||||
// NOTE: a bug in the repeater firmware only ever sends 1 or 0 back, not the
|
||||
// expected client permissions
|
||||
isAdmin = (frame[1] == 1);
|
||||
final prefix = frame.sublist(2, 8);
|
||||
if (!listEquals(prefix, targetPrefix)) return;
|
||||
|
||||
@@ -258,7 +263,7 @@ class _RepeaterLoginDialogState extends State<RepeaterLoginDialog> {
|
||||
final result = await completer.future;
|
||||
timer.cancel();
|
||||
await subscription.cancel();
|
||||
return result;
|
||||
return (result, isAdmin);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -15,7 +15,7 @@ import 'path_management_dialog.dart';
|
||||
|
||||
class RoomLoginDialog extends StatefulWidget {
|
||||
final Contact room;
|
||||
final Function(String password) onLogin;
|
||||
final Function(String password, bool isAdmin) onLogin;
|
||||
|
||||
const RoomLoginDialog({super.key, required this.room, required this.onLogin});
|
||||
|
||||
@@ -115,6 +115,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
: '${selection.hopCount} hops';
|
||||
appLogger.info('Login routing: $selectionLabel', tag: 'RoomLogin');
|
||||
bool? loginResult;
|
||||
bool isAdmin = false;
|
||||
for (int attempt = 0; attempt < _maxAttempts; attempt++) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
@@ -127,7 +128,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
);
|
||||
await _connector.sendFrame(loginFrame);
|
||||
|
||||
loginResult = await _awaitLoginResponse(timeout);
|
||||
(loginResult, isAdmin) = await _awaitLoginResponse(timeout);
|
||||
if (loginResult == true) {
|
||||
appLogger.info('Login succeeded for ${room.name}', tag: 'RoomLogin');
|
||||
break;
|
||||
@@ -167,7 +168,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
|
||||
if (mounted) {
|
||||
Navigator.pop(context, password);
|
||||
Future.microtask(() => widget.onLogin(password));
|
||||
Future.microtask(() => widget.onLogin(password, isAdmin));
|
||||
}
|
||||
} catch (e) {
|
||||
final room = _resolveRepeater(_connector);
|
||||
@@ -185,16 +186,20 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool?> _awaitLoginResponse(Duration timeout) async {
|
||||
Future<(bool?, bool)> _awaitLoginResponse(Duration timeout) async {
|
||||
final completer = Completer<bool?>();
|
||||
Timer? timer;
|
||||
StreamSubscription<Uint8List>? subscription;
|
||||
final targetPrefix = widget.room.publicKey.sublist(0, 6);
|
||||
bool isAdmin = false;
|
||||
|
||||
subscription = _connector.receivedFrames.listen((frame) {
|
||||
if (frame.isEmpty) return;
|
||||
final code = frame[0];
|
||||
if (code != pushCodeLoginSuccess && code != pushCodeLoginFail) return;
|
||||
// NOTE: a bug in the repeater firmware only ever sends 1 or 0 back, not the
|
||||
// expected client permissions
|
||||
isAdmin = (frame[1] == 1);
|
||||
if (frame.length < 8) return;
|
||||
final prefix = frame.sublist(2, 8);
|
||||
if (!listEquals(prefix, targetPrefix)) return;
|
||||
@@ -214,7 +219,7 @@ class _RoomLoginDialogState extends State<RoomLoginDialog> {
|
||||
final result = await completer.future;
|
||||
timer.cancel();
|
||||
await subscription.cancel();
|
||||
return result;
|
||||
return (result, isAdmin);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user