diff --git a/packages/connector-aliyun-dm/src/index.ts b/packages/connector-aliyun-dm/src/index.ts index 826a2fc0a..8cf3a2265 100644 --- a/packages/connector-aliyun-dm/src/index.ts +++ b/packages/connector-aliyun-dm/src/index.ts @@ -2,6 +2,7 @@ import { ConnectorError, ConnectorErrorCodes, ConnectorMetadata, + EmailMessageTypes, EmailSendMessageFunction, ValidateConfig, EmailConnector, @@ -32,12 +33,30 @@ export default class AliyunDmConnector implements EmailConnector { } }; - // eslint-disable-next-line complexity - public sendMessage: EmailSendMessageFunction = async (address, type, data, config) => { - const emailConfig = - (config as AliyunDmConfig | undefined) ?? (await this.getConfig(this.metadata.id)); + public sendMessage: EmailSendMessageFunction = async (address, type, data) => { + const emailConfig = await this.getConfig(this.metadata.id); await this.validateConfig(emailConfig); - const { accessKeyId, accessKeySecret, accountName, fromAlias, templates } = emailConfig; + + return this.sendMessageCore(address, type, data, emailConfig); + }; + + public sendTestMessage: EmailSendMessageFunction = async (address, type, data, config) => { + if (!config) { + throw new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters); + } + + await this.validateConfig(config); + + return this.sendMessageCore(address, type, data, config as AliyunDmConfig); + }; + + private readonly sendMessageCore = async ( + address: string, + type: keyof EmailMessageTypes, + data: EmailMessageTypes[typeof type], + config: AliyunDmConfig + ) => { + const { accessKeyId, accessKeySecret, accountName, fromAlias, templates } = config; const template = templates.find((template) => template.usageType === type); assert( diff --git a/packages/connector-aliyun-sms/src/index.ts b/packages/connector-aliyun-sms/src/index.ts index e341ae0ee..5f67e9e36 100644 --- a/packages/connector-aliyun-sms/src/index.ts +++ b/packages/connector-aliyun-sms/src/index.ts @@ -2,6 +2,7 @@ import { ConnectorError, ConnectorErrorCodes, ConnectorMetadata, + SmsMessageTypes, SmsSendMessageFunction, ValidateConfig, SmsConnector, @@ -27,11 +28,30 @@ export default class AliyunSmsConnector implements SmsConnector { } }; - public sendMessage: SmsSendMessageFunction = async (phone, type, { code }, config) => { - const smsConfig = - (config as AliyunSmsConfig | undefined) ?? (await this.getConfig(this.metadata.id)); + public sendMessage: SmsSendMessageFunction = async (phone, type, { code }) => { + const smsConfig = await this.getConfig(this.metadata.id); await this.validateConfig(smsConfig); - const { accessKeyId, accessKeySecret, signName, templates } = smsConfig; + + return this.sendMessageCore(phone, type, { code }, smsConfig); + }; + + public sendTestMessage: SmsSendMessageFunction = async (phone, type, { code }, config) => { + if (!config) { + throw new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters); + } + + await this.validateConfig(config); + + return this.sendMessageCore(phone, type, { code }, config as AliyunSmsConfig); + }; + + private readonly sendMessageCore = async ( + phone: string, + type: keyof SmsMessageTypes, + data: SmsMessageTypes[typeof type], + config: AliyunSmsConfig + ) => { + const { accessKeyId, accessKeySecret, signName, templates } = config; const template = templates.find(({ usageType }) => usageType === type); assert( @@ -46,7 +66,7 @@ export default class AliyunSmsConnector implements SmsConnector { PhoneNumbers: phone, SignName: signName, TemplateCode: template.templateCode, - TemplateParam: JSON.stringify({ code }), + TemplateParam: JSON.stringify(data), }, accessKeySecret ); diff --git a/packages/connector-sendgrid-mail/src/index.ts b/packages/connector-sendgrid-mail/src/index.ts index e8905fdb9..e4ef7091f 100644 --- a/packages/connector-sendgrid-mail/src/index.ts +++ b/packages/connector-sendgrid-mail/src/index.ts @@ -2,6 +2,7 @@ import { ConnectorError, ConnectorErrorCodes, ConnectorMetadata, + EmailMessageTypes, EmailSendMessageFunction, ValidateConfig, EmailConnector, @@ -33,12 +34,30 @@ export default class SendGridMailConnector implements EmailConnector { } }; - // eslint-disable-next-line complexity - public sendMessage: EmailSendMessageFunction = async (address, type, data, config) => { - const emailConfig = - (config as SendGridMailConfig | undefined) ?? (await this.getConfig(this.metadata.id)); + public sendMessage: EmailSendMessageFunction = async (address, type, data) => { + const emailConfig = await this.getConfig(this.metadata.id); await this.validateConfig(emailConfig); - const { apiKey, fromEmail, fromName, templates } = emailConfig; + + return this.sendMessageCore(address, type, data, emailConfig); + }; + + public sendTestMessage: EmailSendMessageFunction = async (address, type, data, config) => { + if (!config) { + throw new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters); + } + + await this.validateConfig(config); + + return this.sendMessageCore(address, type, data, config as SendGridMailConfig); + }; + + private readonly sendMessageCore = async ( + address: string, + type: keyof EmailMessageTypes, + data: EmailMessageTypes[typeof type], + config: SendGridMailConfig + ) => { + const { apiKey, fromEmail, fromName, templates } = config; const template = templates.find((template) => template.usageType === type); assert( diff --git a/packages/connector-smtp/src/index.ts b/packages/connector-smtp/src/index.ts index 173e925b1..68a2ef772 100644 --- a/packages/connector-smtp/src/index.ts +++ b/packages/connector-smtp/src/index.ts @@ -2,6 +2,7 @@ import { ConnectorError, ConnectorErrorCodes, ConnectorMetadata, + EmailMessageTypes, EmailSendMessageFunction, ValidateConfig, EmailConnector, @@ -27,11 +28,30 @@ export default class SmtpConnector implements EmailConnector { } }; - public sendMessage: EmailSendMessageFunction = async (address, type, data, config) => { - const emailConfig = - (config as SmtpConfig | undefined) ?? (await this.getConfig(this.metadata.id)); + public sendMessage: EmailSendMessageFunction = async (address, type, data) => { + const emailConfig = await this.getConfig(this.metadata.id); await this.validateConfig(emailConfig); - const { host, port, username, password, fromEmail, replyTo, templates } = emailConfig; + + return this.sendMessageCore(address, type, data, emailConfig); + }; + + public sendTestMessage: EmailSendMessageFunction = async (address, type, data, config) => { + if (!config) { + throw new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters); + } + + await this.validateConfig(config); + + return this.sendMessageCore(address, type, data, config as SmtpConfig); + }; + + private readonly sendMessageCore = async ( + address: string, + type: keyof EmailMessageTypes, + data: EmailMessageTypes[typeof type], + config: SmtpConfig + ) => { + const { host, port, username, password, fromEmail, replyTo, templates } = config; const template = templates.find((template) => template.usageType === type); assert( diff --git a/packages/connector-twilio-sms/src/index.ts b/packages/connector-twilio-sms/src/index.ts index 2df63efa7..88870bfe9 100644 --- a/packages/connector-twilio-sms/src/index.ts +++ b/packages/connector-twilio-sms/src/index.ts @@ -2,6 +2,7 @@ import { ConnectorError, ConnectorErrorCodes, ConnectorMetadata, + SmsMessageTypes, SmsSendMessageFunction, ValidateConfig, SmsConnector, @@ -26,11 +27,30 @@ export default class TwilioSmsConnector implements SmsConnector { } }; - public sendMessage: SmsSendMessageFunction = async (address, type, data, config) => { - const smsConfig = - (config as TwilioSmsConfig | undefined) ?? (await this.getConfig(this.metadata.id)); + public sendMessage: SmsSendMessageFunction = async (address, type, data) => { + const smsConfig = await this.getConfig(this.metadata.id); await this.validateConfig(smsConfig); - const { accountSID, authToken, fromMessagingServiceSID, templates } = smsConfig; + + return this.sendMessageCore(address, type, data, smsConfig); + }; + + public sendTestMessage: SmsSendMessageFunction = async (address, type, data, config) => { + if (!config) { + throw new ConnectorError(ConnectorErrorCodes.InsufficientRequestParameters); + } + + await this.validateConfig(config); + + return this.sendMessageCore(address, type, data, config as TwilioSmsConfig); + }; + + private readonly sendMessageCore = async ( + phone: string, + type: keyof SmsMessageTypes, + data: SmsMessageTypes[typeof type], + config: TwilioSmsConfig + ) => { + const { accountSID, authToken, fromMessagingServiceSID, templates } = config; const template = templates.find((template) => template.usageType === type); assert( @@ -42,7 +62,7 @@ export default class TwilioSmsConnector implements SmsConnector { ); const parameters: PublicParameters = { - To: address, + To: phone, MessagingServiceSid: fromMessagingServiceSID, Body: typeof data.code === 'string' diff --git a/packages/connector-types/src/index.ts b/packages/connector-types/src/index.ts index c6a723dfb..1a670a771 100644 --- a/packages/connector-types/src/index.ts +++ b/packages/connector-types/src/index.ts @@ -66,19 +66,19 @@ export type EmailMessageTypes = { export type SmsMessageTypes = EmailMessageTypes; -export type EmailSendMessageFunction = ( +export type EmailSendMessageFunction, U = unknown> = ( address: string, type: keyof EmailMessageTypes, payload: EmailMessageTypes[typeof type], - config?: Record -) => Promise; + config?: T +) => Promise; -export type SmsSendMessageFunction = ( +export type SmsSendMessageFunction, U = unknown> = ( phone: string, type: keyof SmsMessageTypes, payload: SmsMessageTypes[typeof type], - config?: Record -) => Promise; + config?: T +) => Promise; export interface BaseConnector { metadata: ConnectorMetadata; @@ -88,10 +88,12 @@ export interface BaseConnector { export interface SmsConnector extends BaseConnector { sendMessage: SmsSendMessageFunction; + sendTestMessage: SmsSendMessageFunction; } export interface EmailConnector extends BaseConnector { sendMessage: EmailSendMessageFunction; + sendTestMessage: EmailSendMessageFunction; } export interface SocialConnector extends BaseConnector { diff --git a/packages/core/src/lib/passcode.test.ts b/packages/core/src/lib/passcode.test.ts index e819fcb95..f1de29bed 100644 --- a/packages/core/src/lib/passcode.test.ts +++ b/packages/core/src/lib/passcode.test.ts @@ -119,6 +119,7 @@ describe('sendPasscode', () => { it('should throw error when email or sms connector can not be found', async () => { const sendMessage = jest.fn(); + const sendTestMessage = jest.fn(); const validateConfig = jest.fn(); const getConfig = jest.fn(); mockedGetConnectorInstances.mockResolvedValueOnce([ @@ -133,6 +134,7 @@ describe('sendPasscode', () => { platform: null, }, sendMessage, + sendTestMessage, validateConfig, getConfig, }, @@ -158,6 +160,7 @@ describe('sendPasscode', () => { it('should call sendPasscode with params matching', async () => { const sendMessage = jest.fn(); + const sendTestMessage = jest.fn(); const validateConfig = jest.fn(); const getConfig = jest.fn(); mockedGetConnectorInstances.mockResolvedValueOnce([ @@ -172,6 +175,7 @@ describe('sendPasscode', () => { platform: null, }, sendMessage, + sendTestMessage, validateConfig, getConfig, }, @@ -186,6 +190,7 @@ describe('sendPasscode', () => { platform: null, }, sendMessage, + sendTestMessage, validateConfig, getConfig, }, diff --git a/packages/core/src/routes/connector.test.ts b/packages/core/src/routes/connector.test.ts index d3189e237..c13fc6904 100644 --- a/packages/core/src/routes/connector.test.ts +++ b/packages/core/src/routes/connector.test.ts @@ -116,15 +116,16 @@ describe('connector route', () => { metadata: mockedMetadata, validateConfig: jest.fn(), getConfig: jest.fn(), - sendMessage: async ( + sendTestMessage: async ( address: string, type: keyof EmailMessageTypes, _payload: EmailMessageTypes[typeof type] // eslint-disable-next-line @typescript-eslint/no-empty-function ): Promise => {}, + sendMessage: jest.fn(), }; getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedSmsConnectorInstance]); - const sendMessageSpy = jest.spyOn(mockedSmsConnectorInstance, 'sendMessage'); + const sendMessageSpy = jest.spyOn(mockedSmsConnectorInstance, 'sendTestMessage'); const response = await connectorRequest .post('/connectors/id/test') .send({ phone: '12345678901', config: { test: 123 } }); @@ -146,15 +147,16 @@ describe('connector route', () => { metadata: mockMetadata, validateConfig: jest.fn(), getConfig: jest.fn(), - sendMessage: async ( + sendTestMessage: async ( address: string, type: keyof EmailMessageTypes, _payload: EmailMessageTypes[typeof type] // eslint-disable-next-line @typescript-eslint/no-empty-function ): Promise => {}, + sendMessage: jest.fn(), }; getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedEmailConnector]); - const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendMessage'); + const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendTestMessage'); const response = await connectorRequest .post('/connectors/id/test') .send({ email: 'test@email.com', config: { test: 123 } }); diff --git a/packages/core/src/routes/connector.ts b/packages/core/src/routes/connector.ts index 1049d7e1b..c0bc18c08 100644 --- a/packages/core/src/routes/connector.ts +++ b/packages/core/src/routes/connector.ts @@ -191,7 +191,7 @@ export default function connectorRoutes(router: T) { await connector.validateConfig(config); } - await connector.sendMessage( + await connector.sendTestMessage( subject, 'Test', {