0
Fork 0
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:
Darcy Ye 2022-12-09 12:13:22 +08:00 committed by GitHub
parent 698610a12f
commit ce1aaeeae3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 7 deletions

View file

@ -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 */

View file

@ -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 })
); );