From 6cac3ee3f99349f6d713e1d09de5a66c0f8a2ebf Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Thu, 15 Jun 2023 15:08:19 +0800 Subject: [PATCH] feat(console): add custom domain notes for endpoints and social callback uri (#4034) --- .../console/src/hooks/use-custom-domain.ts | 40 +++++++++++++++++++ .../components/AdvancedSettings.tsx | 27 +++++++++++-- .../ApplicationDetails/index.module.scss | 6 +++ .../components/ConnectorForm/ConfigForm.tsx | 29 ++++++++++++-- .../TenantDomainSettings/index.tsx | 29 ++------------ packages/console/src/utils/domain.ts | 1 + .../de/translation/admin-console/domain.ts | 4 ++ .../en/translation/admin-console/domain.ts | 4 ++ .../es/translation/admin-console/domain.ts | 4 ++ .../fr/translation/admin-console/domain.ts | 4 ++ .../it/translation/admin-console/domain.ts | 4 ++ .../ja/translation/admin-console/domain.ts | 4 ++ .../ko/translation/admin-console/domain.ts | 4 ++ .../pl-pl/translation/admin-console/domain.ts | 4 ++ .../pt-br/translation/admin-console/domain.ts | 4 ++ .../pt-pt/translation/admin-console/domain.ts | 4 ++ .../ru/translation/admin-console/domain.ts | 4 ++ .../tr-tr/translation/admin-console/domain.ts | 4 ++ .../zh-cn/translation/admin-console/domain.ts | 3 ++ .../zh-hk/translation/admin-console/domain.ts | 3 ++ .../zh-tw/translation/admin-console/domain.ts | 3 ++ 21 files changed, 157 insertions(+), 32 deletions(-) create mode 100644 packages/console/src/hooks/use-custom-domain.ts create mode 100644 packages/console/src/utils/domain.ts diff --git a/packages/console/src/hooks/use-custom-domain.ts b/packages/console/src/hooks/use-custom-domain.ts new file mode 100644 index 000000000..f17dbbcd5 --- /dev/null +++ b/packages/console/src/hooks/use-custom-domain.ts @@ -0,0 +1,40 @@ +import { type Domain } from '@logto/schemas'; +import { conditional } from '@silverhand/essentials'; +import useSWR from 'swr'; + +import { customDomainSyncInterval } from '@/consts/custom-domain'; +import { isCloud } from '@/consts/env'; + +import { type RequestError } from './use-api'; + +const useCustomDomain = (autoSync = false) => { + const { data, error, mutate } = useSWR( + isCloud && 'api/domains', + conditional( + autoSync && { + refreshInterval: customDomainSyncInterval * 1000, + } + ) + ); + + const isLoading = !data && !error; + + /** + * 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]; + + return { + data: customDomain, + isLoading, + mutate: (domain?: Domain) => { + if (domain) { + void mutate([domain]); + return; + } + void mutate(); + }, + }; +}; + +export default useCustomDomain; diff --git a/packages/console/src/pages/ApplicationDetails/components/AdvancedSettings.tsx b/packages/console/src/pages/ApplicationDetails/components/AdvancedSettings.tsx index c9170145d..83ed588f1 100644 --- a/packages/console/src/pages/ApplicationDetails/components/AdvancedSettings.tsx +++ b/packages/console/src/pages/ApplicationDetails/components/AdvancedSettings.tsx @@ -3,6 +3,7 @@ import { type SnakeCaseOidcConfig, ApplicationType, customClientMetadataGuard, + DomainStatus, } from '@logto/schemas'; import { appendPath } from '@silverhand/essentials'; import { useContext } from 'react'; @@ -10,6 +11,7 @@ import { useFormContext } from 'react-hook-form'; import { Trans, useTranslation } from 'react-i18next'; import CopyToClipboard from '@/components/CopyToClipboard'; +import DynamicT from '@/components/DynamicT'; import FormCard from '@/components/FormCard'; import FormField from '@/components/FormField'; import Switch from '@/components/Switch'; @@ -17,6 +19,8 @@ import TextInput from '@/components/TextInput'; import TextLink from '@/components/TextLink'; import { openIdProviderConfigPath } from '@/consts/oidc'; import { AppEndpointsContext } from '@/contexts/AppEndpointsProvider'; +import useCustomDomain from '@/hooks/use-custom-domain'; +import { applyDomain } from '@/utils/domain'; import * as styles from '../index.module.scss'; @@ -40,6 +44,10 @@ function AdvancedSettings({ applicationType, oidcConfig }: Props) { min: minTtl, max: maxTtl, }); + const { data: customDomain } = useCustomDomain(); + + const tryApplyCustomDomain = (url: string) => + customDomain?.status === DomainStatus.Active ? applyDomain(url, customDomain.domain) : url; return ( @@ -76,24 +84,35 @@ function AdvancedSettings({ applicationType, oidcConfig }: Props) { > + {customDomain?.status === DomainStatus.Active && userEndpoint && ( +
+ +
+ )} {[ApplicationType.Traditional, ApplicationType.SPA].includes(applicationType) && ( (); const { userEndpoint } = useContext(AppEndpointsContext); + const { data: customDomain } = useCustomDomain(); + const callbackUri = new URL(`/callback/${connectorId}`, userEndpoint).toString(); return (
{connectorType === ConnectorType.Social && ( - + -
{t('connectors.guide.callback_uri_description')}
+ {customDomain?.status === DomainStatus.Active && userEndpoint && ( +
+ +
+ )}
)} {formItems ? ( diff --git a/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx b/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx index dc4f24cff..981c951d6 100644 --- a/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx +++ b/packages/console/src/pages/TenantSettings/TenantDomainSettings/index.tsx @@ -1,13 +1,9 @@ import { withAppInsights } from '@logto/app-insights/react'; -import { type Domain } from '@logto/schemas'; -import { conditional } from '@silverhand/essentials'; -import useSWR from 'swr'; import FormCard from '@/components/FormCard'; import FormField from '@/components/FormField'; import PageMeta from '@/components/PageMeta'; -import { customDomainSyncInterval } from '@/consts/custom-domain'; -import { type RequestError } from '@/hooks/use-api'; +import useCustomDomain from '@/hooks/use-custom-domain'; import AddDomainForm from './AddDomainForm'; import CustomDomain from './CustomDomain'; @@ -15,15 +11,7 @@ import DefaultDomain from './DefaultDomain'; import * as styles from './index.module.scss'; function TenantDomainSettings() { - const { data, error, mutate } = useSWR('api/domains', { - refreshInterval: customDomainSyncInterval * 1000, - }); - - const isLoading = !data && !error; - /** - * 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 { data: customDomain, isLoading, mutate } = useCustomDomain(true); if (isLoading) { return null; @@ -38,18 +26,9 @@ function TenantDomainSettings() { > {customDomain ? ( - { - void mutate(); - }} - /> + ) : ( - { - void mutate([domain]); - }} - /> + )} diff --git a/packages/console/src/utils/domain.ts b/packages/console/src/utils/domain.ts new file mode 100644 index 000000000..1e30d6b21 --- /dev/null +++ b/packages/console/src/utils/domain.ts @@ -0,0 +1 @@ +export const applyDomain = (url: string, domain: string) => url.replace(new URL(url).host, domain); diff --git a/packages/phrases/src/locales/de/translation/admin-console/domain.ts b/packages/phrases/src/locales/de/translation/admin-console/domain.ts index 043d9d479..4975fbabe 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto bietet eine vorkonfigurierte Standarddomain, die ohne zusätzliche Einrichtung verwendet werden kann. Diese Standarddomain dient als Backup-Option, auch wenn Sie eine benutzerdefinierte Domain aktiviert haben.', default_domain_field: 'Logto Standard-Domain', }, + custom_endpoint_note: + 'Sie können den Domainnamen dieser Endpunkte anpassen, wie Sie möchten. Wählen Sie entweder "{{custom}}" oder "{{default}}".', + custom_social_callback_url_note: + 'Sie können den Domainnamen dieser URI anpassen, um mit dem Endpunkt Ihrer Anwendung übereinzustimmen. Wählen Sie entweder "{{custom}}" oder "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/en/translation/admin-console/domain.ts b/packages/phrases/src/locales/en/translation/admin-console/domain.ts index 07a1d23e2..6592ab4f3 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto offers a pre-configured default domain, ready to use without any additional setup. This default domain serves as a backup option even if you enabled a custom domain.', // UNTRANSLATED default_domain_field: 'Logto default domain', }, + custom_endpoint_note: + 'You can customize the domain name of these endpoints as your required. Choose either "{{custom}}" or "{{default}}".', + custom_social_callback_url_note: + 'You can customize the domain name of this URI to match your application’s endpoint. Choose either "{{custom}}" or "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/es/translation/admin-console/domain.ts b/packages/phrases/src/locales/es/translation/admin-console/domain.ts index 699ec8fae..d437995c9 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto ofrece un dominio predeterminado preconfigurado, listo para usar sin ninguna configuración adicional. Este dominio predeterminado sirve como opción de respaldo incluso si habilitó un dominio personalizado.', default_domain_field: 'Dominio predeterminado de Logto', }, + custom_endpoint_note: + 'Puede personalizar el nombre de dominio de estos puntos finales según sea necesario. Elija "{{custom}}" o "{{default}}".', + custom_social_callback_url_note: + 'Puede personalizar el nombre de dominio de esta URI para que coincida con el punto final de su aplicación. Elija "{{custom}}" o "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/domain.ts b/packages/phrases/src/locales/fr/translation/admin-console/domain.ts index c3360ebab..53d786085 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto offre un domaine par défaut préconfiguré, prêt à être utilisé sans aucune configuration supplémentaire. Ce domaine par défaut sert de solution de secours même si vous avez activé un domaine personnalisé.', default_domain_field: 'Domaine par défaut de Logto', }, + custom_endpoint_note: + 'Vous pouvez personnaliser le nom de domaine de ces points de terminaison selon vos besoins. Choisissez soit "{{custom}}" ou "{{default}}".', + custom_social_callback_url_note: + 'Vous pouvez personnaliser le nom de domaine de cette URI pour correspondre au point de terminaison de votre application. Choisissez soit "{{custom}}" ou "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/it/translation/admin-console/domain.ts b/packages/phrases/src/locales/it/translation/admin-console/domain.ts index d23a5ecc8..3f5854d24 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { "Logto offre un dominio preconfigurato predefinito, pronto all'uso senza alcuna configurazione aggiuntiva. Questo dominio predefinito serve come opzione di backup anche se hai abilitato un dominio personalizzato.", default_domain_field: 'Dominio predefinito Logto', }, + custom_endpoint_note: + 'Puoi personalizzare il nome di dominio di questi endpoint come richiesto. Scegli "{{custom}}" o "{{default}}".', + custom_social_callback_url_note: + 'Puoi personalizzare il nome di dominio di questo URI per corrispondere all\'endpoint della tua applicazione. Scegli "{{custom}}" o "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/ja/translation/admin-console/domain.ts b/packages/phrases/src/locales/ja/translation/admin-console/domain.ts index 1a96473be..316079e2c 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/domain.ts @@ -46,6 +46,10 @@ const domain = { 'Logtoは、追加のセットアップなしで使用できる事前に構成されたデフォルトドメインを提供しています。このデフォルトドメインは、カスタムドメインを有効にしていない場合でもバックアップオプションとして機能します。', default_domain_field: 'Logtoデフォルトドメイン', }, + custom_endpoint_note: + 'これらのエンドポイントのドメイン名を必要に応じてカスタマイズできます。 "{{custom}}" または "{{default}}" のいずれかを選択してください。', + custom_social_callback_url_note: + 'このURIのドメイン名をアプリケーションのエンドポイントに合わせてカスタマイズできます。 "{{custom}}" または "{{default}}" のいずれかを選択してください。', }; export default domain; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/domain.ts b/packages/phrases/src/locales/ko/translation/admin-console/domain.ts index 74c79b285..221b1f50e 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/domain.ts @@ -46,6 +46,10 @@ const domain = { 'Logto는 추가 구성 없이 사용할 수 있는 미리 구성된 기본 도메인을 제공합니다. 이 기본 도메인은 사용자 지정 도메인을 사용하지 않더라도 백업 옵션으로 사용됩니다.', default_domain_field: 'Logto 기본 도메인', }, + custom_endpoint_note: + '이 엔드포인트의 도메인 이름을 필요에 따라 사용자 정의할 수 있습니다. "{{custom}}" 또는 "{{default}}" 중 하나를 선택하세요.', + custom_social_callback_url_note: + '이 URI의 도메인 이름을 애플리케이션 엔드포인트와 일치하도록 사용자 정의할 수 있습니다. "{{custom}}" 또는 "{{default}}" 중 하나를 선택하세요.', }; export default domain; diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/domain.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/domain.ts index 6842b1346..1386dd5db 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto oferuje prekonfigurowaną domenę domyślną, gotową do użycia bez dodatkowej konfiguracji. Ta domyślna domena służy jako opcja zapasowa, nawet jeśli włączyłeś niestandardową domenę.', default_domain_field: 'Domyślna domena Logto', }, + custom_endpoint_note: + 'Możesz dostosować nazwę domeny tych punktów końcowych według swoich wymagań. Wybierz "{{custom}}" lub "{{default}}".', + custom_social_callback_url_note: + 'Możesz dostosować nazwę domeny tego adresu URI, aby dopasować ją do punktu końcowego Twojej aplikacji. Wybierz "{{custom}}" lub "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/domain.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/domain.ts index c64503892..b324b7e0f 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto oferece um domínio padrão pré-configurado, pronto para uso sem nenhuma configuração adicional. Este domínio padrão serve como uma opção de backup mesmo se você habilitou um domínio personalizado.', default_domain_field: 'Domínio padrão do Logto', }, + custom_endpoint_note: + 'Você pode personalizar o nome de domínio desses endpoints conforme necessário. Escolha "{{custom}}" ou "{{default}}".', + custom_social_callback_url_note: + 'Você pode personalizar o nome de domínio desta URI para corresponder ao endpoint de seu aplicativo. Escolha "{{custom}}" ou "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/domain.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/domain.ts index 17ef90550..fd6c506ca 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto oferece um domínio predefinido pré-configurado, pronto para usar sem qualquer configuração adicional. Este domínio predefinido serve como opção de backup mesmo que tenha ativado um domínio personalizado.', default_domain_field: 'Domínio predefinido da Logto', }, + custom_endpoint_note: + 'Pode personalizar o nome de domínio desses endpoints conforme necessário. Escolha "{{custom}}" ou "{{default}}".', + custom_social_callback_url_note: + 'Pode personalizar o nome de domínio deste URI para corresponder ao endpoint da sua aplicação. Escolha "{{custom}}" ou "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/ru/translation/admin-console/domain.ts b/packages/phrases/src/locales/ru/translation/admin-console/domain.ts index 5e480a143..a8eb807e8 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/domain.ts @@ -46,6 +46,10 @@ const domain = { 'Logto предлагает предварительно настроенный домен по умолчанию, готовый к использованию без дополнительной настройки. Этот домен по умолчанию служит как резервный вариант, даже если вы включили пользовательский домен.', default_domain_field: 'Домен по умолчанию Logto', }, + custom_endpoint_note: + 'Вы можете настроить имя домена этих конечных точек по своему усмотрению. Выберите "{{custom}}" или "{{default}}".', + custom_social_callback_url_note: + 'Вы можете настроить имя домена этого URI, чтобы соответствовать конечной точке вашего приложения. Выберите "{{custom}}" или "{{default}}".', }; export default domain; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/domain.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/domain.ts index 5022fb121..1856ccfdc 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/domain.ts @@ -47,6 +47,10 @@ const domain = { 'Logto, ek bir yapılandırma olmadan kullanıma hazır önceden yapılandırılmış bir varsayılan alan adı sunar. Bu varsayılan alan adı, özel bir alan adı etkinleştirdiyseniz bile yedek seçeneği olarak hizmet verir.', default_domain_field: 'Logto varsayılan alan adı', }, + custom_endpoint_note: + 'Bu uç noktaların alan adını özelleştirebilirsiniz. "{{custom}}" veya "{{default}}" seçeneklerinden birini seçin.', + custom_social_callback_url_note: + 'Bu URI\'nin alan adını uygulamanızın uç noktasıyla eşleştirmek için özelleştirebilirsiniz. "{{custom}}" veya "{{default}}" seçeneklerinden birini seçin.', }; export default domain; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/domain.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/domain.ts index 9ede13d1b..a7398e3e4 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/domain.ts @@ -42,6 +42,9 @@ const domain = { 'Logto 提供了一个预配置的默认域名,无需任何其他设置即可使用。即使您启用了自定义域名,此默认域名也可作为备用选项。', default_domain_field: 'Logto 默认域名', }, + custom_endpoint_note: '您可以根据需要自定义这些端点的域名。选择 "{{custom}}" 或 "{{default}}"。', + custom_social_callback_url_note: + '您可以根据需要自定义此 URI 的域名,以匹配您的应用程序端点。选择 "{{custom}}" 或 "{{default}}"。', }; export default domain; diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/domain.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/domain.ts index 8bfec41cc..eb9181d98 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/domain.ts @@ -42,6 +42,9 @@ const domain = { 'Logto提供預配置的默認域名,無需進行任何其他設置即可使用。即使啟用了自定義域名,此默認域名也可作為備用選項。', default_domain_field: 'Logto 默認域名', }, + custom_endpoint_note: '您可以根據需要自定義這些端點的域名。選擇“{{custom}}”或“{{default}}”。', + custom_social_callback_url_note: + '您可以自定義此URI的域名以匹配您的應用程序端點。選擇“{{custom}}”或“{{default}}”。', }; export default domain; diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/domain.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/domain.ts index e5a4c00fd..a2847ee6f 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/domain.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/domain.ts @@ -42,6 +42,9 @@ const domain = { 'Logto 提供預先配置的預設網域,無需進行任何其他設置即可使用。即使啟用了自訂網域,此預設網域也可作為備用選項。', default_domain_field: 'Logto 默認網域', }, + custom_endpoint_note: '您可以根據需要自定義這些端點的域名。選擇“{{custom}}”或“{{default}}”。', + custom_social_callback_url_note: + '您可以自定義此 URI 的域名以匹配您的應用程序端點。選擇“{{custom}}”或“{{default}}”。', }; export default domain;