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:
parent
b483800e6a
commit
3b90e04f47
3 changed files with 31 additions and 1 deletions
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.',
|
||||||
|
|
Loading…
Reference in a new issue