diff --git a/lib/screens/common_widgets/auth/api_key_auth_fields.dart b/lib/screens/common_widgets/auth/api_key_auth_fields.dart index 8fd272c9..1bf5a3e7 100644 --- a/lib/screens/common_widgets/auth/api_key_auth_fields.dart +++ b/lib/screens/common_widgets/auth/api_key_auth_fields.dart @@ -75,7 +75,8 @@ class _ApiKeyAuthFieldsState extends State { AuthTextField( readOnly: widget.readOnly, controller: _keyController, - hintText: "API Key", + title: "API Key", + hintText: "Key", isObscureText: true, onChanged: (value) => _updateApiKeyAuth(), ), @@ -84,22 +85,21 @@ class _ApiKeyAuthFieldsState extends State { } void _updateApiKeyAuth() { - widget.updateAuth( - widget.authData?.copyWith( - type: APIAuthType.apiKey, - apikey: AuthApiKeyModel( - key: _keyController.text.trim(), - name: _nameController.text.trim(), - location: _addKeyTo, - ), - ) ?? AuthModel( + widget.updateAuth(widget.authData?.copyWith( type: APIAuthType.apiKey, apikey: AuthApiKeyModel( key: _keyController.text.trim(), name: _nameController.text.trim(), location: _addKeyTo, ), - ) - ); + ) ?? + AuthModel( + type: APIAuthType.apiKey, + apikey: AuthApiKeyModel( + key: _keyController.text.trim(), + name: _nameController.text.trim(), + location: _addKeyTo, + ), + )); } } diff --git a/lib/screens/common_widgets/auth/digest_auth_fields.dart b/lib/screens/common_widgets/auth/digest_auth_fields.dart index 859f3cec..aa31efa4 100644 --- a/lib/screens/common_widgets/auth/digest_auth_fields.dart +++ b/lib/screens/common_widgets/auth/digest_auth_fields.dart @@ -51,6 +51,8 @@ class _DigestAuthFieldsState extends State { readOnly: widget.readOnly, controller: _usernameController, hintText: "Username", + infoText: + "Your username for digest authentication. This will be sent to the server for credential verification.", onChanged: (_) => _updateDigestAuth(), ), const SizedBox(height: 12), @@ -59,6 +61,8 @@ class _DigestAuthFieldsState extends State { controller: _passwordController, hintText: "Password", isObscureText: true, + infoText: + "Your password for digest authentication. This is hashed and not sent in plain text to the server.", onChanged: (_) => _updateDigestAuth(), ), const SizedBox(height: 12), @@ -66,6 +70,8 @@ class _DigestAuthFieldsState extends State { readOnly: widget.readOnly, controller: _realmController, hintText: "Realm", + infoText: + "Authentication realm as specified by the server. This defines the protection space for the credentials.", onChanged: (_) => _updateDigestAuth(), ), const SizedBox(height: 12), @@ -73,6 +79,8 @@ class _DigestAuthFieldsState extends State { readOnly: widget.readOnly, controller: _nonceController, hintText: "Nonce", + infoText: + "Server-generated random value used to prevent replay attacks.", onChanged: (_) => _updateDigestAuth(), ), const SizedBox(height: 12), @@ -92,7 +100,7 @@ class _DigestAuthFieldsState extends State { ('SHA-256', 'SHA-256'), ('SHA-256-sess', 'SHA-256-sess'), ], - tooltip: "this algorithm will be used to produce the digest", + tooltip: "Algorithm that will be used to produce the digest", isOutlined: true, onChanged: (String? newLocation) { if (newLocation != null) { @@ -107,7 +115,9 @@ class _DigestAuthFieldsState extends State { AuthTextField( readOnly: widget.readOnly, controller: _qopController, - hintText: "QOP (e.g. auth)", + hintText: "QOP", + infoText: + "Quality of Protection. Typically 'auth' for authentication only, or 'auth-int' for authentication with integrity protection.", onChanged: (_) => _updateDigestAuth(), ), const SizedBox(height: 12), @@ -115,6 +125,8 @@ class _DigestAuthFieldsState extends State { readOnly: widget.readOnly, controller: _opaqueController, hintText: "Opaque", + infoText: + "Server-specified data string that should be returned unchanged in the authorization header. Usually obtained from server's 401 response.", onChanged: (_) => _updateDigestAuth(), ), ], diff --git a/lib/screens/common_widgets/auth/jwt_auth_fields.dart b/lib/screens/common_widgets/auth/jwt_auth_fields.dart index 44f97c98..2982ab07 100644 --- a/lib/screens/common_widgets/auth/jwt_auth_fields.dart +++ b/lib/screens/common_widgets/auth/jwt_auth_fields.dart @@ -115,6 +115,8 @@ class _JwtAuthFieldsState extends State { controller: _secretController, isObscureText: true, hintText: "Secret key", + infoText: + "The secret key used to sign the JWT token. Keep this secure and match it with your server configuration.", onChanged: (value) => _updateJwtAuth(), ), const SizedBox(height: 16), @@ -139,7 +141,7 @@ class _JwtAuthFieldsState extends State { ), ] else ...[ Text( - "Private Key (PEM Format)", + "Private Key", style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, diff --git a/lib/screens/common_widgets/auth_textfield.dart b/lib/screens/common_widgets/auth_textfield.dart index 28610c9b..754a5d81 100644 --- a/lib/screens/common_widgets/auth_textfield.dart +++ b/lib/screens/common_widgets/auth_textfield.dart @@ -4,19 +4,22 @@ import 'package:flutter/material.dart'; class AuthTextField extends StatefulWidget { final String hintText; + final String? title; final TextEditingController controller; final bool isObscureText; final Function(String)? onChanged; final bool readOnly; + final String? infoText; - const AuthTextField({ - super.key, - required this.hintText, - required this.controller, - required this.onChanged, - this.readOnly = false, - this.isObscureText = false, - }); + const AuthTextField( + {super.key, + this.title, + required this.hintText, + required this.controller, + required this.onChanged, + this.readOnly = false, + this.isObscureText = false, + this.infoText}); @override State createState() => _AuthFieldState(); @@ -44,12 +47,25 @@ class _AuthFieldState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - widget.hintText, - style: TextStyle( - fontWeight: FontWeight.normal, - fontSize: 14, - ), + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text(widget.title ?? widget.hintText), + if (widget.infoText != null) + Tooltip( + message: widget.infoText!, + triggerMode: TooltipTriggerMode.tap, + showDuration: Duration(seconds: 5), + child: Padding( + padding: const EdgeInsets.only(left: 4.0), + child: Icon( + Icons.help_outline_rounded, + color: Theme.of(context).colorScheme.secondary, + size: 18, + ), + ), + ), + ], ), const SizedBox(height: 6), TextFormField(