server delete functionality and minor cleanups
continuous-integration/drone/pr Build is running Details

This commit is contained in:
Dan Ballard 2021-11-03 18:56:53 -07:00
parent 07b00ee1d0
commit 87f7c2c29b
15 changed files with 202 additions and 44 deletions

View File

@ -1 +1 @@
v1.3.1-23-gb47b270-2021-11-03-19-29 v1.3.1-25-g4adb501-2021-11-04-04-20

View File

@ -104,6 +104,12 @@ class CwtchNotifier {
// todo standarize // todo standarize
error.handleUpdate("deleteprofile.success"); error.handleUpdate("deleteprofile.success");
break; break;
case "ServerDeleted":
error.handleUpdate("deletedserver." + data["Status"]);
if (data["Status"] == "success") {
serverListState.delete(data["Identity"]);
}
break;
case "DeleteContact": case "DeleteContact":
profileCN.getProfile(data["ProfileOnion"])?.contactList.removeContact(data["RemotePeer"]); profileCN.getProfile(data["ProfileOnion"])?.contactList.removeContact(data["RemotePeer"]);
break; break;

View File

@ -21,6 +21,27 @@ class ErrorHandler extends ChangeNotifier {
bool deleteProfileError = false; bool deleteProfileError = false;
bool deleteProfileSuccess = false; bool deleteProfileSuccess = false;
static const String deletedServerErrorPrefix = "deletedserver";
bool deletedServerError = false;
bool deletedServerSuccess = false;
reset() {
invalidImportStringError = false;
contactAlreadyExistsError = false;
explicitAddContactSuccess = false;
importBundleError = false;
importBundleSuccess = false;
deleteProfileError = false;
deleteProfileSuccess = false;
deletedServerError = false;
deletedServerSuccess = false;
notifyListeners();
}
/// Called by the event bus. /// Called by the event bus.
handleUpdate(String error) { handleUpdate(String error) {
var parts = error.split("."); var parts = error.split(".");
@ -37,6 +58,8 @@ class ErrorHandler extends ChangeNotifier {
case deleteProfileErrorPrefix: case deleteProfileErrorPrefix:
handleDeleteProfileError(errorType); handleDeleteProfileError(errorType);
break; break;
case deletedServerErrorPrefix:
handleDeletedServerError(errorType);
} }
notifyListeners(); notifyListeners();
@ -91,4 +114,19 @@ class ErrorHandler extends ChangeNotifier {
break; break;
} }
} }
handleDeletedServerError(String errorType) {
// reset
deletedServerError = false;
deletedServerSuccess = false;
switch (errorType) {
case successErrorType:
deletedServerSuccess = true;
break;
default:
deletedServerError = true;
break;
}
}
} }

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "de", "@@locale": "de",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "en", "@@locale": "en",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "es", "@@locale": "es",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -1,25 +1,30 @@
{ {
"@@locale": "fr", "@@locale": "fr",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"copyAddress": "Copy Address", "plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"settingServers": "Hosting Servers", "deleteServerConfirmBtn": "Really delete server",
"enterServerPassword": "Enter password to unlock server", "deleteServerSuccess": "Successfully deleted server",
"unlockProfileTip": "Please create or unlock a profile to begin!", "enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"unlockServerTip": "Please create or unlock a server to begin!", "copyAddress": "Copier l'adresse",
"addServerTooltip": "Add new server", "settingServersDescription": "L'expérience des serveurs d'hébergement permet d'héberger et de gérer les serveurs Cwtch.",
"serversManagerTitleShort": "Servers", "settingServers": "Serveurs d'hébergement",
"serversManagerTitleLong": "Servers You Host", "enterServerPassword": "Entrez le mot de passe pour déverrouiller le serveur",
"saveServerButton": "Save Server", "unlockProfileTip": "Veuillez créer ou déverrouiller un profil pour commencer !",
"serverAutostartDescription": "Controls if the application will automatically launch the server on start", "unlockServerTip": "Veuillez créer ou déverrouiller un serveur pour commencer !",
"serverAutostartLabel": "Autostart", "addServerTooltip": "Ajouter un nouveau serveur",
"serverEnabledDescription": "Start or stop the server", "serversManagerTitleShort": "Serveurs",
"serverEnabled": "Server Enabled", "serversManagerTitleLong": "Serveurs que vous hébergez",
"serverDescriptionDescription": "Your description of the server for personal management use only, will never be shared", "saveServerButton": "Enregistrer le serveur",
"serverDescriptionLabel": "Server Description", "serverAutostartDescription": "Contrôle si l'application lance automatiquement le serveur au démarrage.",
"serverAddress": "Server Address", "serverAutostartLabel": "Démarrage automatique",
"editServerTitle": "Edit Server", "serverEnabledDescription": "Démarrer ou arrêter le serveur",
"addServerTitle": "Add Server", "serverEnabled": "Serveur activé",
"serverDescriptionDescription": "Votre description du serveur est à des fins de gestion personnelle uniquement, elle ne sera jamais partagée.",
"serverDescriptionLabel": "Description du serveur",
"serverAddress": "Adresse du serveur",
"editServerTitle": "Modifier le serveur",
"addServerTitle": "Ajouter un serveur",
"titleManageProfilesShort": "Profils", "titleManageProfilesShort": "Profils",
"descriptionStreamerMode": "Si elle est activée, cette option donne un rendu visuel plus privé à l'application pour la diffusion en direct ou la présentation, par exemple, en masquant profil et adresses de contacts.", "descriptionStreamerMode": "Si elle est activée, cette option donne un rendu visuel plus privé à l'application pour la diffusion en direct ou la présentation, par exemple, en masquant profil et adresses de contacts.",
"descriptionFileSharing": "L'expérience de partage de fichiers vous permet d'envoyer et de recevoir des fichiers à partir de contacts et de groupes Cwtch. Notez que si vous partagez un fichier avec un groupe, les membres de ce groupe se connecteront avec vous directement via Cwtch pour le télécharger.", "descriptionFileSharing": "L'expérience de partage de fichiers vous permet d'envoyer et de recevoir des fichiers à partir de contacts et de groupes Cwtch. Notez que si vous partagez un fichier avec un groupe, les membres de ce groupe se connecteront avec vous directement via Cwtch pour le télécharger.",

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "it", "@@locale": "it",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "pl", "@@locale": "pl",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -1,6 +1,11 @@
{ {
"@@locale": "pt", "@@locale": "pt",
"@@last_modified": "2021-11-02T23:03:43+01:00", "@@last_modified": "2021-11-04T02:39:11+01:00",
"plainServerDescription": "We recommend that you protect your Cwtch servers with a password. If you do not set a password on this server then anyone who has access to this device may be able to access information about this server, including sensitive cryptographic keys.",
"encryptedServerDescription": "Encrypting a server with a password protects it from other people who may also use this device. Encrypted servers cannot be decrypted, displayed or accessed until the correct password is entered to unlock them.",
"deleteServerConfirmBtn": "Really delete server",
"deleteServerSuccess": "Successfully deleted server",
"enterCurrentPasswordForDeleteServer": "Please enter current password to delete this server",
"copyAddress": "Copy Address", "copyAddress": "Copy Address",
"settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers", "settingServersDescription": "The hosting servers experiment enables hosting and managing Cwtch servers",
"settingServers": "Hosting Servers", "settingServers": "Hosting Servers",

View File

@ -34,6 +34,11 @@ class ServerListState extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void delete(String onion) {
_servers.removeWhere((element) => element.onion == onion);
notifyListeners();
}
List<ServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier List<ServerInfoState> get servers => _servers.sublist(0); //todo: copy?? dont want caller able to bypass changenotifier
} }

View File

@ -164,6 +164,7 @@ class _AddEditServerViewState extends State<AddEditServerView> {
// ***** Password ***** // ***** Password *****
// use password toggle
Visibility( Visibility(
visible: serverInfoState.onion.isEmpty, visible: serverInfoState.onion.isEmpty,
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
@ -186,20 +187,19 @@ class _AddEditServerViewState extends State<AddEditServerView> {
Padding( Padding(
padding: EdgeInsets.symmetric(horizontal: 24), padding: EdgeInsets.symmetric(horizontal: 24),
child: Text( child: Text(
usePassword ? AppLocalizations.of(context)!.encryptedProfileDescription : AppLocalizations.of(context)!.plainProfileDescription, usePassword ? AppLocalizations.of(context)!.encryptedServerDescription : AppLocalizations.of(context)!.plainServerDescription,
textAlign: TextAlign.center, textAlign: TextAlign.center,
)) )),
SizedBox(
height: 20,
),
])), ])),
SizedBox(
height: 20,
), // current password
Visibility( Visibility(
// Currently we don't support password change for servers so also gate this on Add server, when ready to support changing password remove the onion.isEmpty check visible: serverInfoState.onion.isNotEmpty && serverInfoState.isEncrypted,
visible: serverInfoState.onion.isEmpty && usePassword, child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[
Visibility(
visible: serverInfoState.onion.isNotEmpty && serverInfoState.isEncrypted,
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
CwtchLabel(label: AppLocalizations.of(context)!.currentPasswordLabel), CwtchLabel(label: AppLocalizations.of(context)!.currentPasswordLabel),
SizedBox( SizedBox(
height: 20, height: 20,
@ -215,8 +215,8 @@ class _AddEditServerViewState extends State<AddEditServerView> {
usePassword) { usePassword) {
return AppLocalizations.of(context)!.passwordErrorEmpty; return AppLocalizations.of(context)!.passwordErrorEmpty;
} }
if (Provider.of<ErrorHandler>(context).deleteProfileError == true) { if (Provider.of<ErrorHandler>(context).deletedServerError == true) {
return AppLocalizations.of(context)!.enterCurrentPasswordForDelete; return AppLocalizations.of(context)!.enterCurrentPasswordForDeleteServer;
} }
return null; return null;
}, },
@ -225,6 +225,12 @@ class _AddEditServerViewState extends State<AddEditServerView> {
height: 20, height: 20,
), ),
])), ])),
// new passwords 1 & 2
Visibility(
// Currently we don't support password change for servers so also gate this on Add server, when ready to support changing password remove the onion.isEmpty check
visible: serverInfoState.onion.isEmpty && usePassword,
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
CwtchLabel(label: AppLocalizations.of(context)!.newPassword), CwtchLabel(label: AppLocalizations.of(context)!.newPassword),
SizedBox( SizedBox(
height: 20, height: 20,
@ -263,6 +269,7 @@ class _AddEditServerViewState extends State<AddEditServerView> {
}), }),
]), ]),
), ),
SizedBox( SizedBox(
height: 20, height: 20,
), ),
@ -281,13 +288,25 @@ class _AddEditServerViewState extends State<AddEditServerView> {
), ),
], ],
), ),
Visibility(
visible: serverInfoState.onion.isNotEmpty,
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [
SizedBox(
height: 20,
),
Tooltip(
message: AppLocalizations.of(context)!.enterCurrentPasswordForDeleteServer,
child: ElevatedButton.icon(
onPressed: () {
showAlertDialog(context);
},
icon: Icon(Icons.delete_forever),
label: Text(AppLocalizations.of(context)!.deleteBtn),
))
]))
// ***** END Password ***** // ***** END Password *****
])))))); ]))))));
}); });
}); });
@ -327,4 +346,53 @@ class _AddEditServerViewState extends State<AddEditServerView> {
} }
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = ElevatedButton(
child: Text(AppLocalizations.of(context)!.cancel),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
},
);
Widget continueButton = ElevatedButton(
child: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn),
onPressed: () {
var onion = Provider
.of<ServerInfoState>(context, listen: false)
.onion;
Provider
.of<FlwtchState>(context, listen: false)
.cwtch
.DeleteServer(onion, Provider.of<ServerInfoState>(context, listen: false).isEncrypted ? ctrlrOldPass.value.text : DefaultPassword);
Future.delayed(
const Duration(milliseconds: 500),
() {
if (globalErrorHandler.deletedServerSuccess) {
final snackBar = SnackBar(content: Text(AppLocalizations.of(context)!.deleteServerSuccess + ":" + onion));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Navigator.of(context).popUntil((route) => route.settings.name == "servers"); // dismiss dialog
} else {
Navigator.of(context).pop();
}
},
);
});
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(AppLocalizations.of(context)!.deleteServerConfirmBtn),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
} }

View File

@ -129,6 +129,7 @@ class _ProfileMgrViewState extends State<ProfileMgrView> {
void _pushServers() { void _pushServers() {
Navigator.of(context).push(MaterialPageRoute<void>( Navigator.of(context).push(MaterialPageRoute<void>(
settings: RouteSettings(name: "servers"),
builder: (BuildContext context) { builder: (BuildContext context) {
return MultiProvider( return MultiProvider(
providers: [Provider.value(value: Provider.of<FlwtchState>(context))], providers: [Provider.value(value: Provider.of<FlwtchState>(context))],

View File

@ -7,6 +7,7 @@ import 'package:cwtch/widgets/profileimage.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../errorHandler.dart';
import '../main.dart'; import '../main.dart';
import '../model.dart'; import '../model.dart';
import '../settings.dart'; import '../settings.dart';
@ -101,6 +102,7 @@ class _ProfileRowState extends State<ProfileRow> {
} }
void _pushEditProfile({onion: "", displayName: "", profileImage: "", encrypted: true}) { void _pushEditProfile({onion: "", displayName: "", profileImage: "", encrypted: true}) {
Provider.of<ErrorHandler>(context).reset();
Navigator.of(context).push(MaterialPageRoute<void>( Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) { builder: (BuildContext context) {
return MultiProvider( return MultiProvider(

View File

@ -8,6 +8,7 @@ import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../cwtch_icons_icons.dart'; import '../cwtch_icons_icons.dart';
import '../errorHandler.dart';
import '../model.dart'; import '../model.dart';
import '../settings.dart'; import '../settings.dart';
@ -80,7 +81,9 @@ class _ServerRowState extends State<ServerRow> {
} }
void _pushEditServer(ServerInfoState server ) { void _pushEditServer(ServerInfoState server ) {
Provider.of<ErrorHandler>(context).reset();
Navigator.of(context).push(MaterialPageRoute<void>( Navigator.of(context).push(MaterialPageRoute<void>(
settings: RouteSettings(name: "serveraddedit"),
builder: (BuildContext context) { builder: (BuildContext context) {
return MultiProvider( return MultiProvider(
providers: [ChangeNotifierProvider<ServerInfoState>( providers: [ChangeNotifierProvider<ServerInfoState>(