prompt password
Some checks are pending
BlockStorage/repertory/pipeline/head Build queued...

This commit is contained in:
Scott E. Graves 2025-03-20 17:33:32 -05:00
parent 1b6237b9fc
commit b72744716d
3 changed files with 67 additions and 17 deletions

View File

@ -8,6 +8,10 @@ import 'package:sodium_libs/sodium_libs.dart';
typedef Validator = bool Function(String); typedef Validator = bool Function(String);
class NullPasswordException implements Exception {
String error() => 'password cannot be null';
}
// ignore: prefer_function_declarations_over_variables // ignore: prefer_function_declarations_over_variables
final Validator noRestrictedChars = (value) { final Validator noRestrictedChars = (value) {
return [ return [
@ -226,8 +230,13 @@ bool validateSettings(
return failed.isEmpty; return failed.isEmpty;
} }
Map<String, dynamic> convertAllToString(Map<String, dynamic> settings) { Future<Map<String, dynamic>> convertAllToString(
final password = 'test'; Map<String, dynamic> settings,
) async {
final password = await promptPassword();
if (password == null) {
throw NullPasswordException();
}
settings.forEach((key, value) { settings.forEach((key, value) {
if (value is Map<String, dynamic>) { if (value is Map<String, dynamic>) {
@ -260,11 +269,9 @@ String encryptValue(String value, String password) {
message: Uint8List.fromList(password.toCharArray()), message: Uint8List.fromList(password.toCharArray()),
); );
debugPrint("key: ${base64Encode(keyHash)}");
final crypto = sodium.crypto.aeadXChaCha20Poly1305IETF; final crypto = sodium.crypto.aeadXChaCha20Poly1305IETF;
final nonce = sodium.secureRandom(crypto.nonceBytes).extractBytes(); final nonce = sodium.secureRandom(crypto.nonceBytes).extractBytes();
debugPrint("nonce: ${base64Encode(nonce)}");
final data = crypto.encrypt( final data = crypto.encrypt(
additionalData: Uint8List.fromList('repertory'.toCharArray()), additionalData: Uint8List.fromList('repertory'.toCharArray()),
key: SecureKey.fromList(sodium, keyHash), key: SecureKey.fromList(sodium, keyHash),
@ -274,3 +281,42 @@ String encryptValue(String value, String password) {
return base64Encode(Uint8List.fromList([...nonce, ...data])); return base64Encode(Uint8List.fromList([...nonce, ...data]));
} }
Future<String?> promptPassword() async {
if (constants.navigatorKey.currentContext == null) {
return null;
}
String updatedValue1 = '';
return await showDialog(
context: constants.navigatorKey.currentContext!,
builder: (context) {
return AlertDialog(
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () => Navigator.of(context).pop(null),
),
TextButton(
child: const Text('OK'),
onPressed: () {
if (updatedValue1.isEmpty) {
return displayErrorMessage(context, "Password is not valid");
}
Navigator.of(context).pop(updatedValue1);
},
),
],
content: TextField(
autofocus: true,
controller: TextEditingController(text: updatedValue1),
obscureText: true,
obscuringCharacter: '*',
onChanged: (value) => updatedValue1 = value,
),
title: const Text('Enter Authentication Password'),
);
},
);
}

View File

@ -94,10 +94,11 @@ class MountList with ChangeNotifier {
Map<String, dynamic> mountConfig, Map<String, dynamic> mountConfig,
) async { ) async {
try { try {
final map = await convertAllToString(mountConfig);
await http.post( await http.post(
Uri.parse( Uri.parse(
Uri.encodeFull( Uri.encodeFull(
'${getBaseUri()}/api/v1/add_mount?name=$name&type=$type&config=${jsonEncode(convertAllToString(mountConfig))}', '${getBaseUri()}/api/v1/add_mount?name=$name&type=$type&config=${jsonEncode(map)}',
), ),
), ),
); );

View File

@ -1,4 +1,4 @@
import 'dart:convert' show jsonDecode, jsonEncode; import 'dart:convert' show jsonEncode;
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -100,21 +100,24 @@ class _UISettingsWidgetState extends State<UISettingsWidget> {
@override @override
void dispose() { void dispose() {
debugPrint('current: ${jsonEncode(widget.settings)}');
debugPrint('orig: ${jsonEncode(widget.origSettings)}');
if (!DeepCollectionEquality().equals( if (!DeepCollectionEquality().equals(
widget.settings, widget.settings,
widget.origSettings, widget.origSettings,
)) { )) {
http convertAllToString(widget.settings)
.put( .then((map) async {
Uri.parse( try {
Uri.encodeFull( await http.put(
'${getBaseUri()}/api/v1/settings?data=${jsonEncode(convertAllToString(widget.settings))}', Uri.parse(
), Uri.encodeFull(
), '${getBaseUri()}/api/v1/settings?data=${jsonEncode(map)}',
) ),
.then((_) {}) ),
);
} catch (e) {
debugPrint('$e');
}
})
.catchError((e) { .catchError((e) {
debugPrint('$e'); debugPrint('$e');
}); });