mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
feat: add hints and info texts
This commit is contained in:
@@ -63,6 +63,82 @@ const kHintJson =
|
||||
const kHeaderPrefix = 'Bearer';
|
||||
const kQueryParamKey = 'token';
|
||||
|
||||
// OAuth1 Auth
|
||||
const kHintOAuth1ConsumerKey = "Consumer Key";
|
||||
const kInfoOAuth1ConsumerKey =
|
||||
"The consumer key provided by the service provider to identify your application.";
|
||||
const kHintOAuth1ConsumerSecret = "Consumer Secret";
|
||||
const kInfoOAuth1ConsumerSecret =
|
||||
"The consumer secret provided by the service provider. Keep this secure and never expose it publicly.";
|
||||
const kHintOAuth1AccessToken = "Access Token";
|
||||
const kInfoOAuth1AccessToken =
|
||||
"The access token obtained after user authorization. This represents the user's permission to access their data.";
|
||||
const kHintOAuth1TokenSecret = "Token Secret";
|
||||
const kInfoOAuth1TokenSecret =
|
||||
"The token secret associated with the access token. Used to sign requests along with the consumer secret.";
|
||||
const kHintOAuth1CallbackUrl = "Callback URL";
|
||||
const kInfoOAuth1CallbackUrl =
|
||||
"The URL where the user will be redirected after authorization. Must match the URL registered with the service provider.";
|
||||
const kHintOAuth1Verifier = "Verifier";
|
||||
const kInfoOAuth1Verifier =
|
||||
"The verification code received after user authorization. Used to exchange the request token for an access token.";
|
||||
const kHintOAuth1Timestamp = "Timestamp";
|
||||
const kInfoOAuth1Timestamp =
|
||||
"Unix timestamp when the request is made. Usually generated automatically to prevent replay attacks.";
|
||||
const kHintOAuth1Nonce = "Nonce";
|
||||
const kInfoOAuth1Nonce =
|
||||
"A unique random string for each request. Helps prevent replay attacks and ensures request uniqueness.";
|
||||
const kHintOAuth1Realm = "Realm";
|
||||
const kInfoOAuth1Realm =
|
||||
"Optional realm parameter that defines the protection space. Some services require this for proper authentication.";
|
||||
const kLabelOAuth1SignatureMethod = "Signature Method";
|
||||
const kTooltipOAuth1SignatureMethod =
|
||||
"Select the signature method for OAuth 1.0 authentication";
|
||||
|
||||
// OAuth2 Auth
|
||||
const kLabelOAuth2GrantType = "Grant Type";
|
||||
const kTooltipOAuth2GrantType = "Select OAuth 2.0 grant type";
|
||||
const kHintOAuth2AuthorizationUrl = "Authorization URL";
|
||||
const kInfoOAuth2AuthorizationUrl =
|
||||
"The authorization endpoint URL where users are redirected to grant permission to your application.";
|
||||
const kHintOAuth2AccessTokenUrl = "Access Token URL";
|
||||
const kInfoOAuth2AccessTokenUrl =
|
||||
"The token endpoint URL where authorization codes are exchanged for access tokens.";
|
||||
const kHintOAuth2ClientId = "Client ID";
|
||||
const kInfoOAuth2ClientId =
|
||||
"The client identifier issued to your application by the authorization server.";
|
||||
const kHintOAuth2ClientSecret = "Client Secret";
|
||||
const kInfoOAuth2ClientSecret =
|
||||
"The client secret issued to your application. Keep this secure and never expose it publicly.";
|
||||
const kHintOAuth2RedirectUrl = "Redirect URL";
|
||||
const kInfoOAuth2RedirectUrl =
|
||||
"The URL where users are redirected after authorization. Must match the URL registered with the service.";
|
||||
const kHintOAuth2Scope = "Scope";
|
||||
const kInfoOAuth2Scope =
|
||||
"Space-separated list of permissions your application is requesting access to.";
|
||||
const kHintOAuth2State = "State";
|
||||
const kInfoOAuth2State =
|
||||
"An unguessable random string used to protect against cross-site request forgery attacks.";
|
||||
const kHintOAuth2Username = "Username";
|
||||
const kInfoOAuth2Username =
|
||||
"Your username for resource owner password credentials grant type.";
|
||||
const kHintOAuth2Password = "Password";
|
||||
const kInfoOAuth2Password =
|
||||
"Your password for resource owner password credentials grant type.";
|
||||
const kHintOAuth2RefreshToken = "Refresh Token";
|
||||
const kInfoOAuth2RefreshToken =
|
||||
"Token used to obtain new access tokens when the current access token expires.";
|
||||
const kHintOAuth2IdentityToken = "Identity Token";
|
||||
const kInfoOAuth2IdentityToken =
|
||||
"JWT token containing user identity information, typically used in OpenID Connect flows.";
|
||||
const kHintOAuth2AccessToken = "Access Token";
|
||||
const kInfoOAuth2AccessToken =
|
||||
"The token used to access protected resources on behalf of the user.";
|
||||
const kLabelOAuth2CodeChallengeMethod = "Code Challenge Method";
|
||||
const kTooltipOAuth2CodeChallengeMethod =
|
||||
"Code challenge method for PKCE (Proof Key for Code Exchange)";
|
||||
const kButtonClearOAuth2Session = "Clear OAuth2 Session";
|
||||
|
||||
//AuthPAge
|
||||
const kLabelSelectAuthType = "Authentication Type";
|
||||
const kTooltipSelectAuth = "Select Authentication Type";
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:apidash/widgets/widgets.dart';
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:apidash_design_system/widgets/widgets.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'consts.dart';
|
||||
|
||||
class OAuth1Fields extends StatefulWidget {
|
||||
final AuthModel? authData;
|
||||
@@ -95,20 +96,22 @@ class _OAuth1FieldsState extends State<OAuth1Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _consumerKeyController,
|
||||
hintText: "Consumer Key",
|
||||
hintText: kHintOAuth1ConsumerKey,
|
||||
infoText: kInfoOAuth1ConsumerKey,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _consumerSecretController,
|
||||
hintText: "Consumer Secret",
|
||||
hintText: kHintOAuth1ConsumerSecret,
|
||||
infoText: kInfoOAuth1ConsumerSecret,
|
||||
isObscureText: true,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
"Signature Method",
|
||||
kLabelOAuth1SignatureMethod,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 14,
|
||||
@@ -118,65 +121,75 @@ class _OAuth1FieldsState extends State<OAuth1Fields> {
|
||||
ADPopupMenu<OAuth1SignatureMethod>(
|
||||
value: _signatureMethodController.displayType,
|
||||
values: OAuth1SignatureMethod.values.map((e) => (e, e.displayType)),
|
||||
tooltip: "this algorithm will be used to produce the digest",
|
||||
tooltip: kTooltipOAuth1SignatureMethod,
|
||||
isOutlined: true,
|
||||
onChanged: (OAuth1SignatureMethod? newAlgo) {
|
||||
if (newAlgo != null) {
|
||||
setState(() {
|
||||
_signatureMethodController = newAlgo;
|
||||
});
|
||||
onChanged: widget.readOnly
|
||||
? null
|
||||
: (OAuth1SignatureMethod? newAlgo) {
|
||||
if (newAlgo != null) {
|
||||
setState(() {
|
||||
_signatureMethodController = newAlgo;
|
||||
});
|
||||
|
||||
_updateOAuth1();
|
||||
}
|
||||
},
|
||||
_updateOAuth1();
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _accessTokenController,
|
||||
hintText: "Access Token",
|
||||
hintText: kHintOAuth1AccessToken,
|
||||
infoText: kInfoOAuth1AccessToken,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _tokenSecretController,
|
||||
hintText: "Token Secret",
|
||||
hintText: kHintOAuth1TokenSecret,
|
||||
infoText: kInfoOAuth1TokenSecret,
|
||||
isObscureText: true,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _callbackUrlController,
|
||||
hintText: "Callback URL",
|
||||
hintText: kHintOAuth1CallbackUrl,
|
||||
infoText: kInfoOAuth1CallbackUrl,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _verifierController,
|
||||
hintText: "Verifier",
|
||||
hintText: kHintOAuth1Verifier,
|
||||
infoText: kInfoOAuth1Verifier,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _timestampController,
|
||||
hintText: "Timestamp",
|
||||
hintText: kHintOAuth1Timestamp,
|
||||
infoText: kInfoOAuth1Timestamp,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _nonceController,
|
||||
hintText: "Nonce",
|
||||
hintText: kHintOAuth1Nonce,
|
||||
infoText: kInfoOAuth1Nonce,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _realmController,
|
||||
hintText: "Realm",
|
||||
hintText: kHintOAuth1Realm,
|
||||
infoText: kInfoOAuth1Realm,
|
||||
onChanged: (_) => _updateOAuth1(),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:apidash/widgets/field_auth.dart';
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'consts.dart';
|
||||
|
||||
class OAuth2Fields extends StatefulWidget {
|
||||
final AuthModel? authData;
|
||||
@@ -102,24 +103,26 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
physics: ClampingScrollPhysics(),
|
||||
children: [
|
||||
Text(
|
||||
"Grant Type",
|
||||
kLabelOAuth2GrantType,
|
||||
style: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
kVSpacer5,
|
||||
ADPopupMenu<OAuth2GrantType>(
|
||||
value: _grantType.displayType,
|
||||
values: OAuth2GrantType.values.map((e) => (e, e.displayType)),
|
||||
tooltip: "Select OAuth 2.0 grant type",
|
||||
tooltip: kTooltipOAuth2GrantType,
|
||||
isOutlined: true,
|
||||
onChanged: (OAuth2GrantType? newGrantType) {
|
||||
if (newGrantType != null && newGrantType != _grantType) {
|
||||
setState(() {
|
||||
_grantType = newGrantType;
|
||||
});
|
||||
onChanged: widget.readOnly
|
||||
? null
|
||||
: (OAuth2GrantType? newGrantType) {
|
||||
if (newGrantType != null && newGrantType != _grantType) {
|
||||
setState(() {
|
||||
_grantType = newGrantType;
|
||||
});
|
||||
|
||||
_updateOAuth2();
|
||||
}
|
||||
},
|
||||
_updateOAuth2();
|
||||
}
|
||||
},
|
||||
),
|
||||
kVSpacer16,
|
||||
if (_shouldShowField(OAuth2Field.authorizationUrl))
|
||||
@@ -127,7 +130,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _authorizationUrlController,
|
||||
hintText: "Authorization URL",
|
||||
hintText: kHintOAuth2AuthorizationUrl,
|
||||
infoText: kInfoOAuth2AuthorizationUrl,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -136,7 +140,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _usernameController,
|
||||
hintText: "Username",
|
||||
hintText: kHintOAuth2Username,
|
||||
infoText: kInfoOAuth2Username,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -145,7 +150,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _passwordController,
|
||||
hintText: "Password",
|
||||
hintText: kHintOAuth2Password,
|
||||
infoText: kInfoOAuth2Password,
|
||||
isObscureText: true,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
@@ -155,7 +161,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _accessTokenUrlController,
|
||||
hintText: "Access Token URL",
|
||||
hintText: kHintOAuth2AccessTokenUrl,
|
||||
infoText: kInfoOAuth2AccessTokenUrl,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -164,7 +171,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _clientIdController,
|
||||
hintText: "Client ID",
|
||||
hintText: kHintOAuth2ClientId,
|
||||
infoText: kInfoOAuth2ClientId,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -173,14 +181,15 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _clientSecretController,
|
||||
hintText: "Client Secret",
|
||||
hintText: kHintOAuth2ClientSecret,
|
||||
infoText: kInfoOAuth2ClientSecret,
|
||||
isObscureText: true,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
if (_shouldShowField(OAuth2Field.codeChallengeMethod)) ...[
|
||||
Text(
|
||||
"Code Challenge Method",
|
||||
kLabelOAuth2CodeChallengeMethod,
|
||||
style: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
kVSpacer5,
|
||||
@@ -190,17 +199,20 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
('SHA-256', 'sha-256'),
|
||||
('Plaintext', 'plaintext'),
|
||||
],
|
||||
tooltip: "Code challenge method for PKCE",
|
||||
tooltip: kTooltipOAuth2CodeChallengeMethod,
|
||||
isOutlined: true,
|
||||
onChanged: (String? newMethod) {
|
||||
if (newMethod != null && newMethod != _codeChallengeMethod) {
|
||||
setState(() {
|
||||
_codeChallengeMethod = newMethod;
|
||||
});
|
||||
onChanged: widget.readOnly
|
||||
? null
|
||||
: (String? newMethod) {
|
||||
if (newMethod != null &&
|
||||
newMethod != _codeChallengeMethod) {
|
||||
setState(() {
|
||||
_codeChallengeMethod = newMethod;
|
||||
});
|
||||
|
||||
_updateOAuth2();
|
||||
}
|
||||
},
|
||||
_updateOAuth2();
|
||||
}
|
||||
},
|
||||
),
|
||||
kVSpacer16,
|
||||
],
|
||||
@@ -209,7 +221,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _redirectUrlController,
|
||||
hintText: "Redirect URL",
|
||||
hintText: kHintOAuth2RedirectUrl,
|
||||
infoText: kInfoOAuth2RedirectUrl,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -218,7 +231,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _scopeController,
|
||||
hintText: "Scope",
|
||||
hintText: kHintOAuth2Scope,
|
||||
infoText: kInfoOAuth2Scope,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -227,13 +241,14 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _stateController,
|
||||
hintText: "State",
|
||||
hintText: kHintOAuth2State,
|
||||
infoText: kInfoOAuth2State,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
..._buildFieldWithSpacing(
|
||||
ADTextButton(
|
||||
label: "Clear OAuth2 Session",
|
||||
label: kButtonClearOAuth2Session,
|
||||
onPressed: clearStoredCredentials,
|
||||
),
|
||||
),
|
||||
@@ -243,7 +258,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _refreshTokenController,
|
||||
hintText: "Refresh Token",
|
||||
hintText: kHintOAuth2RefreshToken,
|
||||
infoText: kInfoOAuth2RefreshToken,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -251,7 +267,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _identityTokenController,
|
||||
hintText: "Identity Token",
|
||||
hintText: kHintOAuth2IdentityToken,
|
||||
infoText: kInfoOAuth2IdentityToken,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
@@ -259,7 +276,8 @@ class _OAuth2FieldsState extends State<OAuth2Fields> {
|
||||
AuthTextField(
|
||||
readOnly: widget.readOnly,
|
||||
controller: _accessTokenController,
|
||||
hintText: "Access Token",
|
||||
hintText: kHintOAuth2AccessToken,
|
||||
infoText: kInfoOAuth2AccessToken,
|
||||
onChanged: (_) => _updateOAuth2(),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user