diff --git a/.changeset/hungry-dodos-do.md b/.changeset/hungry-dodos-do.md new file mode 100644 index 000000000..035ebf403 --- /dev/null +++ b/.changeset/hungry-dodos-do.md @@ -0,0 +1,10 @@ +--- +"@logto/console": patch +"@logto/phrases": patch +--- + +api resource indicator must be a valid absolute uri + +An invalid indicator will make Console crash without this check. + +Note: We don't mark it as a breaking change as the api behavior has not changed, only adding the check on Console. diff --git a/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx b/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx index 677b88b5a..c8b15ee10 100644 --- a/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx +++ b/packages/console/src/pages/ApiResources/components/CreateForm/index.tsx @@ -1,3 +1,4 @@ +import { isValidUrl } from '@logto/core-kit'; import { type Resource } from '@logto/schemas'; import { useForm } from 'react-hook-form'; import { toast } from 'react-hot-toast'; @@ -29,7 +30,7 @@ function CreateForm({ onClose }: Props) { const { handleSubmit, register, - formState: { isSubmitting }, + formState: { isSubmitting, errors }, } = useForm(); const api = useApi(); @@ -91,8 +92,13 @@ function CreateForm({ onClose }: Props) { )} > + isValidUrl(value) || t('api_resources.invalid_resource_indicator_format'), + })} placeholder={t('api_resources.api_identifier_placeholder')} + error={errors.indicator?.message} /> diff --git a/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts index b7f20a5f1..7999e5ced 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Pro Mandant kann nur eine Standard-API festgelegt werden. Wenn eine Standard-API festgelegt ist, kann der Ressourcenparameter in der Authentifizierungsanfrage weggelassen werden. Folgende Token-Austauschvorgänge verwenden standardmäßig die API als Publikum, was zur Ausgabe von JWTs führt. Erfahren Sie mehr', api_resource_created: 'Die API-Ressource {{name}} wurde erfolgreich erstellt', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/en/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/en/translation/admin-console/api-resources.ts index 301b7bd9f..7a3388a31 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/api-resources.ts @@ -13,6 +13,7 @@ const api_resources = { default_api_label: 'Only zero or one default API can be set per tenant.\nWhen a default API is designated, the resource parameter can be omitted in the auth request. Subsequent token exchanges will use that API as the audience by default, resulting in the issuance of JWTs. Learn more', api_resource_created: 'The API resource {{name}} has been successfully created', + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/es/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/es/translation/admin-console/api-resources.ts index 08ed74828..3aad961ac 100644 --- a/packages/phrases/src/locales/es/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/es/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Sólo se puede establecer cero o una API por defecto por inquilino. Cuando se designa una API por defecto, el parámetro de recurso se puede omitir en la solicitud de autenticación. Las posteriores intercambios de tokens utilizarán esa API como audiencia por defecto, lo que dará lugar a la emisión de JWTs. Obtener más información', api_resource_created: 'El recurso de API {{name}} se ha creado correctamente', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/fr/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/fr/translation/admin-console/api-resources.ts index 2574ba402..cedaf8b96 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Seulement zéro ou une API par défaut peut être définie par tenant. Lorsqu\'une API par défaut est désignée, le paramètre "resource" peut être omis dans la demande d\'authentification. Les échanges de jetons ultérieurs utiliseront cette API comme public cible par défaut, ce qui entraînera la délivrance de JWT. En savoir plus', api_resource_created: 'La ressource API {{name}} a été créée avec succès.', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/it/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/it/translation/admin-console/api-resources.ts index 8d29d4c52..011dc7734 100644 --- a/packages/phrases/src/locales/it/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/it/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Solo zero o una API predefinita possono essere impostate per tenant. Quando viene designata una API predefinita, il parametro di risorsa può essere omesso nella richiesta di autorizzazione. Gli scambi di token successivi utilizzeranno quell API come destinatario per impostazione predefinita, con conseguente rilascio di JWT. Scopri di più', api_resource_created: 'La risorsa API {{name}} è stata creata con successo', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/ja/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/ja/translation/admin-console/api-resources.ts index 6f7e8cad7..441155672 100644 --- a/packages/phrases/src/locales/ja/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/ja/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'テナントごとにデフォルトのAPIを0または1つだけ設定できます。デフォルトのAPIが指定されている場合、認証リクエストでリソースパラメータを省略できます。その後のトークン交換は、デフォルトのAPIを対象として行われます。それにより、JWTが発行されます。詳細を見る', api_resource_created: 'APIリソース{{name}}が正常に作成されました', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/ko/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/ko/translation/admin-console/api-resources.ts index 7771ca919..ee79d3d42 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: '테넌트 당 기본 API는 0개 또는 1개만 지정 할 수 있어요. 기본 API가 지정되면 인증 요청에서 리소스 매개 변수를 생략할 수 있어요. 이후 토큰 교환이 기본적으로 대상에 해당하는 API를 사용하여 수행되어 JWT가 발급되어요. 자세히 알아보기', api_resource_created: '{{name}} API 리소스가 성공적으로 생성되었어요.', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/pl-pl/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/pl-pl/translation/admin-console/api-resources.ts index 630aaecb5..a46740f88 100644 --- a/packages/phrases/src/locales/pl-pl/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/pl-pl/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Tylko jedno API domyślne może być ustawione na jeden najem. Kiedy określone zostanie API domyślne, parametr zasobu może zostać pominięty w żądaniu autoryzacji. Następujące procesy wymiany tokenu będą domyślnie korzystać z tego API, co umożliwi wydanie JWT. Dowiedz się więcej', api_resource_created: 'Zasób API {{name}} został pomyślnie utworzony', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/api-resources.ts index 7b16238e9..6b27574f4 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Apenas uma API padrão pode ser definida por locatário. Quando uma API padrão é definida, o parâmetro de recurso pode ser omitido na solicitação de autenticação. As trocas de token subsequentes usarão essa API como audiência por padrão, resultando na emissão de JWTs. Saiba mais', api_resource_created: 'O recurso API {{name}} foi criado com sucesso', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/api-resources.ts index 6cb4822bc..ebac242fb 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Somente uma API padrão pode ser definida por inquilino. Quando uma API padrão é definida, o parâmetro de recurso pode ser omitido na solicitação de autorização. Subsequentes trocas de token usarão essa API como audiência por padrão, resultando na emissão de JWTs. Saiba mais', api_resource_created: 'O recurso de API {{name}} foi criado com sucesso', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/ru/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/ru/translation/admin-console/api-resources.ts index 5478b03b1..d7f356b55 100644 --- a/packages/phrases/src/locales/ru/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/ru/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'В каждом арендаторе может быть только один API по умолчанию. Когда устанавливается API по умолчанию, можно опустить параметр resource в запросе на аутентификацию. Последующие запросы на обмен токенами будут использовать указанное API в качестве аудитории по умолчанию, что приведет к выдаче JWT. Узнать больше', api_resource_created: 'Ресурс API {{name}} был успешно создан', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/api-resources.ts index 10b022188..241dd02bc 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: 'Mandant başına sadece sıfır veya bir varsayılan API ayarlanabilir. Varsayılan bir API belirlendiğinde, auth isteğindeki kaynak parametresi çıkarılabilir. Sonraki token değişimlerinde varsayılan olarak bu API hedef alınarak JWTler oluşturulur. Daha fazla bilgi edinin', api_resource_created: '{{name}} API kaynağı başarıyla oluşturuldu', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/api-resources.ts index 3a7a22747..0fe1b9b5c 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: '每个租户只能设置零个或一个默认 API。当指定默认 API 时,可以在认证请求中省略资源参数。后续令牌交换将默认使用该 API 作为 Audience,从而签发 JWT。了解更多', api_resource_created: ' API 资源 {{name}} 已成功创建。', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/zh-hk/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/zh-hk/translation/admin-console/api-resources.ts index 2ece458d8..8d5c757ed 100644 --- a/packages/phrases/src/locales/zh-hk/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/zh-hk/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: '一个租户只能设置零或一个默认 API。当指定默认 API 时,可以在身份验证请求中省略资源参数,还可以使用该 API 作为默认受众方进行令牌交换,从而发放 JWT。了解更多', api_resource_created: ' API 資源 {{name}} 已成功創建。', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources); diff --git a/packages/phrases/src/locales/zh-tw/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/zh-tw/translation/admin-console/api-resources.ts index e7321a68c..3c3d730e6 100644 --- a/packages/phrases/src/locales/zh-tw/translation/admin-console/api-resources.ts +++ b/packages/phrases/src/locales/zh-tw/translation/admin-console/api-resources.ts @@ -13,6 +13,8 @@ const api_resources = { default_api_label: '一個租戶只能設定零個或一個預設 API。當指定了預設 API 後,可以在授權請求中省略 `resource` 參數。隨後的令牌交換將使用該 API 作為默認的 Audience,從而產生 JWT。了解更多', api_resource_created: ' API 資源 {{name}} 已成功創建。', + /** UNTRANSLATED */ + invalid_resource_indicator_format: 'API indicator must be a valid absolute URI.', }; export default Object.freeze(api_resources);