0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-04-07 23:01:25 -05:00

feat(core): only allow one enabled sms/email (#337)

This commit is contained in:
Wang Sijie 2022-03-08 15:57:57 +08:00 committed by GitHub
parent 0cc32cadf3
commit 4cc45696a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 1 deletions

View file

@ -1,10 +1,11 @@
import { ConnectorDTO, Connectors } from '@logto/schemas';
import { ConnectorDTO, Connectors, ConnectorType } from '@logto/schemas';
import { object, string } from 'zod';
import { getConnectorInstances, getConnectorInstanceById } from '@/connectors';
import { ConnectorInstance } from '@/connectors/types';
import koaGuard from '@/middleware/koa-guard';
import { updateConnector } from '@/queries/connector';
import assertThat from '@/utils/assert-that';
import { AuthedRouter } from './types';
@ -16,6 +17,21 @@ const transpileConnectorInstance = ({ connector, metadata }: ConnectorInstance):
export default function connectorRoutes<T extends AuthedRouter>(router: T) {
router.get('/connectors', async (ctx, next) => {
const connectorInstances = await getConnectorInstances();
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'
);
ctx.body = connectorInstances.map((connectorInstance) => {
return transpileConnectorInstance(connectorInstance);
});
@ -49,6 +65,26 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
body: { enabled },
} = ctx.guard;
const { metadata } = await getConnectorInstanceById(id);
// 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 } })
)
);
}
const connector = await updateConnector({ set: { enabled }, where: { id } });
ctx.body = { ...connector, metadata };

View file

@ -163,6 +163,8 @@ const errors = {
template_not_found: 'Unable to find correct template in connector config.',
access_token_invalid: "Connector's access token is invalid.",
oauth_code_invalid: 'Unable to get access token, please check authorization code.',
more_than_one_sms: 'The number of SMS connectors is larger then 1.',
more_than_one_email: 'The number of Email connectors is larger then 1.',
},
passcode: {
phone_email_empty: 'Both phone and email are empty.',

View file

@ -163,6 +163,8 @@ const errors = {
template_not_found: '无法从连接器配置中找到对应的模板。',
access_token_invalid: '当前连接器的 access_token 无效。',
oauth_code_invalid: '无法获取 access_token请检查授权 code 是否有效。',
more_than_one_sms: '同时存在超过 1 个短信连接器。',
more_than_one_email: '同时存在超过 1 个邮件连接器。',
},
passcode: {
phone_email_empty: '手机号与邮箱地址均为空。',