@strapi/email 5.37.1 → 5.38.1

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.
Files changed (76) hide show
  1. package/dist/admin/constants.js.map +1 -1
  2. package/dist/admin/constants.mjs.map +1 -1
  3. package/dist/admin/index.js +1 -1
  4. package/dist/admin/index.js.map +1 -1
  5. package/dist/admin/index.mjs.map +1 -1
  6. package/dist/admin/pages/Settings.js +399 -47
  7. package/dist/admin/pages/Settings.js.map +1 -1
  8. package/dist/admin/pages/Settings.mjs +402 -50
  9. package/dist/admin/pages/Settings.mjs.map +1 -1
  10. package/dist/admin/shared/email-address-parser.js +245 -0
  11. package/dist/admin/shared/email-address-parser.js.map +1 -0
  12. package/dist/admin/shared/email-address-parser.mjs +243 -0
  13. package/dist/admin/shared/email-address-parser.mjs.map +1 -0
  14. package/dist/admin/translations/de.json.js +18 -2
  15. package/dist/admin/translations/de.json.js.map +1 -1
  16. package/dist/admin/translations/de.json.mjs +18 -2
  17. package/dist/admin/translations/de.json.mjs.map +1 -1
  18. package/dist/admin/translations/en.json.js +23 -1
  19. package/dist/admin/translations/en.json.js.map +1 -1
  20. package/dist/admin/translations/en.json.mjs +23 -1
  21. package/dist/admin/translations/en.json.mjs.map +1 -1
  22. package/dist/admin/translations/es.json.js +6 -1
  23. package/dist/admin/translations/es.json.js.map +1 -1
  24. package/dist/admin/translations/es.json.mjs +3 -1
  25. package/dist/admin/translations/es.json.mjs.map +1 -1
  26. package/dist/admin/utils/getYupInnerErrors.js.map +1 -1
  27. package/dist/admin/utils/getYupInnerErrors.mjs.map +1 -1
  28. package/dist/admin/utils/prefixPluginTranslations.js.map +1 -1
  29. package/dist/admin/utils/prefixPluginTranslations.mjs.map +1 -1
  30. package/dist/admin/utils/schema.js.map +1 -1
  31. package/dist/admin/utils/schema.mjs.map +1 -1
  32. package/dist/server/bootstrap.js.map +1 -1
  33. package/dist/server/bootstrap.mjs.map +1 -1
  34. package/dist/server/config.js.map +1 -1
  35. package/dist/server/config.mjs.map +1 -1
  36. package/dist/server/controllers/email.js +33 -1
  37. package/dist/server/controllers/email.js.map +1 -1
  38. package/dist/server/controllers/email.mjs +33 -1
  39. package/dist/server/controllers/email.mjs.map +1 -1
  40. package/dist/server/controllers/index.js.map +1 -1
  41. package/dist/server/controllers/index.mjs.map +1 -1
  42. package/dist/server/index.js +8 -8
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs.map +1 -1
  45. package/dist/server/middlewares/index.js.map +1 -1
  46. package/dist/server/middlewares/index.mjs.map +1 -1
  47. package/dist/server/middlewares/rateLimit.js.map +1 -1
  48. package/dist/server/middlewares/rateLimit.mjs.map +1 -1
  49. package/dist/server/routes/admin.js +18 -0
  50. package/dist/server/routes/admin.js.map +1 -1
  51. package/dist/server/routes/admin.mjs +18 -0
  52. package/dist/server/routes/admin.mjs.map +1 -1
  53. package/dist/server/routes/content-api.js.map +1 -1
  54. package/dist/server/routes/content-api.mjs.map +1 -1
  55. package/dist/server/routes/index.js.map +1 -1
  56. package/dist/server/routes/index.mjs.map +1 -1
  57. package/dist/server/routes/validation/email.js.map +1 -1
  58. package/dist/server/routes/validation/email.mjs.map +1 -1
  59. package/dist/server/services/email.js.map +1 -1
  60. package/dist/server/services/email.mjs +1 -1
  61. package/dist/server/services/email.mjs.map +1 -1
  62. package/dist/server/services/index.js.map +1 -1
  63. package/dist/server/services/index.mjs.map +1 -1
  64. package/dist/server/src/bootstrap.d.ts.map +1 -1
  65. package/dist/server/src/controllers/email.d.ts +1 -0
  66. package/dist/server/src/controllers/email.d.ts.map +1 -1
  67. package/dist/server/src/controllers/index.d.ts +1 -0
  68. package/dist/server/src/controllers/index.d.ts.map +1 -1
  69. package/dist/server/src/index.d.ts +1 -0
  70. package/dist/server/src/index.d.ts.map +1 -1
  71. package/dist/server/src/routes/admin.d.ts.map +1 -1
  72. package/dist/shared/email-address-parser.d.ts +81 -0
  73. package/dist/shared/email-address-parser.d.ts.map +1 -0
  74. package/dist/shared/types.d.ts +17 -0
  75. package/dist/shared/types.d.ts.map +1 -1
  76. package/package.json +14 -9
@@ -1 +1 @@
1
- {"version":3,"file":"Settings.mjs","sources":["../../../admin/src/pages/Settings.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page, useNotification, useFetchClient, Layouts } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n SingleSelectOption,\n SingleSelect,\n TextInput,\n Typography,\n Field,\n} from '@strapi/design-system';\nimport { Mail } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useMutation } from 'react-query';\nimport { styled } from 'styled-components';\nimport { ValidationError } from 'yup';\n\nimport { PERMISSIONS } from '../constants';\nimport { getYupInnerErrors } from '../utils/getYupInnerErrors';\nimport { schema } from '../utils/schema';\n\nimport type { EmailSettings } from '../../../shared/types';\n\nconst DocumentationLink = styled.a`\n color: ${({ theme }) => theme.colors.primary600};\n`;\n\ninterface MutationBody {\n to: string;\n}\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n\nconst SettingsPage = () => {\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const { get, post } = useFetchClient();\n\n const [testAddress, setTestAddress] = React.useState('');\n const [isTestAddressValid, setIsTestAddressValid] = React.useState(false);\n\n // TODO: I'm not sure how to type this. I think it should be Record<string, TranslationMessage> but that type is defined in the helper-plugin\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [formErrors, setFormErrors] = React.useState<Record<string, any>>({});\n\n const { data, isLoading } = useQuery(['email', 'settings'], async () => {\n const res = await get<EmailSettings>('/email/settings');\n const {\n data: { config },\n } = res;\n\n return config;\n });\n\n const mutation = useMutation<void, Error, MutationBody>(\n async (body) => {\n await post('/email/test', body);\n },\n {\n onError() {\n toggleNotification!({\n type: 'danger',\n message: formatMessage(\n {\n id: 'email.Settings.email.plugin.notification.test.error',\n defaultMessage: 'Failed to send a test mail to {to}',\n },\n { to: testAddress }\n ),\n });\n },\n onSuccess() {\n toggleNotification!({\n type: 'success',\n message: formatMessage(\n {\n id: 'email.Settings.email.plugin.notification.test.success',\n defaultMessage: 'Email test succeeded, check the {to} mailbox',\n },\n { to: testAddress }\n ),\n });\n },\n retry: false,\n }\n );\n\n React.useEffect(() => {\n schema\n .validate({ email: testAddress }, { abortEarly: false })\n .then(() => setIsTestAddressValid(true))\n .catch(() => setIsTestAddressValid(false));\n }, [testAddress]);\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setTestAddress(() => event.target.value);\n };\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n try {\n await schema.validate({ email: testAddress }, { abortEarly: false });\n } catch (error) {\n if (error instanceof ValidationError) {\n setFormErrors(getYupInnerErrors(error));\n }\n }\n\n mutation.mutate({ to: testAddress });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main labelledBy=\"title\" aria-busy={isLoading || mutation.isLoading}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: 'email.Settings.email.plugin.title',\n defaultMessage: 'Configuration',\n }),\n }\n )}\n </Page.Title>\n <Layouts.Header\n id=\"title\"\n title={formatMessage({\n id: 'email.Settings.email.plugin.title',\n defaultMessage: 'Configuration',\n })}\n subtitle={formatMessage({\n id: 'email.Settings.email.plugin.subTitle',\n defaultMessage: 'Test the settings for the Email plugin',\n })}\n />\n\n <Layouts.Content>\n {data && (\n <form onSubmit={handleSubmit}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={7}>\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'email.Settings.email.plugin.title.config',\n defaultMessage: 'Configuration',\n })}\n </Typography>\n <Typography>\n {formatMessage(\n {\n id: 'email.Settings.email.plugin.text.configuration',\n defaultMessage:\n 'The plugin is configured through the {file} file, checkout this {link} for the documentation.',\n },\n {\n file: './config/plugins.js',\n link: (\n <DocumentationLink\n href=\"https://docs.strapi.io/developer-docs/latest/plugins/email.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {formatMessage({\n id: 'email.link',\n defaultMessage: 'Link',\n })}\n </DocumentationLink>\n ),\n }\n )}\n </Typography>\n </Flex>\n\n <Grid.Root gap={5}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"shipper-email\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.defaultFrom',\n defaultMessage: 'Default sender email',\n })}\n </Field.Label>\n <TextInput\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.defaultFrom',\n defaultMessage: \"ex: Strapi No-Reply '<'no-reply@strapi.io'>'\",\n })}\n disabled\n readOnly\n value={data.settings.defaultFrom}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"response-email\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.defaultReplyTo',\n defaultMessage: 'Default response email',\n })}\n </Field.Label>\n <TextInput\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.defaultReplyTo',\n defaultMessage: `ex: Strapi '<'example@strapi.io'>'`,\n })}\n disabled\n readOnly\n value={data.settings.defaultReplyTo}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"email-provider\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.provider',\n defaultMessage: 'Email provider',\n })}\n </Field.Label>\n <SingleSelect disabled value={data.provider}>\n <SingleSelectOption value={data.provider}>\n {data.provider}\n </SingleSelectOption>\n </SingleSelect>\n </Field.Root>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Box>\n\n <Flex\n alignItems=\"stretch\"\n background=\"neutral0\"\n direction=\"column\"\n gap={4}\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'email.Settings.email.plugin.title.test',\n defaultMessage: 'Test email delivery',\n })}\n </Typography>\n\n <Grid.Root gap={5}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"test-address\"\n error={\n formErrors.email?.id &&\n formatMessage({\n id: `email.${formErrors.email?.id}`,\n defaultMessage: 'This is not a valid email',\n })\n }\n >\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.testAddress',\n defaultMessage: 'Recipient email',\n })}\n </Field.Label>\n <TextInput\n onChange={handleChange}\n value={testAddress}\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.testAddress',\n defaultMessage: 'ex: developer@example.com',\n })}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={7} xs={12} direction=\"column\" alignItems=\"start\">\n <Button\n loading={mutation.isLoading}\n disabled={!isTestAddressValid}\n type=\"submit\"\n startIcon={<Mail />}\n >\n {formatMessage({\n id: 'email.Settings.email.plugin.button.test-email',\n defaultMessage: 'Send test email',\n })}\n </Button>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Flex>\n </form>\n )}\n </Layouts.Content>\n </Page.Main>\n );\n};\n"],"names":["DocumentationLink","styled","a","theme","colors","primary600","ProtectedSettingsPage","_jsx","Page","Protect","permissions","PERMISSIONS","settings","SettingsPage","toggleNotification","useNotification","formatMessage","useIntl","get","post","useFetchClient","testAddress","setTestAddress","React","useState","isTestAddressValid","setIsTestAddressValid","formErrors","setFormErrors","data","isLoading","useQuery","res","config","mutation","useMutation","body","onError","type","message","id","defaultMessage","to","onSuccess","retry","useEffect","schema","validate","email","abortEarly","then","catch","handleChange","event","target","value","handleSubmit","preventDefault","error","ValidationError","getYupInnerErrors","mutate","Loading","_jsxs","Main","labelledBy","aria-busy","Title","name","Layouts","Header","title","subtitle","Content","form","onSubmit","Flex","direction","alignItems","gap","Box","background","hasRadius","shadow","paddingTop","paddingBottom","paddingLeft","paddingRight","Typography","variant","tag","file","link","href","rel","Grid","Root","Item","col","xs","Field","Label","TextInput","placeholder","disabled","readOnly","defaultFrom","defaultReplyTo","SingleSelect","provider","SingleSelectOption","onChange","Button","loading","startIcon","Mail"],"mappings":"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"}
1
+ {"version":3,"file":"Settings.mjs","sources":["../../../admin/src/pages/Settings.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Page, useNotification, useFetchClient, Layouts } from '@strapi/admin/strapi-admin';\nimport {\n Box,\n Button,\n Flex,\n Grid,\n SingleSelectOption,\n SingleSelect,\n TextInput,\n Typography,\n Field,\n Badge,\n} from '@strapi/design-system';\nimport { Mail, Check, Cross } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useQuery, useMutation } from 'react-query';\nimport { styled } from 'styled-components';\nimport { ValidationError } from 'yup';\n\nimport { parseEmailAddress } from '../../../shared/email-address-parser';\nimport { PERMISSIONS } from '../constants';\nimport { getYupInnerErrors } from '../utils/getYupInnerErrors';\nimport { schema } from '../utils/schema';\n\nimport type { EmailSettings, ProviderCapabilities } from '../../../shared/types';\n\nconst DocumentationLink = styled.a`\n color: ${({ theme }) => theme.colors.primary600};\n`;\n\ninterface MutationBody {\n to: string;\n}\n\nconst FEATURE_LABELS: Record<string, { id: string; defaultMessage: string }> = {\n dkim: {\n id: 'email.Settings.capabilities.feature.dkim',\n defaultMessage: 'DKIM',\n },\n pool: {\n id: 'email.Settings.capabilities.feature.pool',\n defaultMessage: 'Connection pool',\n },\n rateLimiting: {\n id: 'email.Settings.capabilities.feature.rateLimiting',\n defaultMessage: 'Rate limiting',\n },\n oauth2: {\n id: 'email.Settings.capabilities.feature.oauth2',\n defaultMessage: 'OAuth2',\n },\n requireTLS: {\n id: 'email.Settings.capabilities.feature.requireTLS',\n defaultMessage: 'Require TLS',\n },\n};\n\nconst CapabilitiesSection = ({\n capabilities,\n isIdle,\n formatMessage,\n}: {\n capabilities: ProviderCapabilities;\n isIdle?: boolean;\n formatMessage: (msg: { id: string; defaultMessage: string }) => string;\n}) => {\n const transport = capabilities.transport;\n const auth = capabilities.auth;\n const features = capabilities.features ?? [];\n\n const encryptionLabel =\n transport?.secure === true\n ? 'TLS'\n : transport?.port === 587\n ? 'STARTTLS'\n : transport?.port === 465\n ? 'TLS'\n : 'None';\n\n return (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'email.Settings.capabilities.title',\n defaultMessage: 'Provider capabilities',\n })}\n </Typography>\n <Typography>\n {formatMessage({\n id: 'email.Settings.capabilities.subtitle',\n defaultMessage: 'Current SMTP configuration and enabled features',\n })}\n </Typography>\n </Flex>\n\n <Grid.Root gap={5}>\n {transport && (transport.host || transport.port) && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"smtp-server\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.capabilities.label.smtpServer',\n defaultMessage: 'SMTP server',\n })}\n </Field.Label>\n <TextInput\n disabled\n readOnly\n value={\n transport.host && transport.port\n ? `${transport.host}:${transport.port}`\n : transport.host || String(transport.port)\n }\n />\n </Field.Root>\n </Grid.Item>\n )}\n\n {transport && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"encryption\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.capabilities.label.encryption',\n defaultMessage: 'Encryption',\n })}\n </Field.Label>\n <TextInput disabled readOnly value={encryptionLabel} />\n </Field.Root>\n </Grid.Item>\n )}\n\n {auth && (auth.type || auth.user) && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"auth-type\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.capabilities.label.authType',\n defaultMessage: 'Authentication',\n })}\n </Field.Label>\n <TextInput\n disabled\n readOnly\n value={\n auth.type\n ? auth.user\n ? `${auth.type} (${auth.user})`\n : auth.type\n : auth.user || 'None'\n }\n />\n </Field.Root>\n </Grid.Item>\n )}\n\n {transport?.pool && isIdle !== undefined && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"pool-status\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.capabilities.label.poolStatus',\n defaultMessage: 'Pool status',\n })}\n </Field.Label>\n <Badge\n backgroundColor={isIdle ? 'success100' : 'primary100'}\n textColor={isIdle ? 'success700' : 'primary700'}\n >\n {isIdle\n ? formatMessage({\n id: 'email.Settings.capabilities.poolStatus.idle',\n defaultMessage: 'Idle',\n })\n : formatMessage({\n id: 'email.Settings.capabilities.poolStatus.active',\n defaultMessage: 'Active',\n })}\n </Badge>\n </Field.Root>\n </Grid.Item>\n )}\n\n {features.length > 0 && (\n <Grid.Item col={12} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"features\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.capabilities.label.features',\n defaultMessage: 'Enabled features',\n })}\n </Field.Label>\n <Flex gap={2} wrap=\"wrap\">\n {features.map((f) => (\n <Badge key={f} backgroundColor=\"neutral100\" textColor=\"neutral700\">\n {formatMessage(\n FEATURE_LABELS[f] ?? {\n id: `email.Settings.capabilities.feature.${f}`,\n defaultMessage: f,\n }\n )}\n </Badge>\n ))}\n </Flex>\n </Field.Root>\n </Grid.Item>\n )}\n </Grid.Root>\n </Flex>\n );\n};\n\nexport const ProtectedSettingsPage = () => (\n <Page.Protect permissions={PERMISSIONS.settings}>\n <SettingsPage />\n </Page.Protect>\n);\n\nconst SettingsPage = () => {\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n const { get, post } = useFetchClient();\n\n const [testAddress, setTestAddress] = React.useState('');\n const [isTestAddressValid, setIsTestAddressValid] = React.useState(false);\n\n // TODO: I'm not sure how to type this. I think it should be Record<string, TranslationMessage> but that type is defined in the helper-plugin\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [formErrors, setFormErrors] = React.useState<Record<string, any>>({});\n\n const { data, isLoading } = useQuery(['email', 'settings'], async () => {\n const res = await get<EmailSettings>('/email/settings');\n const {\n data: { config, supportsVerify, capabilities, isIdle },\n } = res;\n\n return { ...config, supportsVerify, capabilities, isIdle };\n });\n\n const mutation = useMutation<void, Error, MutationBody>(\n async (body) => {\n await post('/email/test', body);\n },\n {\n onError() {\n toggleNotification!({\n type: 'danger',\n message: formatMessage(\n {\n id: 'email.Settings.email.plugin.notification.test.error',\n defaultMessage: 'Failed to send a test mail to {to}',\n },\n { to: testAddress }\n ),\n });\n },\n onSuccess() {\n toggleNotification!({\n type: 'success',\n message: formatMessage(\n {\n id: 'email.Settings.email.plugin.notification.test.success',\n defaultMessage: 'Email test succeeded, check the {to} mailbox',\n },\n { to: testAddress }\n ),\n });\n },\n retry: false,\n }\n );\n\n const [connectionStatus, setConnectionStatus] = React.useState<\n 'idle' | 'loading' | 'success' | 'error'\n >('idle');\n\n const verifyMutation = useMutation(\n async () => {\n await post('/email/verify', {});\n },\n {\n onMutate() {\n setConnectionStatus('loading');\n },\n onError() {\n setConnectionStatus('error');\n toggleNotification!({\n type: 'danger',\n message: formatMessage({\n id: 'email.Settings.email.plugin.notification.verify.error',\n defaultMessage: 'Connection verification failed',\n }),\n });\n },\n onSuccess() {\n setConnectionStatus('success');\n toggleNotification!({\n type: 'success',\n message: formatMessage({\n id: 'email.Settings.email.plugin.notification.verify.success',\n defaultMessage: 'Connection verified successfully',\n }),\n });\n },\n retry: false,\n }\n );\n\n React.useEffect(() => {\n schema\n .validate({ email: testAddress }, { abortEarly: false })\n .then(() => setIsTestAddressValid(true))\n .catch(() => setIsTestAddressValid(false));\n }, [testAddress]);\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setTestAddress(() => event.target.value);\n };\n\n const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n\n try {\n await schema.validate({ email: testAddress }, { abortEarly: false });\n } catch (error) {\n if (error instanceof ValidationError) {\n setFormErrors(getYupInnerErrors(error));\n }\n }\n\n mutation.mutate({ to: testAddress });\n };\n\n if (isLoading) {\n return <Page.Loading />;\n }\n\n return (\n <Page.Main labelledBy=\"title\" aria-busy={isLoading || mutation.isLoading}>\n <Page.Title>\n {formatMessage(\n { id: 'Settings.PageTitle', defaultMessage: 'Settings - {name}' },\n {\n name: formatMessage({\n id: 'email.Settings.email.plugin.title',\n defaultMessage: 'Configuration',\n }),\n }\n )}\n </Page.Title>\n <Layouts.Header\n id=\"title\"\n title={formatMessage({\n id: 'email.Settings.email.plugin.title',\n defaultMessage: 'Configuration',\n })}\n subtitle={formatMessage({\n id: 'email.Settings.email.plugin.subTitle',\n defaultMessage: 'Test the settings for the Email plugin',\n })}\n />\n\n <Layouts.Content>\n {data && (\n <form onSubmit={handleSubmit}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={7}>\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Flex direction=\"column\" alignItems=\"stretch\" gap={1}>\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'email.Settings.email.plugin.title.config',\n defaultMessage: 'Configuration',\n })}\n </Typography>\n <Typography>\n {formatMessage(\n {\n id: 'email.Settings.email.plugin.text.configuration',\n defaultMessage:\n 'The plugin is configured through the {file} file, checkout this {link} for the documentation.',\n },\n {\n file: './config/plugins.js',\n link: (\n <DocumentationLink\n href=\"https://docs.strapi.io/developer-docs/latest/plugins/email.html\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {formatMessage({\n id: 'email.link',\n defaultMessage: 'Link',\n })}\n </DocumentationLink>\n ),\n }\n )}\n </Typography>\n </Flex>\n\n <Grid.Root gap={5}>\n {(() => {\n const parsedFrom = parseEmailAddress(data.settings.defaultFrom);\n const parsedReplyTo = parseEmailAddress(data.settings.defaultReplyTo);\n\n return (\n <>\n {/* Sender Name - only show if name is present */}\n {parsedFrom.name && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"sender-name\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.senderName',\n defaultMessage: 'Default sender name',\n })}\n </Field.Label>\n <TextInput disabled readOnly value={parsedFrom.name} />\n </Field.Root>\n </Grid.Item>\n )}\n\n {/* Sender Email */}\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"sender-email\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.defaultFrom',\n defaultMessage: 'Default sender email',\n })}\n </Field.Label>\n <TextInput\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.defaultFrom',\n defaultMessage: 'ex: no-reply@strapi.io',\n })}\n disabled\n readOnly\n value={parsedFrom.email}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n\n {/* Reply-To Name - only show if name is present */}\n {parsedReplyTo.name && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"reply-to-name\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.replyToName',\n defaultMessage: 'Default reply-to name',\n })}\n </Field.Label>\n <TextInput disabled readOnly value={parsedReplyTo.name} />\n </Field.Root>\n </Grid.Item>\n )}\n\n {/* Reply-To Email */}\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"reply-to-email\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.defaultReplyTo',\n defaultMessage: 'Default response email',\n })}\n </Field.Label>\n <TextInput\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.defaultReplyTo',\n defaultMessage: 'ex: support@strapi.io',\n })}\n disabled\n readOnly\n value={parsedReplyTo.email}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n </>\n );\n })()}\n\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root name=\"email-provider\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.provider',\n defaultMessage: 'Email provider',\n })}\n </Field.Label>\n <SingleSelect disabled value={data.provider}>\n <SingleSelectOption value={data.provider}>\n {data.provider}\n </SingleSelectOption>\n </SingleSelect>\n </Field.Root>\n </Grid.Item>\n\n {data.supportsVerify && (\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"start\">\n <Field.Root name=\"verify-connection\">\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.verifyConnection',\n defaultMessage: 'Connection status',\n })}\n </Field.Label>\n <Flex gap={2} alignItems=\"center\">\n <Button\n variant=\"secondary\"\n loading={verifyMutation.isLoading}\n onClick={() => verifyMutation.mutate()}\n type=\"button\"\n >\n {formatMessage({\n id: 'email.Settings.email.plugin.button.verify',\n defaultMessage: 'Test connection',\n })}\n </Button>\n {connectionStatus === 'success' && (\n <Badge backgroundColor=\"success100\" textColor=\"success700\">\n <Flex gap={1}>\n <Check width=\"1.2rem\" height=\"1.2rem\" />\n {formatMessage({\n id: 'email.Settings.email.plugin.status.connected',\n defaultMessage: 'Connected',\n })}\n </Flex>\n </Badge>\n )}\n {connectionStatus === 'error' && (\n <Badge backgroundColor=\"danger100\" textColor=\"danger700\">\n <Flex gap={1}>\n <Cross width=\"1.2rem\" height=\"1.2rem\" />\n {formatMessage({\n id: 'email.Settings.email.plugin.status.error',\n defaultMessage: 'Error',\n })}\n </Flex>\n </Badge>\n )}\n </Flex>\n </Field.Root>\n </Grid.Item>\n )}\n </Grid.Root>\n </Flex>\n </Box>\n\n {data.capabilities &&\n (data.capabilities.transport ||\n data.capabilities.auth ||\n (data.capabilities.features && data.capabilities.features.length > 0)) && (\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <CapabilitiesSection\n capabilities={data.capabilities}\n isIdle={data.isIdle}\n formatMessage={formatMessage}\n />\n </Box>\n )}\n\n <Flex\n alignItems=\"stretch\"\n background=\"neutral0\"\n direction=\"column\"\n gap={4}\n hasRadius\n shadow=\"filterShadow\"\n paddingTop={6}\n paddingBottom={6}\n paddingLeft={7}\n paddingRight={7}\n >\n <Typography variant=\"delta\" tag=\"h2\">\n {formatMessage({\n id: 'email.Settings.email.plugin.title.test',\n defaultMessage: 'Test email delivery',\n })}\n </Typography>\n\n <Grid.Root gap={5}>\n <Grid.Item col={6} xs={12} direction=\"column\" alignItems=\"stretch\">\n <Field.Root\n name=\"test-address\"\n error={\n formErrors.email?.id &&\n formatMessage({\n id: `email.${formErrors.email?.id}`,\n defaultMessage: 'This is not a valid email',\n })\n }\n >\n <Field.Label>\n {formatMessage({\n id: 'email.Settings.email.plugin.label.testAddress',\n defaultMessage: 'Recipient email',\n })}\n </Field.Label>\n <TextInput\n onChange={handleChange}\n value={testAddress}\n placeholder={formatMessage({\n id: 'email.Settings.email.plugin.placeholder.testAddress',\n defaultMessage: 'ex: developer@example.com',\n })}\n type=\"email\"\n />\n </Field.Root>\n </Grid.Item>\n <Grid.Item col={7} xs={12} direction=\"column\" alignItems=\"start\">\n <Button\n loading={mutation.isLoading}\n disabled={!isTestAddressValid}\n type=\"submit\"\n startIcon={<Mail />}\n >\n {formatMessage({\n id: 'email.Settings.email.plugin.button.test-email',\n defaultMessage: 'Send test email',\n })}\n </Button>\n </Grid.Item>\n </Grid.Root>\n </Flex>\n </Flex>\n </form>\n )}\n </Layouts.Content>\n </Page.Main>\n );\n};\n"],"names":["DocumentationLink","styled","a","theme","colors","primary600","FEATURE_LABELS","dkim","id","defaultMessage","pool","rateLimiting","oauth2","requireTLS","CapabilitiesSection","capabilities","isIdle","formatMessage","transport","auth","features","encryptionLabel","secure","port","_jsxs","Flex","direction","alignItems","gap","_jsx","Typography","variant","tag","Grid","Root","host","Item","col","xs","Field","name","Label","TextInput","disabled","readOnly","value","String","type","user","undefined","Badge","backgroundColor","textColor","length","wrap","map","f","ProtectedSettingsPage","Page","Protect","permissions","PERMISSIONS","settings","SettingsPage","toggleNotification","useNotification","useIntl","get","post","useFetchClient","testAddress","setTestAddress","React","useState","isTestAddressValid","setIsTestAddressValid","formErrors","setFormErrors","data","isLoading","useQuery","res","config","supportsVerify","mutation","useMutation","body","onError","message","to","onSuccess","retry","connectionStatus","setConnectionStatus","verifyMutation","onMutate","useEffect","schema","validate","email","abortEarly","then","catch","handleChange","event","target","handleSubmit","preventDefault","error","ValidationError","getYupInnerErrors","mutate","Loading","Main","labelledBy","aria-busy","Title","Layouts","Header","title","subtitle","Content","form","onSubmit","Box","background","hasRadius","shadow","paddingTop","paddingBottom","paddingLeft","paddingRight","file","link","href","rel","parsedFrom","parseEmailAddress","defaultFrom","parsedReplyTo","defaultReplyTo","_Fragment","placeholder","SingleSelect","provider","SingleSelectOption","Button","loading","onClick","Check","width","height","Cross","onChange","startIcon","Mail"],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * RFC-compliant Email Address Parser
5
+ *
6
+ * Supports:
7
+ * - RFC 5322: Internet Message Format (basic name <email> format)
8
+ * - RFC 2047: MIME encoded-words for non-ASCII characters
9
+ * - RFC 5322: Comments in parentheses
10
+ * - RFC 5322: Quoted strings with special characters
11
+ * - RFC 6531: Internationalized email addresses (UTF-8)
12
+ */ /**
13
+ * Decodes RFC 2047 encoded-words
14
+ * Supports both Base64 (B) and Quoted-Printable (Q) encodings
15
+ *
16
+ * Examples:
17
+ * - =?UTF-8?B?U3RyYXBp?= -> "Strapi"
18
+ * - =?UTF-8?Q?M=C3=BCller?= -> "Müller"
19
+ * - =?ISO-8859-1?Q?=E4=F6=FC?= -> "äöü"
20
+ *
21
+ * @see https://datatracker.ietf.org/doc/html/rfc2047
22
+ */ const decodeRfc2047 = (encoded)=>{
23
+ // Pattern: =?charset?encoding?encoded_text?=
24
+ const rfc2047Pattern = /=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g;
25
+ return encoded.replace(rfc2047Pattern, (match, charset, encoding, text)=>{
26
+ try {
27
+ const upperEncoding = encoding.toUpperCase();
28
+ if (upperEncoding === 'B') {
29
+ // Base64 decoding
30
+ const decoded = atob(text);
31
+ return decodeWithCharset(decoded, charset);
32
+ }
33
+ if (upperEncoding === 'Q') {
34
+ // Quoted-Printable decoding
35
+ // In Q encoding, underscores represent spaces
36
+ const withSpaces = text.replace(/_/g, ' ');
37
+ // Decode =XX hex sequences
38
+ const decoded = withSpaces.replace(/=([0-9A-Fa-f]{2})/g, (_, hex)=>String.fromCharCode(parseInt(hex, 16)));
39
+ return decodeWithCharset(decoded, charset);
40
+ }
41
+ return match;
42
+ } catch {
43
+ // If decoding fails, return original
44
+ return match;
45
+ }
46
+ });
47
+ };
48
+ /**
49
+ * Decode a string with a specific charset
50
+ * Falls back to the original string if decoding fails
51
+ */ const decodeWithCharset = (str, charset)=>{
52
+ try {
53
+ // For UTF-8, we need to handle the bytes properly
54
+ const upperCharset = charset.toUpperCase();
55
+ if (upperCharset === 'UTF-8' || upperCharset === 'UTF8') {
56
+ // Convert byte string to UTF-8
57
+ const bytes = new Uint8Array(str.split('').map((c)=>c.charCodeAt(0)));
58
+ return new TextDecoder('utf-8').decode(bytes);
59
+ }
60
+ // For ISO-8859-1 (Latin-1), characters map directly
61
+ if (upperCharset === 'ISO-8859-1' || upperCharset === 'LATIN1' || upperCharset === 'LATIN-1') {
62
+ return str;
63
+ }
64
+ // For other charsets, try TextDecoder
65
+ const bytes = new Uint8Array(str.split('').map((c)=>c.charCodeAt(0)));
66
+ return new TextDecoder(charset).decode(bytes);
67
+ } catch {
68
+ return str;
69
+ }
70
+ };
71
+ /**
72
+ * Removes RFC 5322 comments from an email string
73
+ * Comments are enclosed in parentheses and can be nested
74
+ *
75
+ * Examples:
76
+ * - "email@example.com (Support Team)" -> "email@example.com"
77
+ * - "(comment) Name <email@example.com>" -> "Name <email@example.com>"
78
+ *
79
+ * @see https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.2
80
+ */ const extractComments = (str)=>{
81
+ const comments = [];
82
+ let result = '';
83
+ let depth = 0;
84
+ let currentComment = '';
85
+ let inQuotes = false;
86
+ let escape = false;
87
+ for (const char of str){
88
+ if (escape) {
89
+ if (depth > 0) {
90
+ currentComment += char;
91
+ } else {
92
+ result += char;
93
+ }
94
+ escape = false;
95
+ } else if (char === '\\') {
96
+ escape = true;
97
+ if (depth > 0) {
98
+ currentComment += char;
99
+ } else {
100
+ result += char;
101
+ }
102
+ } else if (char === '"' && depth === 0) {
103
+ inQuotes = !inQuotes;
104
+ result += char;
105
+ } else if (!inQuotes && char === '(') {
106
+ if (depth === 0) {
107
+ currentComment = '';
108
+ } else {
109
+ currentComment += char;
110
+ }
111
+ depth += 1;
112
+ } else if (!inQuotes && char === ')') {
113
+ depth -= 1;
114
+ if (depth === 0) {
115
+ comments.push(currentComment.trim());
116
+ currentComment = '';
117
+ } else if (depth > 0) {
118
+ currentComment += char;
119
+ }
120
+ } else if (depth > 0) {
121
+ currentComment += char;
122
+ } else {
123
+ result += char;
124
+ }
125
+ }
126
+ return {
127
+ text: result.trim(),
128
+ comments
129
+ };
130
+ };
131
+ /**
132
+ * Unquotes a quoted string according to RFC 5322
133
+ * Handles escaped characters within quoted strings
134
+ *
135
+ * Examples:
136
+ * - "\"John Doe\"" -> "John Doe"
137
+ * - "\"Doe, John\"" -> "Doe, John"
138
+ * - "\"Support \\\"24/7\\\"\"" -> "Support \"24/7\""
139
+ *
140
+ * @see https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.4
141
+ */ const unquoteString = (str)=>{
142
+ const trimmed = str.trim();
143
+ // Check if it's a quoted string
144
+ if (!trimmed.startsWith('"') || !trimmed.endsWith('"')) {
145
+ return trimmed;
146
+ }
147
+ // Remove surrounding quotes
148
+ const inner = trimmed.slice(1, -1);
149
+ // Unescape escaped characters (\" -> ", \\ -> \)
150
+ let result = '';
151
+ let escape = false;
152
+ for (const char of inner){
153
+ if (escape) {
154
+ result += char;
155
+ escape = false;
156
+ } else if (char === '\\') {
157
+ escape = true;
158
+ } else {
159
+ result += char;
160
+ }
161
+ }
162
+ return result;
163
+ };
164
+ /**
165
+ * Parses an email address string according to RFC 5322 and related RFCs
166
+ *
167
+ * Supported formats:
168
+ * 1. Simple email: "email@example.com"
169
+ * 2. Name with angle brackets: "Name <email@example.com>"
170
+ * 3. Quoted name: "\"Doe, John\" <email@example.com>"
171
+ * 4. RFC 2047 encoded: "=?UTF-8?B?...?= <email@example.com>"
172
+ * 5. With comment: "email@example.com (Display Name)"
173
+ * 6. Mixed: "\"Name\" <email@example.com> (comment)"
174
+ *
175
+ * @param emailString - The email address string to parse
176
+ * @returns Parsed email address with name, email, and original string
177
+ *
178
+ * @example
179
+ * parseEmailAddress('Strapi <no-reply@strapi.io>')
180
+ * // { name: 'Strapi', email: 'no-reply@strapi.io', original: '...' }
181
+ *
182
+ * @example
183
+ * parseEmailAddress('=?UTF-8?B?U3RyYXBp?= <no-reply@strapi.io>')
184
+ * // { name: 'Strapi', email: 'no-reply@strapi.io', original: '...' }
185
+ *
186
+ * @example
187
+ * parseEmailAddress('no-reply@strapi.io (Strapi Support)')
188
+ * // { name: 'Strapi Support', email: 'no-reply@strapi.io', original: '...' }
189
+ */ const parseEmailAddress = (emailString)=>{
190
+ if (!emailString || typeof emailString !== 'string') {
191
+ return {
192
+ name: null,
193
+ email: '',
194
+ original: emailString || ''
195
+ };
196
+ }
197
+ const original = emailString;
198
+ // Step 1: Decode any RFC 2047 encoded-words
199
+ let decoded = decodeRfc2047(emailString);
200
+ // Step 2: Extract and remove comments, but save them
201
+ const { text: withoutComments, comments } = extractComments(decoded);
202
+ decoded = withoutComments;
203
+ // Step 3: Try to parse "Name <email>" format
204
+ // This regex handles both quoted and unquoted names
205
+ const angleMatch = decoded.match(/^(.*?)\s*<([^>]+)>\s*$/);
206
+ if (angleMatch) {
207
+ let name = angleMatch[1].trim();
208
+ const email = angleMatch[2].trim();
209
+ // Unquote the name if it's quoted
210
+ if (name) {
211
+ name = unquoteString(name);
212
+ // Decode again in case the name itself contains encoded words
213
+ name = decodeRfc2047(name);
214
+ }
215
+ // If no name in the main part, check comments
216
+ if (!name && comments.length > 0) {
217
+ name = comments[0];
218
+ }
219
+ return {
220
+ name: name || null,
221
+ email,
222
+ original
223
+ };
224
+ }
225
+ // Step 4: Try "email (comment)" format - use comment as name
226
+ // At this point, comments are already extracted
227
+ const trimmedDecoded = decoded.trim();
228
+ // Validate it looks like an email (basic check)
229
+ if (trimmedDecoded.includes('@')) {
230
+ return {
231
+ name: comments.length > 0 ? comments[0] : null,
232
+ email: trimmedDecoded,
233
+ original
234
+ };
235
+ }
236
+ // Step 5: If nothing matched, treat the whole thing as email
237
+ return {
238
+ name: null,
239
+ email: trimmedDecoded,
240
+ original
241
+ };
242
+ };
243
+
244
+ exports.parseEmailAddress = parseEmailAddress;
245
+ //# sourceMappingURL=email-address-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-address-parser.js","sources":["../../../shared/email-address-parser.ts"],"sourcesContent":["/**\n * RFC-compliant Email Address Parser\n *\n * Supports:\n * - RFC 5322: Internet Message Format (basic name <email> format)\n * - RFC 2047: MIME encoded-words for non-ASCII characters\n * - RFC 5322: Comments in parentheses\n * - RFC 5322: Quoted strings with special characters\n * - RFC 6531: Internationalized email addresses (UTF-8)\n */\n\nexport interface ParsedEmailAddress {\n /** Display name (decoded if RFC 2047 encoded) */\n name: string | null;\n /** Email address */\n email: string;\n /** Original unparsed string */\n original: string;\n}\n\n/**\n * Decodes RFC 2047 encoded-words\n * Supports both Base64 (B) and Quoted-Printable (Q) encodings\n *\n * Examples:\n * - =?UTF-8?B?U3RyYXBp?= -> \"Strapi\"\n * - =?UTF-8?Q?M=C3=BCller?= -> \"Müller\"\n * - =?ISO-8859-1?Q?=E4=F6=FC?= -> \"äöü\"\n *\n * @see https://datatracker.ietf.org/doc/html/rfc2047\n */\nconst decodeRfc2047 = (encoded: string): string => {\n // Pattern: =?charset?encoding?encoded_text?=\n const rfc2047Pattern = /=\\?([^?]+)\\?([BbQq])\\?([^?]*)\\?=/g;\n\n return encoded.replace(rfc2047Pattern, (match, charset, encoding, text) => {\n try {\n const upperEncoding = encoding.toUpperCase();\n\n if (upperEncoding === 'B') {\n // Base64 decoding\n const decoded = atob(text);\n return decodeWithCharset(decoded, charset);\n }\n\n if (upperEncoding === 'Q') {\n // Quoted-Printable decoding\n // In Q encoding, underscores represent spaces\n const withSpaces = text.replace(/_/g, ' ');\n // Decode =XX hex sequences\n const decoded = withSpaces.replace(/=([0-9A-Fa-f]{2})/g, (_: string, hex: string) =>\n String.fromCharCode(parseInt(hex, 16))\n );\n return decodeWithCharset(decoded, charset);\n }\n\n return match;\n } catch {\n // If decoding fails, return original\n return match;\n }\n });\n};\n\n/**\n * Decode a string with a specific charset\n * Falls back to the original string if decoding fails\n */\nconst decodeWithCharset = (str: string, charset: string): string => {\n try {\n // For UTF-8, we need to handle the bytes properly\n const upperCharset = charset.toUpperCase();\n if (upperCharset === 'UTF-8' || upperCharset === 'UTF8') {\n // Convert byte string to UTF-8\n const bytes = new Uint8Array(str.split('').map((c) => c.charCodeAt(0)));\n return new TextDecoder('utf-8').decode(bytes);\n }\n // For ISO-8859-1 (Latin-1), characters map directly\n if (upperCharset === 'ISO-8859-1' || upperCharset === 'LATIN1' || upperCharset === 'LATIN-1') {\n return str;\n }\n // For other charsets, try TextDecoder\n const bytes = new Uint8Array(str.split('').map((c) => c.charCodeAt(0)));\n return new TextDecoder(charset).decode(bytes);\n } catch {\n return str;\n }\n};\n\n/**\n * Removes RFC 5322 comments from an email string\n * Comments are enclosed in parentheses and can be nested\n *\n * Examples:\n * - \"email@example.com (Support Team)\" -> \"email@example.com\"\n * - \"(comment) Name <email@example.com>\" -> \"Name <email@example.com>\"\n *\n * @see https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.2\n */\nconst extractComments = (str: string): { text: string; comments: string[] } => {\n const comments: string[] = [];\n let result = '';\n let depth = 0;\n let currentComment = '';\n let inQuotes = false;\n let escape = false;\n\n for (const char of str) {\n if (escape) {\n if (depth > 0) {\n currentComment += char;\n } else {\n result += char;\n }\n escape = false;\n } else if (char === '\\\\') {\n escape = true;\n if (depth > 0) {\n currentComment += char;\n } else {\n result += char;\n }\n } else if (char === '\"' && depth === 0) {\n inQuotes = !inQuotes;\n result += char;\n } else if (!inQuotes && char === '(') {\n if (depth === 0) {\n currentComment = '';\n } else {\n currentComment += char;\n }\n depth += 1;\n } else if (!inQuotes && char === ')') {\n depth -= 1;\n if (depth === 0) {\n comments.push(currentComment.trim());\n currentComment = '';\n } else if (depth > 0) {\n currentComment += char;\n }\n } else if (depth > 0) {\n currentComment += char;\n } else {\n result += char;\n }\n }\n\n return { text: result.trim(), comments };\n};\n\n/**\n * Unquotes a quoted string according to RFC 5322\n * Handles escaped characters within quoted strings\n *\n * Examples:\n * - \"\\\"John Doe\\\"\" -> \"John Doe\"\n * - \"\\\"Doe, John\\\"\" -> \"Doe, John\"\n * - \"\\\"Support \\\\\\\"24/7\\\\\\\"\\\"\" -> \"Support \\\"24/7\\\"\"\n *\n * @see https://datatracker.ietf.org/doc/html/rfc5322#section-3.2.4\n */\nconst unquoteString = (str: string): string => {\n const trimmed = str.trim();\n\n // Check if it's a quoted string\n if (!trimmed.startsWith('\"') || !trimmed.endsWith('\"')) {\n return trimmed;\n }\n\n // Remove surrounding quotes\n const inner = trimmed.slice(1, -1);\n\n // Unescape escaped characters (\\\" -> \", \\\\ -> \\)\n let result = '';\n let escape = false;\n\n for (const char of inner) {\n if (escape) {\n result += char;\n escape = false;\n } else if (char === '\\\\') {\n escape = true;\n } else {\n result += char;\n }\n }\n\n return result;\n};\n\n/**\n * Parses an email address string according to RFC 5322 and related RFCs\n *\n * Supported formats:\n * 1. Simple email: \"email@example.com\"\n * 2. Name with angle brackets: \"Name <email@example.com>\"\n * 3. Quoted name: \"\\\"Doe, John\\\" <email@example.com>\"\n * 4. RFC 2047 encoded: \"=?UTF-8?B?...?= <email@example.com>\"\n * 5. With comment: \"email@example.com (Display Name)\"\n * 6. Mixed: \"\\\"Name\\\" <email@example.com> (comment)\"\n *\n * @param emailString - The email address string to parse\n * @returns Parsed email address with name, email, and original string\n *\n * @example\n * parseEmailAddress('Strapi <no-reply@strapi.io>')\n * // { name: 'Strapi', email: 'no-reply@strapi.io', original: '...' }\n *\n * @example\n * parseEmailAddress('=?UTF-8?B?U3RyYXBp?= <no-reply@strapi.io>')\n * // { name: 'Strapi', email: 'no-reply@strapi.io', original: '...' }\n *\n * @example\n * parseEmailAddress('no-reply@strapi.io (Strapi Support)')\n * // { name: 'Strapi Support', email: 'no-reply@strapi.io', original: '...' }\n */\nexport const parseEmailAddress = (emailString: string | undefined | null): ParsedEmailAddress => {\n if (!emailString || typeof emailString !== 'string') {\n return { name: null, email: '', original: emailString || '' };\n }\n\n const original = emailString;\n\n // Step 1: Decode any RFC 2047 encoded-words\n let decoded = decodeRfc2047(emailString);\n\n // Step 2: Extract and remove comments, but save them\n const { text: withoutComments, comments } = extractComments(decoded);\n decoded = withoutComments;\n\n // Step 3: Try to parse \"Name <email>\" format\n // This regex handles both quoted and unquoted names\n const angleMatch = decoded.match(/^(.*?)\\s*<([^>]+)>\\s*$/);\n\n if (angleMatch) {\n let name = angleMatch[1].trim();\n const email = angleMatch[2].trim();\n\n // Unquote the name if it's quoted\n if (name) {\n name = unquoteString(name);\n // Decode again in case the name itself contains encoded words\n name = decodeRfc2047(name);\n }\n\n // If no name in the main part, check comments\n if (!name && comments.length > 0) {\n name = comments[0];\n }\n\n return {\n name: name || null,\n email,\n original,\n };\n }\n\n // Step 4: Try \"email (comment)\" format - use comment as name\n // At this point, comments are already extracted\n const trimmedDecoded = decoded.trim();\n\n // Validate it looks like an email (basic check)\n if (trimmedDecoded.includes('@')) {\n return {\n name: comments.length > 0 ? comments[0] : null,\n email: trimmedDecoded,\n original,\n };\n }\n\n // Step 5: If nothing matched, treat the whole thing as email\n return {\n name: null,\n email: trimmedDecoded,\n original,\n };\n};\n\n/**\n * Formats an email address according to RFC 5322\n *\n * @param name - Display name (will be quoted if contains special chars)\n * @param email - Email address\n * @returns Formatted email address string\n *\n * @example\n * formatEmailAddress('Strapi', 'no-reply@strapi.io')\n * // 'Strapi <no-reply@strapi.io>'\n *\n * @example\n * formatEmailAddress('Doe, John', 'john@example.com')\n * // '\"Doe, John\" <john@example.com>'\n */\nexport const formatEmailAddress = (name: string | null, email: string): string => {\n if (!name) {\n return email;\n }\n\n // Check if name needs quoting (contains special characters)\n // RFC 5322 specials: ()<>@,;:\\\".[]\n const needsQuoting = /[()<>@,;:\\\\\".[\\]]/.test(name) || name.includes(' ');\n\n if (needsQuoting && !name.startsWith('\"')) {\n // Escape any existing quotes and backslashes\n const escaped = name.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n return `\"${escaped}\" <${email}>`;\n }\n\n return `${name} <${email}>`;\n};\n\n/**\n * Validates an email address according to RFC 5322\n * This is a simplified validation that covers most common cases\n *\n * @param email - Email address to validate\n * @returns true if the email appears valid\n */\nexport const isValidEmail = (email: string): boolean => {\n if (!email || typeof email !== 'string') {\n return false;\n }\n\n // Basic RFC 5322 pattern (simplified)\n // Allows internationalized domains (RFC 6531)\n const emailPattern =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~\\u0080-\\uFFFF-]+@[a-zA-Z0-9\\u0080-\\uFFFF](?:[a-zA-Z0-9\\u0080-\\uFFFF-]{0,61}[a-zA-Z0-9\\u0080-\\uFFFF])?(?:\\.[a-zA-Z0-9\\u0080-\\uFFFF](?:[a-zA-Z0-9\\u0080-\\uFFFF-]{0,61}[a-zA-Z0-9\\u0080-\\uFFFF])?)*$/;\n\n return emailPattern.test(email);\n};\n\n/**\n * Parses multiple email addresses separated by commas\n * Handles quoted strings that may contain commas\n *\n * @param emailsString - Comma-separated email addresses\n * @returns Array of parsed email addresses\n *\n * @example\n * parseMultipleEmailAddresses('a@example.com, \"Doe, John\" <b@example.com>')\n * // [{ name: null, email: 'a@example.com', ... }, { name: 'Doe, John', email: 'b@example.com', ... }]\n */\nexport const parseMultipleEmailAddresses = (\n emailsString: string | undefined | null\n): ParsedEmailAddress[] => {\n if (!emailsString || typeof emailsString !== 'string') {\n return [];\n }\n\n const addresses: string[] = [];\n let current = '';\n let inQuotes = false;\n let depth = 0;\n let prevChar = '';\n\n for (const char of emailsString) {\n // Handle escape sequences\n if (prevChar === '\\\\') {\n current += char;\n prevChar = char;\n } else if (char === '\"') {\n inQuotes = !inQuotes;\n current += char;\n prevChar = char;\n } else if (!inQuotes && (char === '<' || char === '(')) {\n depth += 1;\n current += char;\n prevChar = char;\n } else if (!inQuotes && (char === '>' || char === ')')) {\n depth -= 1;\n current += char;\n prevChar = char;\n } else if (!inQuotes && char === ',' && depth === 0) {\n const trimmed = current.trim();\n if (trimmed) {\n addresses.push(trimmed);\n }\n current = '';\n prevChar = char;\n } else {\n current += char;\n prevChar = char;\n }\n }\n\n // Don't forget the last address\n const trimmed = current.trim();\n if (trimmed) {\n addresses.push(trimmed);\n }\n\n return addresses.map(parseEmailAddress);\n};\n"],"names":["decodeRfc2047","encoded","rfc2047Pattern","replace","match","charset","encoding","text","upperEncoding","toUpperCase","decoded","atob","decodeWithCharset","withSpaces","_","hex","String","fromCharCode","parseInt","str","upperCharset","bytes","Uint8Array","split","map","c","charCodeAt","TextDecoder","decode","extractComments","comments","result","depth","currentComment","inQuotes","escape","char","push","trim","unquoteString","trimmed","startsWith","endsWith","inner","slice","parseEmailAddress","emailString","name","email","original","withoutComments","angleMatch","length","trimmedDecoded","includes"],"mappings":"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"}