mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
feat(core): cannot delete custom phrase used as default language in sign-in exp (#1951)
This commit is contained in:
parent
29466a9350
commit
a1aef26905
8 changed files with 49 additions and 1 deletions
packages
core/src/routes
phrases/src/locales
|
@ -1,5 +1,6 @@
|
||||||
import { CustomPhrase } from '@logto/schemas';
|
import { CustomPhrase } from '@logto/schemas';
|
||||||
|
|
||||||
|
import { mockSignInExperience } from '@/__mocks__';
|
||||||
import RequestError from '@/errors/RequestError';
|
import RequestError from '@/errors/RequestError';
|
||||||
import customPhraseRoutes from '@/routes/custom-phrase';
|
import customPhraseRoutes from '@/routes/custom-phrase';
|
||||||
import { createRequester } from '@/utils/test-utils';
|
import { createRequester } from '@/utils/test-utils';
|
||||||
|
@ -48,6 +49,12 @@ jest.mock('@/queries/custom-phrase', () => ({
|
||||||
upsertCustomPhrase: async (customPhrase: CustomPhrase) => upsertCustomPhrase(customPhrase),
|
upsertCustomPhrase: async (customPhrase: CustomPhrase) => upsertCustomPhrase(customPhrase),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const findDefaultSignInExperience = jest.fn(async () => mockSignInExperience);
|
||||||
|
|
||||||
|
jest.mock('@/queries/sign-in-experience', () => ({
|
||||||
|
findDefaultSignInExperience: async () => findDefaultSignInExperience(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('customPhraseRoutes', () => {
|
describe('customPhraseRoutes', () => {
|
||||||
const customPhraseRequest = createRequester({ authedRoutes: customPhraseRoutes });
|
const customPhraseRequest = createRequester({ authedRoutes: customPhraseRoutes });
|
||||||
|
|
||||||
|
@ -122,8 +129,13 @@ describe('customPhraseRoutes', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 404 status code when the specified custom phrase does not exist before deleting', async () => {
|
it('should return 404 status code when the specified custom phrase does not exist before deleting', async () => {
|
||||||
const response = await customPhraseRequest.delete(`/custom-phrases/en-UK`);
|
const response = await customPhraseRequest.delete('/custom-phrases/en-UK');
|
||||||
expect(response.status).toEqual(404);
|
expect(response.status).toEqual(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return 400 status code when the specified custom phrase is used as default language in sign-in experience', async () => {
|
||||||
|
const response = await customPhraseRequest.delete('/custom-phrases/en');
|
||||||
|
expect(response.status).toEqual(400);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { CustomPhrases, translationGuard } from '@logto/schemas';
|
import { CustomPhrases, translationGuard } from '@logto/schemas';
|
||||||
|
|
||||||
|
import RequestError from '@/errors/RequestError';
|
||||||
import koaGuard from '@/middleware/koa-guard';
|
import koaGuard from '@/middleware/koa-guard';
|
||||||
import {
|
import {
|
||||||
deleteCustomPhraseByLanguageKey,
|
deleteCustomPhraseByLanguageKey,
|
||||||
|
@ -7,6 +8,7 @@ import {
|
||||||
findCustomPhraseByLanguageKey,
|
findCustomPhraseByLanguageKey,
|
||||||
upsertCustomPhrase,
|
upsertCustomPhrase,
|
||||||
} from '@/queries/custom-phrase';
|
} from '@/queries/custom-phrase';
|
||||||
|
import { findDefaultSignInExperience } from '@/queries/sign-in-experience';
|
||||||
|
|
||||||
import { AuthedRouter } from './types';
|
import { AuthedRouter } from './types';
|
||||||
|
|
||||||
|
@ -70,6 +72,17 @@ export default function customPhraseRoutes<T extends AuthedRouter>(router: T) {
|
||||||
params: { languageKey },
|
params: { languageKey },
|
||||||
} = ctx.guard;
|
} = ctx.guard;
|
||||||
|
|
||||||
|
const {
|
||||||
|
languageInfo: { fallbackLanguage },
|
||||||
|
} = await findDefaultSignInExperience();
|
||||||
|
|
||||||
|
if (fallbackLanguage === languageKey) {
|
||||||
|
throw new RequestError({
|
||||||
|
code: 'localization.cannot_delete_default_language',
|
||||||
|
languageKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await deleteCustomPhraseByLanguageKey(languageKey);
|
await deleteCustomPhraseByLanguageKey(languageKey);
|
||||||
ctx.status = 204;
|
ctx.status = 204;
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,10 @@ const errors = {
|
||||||
not_one_and_only_one_primary_sign_in_method:
|
not_one_and_only_one_primary_sign_in_method:
|
||||||
'There must be one and only one primary sign-in method. Please check your input.',
|
'There must be one and only one primary sign-in method. Please check your input.',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language:
|
||||||
|
'You cannot delete {{languageKey}} language since it is used as default language in sign-in experience.', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type: 'Invalid Zod type. Please check route guard config.',
|
invalid_zod_type: 'Invalid Zod type. Please check route guard config.',
|
||||||
not_supported_zod_type_for_params:
|
not_supported_zod_type_for_params:
|
||||||
|
|
|
@ -109,6 +109,10 @@ const errors = {
|
||||||
not_one_and_only_one_primary_sign_in_method:
|
not_one_and_only_one_primary_sign_in_method:
|
||||||
'Il doit y avoir une et une seule méthode de connexion primaire. Veuillez vérifier votre saisie.',
|
'Il doit y avoir une et une seule méthode de connexion primaire. Veuillez vérifier votre saisie.',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language:
|
||||||
|
'You cannot delete {{languageKey}} language since it is used as default language in sign-in experience.', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type: 'Type Zod non valide. Veuillez vérifier la configuration du garde-route.',
|
invalid_zod_type: 'Type Zod non valide. Veuillez vérifier la configuration du garde-route.',
|
||||||
not_supported_zod_type_for_params:
|
not_supported_zod_type_for_params:
|
||||||
|
|
|
@ -98,6 +98,10 @@ const errors = {
|
||||||
not_one_and_only_one_primary_sign_in_method:
|
not_one_and_only_one_primary_sign_in_method:
|
||||||
'반드시 하나의 메인 로그인 방법이 설정되어야 해요. 입력된 값을 확인해주세요.',
|
'반드시 하나의 메인 로그인 방법이 설정되어야 해요. 입력된 값을 확인해주세요.',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language:
|
||||||
|
'You cannot delete {{languageKey}} language since it is used as default language in sign-in experience.', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type: '유요하지 않은 Zod 종류에요. Route Guard 설정을 확인해주세요.',
|
invalid_zod_type: '유요하지 않은 Zod 종류에요. Route Guard 설정을 확인해주세요.',
|
||||||
not_supported_zod_type_for_params:
|
not_supported_zod_type_for_params:
|
||||||
|
|
|
@ -104,6 +104,10 @@ const errors = {
|
||||||
not_one_and_only_one_primary_sign_in_method:
|
not_one_and_only_one_primary_sign_in_method:
|
||||||
'Deve haver um e apenas um método de login principal. Por favor, verifique sua entrada.',
|
'Deve haver um e apenas um método de login principal. Por favor, verifique sua entrada.',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language:
|
||||||
|
'You cannot delete {{languageKey}} language since it is used as default language in sign-in experience.', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type: 'Tipo de Zod inválido. Verifique a configuração do protetor de rota.',
|
invalid_zod_type: 'Tipo de Zod inválido. Verifique a configuração do protetor de rota.',
|
||||||
not_supported_zod_type_for_params:
|
not_supported_zod_type_for_params:
|
||||||
|
|
|
@ -102,6 +102,10 @@ const errors = {
|
||||||
not_one_and_only_one_primary_sign_in_method:
|
not_one_and_only_one_primary_sign_in_method:
|
||||||
'Yalnızca bir tane birincil oturum açma yöntemi olmalıdır. Lütfen inputu kontrol ediniz.',
|
'Yalnızca bir tane birincil oturum açma yöntemi olmalıdır. Lütfen inputu kontrol ediniz.',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language:
|
||||||
|
'You cannot delete {{languageKey}} language since it is used as default language in sign-in experience.', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type:
|
invalid_zod_type:
|
||||||
'Geçersiz Zod tipi. Lütfen yönlendirici koruma yapılandırmasını kontrol ediniz.',
|
'Geçersiz Zod tipi. Lütfen yönlendirici koruma yapılandırmasını kontrol ediniz.',
|
||||||
|
|
|
@ -96,6 +96,9 @@ const errors = {
|
||||||
enabled_connector_not_found: '未找到已启用的 {{type}} 连接器',
|
enabled_connector_not_found: '未找到已启用的 {{type}} 连接器',
|
||||||
not_one_and_only_one_primary_sign_in_method: '主要的登录方式必须有且仅有一个,请检查你的输入。',
|
not_one_and_only_one_primary_sign_in_method: '主要的登录方式必须有且仅有一个,请检查你的输入。',
|
||||||
},
|
},
|
||||||
|
localization: {
|
||||||
|
cannot_delete_default_language: '不能删除「登录体验」正在使用的默认语言 {{languageKey}}。', // UNTRANSLATED
|
||||||
|
},
|
||||||
swagger: {
|
swagger: {
|
||||||
invalid_zod_type: '无效的 Zod 类型,请检查路由 guard 配置。',
|
invalid_zod_type: '无效的 Zod 类型,请检查路由 guard 配置。',
|
||||||
not_supported_zod_type_for_params: '请求参数不支持的 Zod 类型,请检查路由 guard 配置。',
|
not_supported_zod_type_for_params: '请求参数不支持的 Zod 类型,请检查路由 guard 配置。',
|
||||||
|
|
Loading…
Add table
Reference in a new issue