0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-20 21:32:31 -05:00

refactor(connector): create PasswordlessConnector abstract class to share common logics

This commit is contained in:
Darcy Ye 2022-08-17 15:10:57 +08:00
parent c16f49cb2f
commit 473b219c3d
No known key found for this signature in database
GPG key ID: B46F4C07EDEFC610

View file

@ -1,58 +1,21 @@
import { Optional } from '@silverhand/essentials';
import { ConnectorMetadata } from './types'; import { ConnectorMetadata } from './types';
export type EmailMessageTypes = { // We will have message type 'ForgotPassword' available in the near future.
SignIn: { type MessageTypes = 'SignIn' | 'Register' | 'Test';
code: string;
};
Register: {
code: string;
};
ForgotPassword: {
code: string;
};
Test: Record<string, unknown>;
};
export type SmsMessageTypes = EmailMessageTypes; type SendMessageFunction = (
to: string,
export type EmailSendMessageFunction<T = unknown> = ( type: MessageTypes,
address: string, payload: { code: string }
type: keyof EmailMessageTypes,
payload: EmailMessageTypes[typeof type]
) => Promise<T>;
export type EmailSendTestMessageFunction<T = unknown> = (
config: Record<string, unknown>,
address: string,
type: keyof EmailMessageTypes,
payload: EmailMessageTypes[typeof type]
) => Promise<T>;
export type EmailSendMessageByFunction<T> = (
config: T,
address: string,
type: keyof EmailMessageTypes,
payload: EmailMessageTypes[typeof type]
) => Promise<unknown>; ) => Promise<unknown>;
export type SmsSendMessageFunction<T = unknown> = ( type SendMessageByFunction<T = Record<string, unknown>> = (
phone: string,
type: keyof SmsMessageTypes,
payload: SmsMessageTypes[typeof type]
) => Promise<T>;
export type SmsSendTestMessageFunction<T = unknown> = (
config: Record<string, unknown>,
phone: string,
type: keyof SmsMessageTypes,
payload: SmsMessageTypes[typeof type]
) => Promise<T>;
export type SmsSendMessageByFunction<T> = (
config: T, config: T,
phone: string, to: string,
type: keyof SmsMessageTypes, type: MessageTypes,
payload: SmsMessageTypes[typeof type] payload: { code: string }
) => Promise<unknown>; ) => Promise<unknown>;
export type ValidateConfig<T> = (config: unknown) => asserts config is T; export type ValidateConfig<T> = (config: unknown) => asserts config is T;
@ -64,7 +27,7 @@ export type GetAuthorizationUri = (payload: {
export type GetUserInfo = ( export type GetUserInfo = (
data: unknown data: unknown
) => Promise<{ id: string } & Record<string, string | undefined>>; ) => Promise<{ id: string } & Record<string, Optional<string>>>;
export type GetConnectorConfig = (id: string) => Promise<unknown>; export type GetConnectorConfig = (id: string) => Promise<unknown>;
@ -73,52 +36,37 @@ export type AuthResponseParser<T = Record<string, unknown>> = (response: unknown
abstract class BaseConnector<T> { abstract class BaseConnector<T> {
public getConfig: GetConnectorConfig; public getConfig: GetConnectorConfig;
public metadata!: ConnectorMetadata; public metadata!: ConnectorMetadata;
public abstract validateConfig: ValidateConfig<T>;
constructor(getConnectorConfig: GetConnectorConfig) { constructor(getConnectorConfig: GetConnectorConfig) {
this.getConfig = getConnectorConfig; this.getConfig = getConnectorConfig;
} }
public abstract validateConfig(config: unknown): asserts config is T;
} }
export abstract class SmsConnector<T> extends BaseConnector<T> { abstract class PasswordlessConnector<T> extends BaseConnector<T> {
protected abstract readonly sendMessageBy: EmailSendMessageByFunction<T>; protected abstract readonly sendMessageBy: SendMessageByFunction<T>;
public sendMessage: EmailSendMessageFunction = async (address, type, data) => { public sendMessage: SendMessageFunction = async (address, type, data) => {
const config = await this.getConfig(this.metadata.id); const config = await this.getConfig(this.metadata.id);
this.validateConfig(config); this.validateConfig(config);
return this.sendMessageBy(config, address, type, data); return this.sendMessageBy(config, address, type, data);
}; };
public sendTestMessage?: EmailSendTestMessageFunction = async (config, address, type, data) => { public sendTestMessage?: SendMessageByFunction = async (config, address, type, data) => {
this.validateConfig(config); this.validateConfig(config);
return this.sendMessageBy(config, address, type, data); return this.sendMessageBy(config, address, type, data);
}; };
} }
export abstract class EmailConnector<T> extends BaseConnector<T> { export abstract class SmsConnector<T> extends PasswordlessConnector<T> {}
protected abstract readonly sendMessageBy: SmsSendMessageByFunction<T>;
public sendMessage: SmsSendMessageFunction = async (address, type, data) => { export abstract class EmailConnector<T> extends PasswordlessConnector<T> {}
const config = await this.getConfig(this.metadata.id);
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
public sendTestMessage?: SmsSendTestMessageFunction = async (config, address, type, data) => {
this.validateConfig(config);
return this.sendMessageBy(config, address, type, data);
};
}
export abstract class SocialConnector<T> extends BaseConnector<T> { export abstract class SocialConnector<T> extends BaseConnector<T> {
public abstract getAuthorizationUri: GetAuthorizationUri; public abstract getAuthorizationUri: GetAuthorizationUri;
public abstract getUserInfo: GetUserInfo; public abstract getUserInfo: GetUserInfo;
protected authResponseParser?: AuthResponseParser; protected abstract authResponseParser?: AuthResponseParser;
} }