0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(core): add extraInfo to connector GET APIs response (#4100)

This commit is contained in:
Darcy Ye 2023-07-03 14:54:53 +08:00 committed by GitHub
parent e89ccd4d4c
commit 909591f1c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 7 deletions

View file

@ -1,3 +1,4 @@
/* eslint-disable max-lines */
import { buildRawConnector } from '@logto/cli/lib/connector/index.js';
import { demoConnectorIds, validateConfig } from '@logto/connector-kit';
import {
@ -12,11 +13,13 @@ import { string, object } from 'zod';
import RequestError from '#src/errors/RequestError/index.js';
import koaGuard from '#src/middleware/koa-guard.js';
import SystemContext from '#src/tenants/SystemContext.js';
import assertThat from '#src/utils/assert-that.js';
import {
loadConnectorFactories,
transpileConnectorFactory,
transpileLogtoConnector,
buildExtraInfoFromEmailServiceData,
} from '#src/utils/connectors/index.js';
import { checkSocialConnectorTargetAndPlatformUniqueness } from '#src/utils/connectors/platform.js';
@ -43,6 +46,15 @@ export default function connectorRoutes<T extends AuthedRouter>(
signInExperiences: { removeUnavailableSocialConnectorTargets },
} = tenant.libraries;
// Will accept other source of `extraInfo` in the future.
const { emailServiceProviderConfig } = SystemContext.shared;
const buildExtraInfo = (connectorFactoryId: string) => {
const extraInfo = {
...buildExtraInfoFromEmailServiceData(connectorFactoryId, emailServiceProviderConfig),
};
return cleanDeep(extraInfo, { emptyObjects: false });
};
router.post(
'/connectors',
koaGuard({
@ -152,7 +164,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
}
const connector = await getLogtoConnectorById(insertConnectorId);
ctx.body = await transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector, buildExtraInfo(connector.metadata.id));
return next();
}
@ -187,7 +199,9 @@ export default function connectorRoutes<T extends AuthedRouter>(
: connectors;
ctx.body = await Promise.all(
filteredConnectors.map(async (connector) => transpileLogtoConnector(connector))
filteredConnectors.map(async (connector) =>
transpileLogtoConnector(connector, buildExtraInfo(connector.metadata.id))
)
);
return next();
@ -210,7 +224,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
// Hide demo connector
assertThat(!demoConnectorIds.includes(connector.metadata.id), 'connector.not_found');
ctx.body = await transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector, buildExtraInfo(connector.metadata.id));
return next();
}
@ -310,7 +324,7 @@ export default function connectorRoutes<T extends AuthedRouter>(
jsonbMode: 'replace',
});
const connector = await getLogtoConnectorById(id);
ctx.body = await transpileLogtoConnector(connector);
ctx.body = await transpileLogtoConnector(connector, buildExtraInfo(connector.metadata.id));
return next();
}
@ -346,3 +360,5 @@ export default function connectorRoutes<T extends AuthedRouter>(
connectorConfigTestingRoutes(router, tenant);
connectorAuthorizationUriRoutes(router, tenant);
}
/** TODO @Darcy: refactor this file later. */
/* eslint-enable max-lines */

View file

@ -12,10 +12,11 @@ import {
ConnectorType,
type EmailConnector,
type SmsConnector,
ServiceConnector,
} from '@logto/connector-kit';
import type { ConnectorFactoryResponse, ConnectorResponse } from '@logto/schemas';
import type { ConnectorFactoryResponse, ConnectorResponse, EmailServiceData } from '@logto/schemas';
import { findPackage } from '@logto/shared';
import { conditional, deduplicate, pick, trySafe } from '@silverhand/essentials';
import { conditional, deduplicate, pick, trySafe, type Optional } from '@silverhand/essentials';
import { EnvSet } from '#src/env-set/index.js';
import RequestError from '#src/errors/RequestError/index.js';
@ -29,7 +30,7 @@ export const isPasswordlessLogtoConnector = (
export const transpileLogtoConnector = async (
connector: LogtoConnector,
extraInfo?: Record<string, unknown>
extraInfo?: ConnectorResponse['extraInfo']
): Promise<ConnectorResponse> => {
const usagePayload = conditional(
/** Should do the check in advance since only passwordless connectors could have `getUsage` method. */
@ -67,6 +68,20 @@ export const transpileConnectorFactory = ({
};
};
/**
* `extraInfo` is only used to expose email service vendors `fromEmail` setup to Logto email connector.
* Can extend this method in the future for other use cases.
*/
export const buildExtraInfoFromEmailServiceData = (
connectorFactoryId: string,
emailServiceProviderConfig?: EmailServiceData
): Optional<Record<string, unknown>> => {
return conditional(
connectorFactoryId === ServiceConnector.Email &&
emailServiceProviderConfig?.fromEmail && { fromEmail: emailServiceProviderConfig.fromEmail }
);
};
const checkDuplicateConnectorFactoriesId = (connectorFactories: ConnectorFactory[]) => {
const connectorFactoryIds = connectorFactories.map(({ metadata }) => metadata.id);
const deduplicatedConnectorFactoryIds = deduplicate(connectorFactoryIds);