mirror of
https://github.com/logto-io/logto.git
synced 2025-03-10 22:22:45 -05:00
feat(core): validate connector config before enabling (#478)
* feat(core): validate connector config before enabling * feat(core): remove code redundancy
This commit is contained in:
parent
4c18734530
commit
004fe65d5a
2 changed files with 74 additions and 10 deletions
|
@ -182,7 +182,7 @@ describe('connector route', () => {
|
||||||
expect(response).toHaveProperty('statusCode', 400);
|
expect(response).toHaveProperty('statusCode', 400);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('enables one of the social connectors', async () => {
|
it('enables one of the social connectors (with valid config)', async () => {
|
||||||
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
return {
|
return {
|
||||||
connector: {
|
connector: {
|
||||||
|
@ -199,6 +199,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
|
validateConfig: jest.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const response = await connectorRequest
|
const response = await connectorRequest
|
||||||
|
@ -223,6 +224,34 @@ describe('connector route', () => {
|
||||||
expect(response).toHaveProperty('statusCode', 200);
|
expect(response).toHaveProperty('statusCode', 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('enables one of the social connectors (with invalid config)', async () => {
|
||||||
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
|
return {
|
||||||
|
connector: {
|
||||||
|
id: 'connector_0',
|
||||||
|
enabled: true,
|
||||||
|
config: {},
|
||||||
|
createdAt: 1_234_567_890_123,
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
id: 'connector_0',
|
||||||
|
type: ConnectorType.Social,
|
||||||
|
name: {},
|
||||||
|
logo: './logo.png',
|
||||||
|
description: {},
|
||||||
|
readme: 'README.md',
|
||||||
|
},
|
||||||
|
validateConfig: async () => {
|
||||||
|
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const response = await connectorRequest
|
||||||
|
.patch('/connectors/connector_0/enabled')
|
||||||
|
.send({ enabled: true });
|
||||||
|
expect(response).toHaveProperty('statusCode', 500);
|
||||||
|
});
|
||||||
|
|
||||||
it('disables one of the social connectors', async () => {
|
it('disables one of the social connectors', async () => {
|
||||||
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
return {
|
return {
|
||||||
|
@ -264,7 +293,7 @@ describe('connector route', () => {
|
||||||
expect(response).toHaveProperty('statusCode', 200);
|
expect(response).toHaveProperty('statusCode', 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('enables one of the email/sms connectors', async () => {
|
it('enables one of the email/sms connectors (with valid config)', async () => {
|
||||||
getConnectorInstancesPlaceHolder.mockResolvedValueOnce(mockConnectorInstanceList);
|
getConnectorInstancesPlaceHolder.mockResolvedValueOnce(mockConnectorInstanceList);
|
||||||
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
return {
|
return {
|
||||||
|
@ -282,6 +311,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
|
validateConfig: jest.fn(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const response = await connectorRequest
|
const response = await connectorRequest
|
||||||
|
@ -321,6 +351,35 @@ describe('connector route', () => {
|
||||||
expect(response).toHaveProperty('statusCode', 200);
|
expect(response).toHaveProperty('statusCode', 200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('enables one of the email/sms connectors (with invalid config)', async () => {
|
||||||
|
getConnectorInstancesPlaceHolder.mockResolvedValueOnce(mockConnectorInstanceList);
|
||||||
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
|
return {
|
||||||
|
connector: {
|
||||||
|
id: 'connector_1',
|
||||||
|
enabled: true,
|
||||||
|
config: {},
|
||||||
|
createdAt: 1_234_567_890_234,
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
id: 'connector_1',
|
||||||
|
type: ConnectorType.SMS,
|
||||||
|
name: {},
|
||||||
|
logo: './logo.png',
|
||||||
|
description: {},
|
||||||
|
readme: 'README.md',
|
||||||
|
},
|
||||||
|
validateConfig: async () => {
|
||||||
|
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
const response = await connectorRequest
|
||||||
|
.patch('/connectors/connector_1/enabled')
|
||||||
|
.send({ enabled: true });
|
||||||
|
expect(response).toHaveProperty('statusCode', 500);
|
||||||
|
});
|
||||||
|
|
||||||
it('disables one of the email/sms connectors', async () => {
|
it('disables one of the email/sms connectors', async () => {
|
||||||
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
getConnectorInstanceByIdPlaceHolder.mockImplementationOnce(async (_id: string) => {
|
||||||
return {
|
return {
|
||||||
|
@ -417,7 +476,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
validateConfig: async (_config) => {
|
validateConfig: async () => {
|
||||||
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
|
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -445,8 +504,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
validateConfig: jest.fn(),
|
||||||
validateConfig: async (_config) => {},
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const response = await connectorRequest
|
const response = await connectorRequest
|
||||||
|
@ -493,8 +551,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
validateConfig: jest.fn(),
|
||||||
validateConfig: async (_config: any) => {},
|
|
||||||
sendMessage: async (
|
sendMessage: async (
|
||||||
address: string,
|
address: string,
|
||||||
type: keyof EmailMessageTypes,
|
type: keyof EmailMessageTypes,
|
||||||
|
@ -538,8 +595,7 @@ describe('connector route', () => {
|
||||||
description: {},
|
description: {},
|
||||||
readme: 'README.md',
|
readme: 'README.md',
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
validateConfig: jest.fn(),
|
||||||
validateConfig: async (_config: any) => {},
|
|
||||||
sendMessage: async (
|
sendMessage: async (
|
||||||
address: string,
|
address: string,
|
||||||
type: keyof EmailMessageTypes,
|
type: keyof EmailMessageTypes,
|
||||||
|
|
|
@ -73,7 +73,15 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
|
||||||
params: { id },
|
params: { id },
|
||||||
body: { enabled },
|
body: { enabled },
|
||||||
} = ctx.guard;
|
} = ctx.guard;
|
||||||
const { metadata } = await getConnectorInstanceById(id);
|
const {
|
||||||
|
connector: { config },
|
||||||
|
metadata,
|
||||||
|
validateConfig,
|
||||||
|
} = await getConnectorInstanceById(id);
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
await validateConfig(config);
|
||||||
|
}
|
||||||
|
|
||||||
// Only allow one enabled connector for SMS and Email.
|
// Only allow one enabled connector for SMS and Email.
|
||||||
// disable other connectors before enable this one.
|
// disable other connectors before enable this one.
|
||||||
|
|
Loading…
Add table
Reference in a new issue