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

feat(core): add unknown session fallback uri field

add unknown session fallbacl uri field to the application details page
This commit is contained in:
simeng-li 2024-11-11 11:32:03 +08:00
parent b483800e6a
commit 3b90e04f47
No known key found for this signature in database
GPG key ID: 14EA7BB1541E8075
3 changed files with 31 additions and 1 deletions

View file

@ -6,6 +6,7 @@ import { Trans, useTranslation } from 'react-i18next';
import FormCard from '@/components/FormCard'; import FormCard from '@/components/FormCard';
import MultiTextInputField from '@/components/MultiTextInputField'; import MultiTextInputField from '@/components/MultiTextInputField';
import { isDevFeaturesEnabled } from '@/consts/env';
import CodeEditor from '@/ds-components/CodeEditor'; import CodeEditor from '@/ds-components/CodeEditor';
import FormField from '@/ds-components/FormField'; import FormField from '@/ds-components/FormField';
import type { MultiTextInputRule } from '@/ds-components/MultiTextInput/types'; import type { MultiTextInputRule } from '@/ds-components/MultiTextInput/types';
@ -17,6 +18,7 @@ import TextInput from '@/ds-components/TextInput';
import TextLink from '@/ds-components/TextLink'; import TextLink from '@/ds-components/TextLink';
import useDocumentationUrl from '@/hooks/use-documentation-url'; import useDocumentationUrl from '@/hooks/use-documentation-url';
import { isJsonObject } from '@/utils/json'; import { isJsonObject } from '@/utils/json';
import { uriValidator } from '@/utils/validator';
import ProtectedAppSettings from './ProtectedAppSettings'; import ProtectedAppSettings from './ProtectedAppSettings';
import { type ApplicationForm } from './utils'; import { type ApplicationForm } from './utils';
@ -34,10 +36,16 @@ function Settings({ data }: Props) {
formState: { errors }, formState: { errors },
} = useFormContext<ApplicationForm>(); } = useFormContext<ApplicationForm>();
const { type: applicationType } = data; const { type: applicationType, isThirdParty } = data;
const isNativeApp = applicationType === ApplicationType.Native; const isNativeApp = applicationType === ApplicationType.Native;
const isProtectedApp = applicationType === ApplicationType.Protected; const isProtectedApp = applicationType === ApplicationType.Protected;
// TODO: Remove dev features check after the feature is ready for production
const showUnknownSessionFallbackUri =
(applicationType === ApplicationType.Traditional || applicationType === ApplicationType.SPA) &&
!isThirdParty &&
isDevFeaturesEnabled;
const uriPatternRules: MultiTextInputRule = { const uriPatternRules: MultiTextInputRule = {
pattern: { pattern: {
verify: (value) => !value || validateRedirectUrl(value, isNativeApp ? 'mobile' : 'web'), verify: (value) => !value || validateRedirectUrl(value, isNativeApp ? 'mobile' : 'web'),
@ -164,6 +172,20 @@ function Settings({ data }: Props) {
)} )}
/> />
)} )}
{showUnknownSessionFallbackUri && (
<FormField
title="application_details.field_unknown_session_fallback_uri"
tip={t('application_details.field_unknown_session_fallback_uri_tip')}
>
<TextInput
{...register('unknownSessionFallbackUri', {
validate: (value) => !value || uriValidator(value) || t('errors.invalid_uri_format'),
})}
error={errors.unknownSessionFallbackUri?.message}
placeholder={t('application_details.post_sign_out_redirect_uri_placeholder')}
/>
</FormField>
)}
<Controller <Controller
name="customData" name="customData"
control={control} control={control}

View file

@ -11,6 +11,7 @@ export type ApplicationForm = {
oidcClientMetadata?: ApplicationResponse['oidcClientMetadata']; oidcClientMetadata?: ApplicationResponse['oidcClientMetadata'];
customClientMetadata?: ApplicationResponse['customClientMetadata']; customClientMetadata?: ApplicationResponse['customClientMetadata'];
isAdmin?: ApplicationResponse['isAdmin']; isAdmin?: ApplicationResponse['isAdmin'];
unknownSessionFallbackUri?: ApplicationResponse['unknownSessionFallbackUri'];
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
protectedAppMetadata?: Omit<Exclude<ProtectedAppMetadataType, null>, 'customDomains'>; // Custom domains are handled separately protectedAppMetadata?: Omit<Exclude<ProtectedAppMetadataType, null>, 'customDomains'>; // Custom domains are handled separately
customData?: string; customData?: string;
@ -33,6 +34,7 @@ export const applicationFormDataParser = {
/** Specific metadata for protected apps */ /** Specific metadata for protected apps */
protectedAppMetadata, protectedAppMetadata,
customData, customData,
unknownSessionFallbackUri,
} = data; } = data;
return { return {
@ -46,6 +48,7 @@ export const applicationFormDataParser = {
...customClientMetadata, ...customClientMetadata,
}, },
customData: JSON.stringify(customData, null, 2), customData: JSON.stringify(customData, null, 2),
unknownSessionFallbackUri,
isAdmin, isAdmin,
} }
), ),
@ -68,6 +71,7 @@ export const applicationFormDataParser = {
isAdmin, isAdmin,
protectedAppMetadata, protectedAppMetadata,
customData, customData,
unknownSessionFallbackUri,
} = data; } = data;
return { return {
@ -90,6 +94,7 @@ export const applicationFormDataParser = {
customClientMetadata?.corsAllowedOrigins customClientMetadata?.corsAllowedOrigins
), ),
}, },
unknownSessionFallbackUri,
...conditional( ...conditional(
// Invalid JSON string will be guarded by the form field validation // Invalid JSON string will be guarded by the form field validation
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment

View file

@ -100,6 +100,9 @@ const application_details = {
field_custom_data_tip: field_custom_data_tip:
'Additional custom application info not listed in the pre-defined application properties, such as business-specific settings and configurations.', 'Additional custom application info not listed in the pre-defined application properties, such as business-specific settings and configurations.',
custom_data_invalid: 'Custom data must be a valid JSON object', custom_data_invalid: 'Custom data must be a valid JSON object',
field_unknown_session_fallback_uri: 'Unknown session sign-in fallback URI',
field_unknown_session_fallback_uri_tip:
'The fallback URI when the user accesses the sign-in page without a valid session. User will be redirected to this URI to initiate a new authentication flow.',
branding: { branding: {
name: 'Branding', name: 'Branding',
description: 'Customize your app logo and branding color for the app-level experience.', description: 'Customize your app logo and branding color for the app-level experience.',