@logto/connector-aws-ses 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +12 -6
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { assert } from "@silverhand/essentials";
|
|
2
|
+
import { assert, trySafe } from "@silverhand/essentials";
|
|
3
3
|
import { SESv2ServiceException } from "@aws-sdk/client-sesv2";
|
|
4
4
|
import {
|
|
5
5
|
ConnectorError,
|
|
@@ -149,7 +149,9 @@ var awsSesConfigGuard = z.object({
|
|
|
149
149
|
|
|
150
150
|
// src/utils.ts
|
|
151
151
|
import { SendEmailCommand, SESv2Client } from "@aws-sdk/client-sesv2";
|
|
152
|
-
import {
|
|
152
|
+
import {
|
|
153
|
+
replaceSendMessageHandlebars
|
|
154
|
+
} from "@logto/connector-kit";
|
|
153
155
|
var makeClient = (accessKeyId, secretAccessKey, region) => {
|
|
154
156
|
const credentials = {
|
|
155
157
|
accessKeyId,
|
|
@@ -182,12 +184,13 @@ var makeCommand = (config, emailContent, to) => {
|
|
|
182
184
|
};
|
|
183
185
|
|
|
184
186
|
// src/index.ts
|
|
185
|
-
var sendMessage = (getConfig) => async (data, inputConfig) => {
|
|
187
|
+
var sendMessage = (getConfig, getI18nEmailTemplate) => async (data, inputConfig) => {
|
|
186
188
|
const { to, type, payload } = data;
|
|
187
189
|
const config = inputConfig ?? await getConfig(defaultMetadata.id);
|
|
188
190
|
validateConfig(config, awsSesConfigGuard);
|
|
189
191
|
const { accessKeyId, accessKeySecret, region, templates } = config;
|
|
190
|
-
const
|
|
192
|
+
const customTemplate = await trySafe(async () => getI18nEmailTemplate?.(type, payload.locale));
|
|
193
|
+
const template = customTemplate ?? templates.find((template2) => template2.usageType === type);
|
|
191
194
|
assert(
|
|
192
195
|
template,
|
|
193
196
|
new ConnectorError(
|
|
@@ -212,12 +215,15 @@ var sendMessage = (getConfig) => async (data, inputConfig) => {
|
|
|
212
215
|
throw error;
|
|
213
216
|
}
|
|
214
217
|
};
|
|
215
|
-
var createAwsSesConnector = async ({
|
|
218
|
+
var createAwsSesConnector = async ({
|
|
219
|
+
getConfig,
|
|
220
|
+
getI18nEmailTemplate
|
|
221
|
+
}) => {
|
|
216
222
|
return {
|
|
217
223
|
metadata: defaultMetadata,
|
|
218
224
|
type: ConnectorType.Email,
|
|
219
225
|
configGuard: awsSesConfigGuard,
|
|
220
|
-
sendMessage: sendMessage(getConfig)
|
|
226
|
+
sendMessage: sendMessage(getConfig, getI18nEmailTemplate)
|
|
221
227
|
};
|
|
222
228
|
};
|
|
223
229
|
var index_default = createAwsSesConnector;
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import { assert } from '@silverhand/essentials';\n\nimport type { SESv2Client, SendEmailCommand, SendEmailCommandOutput } from '@aws-sdk/client-sesv2';\nimport { SESv2ServiceException } from '@aws-sdk/client-sesv2';\nimport type {\n CreateConnector,\n EmailConnector,\n GetConnectorConfig,\n SendMessageFunction,\n} from '@logto/connector-kit';\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n ConnectorType,\n validateConfig,\n} from '@logto/connector-kit';\n\nimport { defaultMetadata } from './constant.js';\nimport { awsSesConfigGuard } from './types.js';\nimport { makeClient, makeCommand, makeEmailContent } from './utils.js';\n\nconst sendMessage =\n (getConfig: GetConnectorConfig): SendMessageFunction =>\n async (data, inputConfig) => {\n const { to, type, payload } = data;\n const config = inputConfig ?? (await getConfig(defaultMetadata.id));\n validateConfig(config, awsSesConfigGuard);\n const { accessKeyId, accessKeySecret, region, templates } = config;\n const template = templates.find((template) => template.usageType === type);\n\n assert(\n template,\n new ConnectorError(\n ConnectorErrorCodes.TemplateNotFound,\n `Cannot find template for type: ${type}`\n )\n );\n\n const client: SESv2Client = makeClient(accessKeyId, accessKeySecret, region);\n const emailContent = makeEmailContent(template, payload);\n const command: SendEmailCommand = makeCommand(config, emailContent, to);\n\n try {\n const response: SendEmailCommandOutput = await client.send(command);\n\n assert(\n response.$metadata.httpStatusCode === 200,\n new ConnectorError(ConnectorErrorCodes.InvalidResponse, response)\n );\n\n return response.MessageId;\n } catch (error: unknown) {\n if (error instanceof SESv2ServiceException) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, error.message);\n }\n\n throw error;\n }\n };\n\nconst createAwsSesConnector: CreateConnector<EmailConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Email,\n configGuard: awsSesConfigGuard,\n sendMessage: sendMessage(getConfig),\n };\n};\n\nexport default createAwsSesConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType } from '@logto/connector-kit';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'aws-ses-mail',\n target: 'aws-ses',\n platform: null,\n name: {\n en: 'AWS Direct Mail',\n 'zh-CN': 'AWS邮件推送',\n 'tr-TR': 'AWS Direct Mail',\n ko: 'AWS 다이렉트 메일',\n },\n logo: './logo.svg',\n logoDark: './logo-dark.svg',\n description: {\n en: 'Amazon SES is a cloud email service provider that can integrate into any application for bulk email sending.',\n 'zh-CN':\n 'Amazon SES 是云电子邮件发送服务提供商,它可以集成到任何应用程序中,用于批量发送电子邮件。',\n 'tr-TR':\n 'Amazon SES, toplu e-posta dağıtımı için herhangi bir uygulamaya entegre edilebilen bir bulut e-posta dağıtım hizmeti sağlayıcısıdır.',\n ko: 'Amazon SES는 모든 애플리케이션에 통합하여 대량으로 이메일을 전송할 수 있는 클라우드 이메일 서비스 공급자입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'accessKeyId',\n label: 'Access Key ID',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-id>',\n },\n {\n key: 'accessKeySecret',\n label: 'Access Key Secret',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-secret>',\n },\n {\n key: 'region',\n label: 'Region',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<region>',\n },\n {\n key: 'emailAddress',\n label: 'Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address>',\n },\n {\n key: 'emailAddressIdentityArn',\n label: 'Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address-identity-arn>',\n },\n {\n key: 'feedbackForwardingEmailAddress',\n label: 'Feedback Forwarding Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address>',\n },\n {\n key: 'feedbackForwardingEmailAddressIdentityArn',\n label: 'Feedback Forwarding Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address-identity-arn>',\n },\n {\n key: 'configurationSetName',\n label: 'Configuration Set Name',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<configuration-set-name>',\n },\n {\n key: 'templates',\n label: 'Templates',\n type: ConnectorConfigFormItemType.Json,\n required: true,\n defaultValue: [\n {\n usageType: 'SignIn',\n subject: '<sign-in-template-subject>',\n content:\n 'Your Logto sign-in verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Register',\n subject: '<register-template-subject>',\n content:\n 'Your Logto sign-up verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'ForgotPassword',\n subject: '<forgot-password-template-subject>',\n content:\n 'Your Logto password change verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Generic',\n subject: '<generic-template-subject>',\n content:\n 'Your Logto verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n ],\n },\n ],\n};\n","import { z } from 'zod';\n\n/**\n * UsageType here is used to specify the use case of the template, can be either\n * 'Register', 'SignIn', 'ForgotPassword', 'Generic'.\n */\nconst requiredTemplateUsageTypes = ['Register', 'SignIn', 'ForgotPassword', 'Generic'];\nconst templateGuard = z.object({\n usageType: z.string(),\n subject: z.string(),\n content: z.string(), // With variable {{code}}, support HTML\n});\n\nexport type Template = z.infer<typeof templateGuard>;\n\nexport const awsSesConfigGuard = z.object({\n accessKeyId: z.string(),\n accessKeySecret: z.string(),\n region: z.string(),\n emailAddress: z.string().optional(),\n emailAddressIdentityArn: z.string().optional(),\n templates: z.array(templateGuard).refine(\n (templates) =>\n requiredTemplateUsageTypes.every((requiredType) =>\n templates.map((template) => template.usageType).includes(requiredType)\n ),\n (templates) => ({\n message: `Template with UsageType (${requiredTemplateUsageTypes\n .filter(\n (requiredType) => !templates.map((template) => template.usageType).includes(requiredType)\n )\n .join(', ')}) should be provided!`,\n })\n ),\n feedbackForwardingEmailAddress: z.string().optional(),\n feedbackForwardingEmailAddressIdentityArn: z.string().optional(),\n configurationSetName: z.string().optional(),\n});\n\nexport type AwsSesConfig = z.infer<typeof awsSesConfigGuard>;\n","import type { EmailContent } from '@aws-sdk/client-sesv2';\nimport { SendEmailCommand, SESv2Client } from '@aws-sdk/client-sesv2';\nimport type { AwsCredentialIdentity } from '@aws-sdk/types';\nimport { replaceSendMessageHandlebars, type SendMessagePayload } from '@logto/connector-kit';\n\nimport type { AwsSesConfig, Template } from './types.js';\n\nexport const makeClient = (\n accessKeyId: string,\n secretAccessKey: string,\n region: string\n): SESv2Client => {\n const credentials: AwsCredentialIdentity = {\n accessKeyId,\n secretAccessKey,\n };\n\n return new SESv2Client({ credentials, region });\n};\n\nexport const makeEmailContent = (template: Template, payload: SendMessagePayload): EmailContent => {\n return {\n Simple: {\n Subject: { Data: replaceSendMessageHandlebars(template.subject, payload), Charset: 'utf8' },\n Body: {\n Html: {\n Data: replaceSendMessageHandlebars(template.content, payload),\n },\n },\n },\n };\n};\n\nexport const makeCommand = (\n config: AwsSesConfig,\n emailContent: EmailContent,\n to: string\n): SendEmailCommand => {\n return new SendEmailCommand({\n Destination: { ToAddresses: [to] },\n Content: emailContent,\n FromEmailAddress: config.emailAddress,\n FromEmailAddressIdentityArn: config.emailAddressIdentityArn,\n FeedbackForwardingEmailAddress: config.feedbackForwardingEmailAddress,\n FeedbackForwardingEmailAddressIdentityArn: config.feedbackForwardingEmailAddressIdentityArn,\n ConfigurationSetName: config.configurationSetName,\n });\n};\n"],"mappings":"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","names":["template"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import { assert, trySafe } from '@silverhand/essentials';\n\nimport type { SESv2Client, SendEmailCommand, SendEmailCommandOutput } from '@aws-sdk/client-sesv2';\nimport { SESv2ServiceException } from '@aws-sdk/client-sesv2';\nimport type {\n CreateConnector,\n EmailConnector,\n GetConnectorConfig,\n GetI18nEmailTemplate,\n SendMessageFunction,\n} from '@logto/connector-kit';\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n ConnectorType,\n validateConfig,\n} from '@logto/connector-kit';\n\nimport { defaultMetadata } from './constant.js';\nimport { awsSesConfigGuard } from './types.js';\nimport { makeClient, makeCommand, makeEmailContent } from './utils.js';\n\nconst sendMessage =\n (\n getConfig: GetConnectorConfig,\n getI18nEmailTemplate?: GetI18nEmailTemplate\n ): SendMessageFunction =>\n async (data, inputConfig) => {\n const { to, type, payload } = data;\n const config = inputConfig ?? (await getConfig(defaultMetadata.id));\n validateConfig(config, awsSesConfigGuard);\n const { accessKeyId, accessKeySecret, region, templates } = config;\n\n const customTemplate = await trySafe(async () => getI18nEmailTemplate?.(type, payload.locale));\n\n // Fall back to the default template if the custom i18n template is not found.\n const template = customTemplate ?? templates.find((template) => template.usageType === type);\n\n assert(\n template,\n new ConnectorError(\n ConnectorErrorCodes.TemplateNotFound,\n `Cannot find template for type: ${type}`\n )\n );\n\n const client: SESv2Client = makeClient(accessKeyId, accessKeySecret, region);\n const emailContent = makeEmailContent(template, payload);\n const command: SendEmailCommand = makeCommand(config, emailContent, to);\n\n try {\n const response: SendEmailCommandOutput = await client.send(command);\n\n assert(\n response.$metadata.httpStatusCode === 200,\n new ConnectorError(ConnectorErrorCodes.InvalidResponse, response)\n );\n\n return response.MessageId;\n } catch (error: unknown) {\n if (error instanceof SESv2ServiceException) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, error.message);\n }\n\n throw error;\n }\n };\n\nconst createAwsSesConnector: CreateConnector<EmailConnector> = async ({\n getConfig,\n getI18nEmailTemplate,\n}) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Email,\n configGuard: awsSesConfigGuard,\n sendMessage: sendMessage(getConfig, getI18nEmailTemplate),\n };\n};\n\nexport default createAwsSesConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType } from '@logto/connector-kit';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'aws-ses-mail',\n target: 'aws-ses',\n platform: null,\n name: {\n en: 'AWS Direct Mail',\n 'zh-CN': 'AWS邮件推送',\n 'tr-TR': 'AWS Direct Mail',\n ko: 'AWS 다이렉트 메일',\n },\n logo: './logo.svg',\n logoDark: './logo-dark.svg',\n description: {\n en: 'Amazon SES is a cloud email service provider that can integrate into any application for bulk email sending.',\n 'zh-CN':\n 'Amazon SES 是云电子邮件发送服务提供商,它可以集成到任何应用程序中,用于批量发送电子邮件。',\n 'tr-TR':\n 'Amazon SES, toplu e-posta dağıtımı için herhangi bir uygulamaya entegre edilebilen bir bulut e-posta dağıtım hizmeti sağlayıcısıdır.',\n ko: 'Amazon SES는 모든 애플리케이션에 통합하여 대량으로 이메일을 전송할 수 있는 클라우드 이메일 서비스 공급자입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'accessKeyId',\n label: 'Access Key ID',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-id>',\n },\n {\n key: 'accessKeySecret',\n label: 'Access Key Secret',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-secret>',\n },\n {\n key: 'region',\n label: 'Region',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<region>',\n },\n {\n key: 'emailAddress',\n label: 'Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address>',\n },\n {\n key: 'emailAddressIdentityArn',\n label: 'Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address-identity-arn>',\n },\n {\n key: 'feedbackForwardingEmailAddress',\n label: 'Feedback Forwarding Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address>',\n },\n {\n key: 'feedbackForwardingEmailAddressIdentityArn',\n label: 'Feedback Forwarding Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address-identity-arn>',\n },\n {\n key: 'configurationSetName',\n label: 'Configuration Set Name',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<configuration-set-name>',\n },\n {\n key: 'templates',\n label: 'Templates',\n type: ConnectorConfigFormItemType.Json,\n required: true,\n defaultValue: [\n {\n usageType: 'SignIn',\n subject: '<sign-in-template-subject>',\n content:\n 'Your Logto sign-in verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Register',\n subject: '<register-template-subject>',\n content:\n 'Your Logto sign-up verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'ForgotPassword',\n subject: '<forgot-password-template-subject>',\n content:\n 'Your Logto password change verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Generic',\n subject: '<generic-template-subject>',\n content:\n 'Your Logto verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n ],\n },\n ],\n};\n","import { z } from 'zod';\n\n/**\n * UsageType here is used to specify the use case of the template, can be either\n * 'Register', 'SignIn', 'ForgotPassword', 'Generic'.\n */\nconst requiredTemplateUsageTypes = ['Register', 'SignIn', 'ForgotPassword', 'Generic'];\nconst templateGuard = z.object({\n usageType: z.string(),\n subject: z.string(),\n content: z.string(), // With variable {{code}}, support HTML\n});\n\nexport type Template = z.infer<typeof templateGuard>;\n\nexport const awsSesConfigGuard = z.object({\n accessKeyId: z.string(),\n accessKeySecret: z.string(),\n region: z.string(),\n emailAddress: z.string().optional(),\n emailAddressIdentityArn: z.string().optional(),\n templates: z.array(templateGuard).refine(\n (templates) =>\n requiredTemplateUsageTypes.every((requiredType) =>\n templates.map((template) => template.usageType).includes(requiredType)\n ),\n (templates) => ({\n message: `Template with UsageType (${requiredTemplateUsageTypes\n .filter(\n (requiredType) => !templates.map((template) => template.usageType).includes(requiredType)\n )\n .join(', ')}) should be provided!`,\n })\n ),\n feedbackForwardingEmailAddress: z.string().optional(),\n feedbackForwardingEmailAddressIdentityArn: z.string().optional(),\n configurationSetName: z.string().optional(),\n});\n\nexport type AwsSesConfig = z.infer<typeof awsSesConfigGuard>;\n","import type { EmailContent } from '@aws-sdk/client-sesv2';\nimport { SendEmailCommand, SESv2Client } from '@aws-sdk/client-sesv2';\nimport type { AwsCredentialIdentity } from '@aws-sdk/types';\nimport {\n type EmailTemplateDetails,\n replaceSendMessageHandlebars,\n type SendMessagePayload,\n} from '@logto/connector-kit';\n\nimport type { AwsSesConfig, Template } from './types.js';\n\nexport const makeClient = (\n accessKeyId: string,\n secretAccessKey: string,\n region: string\n): SESv2Client => {\n const credentials: AwsCredentialIdentity = {\n accessKeyId,\n secretAccessKey,\n };\n\n return new SESv2Client({ credentials, region });\n};\n\nexport const makeEmailContent = (\n template: Template | EmailTemplateDetails,\n payload: SendMessagePayload\n): EmailContent => {\n return {\n Simple: {\n Subject: { Data: replaceSendMessageHandlebars(template.subject, payload), Charset: 'utf8' },\n Body: {\n Html: {\n Data: replaceSendMessageHandlebars(template.content, payload),\n },\n },\n },\n };\n};\n\nexport const makeCommand = (\n config: AwsSesConfig,\n emailContent: EmailContent,\n to: string\n): SendEmailCommand => {\n return new SendEmailCommand({\n Destination: { ToAddresses: [to] },\n Content: emailContent,\n FromEmailAddress: config.emailAddress,\n FromEmailAddressIdentityArn: config.emailAddressIdentityArn,\n FeedbackForwardingEmailAddress: config.feedbackForwardingEmailAddress,\n FeedbackForwardingEmailAddressIdentityArn: config.feedbackForwardingEmailAddressIdentityArn,\n ConfigurationSetName: config.configurationSetName,\n });\n};\n"],"mappings":"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","names":["template"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logto/connector-aws-ses",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Logto Connector for Amazon SES",
|
|
5
5
|
"author": "Jeff <admin@breadth.app>",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@aws-sdk/client-sesv2": "^3.556.0",
|
|
8
8
|
"@aws-sdk/types": "^3.535.0",
|
|
9
|
-
"@logto/connector-kit": "^4.
|
|
9
|
+
"@logto/connector-kit": "^4.2.0",
|
|
10
10
|
"@silverhand/essentials": "^2.9.1",
|
|
11
11
|
"got": "^14.0.0",
|
|
12
12
|
"snakecase-keys": "^8.0.1",
|