0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

feat(core,console): prevent target change after created ()

This commit is contained in:
wangsijie 2022-12-06 18:03:29 +08:00 committed by GitHub
parent 6d76a5e169
commit a64816422e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 30 additions and 5 deletions
packages
console/src/pages/Connectors/components
ConnectorForm
Guide
core/src/routes
phrases/src/locales

View file

@ -17,9 +17,10 @@ import * as styles from './index.module.scss';
type Props = {
connector: ConnectorFactoryResponse;
isAllowEditTarget?: boolean;
};
const ConnectorForm = ({ connector }: Props) => {
const ConnectorForm = ({ connector, isAllowEditTarget }: Props) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { configTemplate, isStandard } = connector;
const {
@ -86,6 +87,7 @@ const ConnectorForm = ({ connector }: Props) => {
<FormField isRequired title="connectors.guide.target">
<TextInput
hasError={Boolean(errors.target)}
disabled={!isAllowEditTarget}
{...register('target', { required: true })}
/>
<div className={styles.tip}>{t('connectors.guide.target_tip')}</div>

View file

@ -109,7 +109,7 @@ const Guide = ({ connector, onClose }: Props) => {
<div className={styles.title}>{t('connectors.guide.connector_setting')}</div>
<FormProvider {...methods}>
<form onSubmit={onSubmit}>
<ConnectorForm connector={connector} />
<ConnectorForm isAllowEditTarget connector={connector} />
{!isSocialConnector && (
<SenderTester
className={styles.tester}

View file

@ -197,6 +197,8 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
if (config) {
validateConfig(config);
}
// Once created, target can not be modified.
assertThat(body.metadata?.target === undefined, 'connector.can_not_modify_target');
const { metadata: databaseMetadata, ...rest } = body;
await updateConnector({

View file

@ -90,6 +90,23 @@ describe('connector PATCH routes', () => {
expect(response).toHaveProperty('statusCode', 500);
});
it('throws when trying to update target', async () => {
getLogtoConnectorsPlaceholder.mockResolvedValue([
{
dbEntry: mockConnector,
metadata: { ...mockMetadata, isStandard: true },
type: ConnectorType.Social,
...mockLogtoConnector,
},
]);
const response = await connectorRequest.patch('/connectors/id').send({
metadata: {
target: 'target',
},
});
expect(response).toHaveProperty('statusCode', 400);
});
it('successfully updates connector configs', async () => {
getLogtoConnectorsPlaceholder.mockResolvedValue([
{
@ -110,7 +127,6 @@ describe('connector PATCH routes', () => {
const response = await connectorRequest.patch('/connectors/id').send({
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
metadata: {
target: 'target',
name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png',
logoDark: null,
@ -122,7 +138,6 @@ describe('connector PATCH routes', () => {
set: {
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
metadata: {
target: 'target',
name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png',
},
@ -153,7 +168,6 @@ describe('connector PATCH routes', () => {
});
const response = await connectorRequest.patch('/connectors/id').send({
metadata: {
target: '',
name: { en: '' },
logo: '',
logoDark: '',

View file

@ -105,6 +105,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.',
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.',
can_not_modify_target: 'The connector target can not be modified.',
},
passcode: {
phone_email_empty: 'Telefonnummer oder E-Mail darf nicht leer sein.',

View file

@ -104,6 +104,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.',
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.',
can_not_modify_target: 'The connector target can not be modified.',
},
passcode: {
phone_email_empty: 'Both phone and email are empty.',

View file

@ -111,6 +111,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.', // UNTRANSLATED
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.', // UNTRANSLATED
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
},
passcode: {
phone_email_empty: "Le téléphone et l'email sont vides.",

View file

@ -103,6 +103,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.', // UNTRANSLATED
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.', // UNTRANSLATED
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
},
passcode: {
phone_email_empty: '휴대전화번호 그리고 이메일이 비어있어요.',

View file

@ -106,6 +106,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.', // UNTRANSLATED
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.', // UNTRANSLATED
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
},
passcode: {
phone_email_empty: 'O campos telefone e email estão vazios.',

View file

@ -105,6 +105,7 @@ const errors = {
multiple_instances_not_supported:
'Can not create multiple instance with picked standard connector.', // UNTRANSLATED
invalid_type_for_syncing_profile: 'You can only sync user profile with social connectors.', // UNTRANSLATED
can_not_modify_target: 'The connector target can not be modified.', // UNTRANSLATED
},
passcode: {
phone_email_empty: 'Hem telefon hem de e-posta adresi yok.',

View file

@ -100,6 +100,7 @@ const errors = {
not_found_with_connector_id: '找不到所给 connector id 对应的连接器',
multiple_instances_not_supported: '你选择的连接器不支持创建多实例。',
invalid_type_for_syncing_profile: '只有社交连接器可以开启用户档案同步。',
can_not_modify_target: '不可修改连接器 target。',
},
passcode: {
phone_email_empty: '手机号与邮箱地址均为空',