diff --git a/lib/screens/common_widgets/auth/consts.dart b/lib/screens/common_widgets/auth/consts.dart index 9258471c..0670d642 100644 --- a/lib/screens/common_widgets/auth/consts.dart +++ b/lib/screens/common_widgets/auth/consts.dart @@ -1,4 +1,6 @@ const kEmpty = ''; + +// API Key Auth const kApiKeyHeaderName = 'x-api-key'; const kAddToLocations = [ ('header', 'Header'), @@ -12,11 +14,14 @@ const kHintTextFieldName = "Header/Query Param Name"; const kLabelApiKey = "API Key"; const kHintTextKey = "Key"; +// Username-password auth const kHintUsername = "Username"; const kHintPassword = "Password"; +// Bearer Token AUth const kHintToken = "Token"; +// Digest Auth const kInfoDigestUsername = "Your username for digest authentication. This will be sent to the server for credential verification."; const kInfoDigestPassword = @@ -35,3 +40,25 @@ const kInfoDigestQop = const kHintDataString = "Opaque"; const kInfoDigestDataString = "Server-specified data string that should be returned unchanged in the authorization header. Usually obtained from server's 401 response."; + +// JWT Auth +const kMsgAddToken = "Add JWT token to"; +const kTooltipTokenAddTo = "Select where to add JWT token"; +const kTextAlgo = "Algorithm"; +const kTooltipJWTAlgo = "Select JWT algorithm"; +const kStartAlgo = "HS"; +const kHintSecret = "Secret Key"; +const kInfoSecret = + "The secret key used to sign the JWT token. Keep this secure and match it with your server configuration."; +const kMsgSecret = "Secret is Base64 encoded"; +const kMsgPrivateKey = "Private Key"; +const kHintRSA = ''' +-----BEGIN RSA PRIVATE KEY----- +Private Key in PKCS#8 PEM Format +-----END RSA PRIVATE KEY----- +'''; +const kMsgPayload = "Payload (JSON format)"; +const kHintJson = + '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}'; +const kHeaderPrefix = 'Bearer'; +const kQueryParamKey = 'token'; diff --git a/lib/screens/common_widgets/auth/jwt_auth_fields.dart b/lib/screens/common_widgets/auth/jwt_auth_fields.dart index 1adfa6c5..146b3e3c 100644 --- a/lib/screens/common_widgets/auth/jwt_auth_fields.dart +++ b/lib/screens/common_widgets/auth/jwt_auth_fields.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:apidash_core/apidash_core.dart'; import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:apidash/widgets/widgets.dart'; +import 'consts.dart'; class JwtAuthFields extends StatefulWidget { final AuthModel? authData; @@ -34,8 +35,8 @@ class _JwtAuthFieldsState extends State { _secretController = TextEditingController(text: jwt?.secret ?? ''); _privateKeyController = TextEditingController(text: jwt?.privateKey ?? ''); _payloadController = TextEditingController(text: jwt?.payload ?? ''); - _addTokenTo = jwt?.addTokenTo ?? 'header'; - _algorithm = jwt?.algorithm ?? 'HS256'; + _addTokenTo = jwt?.addTokenTo ?? kAddToDefaultLocation; + _algorithm = jwt?.algorithm ?? kJwtAlgos[0]; _isSecretBase64Encoded = jwt?.isSecretBase64Encoded ?? false; } @@ -45,7 +46,7 @@ class _JwtAuthFieldsState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Add JWT token to", + kMsgAddToken, style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, @@ -53,13 +54,9 @@ class _JwtAuthFieldsState extends State { ), SizedBox(height: 4), ADPopupMenu( - value: - _addTokenTo == 'header' ? 'Request Header' : 'Query Parameters', - values: const [ - ('header', 'Request Header'), - ('query', 'Query Parameters'), - ], - tooltip: "Select where to add JWT token", + value: kAddToLocationsMap[_addTokenTo], + values: kAddToLocations, + tooltip: kTooltipTokenAddTo, isOutlined: true, onChanged: widget.readOnly ? null @@ -74,7 +71,7 @@ class _JwtAuthFieldsState extends State { ), const SizedBox(height: 16), Text( - "Algorithm", + kTextAlgo, style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, @@ -83,23 +80,8 @@ class _JwtAuthFieldsState extends State { SizedBox(height: 4), ADPopupMenu( value: _algorithm, - values: const [ - ('HS256', 'HS256'), - ('HS384', 'HS384'), - ('HS512', 'HS512'), - ('RS256', 'RS256'), - ('RS384', 'RS384'), - ('RS512', 'RS512'), - ('PS256', 'PS256'), - ('PS384', 'PS384'), - ('PS512', 'PS512'), - ('ES256', 'ES256'), - ('ES256K', 'ES256K'), - ('ES384', 'ES384'), - ('ES512', 'ES512'), - ('EdDSA', 'EdDSA'), - ], - tooltip: "Select JWT algorithm", + values: kJwtAlgos.map((i) => (i, null)), + tooltip: kTooltipJWTAlgo, isOutlined: true, onChanged: widget.readOnly ? null @@ -113,20 +95,19 @@ class _JwtAuthFieldsState extends State { }, ), const SizedBox(height: 16), - if (_algorithm.startsWith('HS')) ...[ + if (_algorithm.startsWith(kStartAlgo)) ...[ AuthTextField( readOnly: widget.readOnly, 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.", + hintText: kHintSecret, + infoText: kInfoSecret, onChanged: (value) => _updateJwtAuth(), ), const SizedBox(height: 16), CheckboxListTile( title: Text( - "Secret is Base64 encoded", + kMsgSecret, style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, @@ -145,7 +126,7 @@ class _JwtAuthFieldsState extends State { ), ] else ...[ Text( - "Private Key", + kMsgPrivateKey, style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, @@ -163,11 +144,7 @@ class _JwtAuthFieldsState extends State { maxWidth: MediaQuery.sizeOf(context).width - 100, ), contentPadding: const EdgeInsets.all(18), - hintText: ''' ------BEGIN RSA PRIVATE KEY----- -Private Key in PKCS#8 PEM Format ------END RSA PRIVATE KEY----- -''', + hintText: kHintRSA, hintStyle: Theme.of(context).textTheme.bodyMedium, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -188,7 +165,7 @@ Private Key in PKCS#8 PEM Format ], const SizedBox(height: 16), Text( - "Payload (JSON format)", + kMsgPayload, style: TextStyle( fontWeight: FontWeight.normal, fontSize: 14, @@ -206,8 +183,7 @@ Private Key in PKCS#8 PEM Format maxWidth: MediaQuery.sizeOf(context).width - 100, ), contentPadding: const EdgeInsets.all(18), - hintText: - '{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}', + hintText: kHintJson, hintStyle: Theme.of(context).textTheme.bodyMedium, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), @@ -230,21 +206,26 @@ Private Key in PKCS#8 PEM Format } void _updateJwtAuth() { + final jwt = AuthJwtModel( + secret: _secretController.text.trim(), + privateKey: _privateKeyController.text.trim(), + payload: _payloadController.text.trim(), + addTokenTo: _addTokenTo, + algorithm: _algorithm, + isSecretBase64Encoded: _isSecretBase64Encoded, + headerPrefix: kHeaderPrefix, + queryParamKey: kQueryParamKey, + header: '', + ); widget.updateAuth( widget.authData?.copyWith( - type: APIAuthType.jwt, - jwt: AuthJwtModel( - secret: _secretController.text.trim(), - privateKey: _privateKeyController.text.trim(), - payload: _payloadController.text.trim(), - addTokenTo: _addTokenTo, - algorithm: _algorithm, - isSecretBase64Encoded: _isSecretBase64Encoded, - headerPrefix: 'Bearer', - queryParamKey: 'token', - header: '', - ), - ), + type: APIAuthType.jwt, + jwt: jwt, + ) ?? + AuthModel( + type: APIAuthType.jwt, + jwt: jwt, + ), ); } } diff --git a/packages/better_networking/lib/consts.dart b/packages/better_networking/lib/consts.dart index 5d1819be..778dba2d 100644 --- a/packages/better_networking/lib/consts.dart +++ b/packages/better_networking/lib/consts.dart @@ -26,6 +26,23 @@ enum APIAuthType { const kDigestAlgos = ['MD5', 'MD5-sess', 'SHA-256', 'SHA-256-sess']; const kQop = ['auth', 'auth-int']; +const kJwtAlgos = [ + 'HS256', + 'HS384', + 'HS512', + 'RS256', + 'RS384', + 'RS512', + 'PS256', + 'PS384', + 'PS512', + 'ES256', + 'ES256K', + 'ES384', + 'ES512', + 'EdDSA', +]; + enum HTTPVerb { get("GET"), head("HEAD"),