From b277cb3b997c84128edb80992eb7c9fbccd34b73 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Tue, 14 Nov 2023 10:07:13 +0800 Subject: [PATCH] feat(core,phrases): add sso domains validation (#4855) * feat(core,phrases): add sso domains validation add sso domains validation * chore(core): align the naming align the naming --- .../core/src/routes/sso-connector/index.ts | 7 +++ .../src/routes/sso-connector/utils.test.ts | 44 ++++++++++++- .../core/src/routes/sso-connector/utils.ts | 61 ++++++++++++++++++- packages/core/src/sso/index.ts | 22 +++++++ .../phrases/src/locales/de/errors/index.ts | 2 + .../src/locales/de/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/en/errors/index.ts | 2 + .../src/locales/en/errors/single-sign-on.ts | 6 ++ .../phrases/src/locales/es/errors/index.ts | 2 + .../src/locales/es/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/fr/errors/index.ts | 2 + .../src/locales/fr/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/it/errors/index.ts | 2 + .../src/locales/it/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/ja/errors/index.ts | 2 + .../src/locales/ja/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/ko/errors/index.ts | 2 + .../src/locales/ko/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/pl-pl/errors/index.ts | 2 + .../locales/pl-pl/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/pt-br/errors/index.ts | 2 + .../locales/pt-br/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/pt-pt/errors/index.ts | 2 + .../locales/pt-pt/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/ru/errors/index.ts | 2 + .../src/locales/ru/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/tr-tr/errors/index.ts | 2 + .../locales/tr-tr/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/zh-cn/errors/index.ts | 2 + .../locales/zh-cn/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/zh-hk/errors/index.ts | 2 + .../locales/zh-hk/errors/single-sign-on.ts | 8 +++ .../phrases/src/locales/zh-tw/errors/index.ts | 2 + .../locales/zh-tw/errors/single-sign-on.ts | 8 +++ 34 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 packages/phrases/src/locales/de/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/en/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/es/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/fr/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/it/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/ja/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/ko/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/pl-pl/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/pt-br/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/pt-pt/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/ru/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/tr-tr/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/zh-cn/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/zh-hk/errors/single-sign-on.ts create mode 100644 packages/phrases/src/locales/zh-tw/errors/single-sign-on.ts diff --git a/packages/core/src/routes/sso-connector/index.ts b/packages/core/src/routes/sso-connector/index.ts index 9ba38cb00..57b6e996c 100644 --- a/packages/core/src/routes/sso-connector/index.ts +++ b/packages/core/src/routes/sso-connector/index.ts @@ -22,6 +22,7 @@ import { parseFactoryDetail, parseConnectorConfig, fetchConnectorProviderDetails, + validateConnectorDomains, } from './utils.js'; export default function singleSignOnRoutes(...args: RouterInitArgs) { @@ -93,6 +94,9 @@ export default function singleSignOnRoutes(...args: Rout }); } + // Validate the connector domains if it's provided + validateConnectorDomains(rest.domains); + /* Validate the connector config if it's provided. Allow partial config settings on create. @@ -195,6 +199,9 @@ export default function singleSignOnRoutes(...args: Rout const { providerName } = originalConnector; const { config, ...rest } = body; + // Validate the connector domains if it's provided + validateConnectorDomains(rest.domains); + // Validate the connector config if it's provided const parsedConfig = config && parseConnectorConfig(providerName, config); diff --git a/packages/core/src/routes/sso-connector/utils.test.ts b/packages/core/src/routes/sso-connector/utils.test.ts index ed3ff4f5e..eb4734164 100644 --- a/packages/core/src/routes/sso-connector/utils.test.ts +++ b/packages/core/src/routes/sso-connector/utils.test.ts @@ -1,6 +1,7 @@ import { createMockUtils } from '@logto/shared/esm'; import { mockSsoConnector } from '#src/__mocks__/sso.js'; +import RequestError from '#src/errors/RequestError/index.js'; import { SsoProviderName } from '#src/sso/types/index.js'; const { jest } = import.meta; @@ -12,7 +13,8 @@ await mockEsmWithActual('#src/sso/OidcConnector/utils.js', () => ({ })); const { ssoConnectorFactories } = await import('#src/sso/index.js'); -const { parseFactoryDetail, fetchConnectorProviderDetails } = await import('./utils.js'); +const { parseFactoryDetail, fetchConnectorProviderDetails, validateConnectorDomains } = + await import('./utils.js'); const mockTenantId = 'mock_tenant_id'; @@ -99,3 +101,43 @@ describe('fetchConnectorProviderDetails', () => { ); }); }); + +describe('validateConnectorDomains', () => { + it('should directly return if domains are not provided', () => { + expect(() => { + validateConnectorDomains(); + }).not.toThrow(); + }); + + it('should directly return if domains are empty', () => { + expect(() => { + validateConnectorDomains([]); + }).not.toThrow(); + }); + + it('should throw error if domains are duplicated', () => { + expect(() => { + validateConnectorDomains(['foo.io', 'bar.io', 'foo.io']); + }).toMatchError( + new RequestError( + { code: 'single_sign_on.duplicated_domains', status: 422 }, + { + data: ['foo.io'], + } + ) + ); + }); + + it('should throw error if domains are in the blacklist', () => { + expect(() => { + validateConnectorDomains(['foo.io', 'bar.io', 'gmail.com']); + }).toMatchError( + new RequestError( + { code: 'single_sign_on.forbidden_domains', status: 422 }, + { + data: ['gmail.com'], + } + ) + ); + }); +}); diff --git a/packages/core/src/routes/sso-connector/utils.ts b/packages/core/src/routes/sso-connector/utils.ts index b1bdde08b..44f9fe3c5 100644 --- a/packages/core/src/routes/sso-connector/utils.ts +++ b/packages/core/src/routes/sso-connector/utils.ts @@ -3,7 +3,11 @@ import { type JsonObject, type SsoConnectorWithProviderConfig } from '@logto/sch import { conditional, trySafe } from '@silverhand/essentials'; import RequestError from '#src/errors/RequestError/index.js'; -import { type SingleSignOnFactory, ssoConnectorFactories } from '#src/sso/index.js'; +import { + type SingleSignOnFactory, + ssoConnectorFactories, + singleSignOnDomainBlackList, +} from '#src/sso/index.js'; import { type SupportedSsoConnector, type SsoProviderName } from '#src/sso/types/index.js'; const isKeyOfI18nPhrases = (key: string, phrases: I18nPhrases): key is keyof I18nPhrases => @@ -73,3 +77,58 @@ export const fetchConnectorProviderDetails = async ( ...conditional(providerConfig && { providerConfig }), }; }; + +/** + * Validate the connector domains using the domain blacklist. + * - Throw error if the domains are invalid. + * - Throw error if the domains are duplicated. + * + * @param domains + * @returns + */ +export const validateConnectorDomains = (domains?: string[]) => { + if (!domains || domains.length === 0) { + return; + } + + const blackListSet = new Set(singleSignOnDomainBlackList); + const validDomainSet = new Set(); + const duplicatedDomains = new Set(); + const forbiddenDomains = new Set(); + + for (const domain of domains) { + if (blackListSet.has(domain)) { + forbiddenDomains.add(domain); + } + + if (validDomainSet.has(domain)) { + duplicatedDomains.add(domain); + } else { + validDomainSet.add(domain); + } + } + + if (forbiddenDomains.size > 0) { + throw new RequestError( + { + code: 'single_sign_on.forbidden_domains', + status: 422, + }, + { + data: [...forbiddenDomains], + } + ); + } + + if (duplicatedDomains.size > 0) { + throw new RequestError( + { + code: 'single_sign_on.duplicated_domains', + status: 422, + }, + { + data: [...duplicatedDomains], + } + ); + } +}; diff --git a/packages/core/src/sso/index.ts b/packages/core/src/sso/index.ts index f4573230f..b17a534cf 100644 --- a/packages/core/src/sso/index.ts +++ b/packages/core/src/sso/index.ts @@ -38,3 +38,25 @@ export const standardSsoConnectorProviders = Object.freeze([ SsoProviderName.OIDC, SsoProviderName.SAML, ]); + +export const singleSignOnDomainBlackList = Object.freeze([ + 'gmail.com', + 'yahoo.com', + 'hotmail.com', + 'outlook.com', + 'live.com', + 'icloud.com', + 'aol.com', + 'yandex.com', + 'mail.com', + 'protonmail.com', + 'yanex.com', + 'gmx.com', + 'mail.ru', + 'zoho.com', + 'qq.com', + '163.com', + '126.com', + 'sina.com', + 'sohu.com', +]); diff --git a/packages/phrases/src/locales/de/errors/index.ts b/packages/phrases/src/locales/de/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/de/errors/index.ts +++ b/packages/phrases/src/locales/de/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/de/errors/single-sign-on.ts b/packages/phrases/src/locales/de/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/de/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/en/errors/index.ts b/packages/phrases/src/locales/en/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/en/errors/index.ts +++ b/packages/phrases/src/locales/en/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/en/errors/single-sign-on.ts b/packages/phrases/src/locales/en/errors/single-sign-on.ts new file mode 100644 index 000000000..03c486112 --- /dev/null +++ b/packages/phrases/src/locales/en/errors/single-sign-on.ts @@ -0,0 +1,6 @@ +const single_sign_on = { + forbidden_domains: 'Public email domains are not allowed.', + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/es/errors/index.ts b/packages/phrases/src/locales/es/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/es/errors/index.ts +++ b/packages/phrases/src/locales/es/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/es/errors/single-sign-on.ts b/packages/phrases/src/locales/es/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/es/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/fr/errors/index.ts b/packages/phrases/src/locales/fr/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/fr/errors/index.ts +++ b/packages/phrases/src/locales/fr/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/fr/errors/single-sign-on.ts b/packages/phrases/src/locales/fr/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/fr/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/it/errors/index.ts b/packages/phrases/src/locales/it/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/it/errors/index.ts +++ b/packages/phrases/src/locales/it/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/it/errors/single-sign-on.ts b/packages/phrases/src/locales/it/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/it/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/ja/errors/index.ts b/packages/phrases/src/locales/ja/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/ja/errors/index.ts +++ b/packages/phrases/src/locales/ja/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/ja/errors/single-sign-on.ts b/packages/phrases/src/locales/ja/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/ja/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/ko/errors/index.ts b/packages/phrases/src/locales/ko/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/ko/errors/index.ts +++ b/packages/phrases/src/locales/ko/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/ko/errors/single-sign-on.ts b/packages/phrases/src/locales/ko/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/ko/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/pl-pl/errors/index.ts b/packages/phrases/src/locales/pl-pl/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/pl-pl/errors/index.ts +++ b/packages/phrases/src/locales/pl-pl/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/pl-pl/errors/single-sign-on.ts b/packages/phrases/src/locales/pl-pl/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/pl-pl/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/pt-br/errors/index.ts b/packages/phrases/src/locales/pt-br/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/pt-br/errors/index.ts +++ b/packages/phrases/src/locales/pt-br/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/pt-br/errors/single-sign-on.ts b/packages/phrases/src/locales/pt-br/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/pt-br/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/pt-pt/errors/index.ts b/packages/phrases/src/locales/pt-pt/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/pt-pt/errors/index.ts +++ b/packages/phrases/src/locales/pt-pt/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/pt-pt/errors/single-sign-on.ts b/packages/phrases/src/locales/pt-pt/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/pt-pt/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/ru/errors/index.ts b/packages/phrases/src/locales/ru/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/ru/errors/index.ts +++ b/packages/phrases/src/locales/ru/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/ru/errors/single-sign-on.ts b/packages/phrases/src/locales/ru/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/ru/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/tr-tr/errors/index.ts b/packages/phrases/src/locales/tr-tr/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/tr-tr/errors/index.ts +++ b/packages/phrases/src/locales/tr-tr/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/tr-tr/errors/single-sign-on.ts b/packages/phrases/src/locales/tr-tr/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/tr-tr/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/zh-cn/errors/index.ts b/packages/phrases/src/locales/zh-cn/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/zh-cn/errors/index.ts +++ b/packages/phrases/src/locales/zh-cn/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/zh-cn/errors/single-sign-on.ts b/packages/phrases/src/locales/zh-cn/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/zh-cn/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/zh-hk/errors/index.ts b/packages/phrases/src/locales/zh-hk/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/zh-hk/errors/index.ts +++ b/packages/phrases/src/locales/zh-hk/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/zh-hk/errors/single-sign-on.ts b/packages/phrases/src/locales/zh-hk/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/zh-hk/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on); diff --git a/packages/phrases/src/locales/zh-tw/errors/index.ts b/packages/phrases/src/locales/zh-tw/errors/index.ts index acf9eda5f..74995792d 100644 --- a/packages/phrases/src/locales/zh-tw/errors/index.ts +++ b/packages/phrases/src/locales/zh-tw/errors/index.ts @@ -16,6 +16,7 @@ import role from './role.js'; import scope from './scope.js'; import session from './session.js'; import sign_in_experiences from './sign-in-experiences.js'; +import single_sign_on from './single-sign-on.js'; import storage from './storage.js'; import subscription from './subscription.js'; import swagger from './swagger.js'; @@ -46,6 +47,7 @@ const errors = { subscription, application, organization, + single_sign_on, }; export default Object.freeze(errors); diff --git a/packages/phrases/src/locales/zh-tw/errors/single-sign-on.ts b/packages/phrases/src/locales/zh-tw/errors/single-sign-on.ts new file mode 100644 index 000000000..4950a49e2 --- /dev/null +++ b/packages/phrases/src/locales/zh-tw/errors/single-sign-on.ts @@ -0,0 +1,8 @@ +const single_sign_on = { + /** UNTRANSLATED */ + forbidden_domains: 'Public email domains are not allowed.', + /** UNTRANSLATED */ + duplicated_domains: 'There are duplicate domains.', +}; + +export default Object.freeze(single_sign_on);