@logto/connector-aws-ses 1.5.0 → 1.5.2

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 CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  ConnectorError,
6
6
  ConnectorErrorCodes,
7
7
  ConnectorType,
8
+ getConfigTemplateByType,
8
9
  validateConfig
9
10
  } from "@logto/connector-kit";
10
11
 
@@ -213,9 +214,9 @@ var sendMessage = (getConfig, getI18nEmailTemplate) => async (data, inputConfig)
213
214
  const { to, type, payload } = data;
214
215
  const config = inputConfig ?? await getConfig(defaultMetadata.id);
215
216
  validateConfig(config, awsSesConfigGuard);
216
- const { accessKeyId, accessKeySecret, region, templates } = config;
217
+ const { accessKeyId, accessKeySecret, region } = config;
217
218
  const customTemplate = await trySafe(async () => getI18nEmailTemplate?.(type, payload.locale));
218
- const template = customTemplate ?? templates.find((template2) => template2.usageType === type);
219
+ const template = customTemplate ?? getConfigTemplateByType(type, config);
219
220
  assert(
220
221
  template,
221
222
  new ConnectorError(
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, 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: 'OrganizationInvitation',\n subject: '<organization-invitation-template-subject>',\n content:\n 'Your Logto organization invitation 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 usageType: 'UserPermissionValidation',\n subject: '<user-permission-validation-template-subject>',\n content:\n 'Your Logto permission validation code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'BindNewIdentifier',\n subject: '<bind-new-identifier-template-subject>',\n content:\n 'Your Logto new identifier binding code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'MfaVerification',\n subject: '<mfa-verification-template-subject>',\n content:\n 'Your Logto MFA verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'BindMfa',\n subject: '<bind-mfa-template-subject>',\n content:\n 'Your Logto 2-step verification setup 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"]}
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 getConfigTemplateByType,\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 } = 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 ?? getConfigTemplateByType(type, config);\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: 'OrganizationInvitation',\n subject: '<organization-invitation-template-subject>',\n content:\n 'Your Logto organization invitation 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 usageType: 'UserPermissionValidation',\n subject: '<user-permission-validation-template-subject>',\n content:\n 'Your Logto permission validation code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'BindNewIdentifier',\n subject: '<bind-new-identifier-template-subject>',\n content:\n 'Your Logto new identifier binding code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'MfaVerification',\n subject: '<mfa-verification-template-subject>',\n content:\n 'Your Logto MFA verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'BindMfa',\n subject: '<bind-mfa-template-subject>',\n content:\n 'Your Logto 2-step verification setup 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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logto/connector-aws-ses",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Logto Connector for Amazon SES",
5
5
  "author": "Jeff <admin@breadth.app>",
6
6
  "dependencies": {
@@ -10,7 +10,7 @@
10
10
  "got": "^14.0.0",
11
11
  "snakecase-keys": "^8.0.1",
12
12
  "zod": "3.24.3",
13
- "@logto/connector-kit": "^4.6.0"
13
+ "@logto/connector-kit": "^5.0.0"
14
14
  },
15
15
  "main": "./lib/index.js",
16
16
  "module": "./lib/index.js",
@@ -64,7 +64,8 @@
64
64
  "dev": "tsup --watch",
65
65
  "lint": "eslint --ext .ts src",
66
66
  "lint:report": "pnpm lint --format json --output-file report.json",
67
- "test": "vitest src",
67
+ "test": "vitest run src",
68
+ "test:watch": "vitest src --watch",
68
69
  "test:ci": "pnpm run test --silent --coverage"
69
70
  }
70
71
  }