0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

refactor(connector): fix according to @logto/connector-schemas changes

This commit is contained in:
Darcy Ye 2022-08-19 13:15:02 +08:00
parent 91f8fe8444
commit bd0265c25a
No known key found for this signature in database
GPG key ID: B46F4C07EDEFC610
12 changed files with 52 additions and 181 deletions

View file

@ -34,24 +34,13 @@ export default class AliyunDmConnector extends LogtoConnector<AliyunDmConfig> {
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<AliyunDmConfig> = async (
{ to, type, payload },
config
) => {
// eslint-disable-next-line complexity
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { accessKeyId, accessKeySecret, accountName, fromAlias, templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -29,24 +29,12 @@ export default class AliyunSmsConnector extends LogtoConnector<AliyunSmsConfig>
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<AliyunSmsConfig> = async (
{ to, type, payload },
config
) => {
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { accessKeyId, accessKeySecret, signName, templates } = config;
const template = templates.find(({ usageType }) => usageType === type);

View file

@ -30,24 +30,12 @@ export default class MockMailConnector extends LogtoConnector<MockMailConfig> {
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<MockMailConfig> = async (
{ to, type, payload },
config
) => {
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -30,24 +30,12 @@ export default class MockLogtoConnector extends LogtoConnector<MockSmsConfig> {
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<MockSmsConfig> = async (
{ to, type, payload },
config
) => {
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -35,24 +35,13 @@ export default class SendGridMailConnector extends LogtoConnector<SendGridMailCo
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<SendGridMailConfig> = async (
{ to, type, payload },
config
) => {
// eslint-disable-next-line complexity
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { apiKey, fromEmail, fromName, templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -29,24 +29,12 @@ export default class SmtpConnector extends LogtoConnector<SmtpConfig> {
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<SmtpConfig> = async (
{ to, type, payload },
config
) => {
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { host, port, username, password, fromEmail, replyTo, templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -28,24 +28,12 @@ export default class TwilioSmsConnector extends LogtoConnector<TwilioSmsConfig>
}
};
public sendMessage: SendMessageFunction = async ({ to, type, payload }) => {
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
public sendTestMessage: SendMessageFunction = async ({ to, type, payload }, config) => {
this.validateConfig(config);
return this.sendMessageBy({ to, type, payload }, config);
};
protected readonly sendMessageBy: SendMessageFunction<TwilioSmsConfig> = async (
{ to, type, payload },
config
) => {
public sendMessage: SendMessageFunction = async ({ to, type, payload }, inputConfig) => {
const config = inputConfig ?? (await this.getConfig(this.metadata.id));
assert(config, new ConnectorError(ConnectorErrorCodes.InvalidConfig));
this.validateConfig(config);
const { accountSID, authToken, fromMessagingServiceSID, templates } = config;
const template = templates.find((template) => template.usageType === type);

View file

@ -10,7 +10,7 @@ import RequestError from '@/errors/RequestError';
import { findAllConnectors, insertConnector } from '@/queries/connector';
import { defaultConnectorPackages } from './consts';
import { ConnectorInstance, SocialConnectorInstance } from './types';
import { ConnectorInstance } from './types';
import { getConnectorConfig } from './utilities';
// eslint-disable-next-line @silverhand/fp/no-let
@ -133,18 +133,10 @@ export const getConnectorInstanceById = async (id: string): Promise<ConnectorIns
return pickedConnectorInstance;
};
export const isSocialConnectorInstance = (
instance: ConnectorInstance
): instance is SocialConnectorInstance => {
return instance.metadata.type === ConnectorType.Social;
};
export const getSocialConnectorInstanceById = async (
id: string
): Promise<SocialConnectorInstance> => {
export const getSocialConnectorInstanceById = async (id: string): Promise<ConnectorInstance> => {
const connector = await getConnectorInstanceById(id);
if (!isSocialConnectorInstance(connector)) {
if (connector.metadata.type !== ConnectorType.Social) {
throw new RequestError({
code: 'entity.not_found',
id,

View file

@ -1,10 +1,4 @@
import {
LogtoConnector,
SendMessageFunction,
AuthResponseParser,
GetAuthorizationUri,
GetUserInfo,
} from '@logto/connector-schemas';
import { LogtoConnector } from '@logto/connector-schemas';
import { Connector, PasscodeType } from '@logto/schemas';
import { z } from 'zod';
@ -23,25 +17,3 @@ export type SocialUserInfo = z.infer<typeof socialUserInfoGuard>;
export class ConnectorInstance<T = unknown> extends LogtoConnector<T> {
public connector!: Connector;
}
export class SmsConnectorInstance<T = unknown> extends LogtoConnector<T> {
public connector!: Connector;
public sendMessage!: SendMessageFunction;
public sendTestMessage?: SendMessageFunction;
protected readonly sendMessageBy!: SendMessageFunction<T>;
}
export class EmailConnectorInstance<T = unknown> extends LogtoConnector<T> {
public connector!: Connector;
public sendMessage!: SendMessageFunction;
public sendTestMessage?: SendMessageFunction;
protected readonly sendMessageBy!: SendMessageFunction<T>;
}
export class SocialConnectorInstance<T = unknown> extends LogtoConnector<T> {
public connector!: Connector;
public getAuthorizationUri!: GetAuthorizationUri;
public getUserInfo!: GetUserInfo;
protected authResponseParser?: AuthResponseParser;
}

View file

@ -3,7 +3,6 @@ import { Passcode, PasscodeType } from '@logto/schemas';
import { customAlphabet, nanoid } from 'nanoid';
import { getConnectorInstances } from '@/connectors';
import { EmailConnectorInstance, SmsConnectorInstance } from '@/connectors/types';
import RequestError from '@/errors/RequestError';
import {
consumePasscode,
@ -49,12 +48,10 @@ export const sendPasscode = async (passcode: Passcode) => {
const connectorInstances = await getConnectorInstances();
const emailConnectorInstance = connectorInstances.find(
(connector): connector is EmailConnectorInstance =>
connector.connector.enabled && connector.metadata.type === ConnectorType.Email
(connector) => connector.connector.enabled && connector.metadata.type === ConnectorType.Email
);
const smsConnectorInstance = connectorInstances.find(
(connector): connector is SmsConnectorInstance =>
connector.connector.enabled && connector.metadata.type === ConnectorType.SMS
(connector) => connector.connector.enabled && connector.metadata.type === ConnectorType.SMS
);
const connectorInstance = passcode.email ? emailConnectorInstance : smsConnectorInstance;

View file

@ -112,11 +112,9 @@ describe('connector route', () => {
validateConfig: jest.fn(),
getConfig: jest.fn(),
sendMessage: jest.fn(),
sendMessageBy: jest.fn(),
sendTestMessage: jest.fn(),
};
getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedSmsConnectorInstance]);
const sendMessageSpy = jest.spyOn(mockedSmsConnectorInstance, 'sendTestMessage');
const sendMessageSpy = jest.spyOn(mockedSmsConnectorInstance, 'sendMessage');
const response = await connectorRequest
.post('/connectors/id/test')
.send({ phone: '12345678901', config: { test: 123 } });
@ -141,11 +139,9 @@ describe('connector route', () => {
validateConfig: jest.fn(),
getConfig: jest.fn(),
sendMessage: jest.fn(),
sendMessageBy: jest.fn(),
sendTestMessage: jest.fn(),
};
getConnectorInstancesPlaceHolder.mockResolvedValueOnce([mockedEmailConnector]);
const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendTestMessage');
const sendMessageSpy = jest.spyOn(mockedEmailConnector, 'sendMessage');
const response = await connectorRequest
.post('/connectors/id/test')
.send({ email: 'test@email.com', config: { test: 123 } });

View file

@ -3,11 +3,7 @@ import { emailRegEx, phoneRegEx } from '@logto/shared';
import { object, string } from 'zod';
import { getConnectorInstances, getConnectorInstanceById } from '@/connectors';
import {
ConnectorInstance,
EmailConnectorInstance,
SmsConnectorInstance,
} from '@/connectors/types';
import { ConnectorInstance } from '@/connectors/types';
import RequestError from '@/errors/RequestError';
import koaGuard from '@/middleware/koa-guard';
import { updateConnector } from '@/queries/connector';
@ -184,13 +180,13 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
const subject = phone ?? email;
assertThat(subject, new RequestError({ code: 'guard.invalid_input' }));
const connector: SmsConnectorInstance | EmailConnectorInstance | undefined = phone
const connector: ConnectorInstance | undefined = phone
? connectorInstances.find(
(connector): connector is SmsConnectorInstance =>
(connector) =>
connector.metadata.id === id && connector.metadata.type === ConnectorType.SMS
)
: connectorInstances.find(
(connector): connector is EmailConnectorInstance =>
(connector) =>
connector.metadata.id === id && connector.metadata.type === ConnectorType.Email
);
@ -202,9 +198,9 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
})
);
const { sendTestMessage } = connector;
const { sendMessage } = connector;
assertThat(
sendTestMessage,
sendMessage,
new RequestError({
code: 'connector.not_implemented',
method: 'sendTestMessage',
@ -212,7 +208,7 @@ export default function connectorRoutes<T extends AuthedRouter>(router: T) {
})
);
await sendTestMessage(
await sendMessage(
{
to: subject,
type: 'Test',