mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
fix: should block add of social connector when original target and platform exists (#2610)
This commit is contained in:
parent
698610a12f
commit
ce1aaeeae3
2 changed files with 68 additions and 7 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable max-lines */
|
||||||
import type { EmailConnector, SmsConnector } from '@logto/connector-kit';
|
import type { EmailConnector, SmsConnector } from '@logto/connector-kit';
|
||||||
import { ConnectorPlatform, MessageTypes } from '@logto/connector-kit';
|
import { ConnectorPlatform, MessageTypes } from '@logto/connector-kit';
|
||||||
import { ConnectorType } from '@logto/schemas';
|
import { ConnectorType } from '@logto/schemas';
|
||||||
|
@ -159,6 +160,14 @@ describe('connector route', () => {
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
mockedCountConnectorByConnectorId.mockResolvedValueOnce({ count: 0 });
|
mockedCountConnectorByConnectorId.mockResolvedValueOnce({ count: 0 });
|
||||||
|
getLogtoConnectorsPlaceHolder.mockResolvedValueOnce([
|
||||||
|
{
|
||||||
|
dbEntry: { ...mockConnector, connectorId: 'id0' },
|
||||||
|
metadata: { ...mockMetadata, id: 'id0' },
|
||||||
|
type: ConnectorType.Sms,
|
||||||
|
...mockLogtoConnector,
|
||||||
|
},
|
||||||
|
]);
|
||||||
const response = await connectorRequest.post('/connectors').send({
|
const response = await connectorRequest.post('/connectors').send({
|
||||||
connectorId: 'connectorId',
|
connectorId: 'connectorId',
|
||||||
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
|
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
|
||||||
|
@ -194,13 +203,27 @@ describe('connector route', () => {
|
||||||
loadConnectorFactoriesPlaceHolder.mockResolvedValueOnce([
|
loadConnectorFactoriesPlaceHolder.mockResolvedValueOnce([
|
||||||
{
|
{
|
||||||
...mockConnectorFactory,
|
...mockConnectorFactory,
|
||||||
metadata: { ...mockConnectorFactory.metadata, id: 'id0', isStandard: true },
|
metadata: {
|
||||||
|
...mockMetadata,
|
||||||
|
id: 'id0',
|
||||||
|
isStandard: true,
|
||||||
|
platform: ConnectorPlatform.Universal,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
mockedCountConnectorByConnectorId.mockResolvedValueOnce({ count: 1 });
|
mockedCountConnectorByConnectorId.mockResolvedValueOnce({ count: 1 });
|
||||||
|
getLogtoConnectorsPlaceHolder.mockResolvedValueOnce([
|
||||||
|
{
|
||||||
|
dbEntry: { ...mockConnector, connectorId: 'id0' },
|
||||||
|
metadata: { ...mockMetadata, id: 'id0', platform: ConnectorPlatform.Universal },
|
||||||
|
type: ConnectorType.Social,
|
||||||
|
...mockLogtoConnector,
|
||||||
|
},
|
||||||
|
]);
|
||||||
const response = await connectorRequest.post('/connectors').send({
|
const response = await connectorRequest.post('/connectors').send({
|
||||||
connectorId: 'id0',
|
connectorId: 'id0',
|
||||||
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
|
config: { cliend_id: 'client_id', client_secret: 'client_secret' },
|
||||||
|
metadata: { target: 'new_target' },
|
||||||
});
|
});
|
||||||
expect(response.body).toMatchObject(
|
expect(response.body).toMatchObject(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
|
@ -209,6 +232,7 @@ describe('connector route', () => {
|
||||||
cliend_id: 'client_id',
|
cliend_id: 'client_id',
|
||||||
client_secret: 'client_secret',
|
client_secret: 'client_secret',
|
||||||
},
|
},
|
||||||
|
metadata: { target: 'new_target' },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
expect(response).toHaveProperty('statusCode', 200);
|
expect(response).toHaveProperty('statusCode', 200);
|
||||||
|
@ -264,7 +288,7 @@ describe('connector route', () => {
|
||||||
expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']);
|
expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws when add more than 1 social connector instance with same target and platform', async () => {
|
it('throws when add more than 1 social connector instance with same target and platform (add from standard connector)', async () => {
|
||||||
loadConnectorFactoriesPlaceHolder.mockResolvedValueOnce([
|
loadConnectorFactoriesPlaceHolder.mockResolvedValueOnce([
|
||||||
{
|
{
|
||||||
...mockConnectorFactory,
|
...mockConnectorFactory,
|
||||||
|
@ -296,6 +320,39 @@ describe('connector route', () => {
|
||||||
});
|
});
|
||||||
expect(response).toHaveProperty('statusCode', 422);
|
expect(response).toHaveProperty('statusCode', 422);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('throws when add more than 1 social connector instance with same target and platform (add social connector)', async () => {
|
||||||
|
loadConnectorFactoriesPlaceHolder.mockResolvedValueOnce([
|
||||||
|
{
|
||||||
|
...mockConnectorFactory,
|
||||||
|
metadata: {
|
||||||
|
...mockConnectorFactory.metadata,
|
||||||
|
id: 'id0',
|
||||||
|
platform: ConnectorPlatform.Universal,
|
||||||
|
target: 'target',
|
||||||
|
isStandard: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
mockedCountConnectorByConnectorId.mockResolvedValueOnce({ count: 0 });
|
||||||
|
getLogtoConnectorsPlaceHolder.mockResolvedValueOnce([
|
||||||
|
{
|
||||||
|
dbEntry: { ...mockConnector, connectorId: 'id0', metadata: { target: 'target' } },
|
||||||
|
metadata: {
|
||||||
|
...mockMetadata,
|
||||||
|
id: 'id0',
|
||||||
|
target: 'target',
|
||||||
|
platform: ConnectorPlatform.Universal,
|
||||||
|
},
|
||||||
|
type: ConnectorType.Social,
|
||||||
|
...mockLogtoConnector,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const response = await connectorRequest.post('/connectors').send({
|
||||||
|
connectorId: 'id0',
|
||||||
|
});
|
||||||
|
expect(response).toHaveProperty('statusCode', 422);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('POST /connectors/:id/test', () => {
|
describe('POST /connectors/:id/test', () => {
|
||||||
|
@ -426,3 +483,4 @@ describe('connector route', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
/* eslint-enable max-lines */
|
||||||
|
|
|
@ -138,12 +138,15 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
if (body.metadata?.target && connectorFactory.type === ConnectorType.Social) {
|
if (connectorFactory.type === ConnectorType.Social) {
|
||||||
const connectors = await getLogtoConnectors();
|
const connectors = await getLogtoConnectors();
|
||||||
|
const connectorTarget = body.metadata?.target ?? connectorFactory.metadata.target;
|
||||||
assertThat(
|
assertThat(
|
||||||
!connectors.some(
|
!connectors
|
||||||
|
.filter(({ type }) => type === ConnectorType.Social)
|
||||||
|
.some(
|
||||||
({ metadata: { target, platform } }) =>
|
({ metadata: { target, platform } }) =>
|
||||||
target === body.metadata?.target && platform === connectorFactory.metadata.platform
|
target === connectorTarget && platform === connectorFactory.metadata.platform
|
||||||
),
|
),
|
||||||
new RequestError({ code: 'connector.multiple_target_with_same_platform', status: 422 })
|
new RequestError({ code: 'connector.multiple_target_with_same_platform', status: 422 })
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue