Skip to content
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

Add option to enter the password for the live tracking MQTT broker #669

Merged
merged 1 commit into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions lib/ride/services/live_tracking.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LiveTracking {
Future<bool> _connectMQTTClient() async {
// Get the backend that is currently selected.
final settings = getIt<Settings>();
final backend = settings.city.selectedBackend(true);
final backend = settings.city.selectedBackend(false);
final clientId = "priobike-app-$appId";
try {
client = MqttServerClient(
Expand All @@ -81,7 +81,7 @@ class LiveTracking {
);
client!.logging(on: false);
client!.keepAlivePeriod = 30;
client!.secure = false;
client!.secure = true;
client!.port = backend.liveTrackingMQTTPort;
client!.autoReconnect = true;
client!.resubscribeOnAutoReconnect = true;
Expand All @@ -97,7 +97,9 @@ class LiveTracking {
.startClean()
.withWillQos(MqttQos.atMostOnce);
log.i("Connecting to live tracking MQTT broker.");
await client!.connect().timeout(const Duration(seconds: 5));
await client!
.connect(settings.city.selectedBackend(false).liveTrackingMQTTUsername, settings.liveTrackingMQTTPassword)
.timeout(const Duration(seconds: 5));

client!.connectionMessage = MqttConnectMessage()
.withClientIdentifier(client!.clientIdentifier)
Expand Down
11 changes: 11 additions & 0 deletions lib/settings/models/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,17 @@ extension LiveTracking on Backend {
return 20001;
}
}

String get liveTrackingMQTTUsername {
switch (this) {
case Backend.production:
return "priobike";
case Backend.staging:
return "priobike";
case Backend.release:
return "priobike";
}
}
}

extension Simulator on Backend {
Expand Down
26 changes: 26 additions & 0 deletions lib/settings/services/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class Settings with ChangeNotifier {
/// Enable live tracking mode for app.
bool enableLiveTrackingMode;

/// The password for the tracking MQTT broker.
String liveTrackingMQTTPassword;

/// If we want to show the speed with increased precision in the speedometer.
bool isIncreasedSpeedPrecisionInSpeedometerEnabled = false;

Expand Down Expand Up @@ -418,6 +421,23 @@ class Settings with ChangeNotifier {
notifyListeners();
}

static const liveTrackingMQTTPasswordKey = "priobike.settings.liveTrackingMQTTPassword";
static const defaultLiveTrackingMQTTPassword = "";

Future<bool> setLiveTrackingMQTTPassword(String liveTrackingMQTTPassword, [SharedPreferences? storage]) async {
storage ??= await SharedPreferences.getInstance();
final prev = this.liveTrackingMQTTPassword;
this.liveTrackingMQTTPassword = liveTrackingMQTTPassword;
final bool success = await storage.setString(liveTrackingMQTTPasswordKey, liveTrackingMQTTPassword);
if (!success) {
log.e("Failed to set liveTrackingMQTTPassword to $liveTrackingMQTTPassword");
this.liveTrackingMQTTPassword = prev;
} else {
notifyListeners();
}
return success;
}

static const didMigrateBackgroundImagesKey = "priobike.settings.didMigrateBackgroundImages";
static const defaultDidMigrateBackgroundImages = false;

Expand Down Expand Up @@ -494,6 +514,7 @@ class Settings with ChangeNotifier {
this.didMigrateBackgroundImages = defaultDidMigrateBackgroundImages,
this.enableSimulatorMode = defaultSimulatorMode,
this.enableLiveTrackingMode = defaultLiveTrackingMode,
this.liveTrackingMQTTPassword = defaultLiveTrackingMQTTPassword,
this.isIncreasedSpeedPrecisionInSpeedometerEnabled = defaultIsIncreasedSpeedPrecisionInSpeedometerEnabled,
this.speechRate = defaultSpeechRate,
});
Expand Down Expand Up @@ -537,6 +558,11 @@ class Settings with ChangeNotifier {
} catch (e) {
/* Do nothing and use the default value given by the constructor. */
}
try {
liveTrackingMQTTPassword = storage.getString(liveTrackingMQTTPasswordKey) ?? defaultLiveTrackingMQTTPassword;
} catch (e) {
/* Do nothing and use the default value given by the constructor. */
}
}

/// Load the stored settings.
Expand Down
81 changes: 81 additions & 0 deletions lib/settings/views/internal.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'dart:ui';

import 'package:flutter/material.dart' hide Shortcuts;
import 'package:priobike/common/fcm.dart';
import 'package:priobike/common/layout/annotated_region.dart';
import 'package:priobike/common/layout/buttons.dart';
import 'package:priobike/common/layout/dialog.dart';
import 'package:priobike/common/layout/modal.dart';
import 'package:priobike/common/layout/spacing.dart';
import 'package:priobike/common/layout/text.dart';
Expand Down Expand Up @@ -112,6 +115,76 @@ class InternalSettingsViewState extends State<InternalSettingsView> {
super.dispose();
}

/// Show a sheet to edit the current live tracking MQTT password.
void showEditLiveTrackingMQTTPasswordSheet(context) {
showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierColor: Colors.black.withOpacity(0.4),
transitionBuilder: (context, animation, secondaryAnimation, child) => BackdropFilter(
filter: ImageFilter.blur(sigmaX: 4 * animation.value, sigmaY: 4 * animation.value),
child: FadeTransition(
opacity: animation,
child: child,
),
),
pageBuilder: (BuildContext dialogContext, Animation<double> animation, Animation<double> secondaryAnimation) {
final passwordController = TextEditingController();
passwordController.text = settings.liveTrackingMQTTPassword;
return DialogLayout(
title: 'Live Tracking MQTT Passwort',
text: "Bitte gib ein Passwort ein.",
actions: [
TextField(
autofocus: false,
controller: passwordController,
maxLength: 20,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
fillColor: Theme.of(context).colorScheme.primary.withOpacity(0.1),
filled: true,
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderSide: BorderSide.none,
),
suffixIcon: SmallIconButtonTertiary(
icon: Icons.close,
onPressed: () {
passwordController.text = "";
},
color: Theme.of(context).colorScheme.onSurface,
fill: Colors.transparent,
// splash: Colors.transparent,
withBorder: false,
),
contentPadding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
counterStyle: TextStyle(
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
),
),
),
BigButtonPrimary(
label: "Speichern",
onPressed: () async {
final password = passwordController.text;
if (password.trim().isEmpty) {
getIt<Toast>().showError("Das Passwort darf nicht leer sein.");
return;
}
await settings.setLiveTrackingMQTTPassword(password);
getIt<Toast>().showSuccess("Passwort gespeichert!");
Navigator.pop(context);
},
boxConstraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width, minHeight: 36),
)
],
);
},
);
}

/// A callback that is executed when a sg labels mode is selected.
Future<void> onSelectSGLabelsMode(SGLabelsMode mode) async {
// Tell the settings service that we selected the new sg labels mode.
Expand Down Expand Up @@ -540,6 +613,14 @@ class InternalSettingsViewState extends State<InternalSettingsView> {
callback: () => settings.setLiveTrackingMode(!settings.enableLiveTrackingMode),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: SettingsElement(
title: "Live Tracking MQTT Passwort",
icon: Icons.password_rounded,
callback: () => showEditLiveTrackingMQTTPasswordSheet(context),
),
),
Padding(
padding: const EdgeInsets.only(top: 8),
child: SettingsElement(
Expand Down
Loading