mirror of
https://github.com/logto-io/logto.git
synced 2025-01-27 21:39:16 -05:00
refactor(connector): refactor connector
This commit is contained in:
parent
0acd432a3f
commit
7634c425c8
24 changed files with 435 additions and 643 deletions
|
@ -10,10 +10,9 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
AuthResponseParser,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
SocialConnectorInstance,
|
||||
|
@ -22,7 +21,6 @@ import {
|
|||
import { assert } from '@silverhand/essentials';
|
||||
import dayjs from 'dayjs';
|
||||
import got from 'got';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
alipayEndpoint,
|
||||
|
@ -37,7 +35,9 @@ import {
|
|||
} from './constant';
|
||||
import {
|
||||
alipayNativeConfigGuard,
|
||||
authResponseGuard,
|
||||
AlipayNativeConfig,
|
||||
AuthResponse,
|
||||
accessTokenResponseGuard,
|
||||
userInfoResponseGuard,
|
||||
ErrorHandler,
|
||||
|
@ -46,25 +46,17 @@ import { signingParameters } from './utils';
|
|||
|
||||
export type { AlipayNativeConfig } from './types';
|
||||
|
||||
export default class AlipayNativeConnector implements SocialConnectorInstance<AlipayNativeConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
export default class AlipayNativeConnector<T> extends SocialConnectorInstance<
|
||||
AlipayNativeConfig,
|
||||
T
|
||||
> {
|
||||
private readonly signingParameters = signingParameters;
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AlipayNativeConfig {
|
||||
const result = alipayNativeConfigGuard.safeParse(config);
|
||||
|
@ -125,7 +117,7 @@ export default class AlipayNativeConnector implements SocialConnectorInstance<Al
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { auth_code } = await this.authorizationCallbackHandler(data);
|
||||
const { auth_code } = await this.authResponseParser(data);
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
@ -174,6 +166,18 @@ export default class AlipayNativeConnector implements SocialConnectorInstance<Al
|
|||
return { id, avatar, name };
|
||||
};
|
||||
|
||||
protected readonly authResponseParser: AuthResponseParser<AuthResponse> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = authResponseGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
|
||||
private readonly errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
||||
if (invalidAccessTokenCode.includes(code)) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid, msg);
|
||||
|
@ -193,17 +197,5 @@ export default class AlipayNativeConnector implements SocialConnectorInstance<Al
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
const dataGuard = z.object({ auth_code: z.string() });
|
||||
|
||||
const result = dataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
}
|
||||
/* eslint-enable unicorn/text-encoding-identifier-case */
|
||||
|
|
|
@ -57,3 +57,7 @@ export const userInfoResponseGuard = z.object({
|
|||
export type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;
|
||||
|
||||
export type ErrorHandler = (response: AlipayUserInfoShareResponseGuard) => void;
|
||||
|
||||
export const authResponseGuard = z.object({ auth_code: z.string() });
|
||||
|
||||
export type AuthResponse = z.infer<typeof authResponseGuard>;
|
||||
|
|
|
@ -6,10 +6,9 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
AuthResponseParser,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
SocialConnectorInstance,
|
||||
|
@ -18,7 +17,6 @@ import {
|
|||
import { assert } from '@silverhand/essentials';
|
||||
import dayjs from 'dayjs';
|
||||
import got from 'got';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
alipayEndpoint,
|
||||
|
@ -35,7 +33,9 @@ import {
|
|||
} from './constant';
|
||||
import {
|
||||
alipayConfigGuard,
|
||||
authResponseGuard,
|
||||
AlipayConfig,
|
||||
AuthResponse,
|
||||
accessTokenResponseGuard,
|
||||
userInfoResponseGuard,
|
||||
ErrorHandler,
|
||||
|
@ -44,25 +44,14 @@ import { signingParameters } from './utils';
|
|||
|
||||
export type { AlipayConfig } from './types';
|
||||
|
||||
export default class AlipayConnector implements SocialConnectorInstance<AlipayConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
export default class AlipayConnector<T> extends SocialConnectorInstance<AlipayConfig, T> {
|
||||
private readonly signingParameters = signingParameters;
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AlipayConfig {
|
||||
const result = alipayConfigGuard.safeParse(config);
|
||||
|
@ -131,7 +120,7 @@ export default class AlipayConnector implements SocialConnectorInstance<AlipayCo
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { auth_code } = await this.authorizationCallbackHandler(data);
|
||||
const { auth_code } = await this.authResponseParser(data);
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
@ -183,6 +172,21 @@ export default class AlipayConnector implements SocialConnectorInstance<AlipayCo
|
|||
return { id, avatar, name };
|
||||
};
|
||||
|
||||
protected readonly authResponseParser: AuthResponseParser<AuthResponse> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = authResponseGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(
|
||||
ConnectorErrorCodes.InvalidResponse,
|
||||
JSON.stringify(parameterObject)
|
||||
);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
|
||||
private readonly errorHandler: ErrorHandler = ({ code, msg, sub_code, sub_msg }) => {
|
||||
if (invalidAccessTokenCode.includes(code)) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid, msg);
|
||||
|
@ -202,19 +206,4 @@ export default class AlipayConnector implements SocialConnectorInstance<AlipayCo
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
const dataGuard = z.object({ auth_code: z.string() });
|
||||
|
||||
const result = dataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(
|
||||
ConnectorErrorCodes.InvalidResponse,
|
||||
JSON.stringify(parameterObject)
|
||||
);
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -58,3 +58,7 @@ export const userInfoResponseGuard = z.object({
|
|||
export type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;
|
||||
|
||||
export type ErrorHandler = (response: AlipayUserInfoShareResponse) => void;
|
||||
|
||||
export const authResponseGuard = z.object({ auth_code: z.string() });
|
||||
|
||||
export type AuthResponse = z.infer<typeof authResponseGuard>;
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
EmailSendMessageFunction,
|
||||
EmailSendTestMessageFunction,
|
||||
EmailSendMessageByFunction,
|
||||
EmailConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
EmailMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import { HTTPError } from 'got';
|
||||
|
@ -21,24 +17,13 @@ import {
|
|||
sendMailErrorResponseGuard,
|
||||
} from './types';
|
||||
|
||||
export default class AliyunDmConnector implements EmailConnectorInstance<AliyunDmConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class AliyunDmConnector<T> extends EmailConnectorInstance<AliyunDmConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AliyunDmConfig {
|
||||
const result = aliyunDmConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -47,25 +32,11 @@ export default class AliyunDmConnector implements EmailConnectorInstance<AliyunD
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: EmailSendMessageFunction = async (address, type, data) => {
|
||||
const emailConfig = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(emailConfig);
|
||||
|
||||
return this.sendMessageBy(emailConfig, address, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: EmailSendTestMessageFunction = async (config, address, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: AliyunDmConfig,
|
||||
address: string,
|
||||
type: keyof EmailMessageTypes,
|
||||
data: EmailMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: EmailSendMessageByFunction<AliyunDmConfig> = async (
|
||||
config,
|
||||
address,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { accessKeyId, accessKeySecret, accountName, fromAlias, templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SmsSendMessageFunction,
|
||||
SmsSendTestMessageFunction,
|
||||
SmsSendMessageByFunction,
|
||||
SmsConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
SmsMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import { HTTPError } from 'got';
|
||||
|
@ -16,24 +12,13 @@ import { defaultMetadata } from './constant';
|
|||
import { sendSms } from './single-send-text';
|
||||
import { aliyunSmsConfigGuard, AliyunSmsConfig, sendSmsResponseGuard } from './types';
|
||||
|
||||
export default class AliyunSmsConnector implements SmsConnectorInstance<AliyunSmsConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class AliyunSmsConnector<T> extends SmsConnectorInstance<AliyunSmsConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AliyunSmsConfig {
|
||||
const result = aliyunSmsConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -42,25 +27,11 @@ export default class AliyunSmsConnector implements SmsConnectorInstance<AliyunSm
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: SmsSendMessageFunction = async (phone, type, data) => {
|
||||
const smsConfig = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(smsConfig);
|
||||
|
||||
return this.sendMessageBy(smsConfig, phone, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: SmsSendTestMessageFunction = async (config, phone, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, phone, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: AliyunSmsConfig,
|
||||
phone: string,
|
||||
type: keyof SmsMessageTypes,
|
||||
data: SmsMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: SmsSendMessageByFunction<AliyunSmsConfig> = async (
|
||||
config,
|
||||
phone,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { accessKeyId, accessKeySecret, signName, templates } = config;
|
||||
const template = templates.find(({ usageType }) => usageType === type);
|
||||
|
|
|
@ -1,37 +1,25 @@
|
|||
import {
|
||||
ConnectorMetadata,
|
||||
AuthResponseParser,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
} from '@logto/connector-types';
|
||||
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
||||
|
||||
import { scope, defaultMetadata, jwksUri, issuer, authorizationEndpoint } from './constant';
|
||||
import { appleConfigGuard, AppleConfig, dataGuard } from './types';
|
||||
import { appleConfigGuard, authResponseGuard, AppleConfig, AuthResponse } from './types';
|
||||
|
||||
// TO-DO: support nonce validation
|
||||
export default class AppleConnector implements SocialConnectorInstance<AppleConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class AppleConnector<T> extends SocialConnectorInstance<AppleConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AppleConfig {
|
||||
const result = appleConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -59,7 +47,7 @@ export default class AppleConnector implements SocialConnectorInstance<AppleConf
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { id_token: idToken } = await this.authorizationCallbackHandler(data);
|
||||
const { id_token: idToken } = await this.authResponseParser(data);
|
||||
|
||||
if (!idToken) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.SocialIdTokenInvalid);
|
||||
|
@ -89,8 +77,10 @@ export default class AppleConnector implements SocialConnectorInstance<AppleConf
|
|||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
const result = dataGuard.safeParse(parameterObject);
|
||||
protected readonly authResponseParser: AuthResponseParser<AuthResponse> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = authResponseGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
|
|
|
@ -7,6 +7,8 @@ export const appleConfigGuard = z.object({
|
|||
export type AppleConfig = z.infer<typeof appleConfigGuard>;
|
||||
|
||||
// https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/configuring_your_webpage_for_sign_in_with_apple#3331292
|
||||
export const dataGuard = z.object({
|
||||
export const authResponseGuard = z.object({
|
||||
id_token: z.string(),
|
||||
});
|
||||
|
||||
export type AuthResponse = z.infer<typeof authResponseGuard>;
|
||||
|
|
|
@ -11,16 +11,15 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
codeWithRedirectDataGuard,
|
||||
CodeWithRedirectData,
|
||||
GetConnectorConfig,
|
||||
} from '@logto/connector-types';
|
||||
import { assert, conditional } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
||||
import { scopes, defaultMetadata, defaultTimeout, graphAPIEndpoint } from './constant';
|
||||
import { scopes, defaultTimeout, graphAPIEndpoint, defaultMetadata } from './constant';
|
||||
import {
|
||||
azureADConfigGuard,
|
||||
AzureADConfig,
|
||||
|
@ -28,31 +27,19 @@ import {
|
|||
userInfoResponseGuard,
|
||||
} from './types';
|
||||
|
||||
export default class AzureADConnector implements SocialConnectorInstance<AzureADConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
|
||||
export default class AzureADConnector<T> extends SocialConnectorInstance<AzureADConfig, T> {
|
||||
public clientApplication!: ConfidentialClientApplication;
|
||||
public authCodeUrlParams!: AuthorizationUrlRequest;
|
||||
|
||||
cryptoProvider = new CryptoProvider();
|
||||
private readonly authCodeRequest!: AuthorizationCodeRequest;
|
||||
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is AzureADConfig {
|
||||
const result = azureADConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -114,7 +101,7 @@ export default class AzureADConnector implements SocialConnectorInstance<AzureAD
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code, redirectUri } = await this.authorizationCallbackHandler(data);
|
||||
const { code, redirectUri } = await this.authResponseParser(data);
|
||||
const { accessToken } = await this.getAccessToken(code, redirectUri);
|
||||
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
@ -157,7 +144,7 @@ export default class AzureADConnector implements SocialConnectorInstance<AzureAD
|
|||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
public authResponseParser = async (parameterObject: unknown): Promise<CodeWithRedirectData> => {
|
||||
const result = codeWithRedirectDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
AuthResponseParser,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
codeWithRedirectDataGuard,
|
||||
CodeWithRedirectData,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -33,24 +33,13 @@ import {
|
|||
userInfoResponseGuard,
|
||||
} from './types';
|
||||
|
||||
export default class FacebookConnector implements SocialConnectorInstance<FacebookConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class FacebookConnector<T> extends SocialConnectorInstance<FacebookConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is FacebookConfig {
|
||||
const result = facebookConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -106,7 +95,7 @@ export default class FacebookConnector implements SocialConnectorInstance<Facebo
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code, redirectUri } = await this.authorizationCallbackHandler(data);
|
||||
const { code, redirectUri } = await this.authResponseParser(data);
|
||||
const { accessToken } = await this.getAccessToken(code, redirectUri);
|
||||
|
||||
try {
|
||||
|
@ -149,7 +138,9 @@ export default class FacebookConnector implements SocialConnectorInstance<Facebo
|
|||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
public readonly authResponseParser: AuthResponseParser<CodeWithRedirectData> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = codeWithRedirectDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (result.success) {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import {
|
||||
ConnectorMetadata,
|
||||
AuthResponseParser,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
codeDataGuard,
|
||||
CodeData,
|
||||
} from '@logto/connector-types';
|
||||
import { assert, conditional } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -29,24 +29,13 @@ import {
|
|||
userInfoResponseGuard,
|
||||
} from './types';
|
||||
|
||||
export default class GithubConnector implements SocialConnectorInstance<GithubConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class GithubConnector<T> extends SocialConnectorInstance<GithubConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is GithubConfig {
|
||||
const result = githubConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -101,7 +90,7 @@ export default class GithubConnector implements SocialConnectorInstance<GithubCo
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code } = await this.authorizationCallbackHandler(data);
|
||||
const { code } = await this.authResponseParser(data);
|
||||
const { accessToken } = await this.getAccessToken(code);
|
||||
|
||||
try {
|
||||
|
@ -141,7 +130,9 @@ export default class GithubConnector implements SocialConnectorInstance<GithubCo
|
|||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
public readonly authResponseParser: AuthResponseParser<CodeData> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = codeDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (result.success) {
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
* https://developers.google.com/identity/protocols/oauth2/openid-connect
|
||||
*/
|
||||
import {
|
||||
AuthResponseParser,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
codeWithRedirectDataGuard,
|
||||
CodeWithRedirectData,
|
||||
} from '@logto/connector-types';
|
||||
import { conditional, assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -31,24 +31,13 @@ import {
|
|||
userInfoResponseGuard,
|
||||
} from './types';
|
||||
|
||||
export default class GoogleConnector implements SocialConnectorInstance<GoogleConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class GoogleConnector<T> extends SocialConnectorInstance<GoogleConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is GoogleConfig {
|
||||
const result = googleConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -107,7 +96,7 @@ export default class GoogleConnector implements SocialConnectorInstance<GoogleCo
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code, redirectUri } = await this.authorizationCallbackHandler(data);
|
||||
const { code, redirectUri } = await this.authResponseParser(data);
|
||||
const { accessToken } = await this.getAccessToken(code, redirectUri);
|
||||
|
||||
try {
|
||||
|
@ -137,7 +126,9 @@ export default class GoogleConnector implements SocialConnectorInstance<GoogleCo
|
|||
}
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
public readonly authResponseParser: AuthResponseParser<CodeWithRedirectData> = async (
|
||||
parameterObject: unknown
|
||||
) => {
|
||||
const result = codeWithRedirectDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
|
|
|
@ -4,37 +4,22 @@ import path from 'path';
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
EmailSendMessageFunction,
|
||||
EmailSendTestMessageFunction,
|
||||
EmailSendMessageByFunction,
|
||||
EmailConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
EmailMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
|
||||
import { defaultMetadata } from './constant';
|
||||
import { mockMailConfigGuard, MockMailConfig } from './types';
|
||||
|
||||
export default class MockMailConnector implements EmailConnectorInstance<MockMailConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class MockMailConnector<T> extends EmailConnectorInstance<MockMailConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is MockMailConfig {
|
||||
const result = mockMailConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -43,25 +28,11 @@ export default class MockMailConnector implements EmailConnectorInstance<MockMai
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: EmailSendMessageFunction = async (address, type, data) => {
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: EmailSendTestMessageFunction = async (config, address, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: MockMailConfig,
|
||||
address: string,
|
||||
type: keyof EmailMessageTypes,
|
||||
data: EmailMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: EmailSendMessageByFunction<MockMailConfig> = async (
|
||||
config,
|
||||
address,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -4,37 +4,22 @@ import path from 'path';
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SmsSendMessageFunction,
|
||||
SmsSendTestMessageFunction,
|
||||
SmsSendMessageByFunction,
|
||||
SmsConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
SmsMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
|
||||
import { defaultMetadata } from './constant';
|
||||
import { mockSmsConfigGuard, MockSmsConfig } from './types';
|
||||
|
||||
export default class MockSmsConnector implements SmsConnectorInstance<MockSmsConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class MockSmsConnector<T> extends SmsConnectorInstance<MockSmsConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is MockSmsConfig {
|
||||
const result = mockSmsConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -43,25 +28,11 @@ export default class MockSmsConnector implements SmsConnectorInstance<MockSmsCon
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: SmsSendMessageFunction = async (phone, type, data) => {
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, phone, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: SmsSendTestMessageFunction = async (config, phone, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, phone, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: MockSmsConfig,
|
||||
phone: string,
|
||||
type: keyof SmsMessageTypes,
|
||||
data: SmsMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: SmsSendMessageByFunction<MockSmsConfig> = async (
|
||||
config,
|
||||
phone,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -5,8 +5,6 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
} from '@logto/connector-types';
|
||||
|
@ -15,24 +13,13 @@ import { z } from 'zod';
|
|||
import { defaultMetadata } from './constant';
|
||||
import { mockSocialConfigGuard, MockSocialConfig } from './types';
|
||||
|
||||
export default class MockSocialConnector implements SocialConnectorInstance<MockSocialConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class MockSocialConnector<T> extends SocialConnectorInstance<MockSocialConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is MockSocialConfig {
|
||||
const result = mockSocialConfigGuard.safeParse(config);
|
||||
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
EmailSendMessageFunction,
|
||||
EmailSendTestMessageFunction,
|
||||
EmailSendMessageByFunction,
|
||||
EmailConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
EmailMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -22,24 +18,16 @@ import {
|
|||
PublicParameters,
|
||||
} from './types';
|
||||
|
||||
export default class SendGridMailConnector implements EmailConnectorInstance<SendGridMailConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class SendGridMailConnector<T> extends EmailConnectorInstance<
|
||||
SendGridMailConfig,
|
||||
T
|
||||
> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is SendGridMailConfig {
|
||||
const result = sendGridMailConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -48,25 +36,11 @@ export default class SendGridMailConnector implements EmailConnectorInstance<Sen
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: EmailSendMessageFunction = async (address, type, data) => {
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: EmailSendTestMessageFunction = async (config, address, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: SendGridMailConfig,
|
||||
address: string,
|
||||
type: keyof EmailMessageTypes,
|
||||
data: EmailMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: EmailSendMessageByFunction<SendGridMailConfig> = async (
|
||||
config,
|
||||
address,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { apiKey, fromEmail, fromName, templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
EmailSendMessageFunction,
|
||||
EmailSendTestMessageFunction,
|
||||
EmailSendMessageByFunction,
|
||||
EmailConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
EmailMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import nodemailer from 'nodemailer';
|
||||
|
@ -16,24 +12,13 @@ import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
|||
import { defaultMetadata } from './constant';
|
||||
import { ContextType, smtpConfigGuard, SmtpConfig } from './types';
|
||||
|
||||
export default class SmtpConnector implements EmailConnectorInstance<SmtpConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class SmtpConnector<T> extends EmailConnectorInstance<SmtpConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is SmtpConfig {
|
||||
const result = smtpConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -42,25 +27,11 @@ export default class SmtpConnector implements EmailConnectorInstance<SmtpConfig>
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: EmailSendMessageFunction = async (address, type, data) => {
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: EmailSendTestMessageFunction = async (config, address, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, address, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: SmtpConfig,
|
||||
address: string,
|
||||
type: keyof EmailMessageTypes,
|
||||
data: EmailMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: EmailSendMessageByFunction<SmtpConfig> = async (
|
||||
config,
|
||||
address,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { host, port, username, password, fromEmail, replyTo, templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
import {
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
ConnectorMetadata,
|
||||
Connector,
|
||||
SmsSendMessageFunction,
|
||||
SmsSendTestMessageFunction,
|
||||
SmsSendMessageByFunction,
|
||||
SmsConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
SmsMessageTypes,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -15,24 +11,13 @@ import got, { HTTPError } from 'got';
|
|||
import { defaultMetadata, endpoint } from './constant';
|
||||
import { twilioSmsConfigGuard, TwilioSmsConfig, PublicParameters } from './types';
|
||||
|
||||
export default class TwilioSmsConnector implements SmsConnectorInstance<TwilioSmsConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class TwilioSmsConnector<T> extends SmsConnectorInstance<TwilioSmsConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is TwilioSmsConfig {
|
||||
const result = twilioSmsConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -41,25 +26,11 @@ export default class TwilioSmsConnector implements SmsConnectorInstance<TwilioSm
|
|||
}
|
||||
}
|
||||
|
||||
public sendMessage: SmsSendMessageFunction = async (phone, type, data) => {
|
||||
const config = await this.getConfig(this.metadata.id);
|
||||
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, phone, type, data);
|
||||
};
|
||||
|
||||
public sendTestMessage: SmsSendTestMessageFunction = async (config, phone, type, data) => {
|
||||
this.validateConfig(config);
|
||||
|
||||
return this.sendMessageBy(config, phone, type, data);
|
||||
};
|
||||
|
||||
private readonly sendMessageBy = async (
|
||||
config: TwilioSmsConfig,
|
||||
phone: string,
|
||||
type: keyof SmsMessageTypes,
|
||||
data: SmsMessageTypes[typeof type]
|
||||
public readonly sendMessageBy: SmsSendMessageByFunction<TwilioSmsConfig> = async (
|
||||
config,
|
||||
phone,
|
||||
type,
|
||||
data
|
||||
) => {
|
||||
const { accountSID, authToken, fromMessagingServiceSID, templates } = config;
|
||||
const template = templates.find((template) => template.usageType === type);
|
||||
|
|
|
@ -1,26 +1,9 @@
|
|||
// FIXME: @Darcy
|
||||
/* eslint-disable @typescript-eslint/consistent-type-definitions */
|
||||
|
||||
import type { Language } from '@logto/phrases';
|
||||
import { Nullable } from '@silverhand/essentials';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Connector is auto-generated in @logto/schemas according to sql file.
|
||||
* As @logto/schemas depends on this repo (@logto/connector-types), we manually define Connector type again as a temporary solution.
|
||||
*/
|
||||
|
||||
export const arbitraryObjectGuard = z.union([z.object({}).catchall(z.unknown()), z.object({})]);
|
||||
|
||||
export type ArbitraryObject = z.infer<typeof arbitraryObjectGuard>;
|
||||
|
||||
export type Connector = {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
config: ArbitraryObject;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
export enum ConnectorType {
|
||||
Email = 'Email',
|
||||
SMS = 'SMS',
|
||||
|
@ -103,6 +86,13 @@ export type EmailSendTestMessageFunction<T = unknown> = (
|
|||
payload: EmailMessageTypes[typeof type]
|
||||
) => Promise<T>;
|
||||
|
||||
export type EmailSendMessageByFunction<T> = (
|
||||
config: T,
|
||||
address: string,
|
||||
type: keyof EmailMessageTypes,
|
||||
payload: EmailMessageTypes[typeof type]
|
||||
) => Promise<unknown>;
|
||||
|
||||
export type SmsSendMessageFunction<T = unknown> = (
|
||||
phone: string,
|
||||
type: keyof SmsMessageTypes,
|
||||
|
@ -116,45 +106,14 @@ export type SmsSendTestMessageFunction<T = unknown> = (
|
|||
payload: SmsMessageTypes[typeof type]
|
||||
) => Promise<T>;
|
||||
|
||||
export interface BaseConnector<T = unknown> {
|
||||
metadata: ConnectorMetadata;
|
||||
getConfig: GetConnectorConfig;
|
||||
validateConfig: ValidateConfig<T>;
|
||||
}
|
||||
export type SmsSendMessageByFunction<T> = (
|
||||
config: T,
|
||||
phone: string,
|
||||
type: keyof SmsMessageTypes,
|
||||
payload: SmsMessageTypes[typeof type]
|
||||
) => Promise<unknown>;
|
||||
|
||||
export interface SmsConnector<T = unknown> extends BaseConnector<T> {
|
||||
sendMessage: SmsSendMessageFunction;
|
||||
sendTestMessage?: SmsSendTestMessageFunction;
|
||||
}
|
||||
|
||||
export interface SmsConnectorInstance<T = unknown> extends SmsConnector<T> {
|
||||
connector: Connector;
|
||||
}
|
||||
|
||||
export interface EmailConnector<T = unknown> extends BaseConnector<T> {
|
||||
sendMessage: EmailSendMessageFunction;
|
||||
sendTestMessage?: EmailSendTestMessageFunction;
|
||||
}
|
||||
|
||||
export interface EmailConnectorInstance<T = unknown> extends EmailConnector<T> {
|
||||
connector: Connector;
|
||||
}
|
||||
|
||||
export interface SocialConnector<T = unknown> extends BaseConnector<T> {
|
||||
getAuthorizationUri: GetAuthorizationUri;
|
||||
getUserInfo: GetUserInfo;
|
||||
}
|
||||
|
||||
export interface SocialConnectorInstance<T = unknown> extends SocialConnector<T> {
|
||||
connector: Connector;
|
||||
}
|
||||
|
||||
export type ConnectorInstance =
|
||||
| SmsConnectorInstance
|
||||
| EmailConnectorInstance
|
||||
| SocialConnectorInstance;
|
||||
|
||||
export type ValidateConfig<T = unknown> = (config: unknown) => asserts config is T;
|
||||
export type ValidateConfig<T> = (config: unknown) => asserts config is T;
|
||||
|
||||
export type GetAuthorizationUri = (payload: {
|
||||
state: string;
|
||||
|
@ -167,6 +126,8 @@ export type GetUserInfo = (
|
|||
|
||||
export type GetConnectorConfig = (id: string) => Promise<unknown>;
|
||||
|
||||
export type AuthResponseParser<T = Record<string, unknown>> = (response: unknown) => Promise<T>;
|
||||
|
||||
export const codeDataGuard = z.object({
|
||||
code: z.string(),
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"extends": "@silverhand/ts-config/tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"types": ["node"],
|
||||
"outDir": "lib",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ConnectorMetadata,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
AuthResponseParser,
|
||||
codeDataGuard,
|
||||
CodeData,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -35,24 +35,16 @@ import {
|
|||
WechatNativeConfig,
|
||||
} from './types';
|
||||
|
||||
export default class WechatNativeConnector implements SocialConnectorInstance<WechatNativeConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class WechatNativeConnector<T> extends SocialConnectorInstance<
|
||||
WechatNativeConfig,
|
||||
T
|
||||
> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is WechatNativeConfig {
|
||||
const result = wechatNativeConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -108,7 +100,7 @@ export default class WechatNativeConnector implements SocialConnectorInstance<We
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code } = await this.authorizationCallbackHandler(data);
|
||||
const { code } = await this.authResponseParser(data);
|
||||
const { accessToken, openid } = await this.getAccessToken(code);
|
||||
|
||||
try {
|
||||
|
@ -136,6 +128,16 @@ export default class WechatNativeConnector implements SocialConnectorInstance<We
|
|||
}
|
||||
};
|
||||
|
||||
protected authResponseParser: AuthResponseParser<CodeData> = async (parameterObject: unknown) => {
|
||||
const result = codeDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
|
||||
// See https://developers.weixin.qq.com/doc/oplatform/Return_codes/Return_code_descriptions_new.html
|
||||
private readonly getAccessTokenErrorHandler: GetAccessTokenErrorHandler = (accessToken) => {
|
||||
const { errcode, errmsg } = accessToken;
|
||||
|
@ -176,14 +178,4 @@ export default class WechatNativeConnector implements SocialConnectorInstance<We
|
|||
|
||||
throw error;
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
const result = codeDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ConnectorMetadata,
|
||||
AuthResponseParser,
|
||||
GetAuthorizationUri,
|
||||
GetUserInfo,
|
||||
ConnectorError,
|
||||
ConnectorErrorCodes,
|
||||
Connector,
|
||||
SocialConnectorInstance,
|
||||
GetConnectorConfig,
|
||||
codeDataGuard,
|
||||
CodeData,
|
||||
} from '@logto/connector-types';
|
||||
import { assert } from '@silverhand/essentials';
|
||||
import got, { HTTPError } from 'got';
|
||||
|
@ -36,24 +36,13 @@ import {
|
|||
WechatConfig,
|
||||
} from './types';
|
||||
|
||||
export default class WechatConnector implements SocialConnectorInstance<WechatConfig> {
|
||||
public metadata: ConnectorMetadata = defaultMetadata;
|
||||
private _connector?: Connector;
|
||||
|
||||
public get connector() {
|
||||
if (!this._connector) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General);
|
||||
}
|
||||
|
||||
return this._connector;
|
||||
export default class WechatConnector<T> extends SocialConnectorInstance<WechatConfig, T> {
|
||||
constructor(getConnectorConfig: GetConnectorConfig) {
|
||||
super(getConnectorConfig);
|
||||
this.metadata = defaultMetadata;
|
||||
this.metadataParser();
|
||||
}
|
||||
|
||||
public set connector(input: Connector) {
|
||||
this._connector = input;
|
||||
}
|
||||
|
||||
constructor(public readonly getConfig: GetConnectorConfig) {}
|
||||
|
||||
public validateConfig(config: unknown): asserts config is WechatConfig {
|
||||
const result = wechatConfigGuard.safeParse(config);
|
||||
|
||||
|
@ -110,7 +99,7 @@ export default class WechatConnector implements SocialConnectorInstance<WechatCo
|
|||
};
|
||||
|
||||
public getUserInfo: GetUserInfo = async (data) => {
|
||||
const { code } = await this.authorizationCallbackHandler(data);
|
||||
const { code } = await this.authResponseParser(data);
|
||||
const { accessToken, openid } = await this.getAccessToken(code);
|
||||
|
||||
try {
|
||||
|
@ -138,6 +127,16 @@ export default class WechatConnector implements SocialConnectorInstance<WechatCo
|
|||
}
|
||||
};
|
||||
|
||||
protected authResponseParser: AuthResponseParser<CodeData> = async (parameterObject: unknown) => {
|
||||
const result = codeDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
|
||||
// See https://developers.weixin.qq.com/doc/oplatform/Return_codes/Return_code_descriptions_new.html
|
||||
private readonly getAccessTokenErrorHandler: GetAccessTokenErrorHandler = (accessToken) => {
|
||||
const { errcode, errmsg } = accessToken;
|
||||
|
@ -178,14 +177,4 @@ export default class WechatConnector implements SocialConnectorInstance<WechatCo
|
|||
|
||||
throw error;
|
||||
};
|
||||
|
||||
private readonly authorizationCallbackHandler = async (parameterObject: unknown) => {
|
||||
const result = codeDataGuard.safeParse(parameterObject);
|
||||
|
||||
if (!result.success) {
|
||||
throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
|
||||
}
|
||||
|
||||
return result.data;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import { existsSync, readFileSync } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { ConnectorInstance, SocialConnectorInstance } from '@logto/connector-types';
|
||||
import resolvePackagePath from 'resolve-package-path';
|
||||
import { Connector } from '@logto/schemas';
|
||||
|
||||
import envSet from '@/env-set';
|
||||
import RequestError from '@/errors/RequestError';
|
||||
|
@ -32,55 +29,7 @@ const loadConnectors = async () => {
|
|||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const { default: Builder } = await import(packageName);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment
|
||||
const instance: ConnectorInstance = new Builder(getConnectorConfig);
|
||||
// eslint-disable-next-line unicorn/prefer-module
|
||||
const packagePath = resolvePackagePath(packageName, __dirname);
|
||||
|
||||
// For relative path logo url, try to read local asset.
|
||||
if (
|
||||
packagePath &&
|
||||
!instance.metadata.logo.startsWith('http') &&
|
||||
existsSync(path.join(packagePath, '..', instance.metadata.logo))
|
||||
) {
|
||||
const data = readFileSync(path.join(packagePath, '..', instance.metadata.logo));
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
instance.metadata.logo = `data:image/svg+xml;base64,${data.toString('base64')}`;
|
||||
}
|
||||
|
||||
if (
|
||||
packagePath &&
|
||||
instance.metadata.logoDark &&
|
||||
!instance.metadata.logoDark.startsWith('http') &&
|
||||
existsSync(path.join(packagePath, '..', instance.metadata.logoDark))
|
||||
) {
|
||||
const data = readFileSync(path.join(packagePath, '..', instance.metadata.logoDark));
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
instance.metadata.logoDark = `data:image/svg+xml;base64,${data.toString('base64')}`;
|
||||
}
|
||||
|
||||
if (
|
||||
packagePath &&
|
||||
instance.metadata.readme &&
|
||||
existsSync(path.join(packagePath, '..', instance.metadata.readme))
|
||||
) {
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
instance.metadata.readme = readFileSync(
|
||||
path.join(packagePath, '..', instance.metadata.readme),
|
||||
'utf8'
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
packagePath &&
|
||||
instance.metadata.configTemplate &&
|
||||
existsSync(path.join(packagePath, '..', instance.metadata.configTemplate))
|
||||
) {
|
||||
// eslint-disable-next-line @silverhand/fp/no-mutation
|
||||
instance.metadata.configTemplate = readFileSync(
|
||||
path.join(packagePath, '..', instance.metadata.configTemplate),
|
||||
'utf8'
|
||||
);
|
||||
}
|
||||
const instance: ConnectorInstance = new Builder<Connector>(getConnectorConfig);
|
||||
|
||||
return instance;
|
||||
})
|
||||
|
@ -127,13 +76,13 @@ export const getConnectorInstanceById = async (id: string): Promise<ConnectorIns
|
|||
|
||||
const isSocialConnectorInstance = (
|
||||
connector: ConnectorInstance
|
||||
): connector is SocialConnectorInstance => {
|
||||
): connector is InstanceType<typeof SocialConnectorInstance> => {
|
||||
return connector.metadata.type === ConnectorType.Social;
|
||||
};
|
||||
|
||||
export const getSocialConnectorInstanceById = async (
|
||||
id: string
|
||||
): Promise<SocialConnectorInstance> => {
|
||||
): Promise<InstanceType<typeof SocialConnectorInstance>> => {
|
||||
const connector = await getConnectorInstanceById(id);
|
||||
|
||||
if (!isSocialConnectorInstance(connector)) {
|
||||
|
|
176
pnpm-lock.yaml
generated
176
pnpm-lock.yaml
generated
|
@ -660,10 +660,18 @@ importers:
|
|||
'@shopify/jest-koa-mocks': ^5.0.0
|
||||
'@silverhand/eslint-config': 1.0.0-rc.2
|
||||
'@silverhand/essentials': ^1.1.6
|
||||
<<<<<<< HEAD
|
||||
'@silverhand/ts-config': 1.0.0-rc.2
|
||||
'@types/jest': ^28.1.6
|
||||
eslint: ^8.21.0
|
||||
jest: ^28.1.3
|
||||
=======
|
||||
'@silverhand/ts-config': ^0.17.0
|
||||
'@types/jest': ^27.4.1
|
||||
'@types/node': ^16.3.1
|
||||
eslint: ^8.19.0
|
||||
jest: ^27.5.1
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
lint-staged: ^13.0.0
|
||||
prettier: ^2.7.1
|
||||
typescript: ^4.7.4
|
||||
|
@ -676,10 +684,18 @@ importers:
|
|||
'@shopify/jest-koa-mocks': 5.0.0
|
||||
'@silverhand/eslint-config': 1.0.0-rc.2_swk2g7ygmfleszo5c33j4vooni
|
||||
'@silverhand/essentials': 1.1.7
|
||||
<<<<<<< HEAD
|
||||
'@silverhand/ts-config': 1.0.0-rc.2_typescript@4.7.4
|
||||
'@types/jest': 28.1.6
|
||||
eslint: 8.21.0
|
||||
jest: 28.1.3
|
||||
=======
|
||||
'@silverhand/ts-config': 0.17.0_typescript@4.6.3
|
||||
'@types/jest': 27.4.1
|
||||
'@types/node': 16.11.12
|
||||
eslint: 8.19.0
|
||||
jest: 27.5.1
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
lint-staged: 13.0.0
|
||||
prettier: 2.7.1
|
||||
typescript: 4.7.4
|
||||
|
@ -2065,8 +2081,13 @@ packages:
|
|||
resolution: {integrity: sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
jest-message-util: 28.1.3
|
||||
jest-util: 28.1.3
|
||||
|
@ -2081,12 +2102,21 @@ packages:
|
|||
node-notifier:
|
||||
optional: true
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/console': 28.1.3
|
||||
'@jest/reporters': 28.1.3
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/transform': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/console': 27.5.1
|
||||
'@jest/reporters': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/transform': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.3.2
|
||||
|
@ -2123,12 +2153,21 @@ packages:
|
|||
node-notifier:
|
||||
optional: true
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/console': 28.1.3
|
||||
'@jest/reporters': 28.1.3
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/transform': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/console': 27.5.1
|
||||
'@jest/reporters': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/transform': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.3.2
|
||||
|
@ -2161,10 +2200,18 @@ packages:
|
|||
resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/fake-timers': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
jest-mock: 28.1.3
|
||||
=======
|
||||
'@jest/fake-timers': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
jest-mock: 27.5.1
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/@jest/expect-utils/28.1.3:
|
||||
resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==}
|
||||
|
@ -2185,12 +2232,22 @@ packages:
|
|||
resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/types': 28.1.3
|
||||
'@sinonjs/fake-timers': 9.1.2
|
||||
'@types/node': 17.0.23
|
||||
jest-message-util: 28.1.3
|
||||
jest-mock: 28.1.3
|
||||
jest-util: 28.1.3
|
||||
=======
|
||||
'@jest/types': 27.5.1
|
||||
'@sinonjs/fake-timers': 8.1.0
|
||||
'@types/node': 18.6.3
|
||||
jest-message-util: 27.5.1
|
||||
jest-mock: 27.5.1
|
||||
jest-util: 27.5.1
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/@jest/globals/28.1.3:
|
||||
resolution: {integrity: sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==}
|
||||
|
@ -2212,12 +2269,20 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@bcoe/v8-coverage': 0.2.3
|
||||
<<<<<<< HEAD
|
||||
'@jest/console': 28.1.3
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/transform': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@jridgewell/trace-mapping': 0.3.14
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/console': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/transform': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
collect-v8-coverage: 1.0.1
|
||||
exit: 0.1.2
|
||||
|
@ -2300,8 +2365,13 @@ packages:
|
|||
'@jest/schemas': 28.1.3
|
||||
'@types/istanbul-lib-coverage': 2.0.3
|
||||
'@types/istanbul-reports': 3.0.1
|
||||
<<<<<<< HEAD
|
||||
'@types/node': 17.0.23
|
||||
'@types/yargs': 17.0.10
|
||||
=======
|
||||
'@types/node': 18.6.3
|
||||
'@types/yargs': 16.0.4
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
|
||||
/@jridgewell/resolve-uri/3.0.5:
|
||||
|
@ -4941,7 +5011,12 @@ packages:
|
|||
/@types/graceful-fs/4.1.5:
|
||||
resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@types/node': 18.6.3
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/@types/hast/2.3.4:
|
||||
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
|
||||
|
@ -5125,6 +5200,9 @@ packages:
|
|||
/@types/node/17.0.23:
|
||||
resolution: {integrity: sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==}
|
||||
|
||||
/@types/node/18.6.3:
|
||||
resolution: {integrity: sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==}
|
||||
|
||||
/@types/nodemailer/6.4.4:
|
||||
resolution: {integrity: sha512-Ksw4t7iliXeYGvIQcSIgWQ5BLuC/mljIEbjf615svhZL10PE9t+ei8O9gDaD3FPCasUJn9KTLwz2JFJyiiyuqw==}
|
||||
dependencies:
|
||||
|
@ -9363,11 +9441,18 @@ packages:
|
|||
resolution: {integrity: sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/environment': 28.1.3
|
||||
'@jest/expect': 28.1.3
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/environment': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
co: 4.6.0
|
||||
dedent: 0.7.0
|
||||
|
@ -9666,6 +9751,7 @@ packages:
|
|||
resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
chalk: 4.1.2
|
||||
diff-sequences: 28.1.1
|
||||
jest-get-type: 28.0.2
|
||||
|
@ -9699,6 +9785,15 @@ packages:
|
|||
jest-mock: 28.1.3
|
||||
jest-util: 28.1.3
|
||||
jsdom: 19.0.0
|
||||
=======
|
||||
'@jest/environment': 27.5.1
|
||||
'@jest/fake-timers': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
jest-mock: 27.5.1
|
||||
jest-util: 27.5.1
|
||||
jsdom: 16.7.0
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- canvas
|
||||
|
@ -9710,12 +9805,22 @@ packages:
|
|||
resolution: {integrity: sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/environment': 28.1.3
|
||||
'@jest/fake-timers': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
jest-mock: 28.1.3
|
||||
jest-util: 28.1.3
|
||||
=======
|
||||
'@jest/environment': 27.5.1
|
||||
'@jest/fake-timers': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
jest-mock: 27.5.1
|
||||
jest-util: 27.5.1
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/jest-get-type/28.0.2:
|
||||
resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==}
|
||||
|
@ -9727,7 +9832,7 @@ packages:
|
|||
dependencies:
|
||||
'@jest/types': 28.1.3
|
||||
'@types/graceful-fs': 4.1.5
|
||||
'@types/node': 17.0.23
|
||||
'@types/node': 18.6.3
|
||||
anymatch: 3.1.2
|
||||
fb-watchman: 2.0.1
|
||||
graceful-fs: 4.2.9
|
||||
|
@ -9738,6 +9843,35 @@ packages:
|
|||
walker: 1.0.8
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
dev: true
|
||||
|
||||
/jest-jasmine2/27.5.1:
|
||||
resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
dependencies:
|
||||
'@jest/environment': 27.5.1
|
||||
'@jest/source-map': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
chalk: 4.1.2
|
||||
co: 4.6.0
|
||||
expect: 27.5.1
|
||||
is-generator-fn: 2.1.0
|
||||
jest-each: 27.5.1
|
||||
jest-matcher-utils: 27.5.1
|
||||
jest-message-util: 27.5.1
|
||||
jest-runtime: 27.5.1
|
||||
jest-snapshot: 27.5.1
|
||||
jest-util: 27.5.1
|
||||
pretty-format: 27.5.1
|
||||
throat: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/jest-leak-detector/28.1.3:
|
||||
resolution: {integrity: sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==}
|
||||
|
@ -9776,8 +9910,14 @@ packages:
|
|||
resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/jest-pnp-resolver/1.2.2_jest-resolve@28.1.3:
|
||||
resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
|
||||
|
@ -9821,12 +9961,21 @@ packages:
|
|||
resolution: {integrity: sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/console': 28.1.3
|
||||
'@jest/environment': 28.1.3
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/transform': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/console': 27.5.1
|
||||
'@jest/environment': 27.5.1
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/transform': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
emittery: 0.10.2
|
||||
graceful-fs: 4.2.9
|
||||
|
@ -9873,6 +10022,18 @@ packages:
|
|||
strip-bom: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
dev: true
|
||||
|
||||
/jest-serializer/27.5.1:
|
||||
resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
dependencies:
|
||||
'@types/node': 18.6.3
|
||||
graceful-fs: 4.2.9
|
||||
dev: true
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
|
||||
/jest-snapshot/28.1.3:
|
||||
resolution: {integrity: sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==}
|
||||
|
@ -9921,8 +10082,13 @@ packages:
|
|||
resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.3.2
|
||||
graceful-fs: 4.2.9
|
||||
|
@ -9943,9 +10109,15 @@ packages:
|
|||
resolution: {integrity: sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
<<<<<<< HEAD
|
||||
'@jest/test-result': 28.1.3
|
||||
'@jest/types': 28.1.3
|
||||
'@types/node': 17.0.23
|
||||
=======
|
||||
'@jest/test-result': 27.5.1
|
||||
'@jest/types': 27.5.1
|
||||
'@types/node': 18.6.3
|
||||
>>>>>>> f04cfcf3 (refactor(connector): refactor connector)
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
emittery: 0.10.2
|
||||
|
@ -9956,7 +10128,7 @@ packages:
|
|||
resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
|
||||
dependencies:
|
||||
'@types/node': 17.0.23
|
||||
'@types/node': 18.6.3
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue