2022-03-08 15:57:57 +08:00
|
|
|
import { ConnectorDTO, Connectors, ConnectorType } from '@logto/schemas';
|
2022-01-24 14:40:15 +08:00
|
|
|
import { object, string } from 'zod';
|
|
|
|
|
|
|
|
import { getConnectorInstances, getConnectorInstanceById } from '@/connectors';
|
|
|
|
import { ConnectorInstance } from '@/connectors/types';
|
|
|
|
import koaGuard from '@/middleware/koa-guard';
|
2022-01-25 13:47:12 +08:00
|
|
|
import { updateConnector } from '@/queries/connector';
|
2022-03-08 15:57:57 +08:00
|
|
|
import assertThat from '@/utils/assert-that';
|
2022-01-24 14:40:15 +08:00
|
|
|
|
|
|
|
import { AuthedRouter } from './types';
|
|
|
|
|
2022-03-07 13:58:07 +08:00
|
|
|
const transpileConnectorInstance = ({ connector, metadata }: ConnectorInstance): ConnectorDTO => ({
|
2022-01-24 14:40:15 +08:00
|
|
|
...connector,
|
|
|
|
metadata,
|
|
|
|
});
|
|
|
|
|
|
|
|
export default function connectorRoutes<T extends AuthedRouter>(router: T) {
|
|
|
|
router.get('/connectors', async (ctx, next) => {
|
|
|
|
const connectorInstances = await getConnectorInstances();
|
2022-03-08 15:57:57 +08:00
|
|
|
|
|
|
|
assertThat(
|
|
|
|
connectorInstances.filter(
|
|
|
|
(connector) =>
|
|
|
|
connector.connector.enabled && connector.metadata.type === ConnectorType.Email
|
|
|
|
).length <= 1,
|
|
|
|
'connector.more_than_one_email'
|
|
|
|
);
|
|
|
|
assertThat(
|
|
|
|
connectorInstances.filter(
|
|
|
|
(connector) => connector.connector.enabled && connector.metadata.type === ConnectorType.SMS
|
|
|
|
).length <= 1,
|
|
|
|
'connector.more_than_one_sms'
|
|
|
|
);
|
|
|
|
|
2022-01-24 14:40:15 +08:00
|
|
|
ctx.body = connectorInstances.map((connectorInstance) => {
|
|
|
|
return transpileConnectorInstance(connectorInstance);
|
|
|
|
});
|
|
|
|
|
|
|
|
return next();
|
|
|
|
});
|
|
|
|
|
|
|
|
router.get(
|
|
|
|
'/connectors/:id',
|
|
|
|
koaGuard({ params: object({ id: string().min(1) }) }),
|
|
|
|
async (ctx, next) => {
|
|
|
|
const {
|
|
|
|
params: { id },
|
|
|
|
} = ctx.guard;
|
|
|
|
const connectorInstance = await getConnectorInstanceById(id);
|
|
|
|
ctx.body = transpileConnectorInstance(connectorInstance);
|
|
|
|
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
router.patch(
|
|
|
|
'/connectors/:id/enabled',
|
|
|
|
koaGuard({
|
|
|
|
params: object({ id: string().min(1) }),
|
|
|
|
body: Connectors.createGuard.pick({ enabled: true }),
|
|
|
|
}),
|
|
|
|
async (ctx, next) => {
|
|
|
|
const {
|
|
|
|
params: { id },
|
|
|
|
body: { enabled },
|
|
|
|
} = ctx.guard;
|
2022-01-25 13:47:12 +08:00
|
|
|
const { metadata } = await getConnectorInstanceById(id);
|
2022-03-08 15:57:57 +08:00
|
|
|
|
|
|
|
// Only allow one enabled connector for SMS and Email.
|
|
|
|
// disable other connectors before enable this one.
|
|
|
|
if (
|
|
|
|
enabled &&
|
|
|
|
(metadata.type === ConnectorType.SMS || metadata.type === ConnectorType.Email)
|
|
|
|
) {
|
|
|
|
const connectors = await getConnectorInstances();
|
|
|
|
await Promise.all(
|
|
|
|
connectors
|
|
|
|
.filter(
|
|
|
|
(connector) =>
|
|
|
|
connector.metadata.type === metadata.type && connector.connector.enabled
|
|
|
|
)
|
|
|
|
.map(async ({ connector: { id } }) =>
|
|
|
|
updateConnector({ set: { enabled: false }, where: { id } })
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-25 13:47:12 +08:00
|
|
|
const connector = await updateConnector({ set: { enabled }, where: { id } });
|
|
|
|
ctx.body = { ...connector, metadata };
|
2022-01-24 14:40:15 +08:00
|
|
|
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
router.patch(
|
|
|
|
'/connectors/:id',
|
|
|
|
koaGuard({
|
|
|
|
params: object({ id: string().min(1) }),
|
|
|
|
body: Connectors.createGuard
|
|
|
|
.omit({ id: true, type: true, enabled: true, createdAt: true })
|
|
|
|
.partial(),
|
|
|
|
}),
|
|
|
|
async (ctx, next) => {
|
|
|
|
const {
|
|
|
|
params: { id },
|
|
|
|
body,
|
|
|
|
} = ctx.guard;
|
2022-01-25 13:47:12 +08:00
|
|
|
const { metadata, validateConfig } = await getConnectorInstanceById(id);
|
2022-01-24 14:40:15 +08:00
|
|
|
|
|
|
|
if (body.config) {
|
2022-01-25 13:47:12 +08:00
|
|
|
await validateConfig(body.config);
|
2022-01-24 14:40:15 +08:00
|
|
|
}
|
|
|
|
|
2022-01-25 13:47:12 +08:00
|
|
|
const connector = await updateConnector({ set: body, where: { id } });
|
|
|
|
ctx.body = { ...connector, metadata };
|
2022-01-24 14:40:15 +08:00
|
|
|
|
|
|
|
return next();
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|