mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
refactor(toolkit,core,connector): add connector switch for WIP features
This commit is contained in:
parent
3efd6485fc
commit
26466e6542
10 changed files with 51 additions and 27 deletions
|
@ -1,5 +1,3 @@
|
|||
import { getEnv } from '@silverhand/essentials';
|
||||
|
||||
import type { ConnectorMetadata } from '@logto/connector-kit';
|
||||
import { ConnectorConfigFormItemType } from '@logto/connector-kit';
|
||||
|
||||
|
@ -102,11 +100,9 @@ export const defaultMetadata: ConnectorMetadata = {
|
|||
|
||||
export const scope = ['send:email'];
|
||||
|
||||
export const defaultTimeout = 5000;
|
||||
export const defaultTimeout = 10_000;
|
||||
|
||||
export const oldEmailEndpoint = '/services/send-email';
|
||||
export const newEmailEndpoint = '/services/mails';
|
||||
export const emailEndpoint =
|
||||
getEnv('NODE_ENV') === 'production' ? oldEmailEndpoint : newEmailEndpoint;
|
||||
|
||||
export const usageEndpoint = '/services/mails/usage';
|
||||
|
|
|
@ -2,7 +2,7 @@ import nock from 'nock';
|
|||
|
||||
import { VerificationCodeType } from '@logto/connector-kit';
|
||||
|
||||
import { emailEndpoint } from './constant.js';
|
||||
import { newEmailEndpoint } from './constant.js';
|
||||
import { mockedAccessTokenResponse, mockedConfig } from './mock.js';
|
||||
|
||||
const { jest } = import.meta;
|
||||
|
@ -17,14 +17,18 @@ describe('sendMessage()', () => {
|
|||
});
|
||||
|
||||
it('should send message successfully', async () => {
|
||||
nock(mockedConfig.endpoint).post(emailEndpoint).reply(200);
|
||||
nock(mockedConfig.endpoint).post(newEmailEndpoint).reply(200);
|
||||
const connector = await createConnector({ getConfig });
|
||||
await expect(
|
||||
connector.sendMessage({
|
||||
connector.sendMessage(
|
||||
{
|
||||
to: 'wangsijie94@gmail.com',
|
||||
type: VerificationCodeType.SignIn,
|
||||
payload: { code: '1234' },
|
||||
})
|
||||
},
|
||||
undefined,
|
||||
false // Set to `false` since this is not production env.
|
||||
)
|
||||
).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,13 @@ import {
|
|||
ConnectorErrorCodes,
|
||||
} from '@logto/connector-kit';
|
||||
|
||||
import { defaultMetadata, defaultTimeout, emailEndpoint, usageEndpoint } from './constant.js';
|
||||
import {
|
||||
defaultMetadata,
|
||||
defaultTimeout,
|
||||
oldEmailEndpoint,
|
||||
newEmailEndpoint,
|
||||
usageEndpoint,
|
||||
} from './constant.js';
|
||||
import { grantAccessToken } from './grant-access-token.js';
|
||||
import type { LogtoEmailConfig } from './types.js';
|
||||
import { logtoEmailConfigGuard } from './types.js';
|
||||
|
@ -24,9 +30,10 @@ export type { EmailServiceBasicConfig } from './types.js';
|
|||
|
||||
const sendMessage =
|
||||
(getConfig: GetConnectorConfig): SendMessageFunction =>
|
||||
async (data, inputConfig) => {
|
||||
async (data, inputConfig, isDevelopment) => {
|
||||
const config = inputConfig ?? (await getConfig(defaultMetadata.id));
|
||||
validateConfig<LogtoEmailConfig>(config, logtoEmailConfigGuard);
|
||||
const emailEndpoint = isDevelopment ? oldEmailEndpoint : newEmailEndpoint;
|
||||
|
||||
const {
|
||||
endpoint,
|
||||
|
|
|
@ -15,7 +15,8 @@ export type ConnectorLibrary = ReturnType<typeof createConnectorLibrary>;
|
|||
|
||||
export const createConnectorLibrary = (
|
||||
queries: Queries,
|
||||
cloudConnection: CloudConnectionLibrary
|
||||
cloudConnection: CloudConnectionLibrary,
|
||||
isProduction: boolean
|
||||
) => {
|
||||
const { findAllConnectors, findAllConnectorsWellKnown } = queries.connectors;
|
||||
const { getCloudConnectionData } = cloudConnection;
|
||||
|
@ -99,6 +100,7 @@ export const createConnectorLibrary = (
|
|||
validateConfig(config, rawConnector.configGuard);
|
||||
},
|
||||
dbEntry: databaseConnector,
|
||||
isDevelopment: isProduction && ServiceConnector.Email === connectorFactory.metadata.id,
|
||||
};
|
||||
} catch {}
|
||||
})
|
||||
|
|
|
@ -83,7 +83,7 @@ export const createPasscodeLibrary = (queries: Queries, connectorLibrary: Connec
|
|||
})
|
||||
);
|
||||
|
||||
const { dbEntry, metadata, sendMessage } = connector;
|
||||
const { dbEntry, metadata, sendMessage, isDevelopment } = connector;
|
||||
|
||||
const messageTypeResult = verificationCodeTypeGuard.safeParse(passcode.type);
|
||||
|
||||
|
@ -91,13 +91,17 @@ export const createPasscodeLibrary = (queries: Queries, connectorLibrary: Connec
|
|||
throw new ConnectorError(ConnectorErrorCodes.InvalidConfig);
|
||||
}
|
||||
|
||||
const response = await sendMessage({
|
||||
const response = await sendMessage(
|
||||
{
|
||||
to: emailOrPhone,
|
||||
type: messageTypeResult.data,
|
||||
payload: {
|
||||
code: passcode.code,
|
||||
},
|
||||
});
|
||||
},
|
||||
undefined,
|
||||
isDevelopment
|
||||
);
|
||||
|
||||
return { dbEntry, metadata, response };
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ import { phoneRegEx, emailRegEx } from '@logto/core-kit';
|
|||
import { jsonObjectGuard, ConnectorType } from '@logto/schemas';
|
||||
import { string, object } from 'zod';
|
||||
|
||||
import { EnvSet } from '#src/env-set/index.js';
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import koaGuard from '#src/middleware/koa-guard.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
|
@ -84,7 +85,8 @@ export default function connectorConfigTestingRoutes<T extends AuthedRouter>(
|
|||
code: '000000',
|
||||
},
|
||||
},
|
||||
config
|
||||
config,
|
||||
ServiceConnector.Email === connectorFactory.metadata.id && EnvSet.values.isProduction
|
||||
);
|
||||
|
||||
ctx.status = 204;
|
||||
|
|
|
@ -56,7 +56,11 @@ export default class Tenant implements TenantContext {
|
|||
public readonly queries = new Queries(envSet.pool, wellKnownCache),
|
||||
public readonly logtoConfigs = createLogtoConfigLibrary(queries),
|
||||
public readonly cloudConnection = createCloudConnectionLibrary(logtoConfigs),
|
||||
public readonly connectors = createConnectorLibrary(queries, cloudConnection),
|
||||
public readonly connectors = createConnectorLibrary(
|
||||
queries,
|
||||
cloudConnection,
|
||||
EnvSet.values.isProduction
|
||||
),
|
||||
public readonly libraries = new Libraries(id, queries, connectors)
|
||||
) {
|
||||
const isAdminTenant = id === adminTenantId;
|
||||
|
|
|
@ -76,7 +76,8 @@ export class MockTenant implements TenantContext {
|
|||
this.logtoConfigs = createLogtoConfigLibrary(this.queries);
|
||||
this.cloudConnection = createCloudConnectionLibrary(this.logtoConfigs);
|
||||
this.connectors = {
|
||||
...createConnectorLibrary(this.queries, this.cloudConnection),
|
||||
// Manually set the third argument `isDevelopment` to `false` since this is not a production environment.
|
||||
...createConnectorLibrary(this.queries, this.cloudConnection, false),
|
||||
...connectorsOverride,
|
||||
};
|
||||
this.libraries = new Libraries(this.id, this.queries, this.connectors);
|
||||
|
|
|
@ -9,7 +9,7 @@ export { ConnectorType } from '@logto/schemas';
|
|||
*/
|
||||
export type LogtoConnector<T extends AllConnector = AllConnector> = T & {
|
||||
validateConfig: (config: unknown) => void;
|
||||
} & { dbEntry: Connector };
|
||||
} & { dbEntry: Connector; isDevelopment: boolean };
|
||||
|
||||
export const connectorWellKnownGuard = Connectors.guard.pick({
|
||||
id: true,
|
||||
|
|
|
@ -240,7 +240,11 @@ export const sendMessagePayloadGuard = z.object({
|
|||
|
||||
export type SendMessagePayload = z.infer<typeof sendMessagePayloadGuard>;
|
||||
|
||||
export type SendMessageFunction = (data: SendMessagePayload, config?: unknown) => Promise<unknown>;
|
||||
export type SendMessageFunction = (
|
||||
data: SendMessagePayload,
|
||||
config?: unknown,
|
||||
isDevelopment?: boolean
|
||||
) => Promise<unknown>;
|
||||
|
||||
export type GetUsageFunction = (startFrom?: Date) => Promise<number>;
|
||||
|
||||
|
|
Loading…
Reference in a new issue