0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix: drop empty string, undefined and null fields of connector configurable metadata (#2576)

This commit is contained in:
Darcy Ye 2022-12-06 17:04:36 +08:00 committed by GitHub
parent 5d30810eb8
commit 57234cee66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 4 deletions

View file

@ -244,6 +244,7 @@ describe('connector route', () => {
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: 'target', name: { en: '' }, logo: '', logoDark: null },
}); });
expect(response).toHaveProperty('statusCode', 200); expect(response).toHaveProperty('statusCode', 200);
expect(response.body).toMatchObject( expect(response.body).toMatchObject(
@ -253,6 +254,7 @@ describe('connector route', () => {
cliend_id: 'client_id', cliend_id: 'client_id',
client_secret: 'client_secret', client_secret: 'client_secret',
}, },
metadata: { target: 'target' },
}) })
); );
expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']); expect(deleteConnectorByIds).toHaveBeenCalledWith(['id']);

View file

@ -3,6 +3,8 @@ import { emailRegEx, phoneRegEx } from '@logto/core-kit';
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas'; import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
import { arbitraryObjectGuard, Connectors, ConnectorType } from '@logto/schemas'; import { arbitraryObjectGuard, Connectors, ConnectorType } from '@logto/schemas';
import { buildIdGenerator } from '@logto/shared'; import { buildIdGenerator } from '@logto/shared';
import { conditional } from '@silverhand/essentials';
import cleanDeep from 'clean-deep';
import { object, string } from 'zod'; import { object, string } from 'zod';
import { import {
@ -134,9 +136,12 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
); );
const insertConnectorId = generateConnectorId(); const insertConnectorId = generateConnectorId();
const { metadata, ...rest } = body;
ctx.body = await insertConnector({ ctx.body = await insertConnector({
id: insertConnectorId, id: insertConnectorId,
...body, ...conditional(metadata && { metadata: cleanDeep(metadata) }),
...rest,
}); });
/** /**
@ -193,7 +198,12 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
validateConfig(config); validateConfig(config);
} }
await updateConnector({ set: body, where: { id }, jsonbMode: 'replace' }); const { metadata: databaseMetadata, ...rest } = body;
await updateConnector({
set: databaseMetadata ? { metadata: cleanDeep(databaseMetadata), ...rest } : rest,
where: { id },
jsonbMode: 'replace',
});
const connector = await getLogtoConnectorById(id); const connector = await getLogtoConnectorById(id);
ctx.body = transpileLogtoConnector(connector); ctx.body = transpileLogtoConnector(connector);

View file

@ -105,7 +105,6 @@ describe('connector PATCH routes', () => {
target: 'target', target: 'target',
name: { en: 'connector_name', fr: 'connector_name' }, name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png', logo: 'new_logo.png',
logoDark: null,
}, },
}); });
const response = await connectorRequest.patch('/connectors/id').send({ const response = await connectorRequest.patch('/connectors/id').send({
@ -126,7 +125,6 @@ describe('connector PATCH routes', () => {
target: 'target', target: 'target',
name: { en: 'connector_name', fr: 'connector_name' }, name: { en: 'connector_name', fr: 'connector_name' },
logo: 'new_logo.png', logo: 'new_logo.png',
logoDark: null,
}, },
}, },
jsonbMode: 'replace', jsonbMode: 'replace',
@ -135,6 +133,44 @@ describe('connector PATCH routes', () => {
expect(response).toHaveProperty('statusCode', 200); expect(response).toHaveProperty('statusCode', 200);
}); });
it('successfully clear connector config metadata', async () => {
getLogtoConnectorsPlaceholder.mockResolvedValueOnce([
{
dbEntry: mockConnector,
metadata: { ...mockMetadata, isStandard: true },
type: ConnectorType.Social,
...mockLogtoConnector,
},
]);
mockedUpdateConnector.mockResolvedValueOnce({
...mockConnector,
metadata: {
target: '',
name: { en: '' },
logo: '',
logoDark: '',
},
});
const response = await connectorRequest.patch('/connectors/id').send({
metadata: {
target: '',
name: { en: '' },
logo: '',
logoDark: '',
},
});
expect(updateConnector).toHaveBeenCalledWith(
expect.objectContaining({
where: { id: 'id' },
set: {
metadata: {},
},
jsonbMode: 'replace',
})
);
expect(response).toHaveProperty('statusCode', 200);
});
it('throws when set syncProfile to `true` and with non-social connector', async () => { it('throws when set syncProfile to `true` and with non-social connector', async () => {
getLogtoConnectorsPlaceholder.mockResolvedValueOnce([ getLogtoConnectorsPlaceholder.mockResolvedValueOnce([
{ {