0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix(console): add applications and redirect uri placeholder (#6696)

add applications and redirect uri placeholder
This commit is contained in:
simeng-li 2024-10-22 11:36:08 +08:00 committed by GitHub
parent 14e65924f2
commit 11055a6002
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 32 additions and 13 deletions

View file

@ -58,7 +58,7 @@ function ConfigForm({
handleSubmit, handleSubmit,
watch, watch,
} = useForm<IdpInitiatedAuthConfigFormData>({ } = useForm<IdpInitiatedAuthConfigFormData>({
defaultValues: parseResponseToFormData(idpInitiatedAuthConfig), defaultValues: parseResponseToFormData(idpInitiatedAuthConfig, applications),
}); });
const isIdpInitiatedSsoEnabled = watch('isIdpInitiatedSsoEnabled'); const isIdpInitiatedSsoEnabled = watch('isIdpInitiatedSsoEnabled');
@ -98,8 +98,9 @@ function ConfigForm({
useEffect(() => { useEffect(() => {
if (defaultApplication?.type === ApplicationType.SPA) { if (defaultApplication?.type === ApplicationType.SPA) {
setValue('config.autoSendAuthorizationRequest', false); setValue('config.autoSendAuthorizationRequest', false);
setValue('config.redirectUri', undefined);
} }
}, [defaultApplication?.type, setValue]); }, [defaultApplication, setValue]);
const onSubmit = handleSubmit( const onSubmit = handleSubmit(
trySubmitSafe(async (data) => { trySubmitSafe(async (data) => {
@ -113,7 +114,7 @@ function ConfigForm({
await api.delete(buildIdpInitiatedAuthConfigEndpoint(ssoConnector.id)); await api.delete(buildIdpInitiatedAuthConfigEndpoint(ssoConnector.id));
await mutateIdpInitiatedConfig(); await mutateIdpInitiatedConfig();
toast.success(t('general.saved')); toast.success(t('general.saved'));
reset(parseResponseToFormData()); reset(parseResponseToFormData(undefined, applications));
return; return;
} }
@ -172,6 +173,9 @@ function ConfigForm({
}} }}
render={({ field: { value, onChange } }) => ( render={({ field: { value, onChange } }) => (
<Select <Select
placeholder={t(
'enterprise_sso_details.idp_initiated_auth_config.empty_applications_placeholder'
)}
options={applications.map((application) => ({ options={applications.map((application) => ({
value: application.id, value: application.id,
title: `${application.name} (${application.type}, ID: ${application.id})`, title: `${application.name} (${application.type}, ID: ${application.id})`,
@ -278,6 +282,9 @@ function ConfigForm({
value: uri, value: uri,
title: uri, title: uri,
}))} }))}
placeholder={t(
'enterprise_sso_details.idp_initiated_auth_config.redirect_uri_placeholder'
)}
value={value} value={value}
error={emptyRedirectUrisError ?? errors.config?.redirectUri?.message} error={emptyRedirectUrisError ?? errors.config?.redirectUri?.message}
onChange={onChange} onChange={onChange}

View file

@ -26,7 +26,8 @@ function IdpInitiatedAuth({ ssoConnector }: Props) {
const isLoading = useMemo( const isLoading = useMemo(
() => () =>
!applications && !applicationError && !idpInitiatedAuthConfig && !idpInitiatedAuthConfigError, (!applications && !applicationError) ||
(!idpInitiatedAuthConfig && !idpInitiatedAuthConfigError),
[applicationError, applications, idpInitiatedAuthConfig, idpInitiatedAuthConfigError] [applicationError, applications, idpInitiatedAuthConfig, idpInitiatedAuthConfigError]
); );

View file

@ -1,9 +1,11 @@
import { import {
type Application,
ApplicationType, ApplicationType,
SsoConnectorIdpInitiatedAuthConfigs, SsoConnectorIdpInitiatedAuthConfigs,
type CreateSsoConnectorIdpInitiatedAuthConfig, type CreateSsoConnectorIdpInitiatedAuthConfig,
type SsoConnectorIdpInitiatedAuthConfig, type SsoConnectorIdpInitiatedAuthConfig,
} from '@logto/schemas'; } from '@logto/schemas';
import { conditional, type DeepPartial } from '@silverhand/essentials';
import { t } from 'i18next'; import { t } from 'i18next';
import { toast } from 'react-hot-toast'; import { toast } from 'react-hot-toast';
@ -20,11 +22,12 @@ export const buildIdpInitiatedAuthConfigEndpoint = (connectorId: string) =>
type IdpInitiatedAuthConfigData = Pick< type IdpInitiatedAuthConfigData = Pick<
SsoConnectorIdpInitiatedAuthConfig, SsoConnectorIdpInitiatedAuthConfig,
| 'defaultApplicationId' 'defaultApplicationId' | 'autoSendAuthorizationRequest'
| 'autoSendAuthorizationRequest' > & {
| 'redirectUri' authParameters: string;
| 'clientIdpInitiatedAuthCallbackUri' redirectUri: string | undefined;
> & { authParameters: string }; clientIdpInitiatedAuthCallbackUri: string | undefined;
};
const authParametersGuard = SsoConnectorIdpInitiatedAuthConfigs.createGuard.shape.authParameters; const authParametersGuard = SsoConnectorIdpInitiatedAuthConfigs.createGuard.shape.authParameters;
@ -34,11 +37,17 @@ export type IdpInitiatedAuthConfigFormData = {
}; };
export const parseResponseToFormData = ( export const parseResponseToFormData = (
response?: SsoConnectorIdpInitiatedAuthConfig response: SsoConnectorIdpInitiatedAuthConfig | undefined,
): IdpInitiatedAuthConfigFormData => { applications: Application[] = []
): DeepPartial<IdpInitiatedAuthConfigFormData> => {
if (!response) { if (!response) {
return { return {
isIdpInitiatedSsoEnabled: false, isIdpInitiatedSsoEnabled: false,
config: {
// Set default values
defaultApplicationId: applications[0]?.id,
autoSendAuthorizationRequest: false,
},
}; };
} }
@ -55,8 +64,8 @@ export const parseResponseToFormData = (
config: { config: {
defaultApplicationId, defaultApplicationId,
autoSendAuthorizationRequest, autoSendAuthorizationRequest,
redirectUri, redirectUri: conditional(redirectUri),
clientIdpInitiatedAuthCallbackUri, clientIdpInitiatedAuthCallbackUri: conditional(clientIdpInitiatedAuthCallbackUri),
authParameters: JSON.stringify(authParameters, null, 2), authParameters: JSON.stringify(authParameters, null, 2),
}, },
}; };

View file

@ -86,6 +86,7 @@ const enterprise_sso_details = {
'Target application the user will be redirected to after authentication.', 'Target application the user will be redirected to after authentication.',
empty_applications_error: empty_applications_error:
'No applications found. Please add one in the <a>Applications</a> section.', 'No applications found. Please add one in the <a>Applications</a> section.',
empty_applications_placeholder: 'No applications',
authentication_type: 'Authentication type', authentication_type: 'Authentication type',
auto_authentication_disabled_title: 'Redirect to client for SP-initiated SSO (Recommended)', auto_authentication_disabled_title: 'Redirect to client for SP-initiated SSO (Recommended)',
auto_authentication_disabled_description: auto_authentication_disabled_description:
@ -104,6 +105,7 @@ const enterprise_sso_details = {
'The redirect URI to redirect users after successful sign-in. Logto will use this URI as the OIDC redirect URI in the authorization request. Use a dedicated URI for the IdP-initiated SSO authentication flow for better security.', 'The redirect URI to redirect users after successful sign-in. Logto will use this URI as the OIDC redirect URI in the authorization request. Use a dedicated URI for the IdP-initiated SSO authentication flow for better security.',
empty_redirect_uris_error: empty_redirect_uris_error:
'No redirect URI has been registered for the application. Please add one first.', 'No redirect URI has been registered for the application. Please add one first.',
redirect_uri_placeholder: 'Select a post sign-in redirect URI',
auth_params: 'Additional authentication parameters', auth_params: 'Additional authentication parameters',
auth_params_tooltip: auth_params_tooltip:
'Additional parameters to be passed in the authorization request. By default only (openid profile) scopes will be requested, you can specify additional scopes or a exclusive state value here. (e.g., { "scope": "organizations email", "state": "secret_state" }).', 'Additional parameters to be passed in the authorization request. By default only (openid profile) scopes will be requested, you can specify additional scopes or a exclusive state value here. (e.g., { "scope": "organizations email", "state": "secret_state" }).',