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

fix(console): should display custom domain as alternative endpoint in app details and guides (#4501)

fix(console): should display custom domain as alternative endpoint in app guide and details
This commit is contained in:
Charles Zhao 2023-09-15 09:57:41 +08:00 committed by GitHub
parent e1fac554db
commit 926da108e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 31 deletions

View file

@ -12,7 +12,6 @@ import DynamicT from '@/ds-components/DynamicT';
import FormField from '@/ds-components/FormField';
import useCustomDomain from '@/hooks/use-custom-domain';
import type { ConnectorFormType } from '@/types/connector';
import { applyDomain } from '@/utils/domain';
import { jsonValidator } from '@/utils/validator';
import ConfigFormFields from './ConfigFormFields';
@ -32,7 +31,7 @@ function ConfigForm({ formItems, className, connectorId, connectorType }: Props)
formState: { errors },
} = useFormContext<ConnectorFormType>();
const { tenantEndpoint } = useContext(AppDataContext);
const { data: customDomain } = useCustomDomain();
const { data: customDomain, applyDomain: applyCustomDomain } = useCustomDomain();
const callbackUri = new URL(`/callback/${connectorId}`, tenantEndpoint).toString();
return (
@ -45,11 +44,7 @@ function ConfigForm({ formItems, className, connectorId, connectorType }: Props)
<CopyToClipboard
className={styles.copyToClipboard}
variant="border"
value={
customDomain?.status === DomainStatus.Active
? applyDomain(callbackUri, customDomain.domain)
: callbackUri
}
value={applyCustomDomain(callbackUri)}
/>
{customDomain?.status === DomainStatus.Active && tenantEndpoint && (
<div className={styles.description}>

View file

@ -1,9 +1,11 @@
import { type Domain } from '@logto/schemas';
import { DomainStatus, type Domain } from '@logto/schemas';
import { conditional } from '@silverhand/essentials';
import { useCallback, useMemo } from 'react';
import useSWR from 'swr';
import { customDomainSyncInterval } from '@/consts/custom-domain';
import { isCloud } from '@/consts/env';
import { isAbsoluteUrl } from '@/utils/url';
import { type RequestError } from './use-api';
@ -22,18 +24,30 @@ const useCustomDomain = (autoSync = false) => {
/**
* Note: we can only create a custom domain, and we don't have a default id for it, so the first element of the array is the custom domain.
*/
const customDomain = conditional(!isLoading && data)?.[0];
const customDomain = useMemo(() => data?.[0], [data]);
const mutateDomain = useCallback(
(domain?: Domain) => {
void mutate(domain ? [domain] : undefined);
},
[mutate]
);
const applyDomain = useCallback(
(url: string) => {
if (customDomain?.status !== DomainStatus.Active || !isAbsoluteUrl(url)) {
return url;
}
return url.replace(new URL(url).host, customDomain.domain);
},
[customDomain]
);
return {
data: customDomain,
isLoading,
mutate: (domain?: Domain) => {
if (domain) {
void mutate([domain]);
return;
}
void mutate();
},
mutate: mutateDomain,
applyDomain,
};
};

View file

@ -20,7 +20,6 @@ import Switch from '@/ds-components/Switch';
import TextInput from '@/ds-components/TextInput';
import TextLink from '@/ds-components/TextLink';
import useCustomDomain from '@/hooks/use-custom-domain';
import { applyDomain } from '@/utils/domain';
import * as styles from '../index.module.scss';
@ -44,10 +43,7 @@ function AdvancedSettings({ app: { type }, oidcConfig }: Props) {
min: minTtl,
max: maxTtl,
});
const { data: customDomain } = useCustomDomain();
const tryApplyCustomDomain = (url: string) =>
customDomain?.status === DomainStatus.Active ? applyDomain(url, customDomain.domain) : url;
const { data: customDomain, applyDomain: applyCustomDomain } = useCustomDomain();
return (
<FormCard
@ -59,7 +55,7 @@ function AdvancedSettings({ app: { type }, oidcConfig }: Props) {
<FormField title="application_details.config_endpoint">
<CopyToClipboard
className={styles.textField}
value={tryApplyCustomDomain(appendPath(tenantEndpoint, openIdProviderConfigPath).href)}
value={applyCustomDomain(appendPath(tenantEndpoint, openIdProviderConfigPath).href)}
variant="border"
/>
</FormField>
@ -84,21 +80,21 @@ function AdvancedSettings({ app: { type }, oidcConfig }: Props) {
>
<CopyToClipboard
className={styles.textField}
value={tryApplyCustomDomain(oidcConfig.authorization_endpoint)}
value={applyCustomDomain(oidcConfig.authorization_endpoint)}
variant="border"
/>
</FormField>
<FormField title="application_details.token_endpoint">
<CopyToClipboard
className={styles.textField}
value={tryApplyCustomDomain(oidcConfig.token_endpoint)}
value={applyCustomDomain(oidcConfig.token_endpoint)}
variant="border"
/>
</FormField>
<FormField title="application_details.user_info_endpoint">
<CopyToClipboard
className={styles.textField}
value={tryApplyCustomDomain(oidcConfig.userinfo_endpoint)}
value={applyCustomDomain(oidcConfig.userinfo_endpoint)}
variant="border"
/>
</FormField>

View file

@ -21,8 +21,6 @@ function AppGuide({ className, guideId, app, isCompact, onClose }: Props) {
const isCustomDomainActive = customDomain?.status === DomainStatus.Active;
const guide = guides.find(({ id }) => id === guideId);
const GuideComponent = guide?.Component;
const memorizedContext = useMemo(
() =>
conditional(
@ -32,7 +30,7 @@ function AppGuide({ className, guideId, app, isCompact, onClose }: Props) {
Logo: guide.Logo,
app,
endpoint: tenantEndpoint?.toString() ?? '',
alternativeEndpoint: conditional(isCustomDomainActive && tenantEndpoint?.toString()),
alternativeEndpoint: conditional(isCustomDomainActive && customDomain.domain),
redirectUris: app.oidcClientMetadata.redirectUris,
postLogoutRedirectUris: app.oidcClientMetadata.postLogoutRedirectUris,
isCompact: Boolean(isCompact),
@ -42,7 +40,7 @@ function AppGuide({ className, guideId, app, isCompact, onClose }: Props) {
},
}
) satisfies GuideContextType | undefined,
[guide, app, tenantEndpoint, isCustomDomainActive, isCompact]
[guide, app, tenantEndpoint, isCustomDomainActive, customDomain?.domain, isCompact]
);
return memorizedContext ? (

View file

@ -17,6 +17,7 @@ import {
} from '@/ds-components/MultiTextInput/utils';
import TextInput from '@/ds-components/TextInput';
import TextLink from '@/ds-components/TextLink';
import useCustomDomain from '@/hooks/use-custom-domain';
import useDocumentationUrl from '@/hooks/use-documentation-url';
import * as styles from '../index.module.scss';
@ -27,6 +28,7 @@ type Props = {
function Settings({ data }: Props) {
const { tenantEndpoint } = useContext(AppDataContext);
const { applyDomain: applyCustomDomain } = useCustomDomain();
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { getDocumentationUrl } = useDocumentationUrl();
@ -62,7 +64,7 @@ function Settings({ data }: Props) {
{tenantEndpoint && (
<FormField title="application_details.logto_endpoint">
<CopyToClipboard
value={tenantEndpoint.href}
value={applyCustomDomain(tenantEndpoint.href)}
variant="border"
className={styles.textField}
/>

View file

@ -1 +0,0 @@
export const applyDomain = (url: string, domain: string) => url.replace(new URL(url).host, domain);