import 'package:flutter/material.dart'; import 'package:outbag_app/backend/crypto.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:outbag_app/tools/snackbar.dart'; import 'package:provider/provider.dart'; class ChangePasswordDialog extends StatefulWidget { const ChangePasswordDialog({super.key}); @override State createState() => _ChangePasswordDialogState(); } class _ChangePasswordDialogState extends State { final TextEditingController _ctrOldPassword = TextEditingController(); final TextEditingController _ctrNewPassword = TextEditingController(); final TextEditingController _ctrNewPasswordRepeat = TextEditingController(); @override Widget build(BuildContext context) { return AlertDialog( title: const Text('Change Password'), icon: const Icon(Icons.password), content: SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.all(8), child: TextField( controller: _ctrOldPassword, keyboardType: TextInputType.visiblePassword, obscureText: true, decoration: const InputDecoration( prefixIcon: Icon(Icons.lock), labelText: 'Old Password', hintText: 'Your current password', helperText: 'For safety, you have to type your current passwort', border: OutlineInputBorder(), ), ), ), Padding( padding: const EdgeInsets.all(8), child: TextField( controller: _ctrNewPassword, keyboardType: TextInputType.visiblePassword, obscureText: true, decoration: const InputDecoration( prefixIcon: Icon(Icons.lock), labelText: 'New Password', hintText: 'Your new password', helperText: 'Password have to be at least six characters long', border: OutlineInputBorder(), ), ), ), Padding( padding: const EdgeInsets.all(8), child: TextField( controller: _ctrNewPasswordRepeat, keyboardType: TextInputType.visiblePassword, obscureText: true, decoration: const InputDecoration( prefixIcon: Icon(Icons.lock), labelText: 'Repeat new Password', hintText: 'Type your new password again', helperText: 'Type your new password again, to make sure you know it', border: OutlineInputBorder(), ), ), ), ], )), actions: [ TextButton( onPressed: () { // close popup Navigator.of(context).pop(); }, child: const Text('Cancel'), ), FilledButton( onPressed: () async { final scaffMgr = ScaffoldMessenger.of(context); final nav = Navigator.of(context); final user = context.read(); // validate password if (_ctrNewPassword.text.length < 6) { // password has to be at least 6 characters long showSimpleSnackbar(scaffMgr, text: 'Password has to be at least 6 characters longs', action: 'Dismiss'); _ctrNewPasswordRepeat.clear(); return; } if (_ctrNewPassword.text != _ctrNewPasswordRepeat.text) { // new passwords do not match showSimpleSnackbar(scaffMgr, text: 'New passwords do not match', action: 'Dismiss'); _ctrNewPasswordRepeat.clear(); return; } if (hashPassword(_ctrOldPassword.text) != user.password) { // current password wrong showSimpleSnackbar(scaffMgr, text: 'Old password is wrong', action: 'Dismiss'); _ctrOldPassword.clear(); return; } final password = hashPassword(_ctrNewPassword.text); // send request doNetworkRequest(scaffMgr, req: () => postWithCreadentials( path: 'changePassword', target: user.server, body: {'accountKey': password}, credentials: user), onOK: (_) async { // update local user struct final updatedUser = User( username: user.username, password: password, server: user.server); await updatedUser.toDisk(); }, after: () { // close popup nav.pop(); }); }, child: const Text('Change password'), ) ], ); } }