@akemona-org/strapi-plugin-email 3.7.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.
Files changed (42) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +21 -0
  3. package/admin/src/assets/images/logo.svg +1 -0
  4. package/admin/src/containers/Settings/components.js +16 -0
  5. package/admin/src/containers/Settings/index.js +201 -0
  6. package/admin/src/index.js +63 -0
  7. package/admin/src/permissions.js +9 -0
  8. package/admin/src/pluginId.js +5 -0
  9. package/admin/src/translations/ar.json +4 -0
  10. package/admin/src/translations/cs.json +4 -0
  11. package/admin/src/translations/de.json +4 -0
  12. package/admin/src/translations/dk.json +4 -0
  13. package/admin/src/translations/en.json +22 -0
  14. package/admin/src/translations/es.json +4 -0
  15. package/admin/src/translations/fr.json +4 -0
  16. package/admin/src/translations/id.json +4 -0
  17. package/admin/src/translations/index.js +53 -0
  18. package/admin/src/translations/it.json +4 -0
  19. package/admin/src/translations/ja.json +4 -0
  20. package/admin/src/translations/ko.json +4 -0
  21. package/admin/src/translations/ms.json +4 -0
  22. package/admin/src/translations/nl.json +4 -0
  23. package/admin/src/translations/pl.json +4 -0
  24. package/admin/src/translations/pt-BR.json +4 -0
  25. package/admin/src/translations/pt.json +4 -0
  26. package/admin/src/translations/ru.json +4 -0
  27. package/admin/src/translations/sk.json +4 -0
  28. package/admin/src/translations/th.json +4 -0
  29. package/admin/src/translations/tr.json +4 -0
  30. package/admin/src/translations/uk.json +4 -0
  31. package/admin/src/translations/vi.json +4 -0
  32. package/admin/src/translations/zh-Hans.json +22 -0
  33. package/admin/src/translations/zh.json +4 -0
  34. package/admin/src/utils/getTrad.js +5 -0
  35. package/admin/src/utils/schema.js +11 -0
  36. package/config/functions/bootstrap.js +34 -0
  37. package/config/routes.json +49 -0
  38. package/config/settings.js +9 -0
  39. package/controllers/Email.js +66 -0
  40. package/documentation/1.0.0/overrides/email-Email.json +67 -0
  41. package/package.json +48 -0
  42. package/services/Email.js +44 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015-present Strapi Solutions SAS
2
+
3
+ Portions of the Strapi software are licensed as follows:
4
+
5
+ * All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined in "ee/LICENSE".
6
+
7
+ * All software outside of the above-mentioned directories or restrictions above is available under the "MIT Expat" license as set forth below.
8
+
9
+ MIT Expat License
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # Strapi plugin
2
+
3
+ ---
4
+
5
+ ## Deprecation Warning :warning:
6
+
7
+ Hello! We have some news to share,
8
+
9
+ We’ve decided it’ll soon be time to end the support for `strapi-plugin-email`.
10
+
11
+ After years of iterations, Strapi is going to V4 and we won’t maintain V3 packages when it’ll reach its end-of-support milestone (~end of Q3 2022).
12
+
13
+ If you’ve been using `strapi-plugin-email` and have migrated to V4 (or if you want to), you can find the equivalent and updated version of this package at this [URL](https://github.com/strapi/strapi/tree/master/packages/core/email) and with the following name on NPM: `@strapi/plugin-email`.
14
+
15
+ If you’ve contributed to the development of this package, thank you again for that! We hope to see you on the V4 soon.
16
+
17
+ The Akemona team
18
+
19
+ ---
20
+
21
+ > :warning: The Shipper Email may also need to be changed in the `Email Templates` tab on the admin panel for emails to send properly
@@ -0,0 +1 @@
1
+ <svg width="24" height="17" xmlns="http://www.w3.org/2000/svg"><text transform="translate(-23 -9)" fill="#4B515A" fill-rule="evenodd" font-size="24" font-family="AppleColorEmoji, Apple Color Emoji"><tspan x="23" y="28">✉️</tspan></text></svg>
@@ -0,0 +1,16 @@
1
+ import styled from 'styled-components';
2
+ import { Button, Text as TextBase } from '@buffetjs/core';
3
+
4
+ const Text = styled(TextBase)`
5
+ width: 100%;
6
+ padding: 0 15px 17px 15px;
7
+ `;
8
+
9
+ const AlignedButton = styled(Button)`
10
+ height: 34px;
11
+ padding-top: 3px;
12
+ margin: 29px 15px 0 15px;
13
+ min-width: unset;
14
+ `;
15
+
16
+ export { Text, AlignedButton };
@@ -0,0 +1,201 @@
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { useIntl, FormattedMessage } from 'react-intl';
3
+ import { get } from 'lodash';
4
+ import { Header } from '@buffetjs/custom';
5
+ import { Envelope } from '@buffetjs/icons';
6
+ import { colors } from '@buffetjs/styles';
7
+ import {
8
+ FormBloc,
9
+ request,
10
+ SettingsPageTitle,
11
+ SizedInput,
12
+ getYupInnerErrors,
13
+ BaselineAlignment,
14
+ CheckPagePermissions,
15
+ } from 'strapi-helper-plugin';
16
+ import getTrad from '../../utils/getTrad';
17
+ import { AlignedButton, Text } from './components';
18
+ import schema from '../../utils/schema';
19
+ import pluginPermissions from '../../permissions';
20
+
21
+ const SettingsPage = () => {
22
+ const { formatMessage } = useIntl();
23
+ const [formErrors, setFormErrors] = useState({});
24
+ const [isTestButtonLoading, setIsTestButtonLoading] = useState(false);
25
+ const [showLoader, setShowLoader] = useState(false);
26
+ const [config, setConfig] = useState({
27
+ provider: '',
28
+ settings: { defaultFrom: '', defaultReplyTo: '', testAddress: '' },
29
+ });
30
+ const [providers, setProviders] = useState([]);
31
+ const [testAddress, setTestAddress] = useState();
32
+ const [testSuccess, setTestSuccess] = useState(false);
33
+ const isMounted = useRef(true);
34
+
35
+ const title = formatMessage({ id: getTrad('Settings.title') });
36
+
37
+ const handleSubmit = async event => {
38
+ event.preventDefault();
39
+ let errors = {};
40
+
41
+ try {
42
+ await schema.validate({ email: testAddress }, { abortEarly: false });
43
+
44
+ try {
45
+ setIsTestButtonLoading(true);
46
+
47
+ await request('/email/test', {
48
+ method: 'POST',
49
+ body: { to: testAddress },
50
+ });
51
+
52
+ setTestSuccess(true);
53
+
54
+ strapi.notification.success(
55
+ formatMessage({ id: getTrad('Settings.notification.test.success') }, { to: testAddress })
56
+ );
57
+ } catch (err) {
58
+ strapi.notification.error(
59
+ formatMessage({ id: getTrad('Settings.notification.test.error') }, { to: testAddress })
60
+ );
61
+ } finally {
62
+ if (isMounted.current) {
63
+ setIsTestButtonLoading(false);
64
+ }
65
+ }
66
+ } catch (error) {
67
+ errors = getYupInnerErrors(error);
68
+ setFormErrors(errors);
69
+ console.log(errors);
70
+ }
71
+ };
72
+
73
+ useEffect(() => {
74
+ const fetchEmailSettings = () => {
75
+ setShowLoader(true);
76
+
77
+ request('/email/settings', {
78
+ method: 'GET',
79
+ })
80
+ .then(data => {
81
+ setConfig(data.config);
82
+ setProviders([data.config.provider]);
83
+ setTestAddress(get(data, 'config.settings.testAddress'));
84
+ })
85
+ .catch(() =>
86
+ strapi.notification.error(
87
+ formatMessage({ id: getTrad('Settings.notification.config.error') })
88
+ )
89
+ )
90
+ .finally(() => setShowLoader(false));
91
+ };
92
+
93
+ fetchEmailSettings();
94
+ }, [formatMessage]);
95
+
96
+ useEffect(() => {
97
+ return () => {
98
+ isMounted.current = false;
99
+ };
100
+ }, []);
101
+
102
+ return (
103
+ <>
104
+ <CheckPagePermissions permissions={pluginPermissions.settings}>
105
+ <SettingsPageTitle name={title} />
106
+ <div>
107
+ <form onSubmit={handleSubmit}>
108
+ <Header
109
+ title={{ label: title }}
110
+ content={formatMessage({ id: getTrad('Settings.subTitle') })}
111
+ isLoading={showLoader}
112
+ />
113
+ <BaselineAlignment top size="3px" />
114
+ <FormBloc
115
+ title={formatMessage({ id: getTrad('Settings.form.title.config') })}
116
+ isLoading={showLoader}
117
+ >
118
+ <Text fontSize="md" lineHeight="18px">
119
+ <FormattedMessage
120
+ id={getTrad('Settings.form.text.configuration')}
121
+ values={{
122
+ file: <code>./config/plugins.js</code>,
123
+ link: (
124
+ <a
125
+ href="https://strapi.akemona.com/documentation/developer-docs/latest/development/plugins/email.html#configure-the-plugin"
126
+ target="_blank"
127
+ rel="noopener noreferrer"
128
+ >
129
+ link
130
+ </a>
131
+ ),
132
+ }}
133
+ />
134
+ </Text>
135
+ <SizedInput
136
+ disabled
137
+ label={getTrad('Settings.form.label.defaultFrom')}
138
+ name="default-from"
139
+ placeholder={getTrad('Settings.form.placeholder.defaultFrom')}
140
+ size={{ xs: 6 }}
141
+ type="email"
142
+ value={config.settings.defaultFrom}
143
+ />
144
+ <SizedInput
145
+ disabled
146
+ label={getTrad('Settings.form.label.defaultReplyTo')}
147
+ name="default-reply-to"
148
+ placeholder={getTrad('Settings.form.placeholder.defaultReplyTo')}
149
+ size={{ xs: 6 }}
150
+ type="email"
151
+ value={config.settings.defaultReplyTo}
152
+ />
153
+ <SizedInput
154
+ disabled
155
+ label={getTrad('Settings.form.label.provider')}
156
+ name="provider"
157
+ options={providers}
158
+ size={{ xs: 6 }}
159
+ type="select"
160
+ value={`strapi-provider-email-${config.provider}`}
161
+ />
162
+ </FormBloc>
163
+ <BaselineAlignment top size="32px" />
164
+ <FormBloc
165
+ title={formatMessage({ id: getTrad('Settings.form.title.test') })}
166
+ isLoading={showLoader}
167
+ >
168
+ <SizedInput
169
+ label={getTrad('Settings.form.label.testAddress')}
170
+ name="test-address"
171
+ placeholder={getTrad('Settings.form.placeholder.testAddress')}
172
+ onChange={event => setTestAddress(event.target.value)}
173
+ size={{ xs: 6 }}
174
+ type="email"
175
+ value={testAddress}
176
+ error={formErrors.email}
177
+ />
178
+ <AlignedButton
179
+ color="success"
180
+ disabled={testSuccess}
181
+ icon={(
182
+ <Envelope
183
+ fill={testSuccess ? colors.button.disabled.color : null}
184
+ style={{ verticalAlign: 'middle', marginRight: '10px' }}
185
+ />
186
+ )}
187
+ isLoading={isTestButtonLoading}
188
+ style={{ fontWeight: 600 }}
189
+ type="submit"
190
+ >
191
+ {formatMessage({ id: getTrad('Settings.button.test-email') })}
192
+ </AlignedButton>
193
+ </FormBloc>
194
+ </form>
195
+ </div>
196
+ </CheckPagePermissions>
197
+ </>
198
+ );
199
+ };
200
+
201
+ export default SettingsPage;
@@ -0,0 +1,63 @@
1
+ // NOTE TO PLUGINS DEVELOPERS:
2
+ // If you modify this file by adding new options to the plugin entry point
3
+ // Here's the file: strapi/docs/3.x/plugin-development/frontend-field-api.md
4
+ // Here's the file: strapi/docs/3.x/guides/registering-a-field-in-admin.md
5
+ // Also the strapi-generate-plugins/files/admin/src/index.js needs to be updated
6
+ // IF THE DOC IS NOT UPDATED THE PULL REQUEST WILL NOT BE MERGED
7
+
8
+ import React from 'react';
9
+ import { CheckPagePermissions } from 'strapi-helper-plugin';
10
+ import pluginPkg from '../../package.json';
11
+ import pluginId from './pluginId';
12
+ import pluginLogo from './assets/images/logo.svg';
13
+ import pluginPermissions from './permissions';
14
+ import trads from './translations';
15
+ import getTrad from './utils/getTrad';
16
+ import SettingsPage from './containers/Settings';
17
+
18
+ export default strapi => {
19
+ const pluginDescription = pluginPkg.strapi.description || pluginPkg.description;
20
+
21
+ const plugin = {
22
+ blockerComponent: null,
23
+ blockerComponentProps: {},
24
+ description: pluginDescription,
25
+ icon: pluginPkg.strapi.icon,
26
+ id: pluginId,
27
+ isReady: true,
28
+ initializer: () => null,
29
+ injectedComponents: [],
30
+ isRequired: pluginPkg.strapi.required || false,
31
+ layout: null,
32
+ lifecycles: () => {},
33
+ mainComponent: null,
34
+ name: pluginPkg.strapi.name,
35
+ pluginLogo,
36
+ preventComponentRendering: false,
37
+ trads,
38
+ settings: {
39
+ menuSection: {
40
+ id: pluginId,
41
+ title: getTrad('SettingsNav.section-label'),
42
+ links: [
43
+ {
44
+ title: {
45
+ id: getTrad('SettingsNav.link.settings'),
46
+ defaultMessage: 'Settings',
47
+ },
48
+ name: 'settings',
49
+ to: `${strapi.settingsBaseURL}/${pluginId}`,
50
+ Component: () => (
51
+ <CheckPagePermissions permissions={pluginPermissions.settings}>
52
+ <SettingsPage />
53
+ </CheckPagePermissions>
54
+ ),
55
+ permissions: pluginPermissions.settings,
56
+ },
57
+ ],
58
+ },
59
+ },
60
+ };
61
+
62
+ return strapi.registerPlugin(plugin);
63
+ };
@@ -0,0 +1,9 @@
1
+ const pluginPermissions = {
2
+ // This permission regards the main component (App) and is used to tell
3
+ // If the plugin link should be displayed in the menu
4
+ // And also if the plugin is accessible. This use case is found when a user types the url of the
5
+ // plugin directly in the browser
6
+ settings: [{ action: 'plugins::email.settings.read', subject: null }],
7
+ };
8
+
9
+ export default pluginPermissions;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.name.replace(/^strapi-plugin-/i, '');
4
+
5
+ export default pluginId;
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "إرسال بريد.",
3
+ "plugin.description.short": "إرسال بريد."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Odeslat e-maily.",
3
+ "plugin.description.short": "Odeslat e-maily."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Zum Versand von E-Mails.",
3
+ "plugin.description.short": "Zum Versand von E-Mails."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Send e-mails.",
3
+ "plugin.description.short": "Send e-mails."
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "plugin.description.long": "Send emails.",
3
+ "plugin.description.short": "Send emails.",
4
+ "SettingsNav.section-label": "Email plugin",
5
+ "SettingsNav.link.settings": "Email settings",
6
+ "Settings.title": "Email settings",
7
+ "Settings.subTitle": "Test the settings for the email plugin",
8
+ "Settings.button.test-email": "Test email",
9
+ "Settings.notification.test.success": "Email test succeeded, check the {to} mailbox",
10
+ "Settings.notification.test.error": "Failed to send a test mail to {to}",
11
+ "Settings.notification.config.error": "Failed to retrieve the email config",
12
+ "Settings.form.title.config": "Configuration",
13
+ "Settings.form.title.test": "Send a test email",
14
+ "Settings.form.label.provider": "Email provider",
15
+ "Settings.form.label.defaultFrom": "Default shipper email",
16
+ "Settings.form.label.defaultReplyTo": "Default response email",
17
+ "Settings.form.label.testAddress": "Test delivery email address",
18
+ "Settings.form.placeholder.defaultFrom": "ex: Strapi No-Reply <no-reply@strapi.io>",
19
+ "Settings.form.placeholder.defaultReplyTo": "ex: Strapi <example@strapi.io>",
20
+ "Settings.form.placeholder.testAddress": "ex: developer@example.com",
21
+ "Settings.form.text.configuration": "The plugin is configured through the {file} file, checkout this {link} for the documentation."
22
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Enviar correos electrónicos.",
3
+ "plugin.description.short": "Enviar correos electrónicos."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Envoyez des emails.",
3
+ "plugin.description.short": "Envoyez des emails."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Kirim surel.",
3
+ "plugin.description.short": "Kirim surel."
4
+ }
@@ -0,0 +1,53 @@
1
+ import ar from './ar.json';
2
+ import cs from './cs.json';
3
+ import de from './de.json';
4
+ import dk from './dk.json';
5
+ import en from './en.json';
6
+ import es from './es.json';
7
+ import fr from './fr.json';
8
+ import id from './id.json';
9
+ import it from './it.json';
10
+ import ja from './ja.json';
11
+ import ko from './ko.json';
12
+ import ms from './ms.json';
13
+ import nl from './nl.json';
14
+ import pl from './pl.json';
15
+ import ptBR from './pt-BR.json';
16
+ import pt from './pt.json';
17
+ import ru from './ru.json';
18
+ import th from './th.json';
19
+ import tr from './tr.json';
20
+ import uk from './uk.json';
21
+ import vi from './vi.json';
22
+ import zhHans from './zh-Hans.json';
23
+ import zh from './zh.json';
24
+ import sk from './sk.json';
25
+
26
+ const trads = {
27
+ ar,
28
+ cs,
29
+ de,
30
+ dk,
31
+ en,
32
+ es,
33
+ fr,
34
+ id,
35
+ it,
36
+ ja,
37
+ ko,
38
+ ms,
39
+ nl,
40
+ pl,
41
+ 'pt-BR': ptBR,
42
+ pt,
43
+ ru,
44
+ th,
45
+ tr,
46
+ uk,
47
+ vi,
48
+ 'zh-Hans': zhHans,
49
+ zh,
50
+ sk,
51
+ };
52
+
53
+ export default trads;
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Invia le email.",
3
+ "plugin.description.short": "Invia le email."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "メールを送る",
3
+ "plugin.description.short": "メールを送る"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "이메일을 전송합니다.",
3
+ "plugin.description.short": "이메일을 전송합니다."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Penghantaran E-mel.",
3
+ "plugin.description.short": "Penghantaran E-mel."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Verstuur e-mails.",
3
+ "plugin.description.short": "Verstuur e-mails."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Wysyłaj E-maile",
3
+ "plugin.description.short": "Wysyłaj E-maile"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Enviar emails.",
3
+ "plugin.description.short": "Enviar emails."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Enviar emails.",
3
+ "plugin.description.short": "Enviar emails."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Отправка почты.",
3
+ "plugin.description.short": "Отправка почты."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Posielanie e-mailov.",
3
+ "plugin.description.short": "Posielanie e-mailov."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "ส่งอีเมล",
3
+ "plugin.description.short": "ส่งอีเมล"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "E-posta gönder.",
3
+ "plugin.description.short": "E-posta gönder."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Надсилайте листи електронною поштою.",
3
+ "plugin.description.short": "Надсилайте листи електронною поштою."
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "Gửi các email.",
3
+ "plugin.description.short": "Gửi các email."
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "plugin.description.long": "发送电子邮件。",
3
+ "plugin.description.short": "发送电子邮件。",
4
+ "SettingsNav.section-label": "邮件插件",
5
+ "SettingsNav.link.settings": "邮件设置",
6
+ "Settings.title": "邮件设置",
7
+ "Settings.subTitle": "邮件功能设置",
8
+ "Settings.button.test-email": "发送测试邮件",
9
+ "Settings.notification.test.success": "邮件测试成功,请查收 {to} 的收件箱。",
10
+ "Settings.notification.test.error": "给 {to} 的测试邮件发送失败。",
11
+ "Settings.notification.config.error": "获取邮件设置失败",
12
+ "Settings.form.title.config": "配置",
13
+ "Settings.form.title.test": "发送测试邮件",
14
+ "Settings.form.label.provider": "邮件发送方式(Provider)",
15
+ "Settings.form.label.defaultFrom": "默认发送邮箱",
16
+ "Settings.form.label.defaultReplyTo": "默认回复邮箱",
17
+ "Settings.form.label.testAddress": "请输入要接受测试邮件的邮箱地址",
18
+ "Settings.form.placeholder.defaultFrom": "如:Strapi No-Reply <no-reply@strapi.io>",
19
+ "Settings.form.placeholder.defaultReplyTo": "如:Strapi <example@strapi.io>",
20
+ "Settings.form.placeholder.testAddress": "如:developer@example.com",
21
+ "Settings.form.text.configuration": "插件配置文件:{file},配置文档:{link}。"
22
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "plugin.description.long": "寄送電子郵件",
3
+ "plugin.description.short": "寄送電子郵件"
4
+ }
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getTrad = id => `${pluginId}.${id}`;
4
+
5
+ export default getTrad;
@@ -0,0 +1,11 @@
1
+ import * as yup from 'yup';
2
+ import { translatedErrors } from 'strapi-helper-plugin';
3
+
4
+ const schema = yup.object().shape({
5
+ email: yup
6
+ .string()
7
+ .email(translatedErrors.email)
8
+ .required(translatedErrors.required),
9
+ });
10
+
11
+ export default schema;
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ const createProvider = emailConfig => {
6
+ const providerName = _.toLower(emailConfig.provider);
7
+ let provider;
8
+ try {
9
+ provider = require(`strapi-provider-email-${providerName}`);
10
+ } catch (err) {
11
+ throw new Error(
12
+ `The provider package isn't installed. Please run \`npm install strapi-provider-email-${providerName}\` --save`
13
+ );
14
+ }
15
+ return provider.init(emailConfig.providerOptions, emailConfig.settings);
16
+ };
17
+
18
+ module.exports = async () => {
19
+ const emailConfig = _.get(strapi.plugins, 'email.config', {});
20
+ strapi.plugins.email.provider = createProvider(emailConfig);
21
+
22
+ // Add permissions
23
+ const actions = [
24
+ {
25
+ section: 'settings',
26
+ category: 'email',
27
+ displayName: 'Access the Email Settings page',
28
+ uid: 'settings.read',
29
+ pluginName: 'email',
30
+ },
31
+ ];
32
+
33
+ await strapi.admin.services.permission.actionProvider.registerMany(actions);
34
+ };
@@ -0,0 +1,49 @@
1
+ {
2
+ "routes": [
3
+ {
4
+ "method": "POST",
5
+ "path": "/",
6
+ "handler": "Email.send",
7
+ "config": {
8
+ "policies": [],
9
+ "description": "Send an email",
10
+ "tag": {
11
+ "plugin": "email",
12
+ "name": "Email"
13
+ }
14
+ }
15
+ },
16
+ {
17
+ "method": "POST",
18
+ "path": "/test",
19
+ "handler": "Email.test",
20
+ "config": {
21
+ "policies": [
22
+ "admin::isAuthenticatedAdmin",
23
+ ["admin::hasPermissions", ["plugins::email.settings.read"]]
24
+ ],
25
+ "description": "Send an test email",
26
+ "tag": {
27
+ "plugin": "email",
28
+ "name": "Email"
29
+ }
30
+ }
31
+ },
32
+ {
33
+ "method": "GET",
34
+ "path": "/settings",
35
+ "handler": "Email.getSettings",
36
+ "config": {
37
+ "policies": [
38
+ "admin::isAuthenticatedAdmin",
39
+ ["admin::hasPermissions", ["plugins::email.settings.read"]]
40
+ ],
41
+ "description": "Get the email settings",
42
+ "tag": {
43
+ "plugin": "email",
44
+ "name": "Email"
45
+ }
46
+ }
47
+ }
48
+ ]
49
+ }
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ provider: 'sendmail',
5
+ providerOptions: {},
6
+ settings: {
7
+ defaultFrom: 'Strapi <no-reply@strapi.io>',
8
+ },
9
+ };
@@ -0,0 +1,66 @@
1
+ 'use strict';
2
+
3
+ const { isNil, pick } = require('lodash/fp');
4
+
5
+ /**
6
+ * Email.js controller
7
+ *
8
+ * @description: A set of functions called "actions" of the `email` plugin.
9
+ */
10
+ module.exports = {
11
+ async send(ctx) {
12
+ let options = ctx.request.body;
13
+ try {
14
+ await strapi.plugins.email.services.email.send(options);
15
+ } catch (e) {
16
+ if (e.statusCode === 400) {
17
+ return ctx.badRequest(e.message);
18
+ } else {
19
+ throw new Error(`Couldn't send email: ${e.message}.`);
20
+ }
21
+ }
22
+
23
+ // Send 200 `ok`
24
+ ctx.send({});
25
+ },
26
+
27
+ async test(ctx) {
28
+ const { to } = ctx.request.body;
29
+
30
+ if (isNil(to)) {
31
+ throw strapi.errors.badRequest(null, {
32
+ errors: [{ id: 'Email.to.empty', message: 'No recipient(s) are given' }],
33
+ });
34
+ }
35
+
36
+ const email = {
37
+ to: to,
38
+ subject: `Strapi test mail to: ${to}`,
39
+ text: `Great! You have correctly configured the Strapi email plugin with the ${strapi.plugins.email.config.provider} provider. \r\nFor documentation on how to use the email plugin checkout: https://strapi.akemona.com/documentation/developer-docs/latest/development/plugins/email.html`,
40
+ };
41
+
42
+ try {
43
+ await strapi.plugins.email.services.email.send(email);
44
+ } catch (e) {
45
+ if (e.statusCode === 400) {
46
+ return ctx.badRequest(e.message);
47
+ } else {
48
+ throw new Error(`Couldn't send test email: ${e.message}.`);
49
+ }
50
+ }
51
+
52
+ // Send 200 `ok`
53
+ ctx.send({});
54
+ },
55
+
56
+ async getSettings(ctx) {
57
+ const config = strapi.plugins.email.services.email.getProviderSettings();
58
+
59
+ ctx.send({
60
+ config: pick(
61
+ ['provider', 'settings.defaultFrom', 'settings.defaultReplyTo', 'settings.testAddress'],
62
+ config
63
+ ),
64
+ });
65
+ },
66
+ };
@@ -0,0 +1,67 @@
1
+ {
2
+ "paths": {
3
+ "/email/": {
4
+ "post": {
5
+ "deprecated": false,
6
+ "description": "Send an email",
7
+ "requestBody": {
8
+ "content": {
9
+ "application/json": {
10
+ "schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "from": {
14
+ "type": "string",
15
+ "format": "email"
16
+ },
17
+ "to": {
18
+ "type": "string",
19
+ "format": "email",
20
+ "example": "user1@example.com"
21
+ },
22
+ "cc": {
23
+ "type": "string",
24
+ "format": "email",
25
+ "example": "user2@example.com"
26
+ },
27
+ "bcc": {
28
+ "type": "string",
29
+ "format": "email",
30
+ "example": "user3@example.com"
31
+ },
32
+ "replyTo": {
33
+ "type": "string",
34
+ "format": "email",
35
+ "example": "user4@example.com"
36
+ },
37
+ "subject": {
38
+ "type": "string",
39
+ "example": "Lorem ipsum title"
40
+ },
41
+ "text": {
42
+ "type": "string",
43
+ "example": "Lorem ipsum"
44
+ },
45
+ "html": {
46
+ "type": "string",
47
+ "format": "html",
48
+ "example": "<h1>Lorem ipsum</h1>"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ },
55
+ "summary": "",
56
+ "tags": [
57
+ "Email"
58
+ ]
59
+ }
60
+ }
61
+ },
62
+ "tags": [
63
+ {
64
+ "name": "Email"
65
+ }
66
+ ]
67
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@akemona-org/strapi-plugin-email",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "3.7.0",
7
+ "description": "Easily configure your Strapi application to send emails.",
8
+ "strapi": {
9
+ "name": "Email",
10
+ "icon": "paper-plane",
11
+ "description": "email.plugin.description",
12
+ "required": true
13
+ },
14
+ "scripts": {
15
+ "test": "echo \"no tests yet\""
16
+ },
17
+ "dependencies": {
18
+ "@akemona-org/strapi-provider-email-sendmail": "3.7.0",
19
+ "@akemona-org/strapi-utils": "3.7.0",
20
+ "lodash": "4.17.21"
21
+ },
22
+ "devDependencies": {
23
+ "@akemona-org/strapi-helper-plugin": "3.7.0",
24
+ "rimraf": "3.0.2"
25
+ },
26
+ "author": {
27
+ "name": "Akemona team",
28
+ "email": "strapi@akemona.com",
29
+ "url": "https://strapi.akemona.com"
30
+ },
31
+ "maintainers": [
32
+ {
33
+ "name": "Akemona team",
34
+ "email": "strapi@akemona.com",
35
+ "url": "https://strapi.akemona.com"
36
+ }
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git://github.com/akemona/strapi.git"
41
+ },
42
+ "engines": {
43
+ "node": ">=10.16.0 <=14.x.x",
44
+ "npm": ">=6.0.0"
45
+ },
46
+ "license": "SEE LICENSE IN LICENSE",
47
+ "gitHead": "129a8d6191b55810fd66448dcc47fee829df986c"
48
+ }
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+
5
+ const getProviderSettings = () => {
6
+ return strapi.plugins.email.config;
7
+ };
8
+
9
+ const send = async options => {
10
+ return strapi.plugins.email.provider.send(options);
11
+ };
12
+
13
+ /**
14
+ * fill subject, text and html using lodash template
15
+ * @param {object} emailOptions - to, from and replyto...
16
+ * @param {object} emailTemplate - object containing attributes to fill
17
+ * @param {object} data - data used to fill the template
18
+ * @returns {{ subject, text, subject }}
19
+ */
20
+ const sendTemplatedEmail = (emailOptions = {}, emailTemplate = {}, data = {}) => {
21
+ const attributes = ['subject', 'text', 'html'];
22
+ const missingAttributes = _.difference(attributes, Object.keys(emailTemplate));
23
+ if (missingAttributes.length > 0) {
24
+ throw new Error(
25
+ `Following attributes are missing from your email template : ${missingAttributes.join(', ')}`
26
+ );
27
+ }
28
+
29
+ const templatedAttributes = attributes.reduce(
30
+ (compiled, attribute) =>
31
+ emailTemplate[attribute]
32
+ ? Object.assign(compiled, { [attribute]: _.template(emailTemplate[attribute])(data) })
33
+ : compiled,
34
+ {}
35
+ );
36
+
37
+ return strapi.plugins.email.provider.send({ ...emailOptions, ...templatedAttributes });
38
+ };
39
+
40
+ module.exports = {
41
+ getProviderSettings,
42
+ send,
43
+ sendTemplatedEmail,
44
+ };