mirror of
https://github.com/strapi/strapi.git
synced 2025-12-28 15:44:59 +00:00
add the possibility to edit the template for the forgot password email
Signed-off-by: Pierre Noël <petersg83@gmail.com>
This commit is contained in:
parent
bfadebdf2c
commit
e000432027
@ -223,6 +223,7 @@ module.exports = {
|
||||
'/v3.x/admin-panel/customization',
|
||||
'/v3.x/admin-panel/custom-webpack-config',
|
||||
'/v3.x/admin-panel/deploy',
|
||||
'/v3.x/admin-panel/forgot-password',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
48
docs/v3.x/admin-panel/forgot-password.md
Normal file
48
docs/v3.x/admin-panel/forgot-password.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Forgot Password Email
|
||||
|
||||
## Customize forgot password email
|
||||
|
||||
You may want to customize the forgot password email.
|
||||
You can do it by providing your own template (formatted as a [lodash template](https://lodash.com/docs/4.17.15#template)).
|
||||
|
||||
The template will be compiled with the following variables: `url`, `user.email`, `user.username`, `user.firstname`, `user.lastname`.
|
||||
|
||||
### Example
|
||||
|
||||
**Path -** `./config/servers.js`
|
||||
|
||||
```js
|
||||
const forgotPasswordTemplate = require('./email-templates/forgot-password');
|
||||
|
||||
module.exports = ({ env }) => ({
|
||||
// ...
|
||||
admin: {
|
||||
// ...
|
||||
forgotPassword: {
|
||||
from: 'support@mywebsite.fr',
|
||||
replyTo: 'support@mywebsite.fr',
|
||||
emailTemplate: forgotPasswordTemplate,
|
||||
},
|
||||
// ...
|
||||
},
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
**Path -** `./config/email-templates/forgot-password.js`
|
||||
|
||||
```js
|
||||
const subject = `Reset password`;
|
||||
|
||||
const html = `<p>Hi <%= user.firstname %></p>
|
||||
<p>Sorry you lost your password. You can click here to reset it: <%= url %></p>`;
|
||||
|
||||
const text = `Hi <%= user.firstname %>
|
||||
Sorry you lost your password. You can click here to reset it: <%= url %>`;
|
||||
|
||||
module.exports = {
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
};
|
||||
```
|
||||
@ -167,22 +167,25 @@ module.exports = ({ env }) => ({
|
||||
```
|
||||
|
||||
**Available options**
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | ----------- |
|
||||
| `host` | Host name | string | `localhost` |
|
||||
| `port` | Port on which the server should be running. | integer | `1337` |
|
||||
| `emitErrors` | Enable errors to be emitted to `koa` when they happen in order to attach custom logic or use error reporting services. | boolean | `false` |
|
||||
| `url` | Url of the server. Enable proxy support such as Apache or Nginx, example: `https://mywebsite.com/api`. The url can be relative, if so, it is used with `http://${host}:${port}` as the base url. | string | `''` |
|
||||
| `cron` | Cron configuration (powered by [`node-schedule`](https://github.com/node-schedule/node-schedule)) | Object | |
|
||||
| `cron.enabled` | Enable or disable CRON tasks to schedule jobs at specific dates. | boolean | `false` |
|
||||
| `admin` | Admin panel configuration | Object | |
|
||||
| `admin.url` | Url of your admin panel. Default value: `/admin`. Note: If the url is relative, it will be concatenated with `url`. | string | `/admin` |
|
||||
| `admin.autoOpen` | Enable or disabled administration opening on start. | boolean | `true` |
|
||||
| `admin.watchIgnoreFiles` | Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). | Array(string) | `[]` |
|
||||
| `admin.host` | Use a different host for the admin panel. Only used along with `strapi develop --watch-admin` | string | `localhost` |
|
||||
| `admin.port` | Use a different port for the admin panel. Only used along with `strapi develop --watch-admin` | string | `8000` |
|
||||
| `admin.serveAdminPanel` | If false, the admin panel won't be served. Note: the `index.html` will still be served, see [defaultIndex option](./middlewares#global-middlewares) | boolean | `true` |
|
||||
| Property | Description | Type | Default |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `host` | Host name | string | `localhost` |
|
||||
| `port` | Port on which the server should be running. | integer | `1337` |
|
||||
| `emitErrors` | Enable errors to be emitted to `koa` when they happen in order to attach custom logic or use error reporting services. | boolean | `false` |
|
||||
| `url` | Url of the server. Enable proxy support such as Apache or Nginx, example: `https://mywebsite.com/api`. The url can be relative, if so, it is used with `http://${host}:${port}` as the base url. | string | `''` |
|
||||
| `cron` | Cron configuration (powered by [`node-schedule`](https://github.com/node-schedule/node-schedule)) | Object | |
|
||||
| `cron.enabled` | Enable or disable CRON tasks to schedule jobs at specific dates. | boolean | `false` |
|
||||
| `admin` | Admin panel configuration | Object | |
|
||||
| `admin.url` | Url of your admin panel. Default value: `/admin`. Note: If the url is relative, it will be concatenated with `url`. | string | `/admin` |
|
||||
| `admin.autoOpen` | Enable or disabled administration opening on start. | boolean | `true` |
|
||||
| `admin.watchIgnoreFiles` | Add custom files that should not be watched during development. See more [here](https://github.com/paulmillr/chokidar#path-filtering) (property `ignored`). | Array(string) | `[]` |
|
||||
| `admin.host` | Use a different host for the admin panel. Only used along with `strapi develop --watch-admin` | string | `localhost` |
|
||||
| `admin.port` | Use a different port for the admin panel. Only used along with `strapi develop --watch-admin` | string | `8000` |
|
||||
| `admin.serveAdminPanel` | If false, the admin panel won't be served. Note: the `index.html` will still be served, see [defaultIndex option](./middlewares#global-middlewares) | boolean | `true` |
|
||||
| `admin.forgotPassword` | Settings to customize the forgot password email (see more here: [Forgot Password Email](../admin-panel/forgot-password)) | Object | {} |
|
||||
| `admin.forgotPassword.emailTemplate` | Email template as defined in [email plugin](../plugins/email#create-an-email-from-a-template-fillemailoptions) | Object | [Default template](https://github.com/strapi/strapi/tree/master/packages/strapi-admin/config/email-templates/forgot-password.js) |
|
||||
| `admin.forgotPassword.from` | Sender mail address | string | Default value defined in your [provider configuration](../plugins/email#configure-your-provider) |
|
||||
| `admin.forgotPassword.replyTo` | Default address or addresses the receiver is asked to reply to | string | Default value defined in your [provider configuration](../plugins/email#configure-your-provider) |
|
||||
|
||||
## Functions
|
||||
|
||||
|
||||
@ -4,9 +4,13 @@ Thanks to the plugin `Email`, you can send email from your server or externals p
|
||||
|
||||
## Programmatic usage
|
||||
|
||||
### Send an email - `.send()`
|
||||
|
||||
In your custom controllers or services you may want to send email.
|
||||
By using the following function, Strapi will use the configured provider to send an email.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
await strapi.plugins['email'].services.email.send({
|
||||
to: 'paulbocuse@strapi.io',
|
||||
@ -20,6 +24,40 @@ await strapi.plugins['email'].services.email.send({
|
||||
});
|
||||
```
|
||||
|
||||
### Send an email using a template - `.sendTemplatedEmail()`
|
||||
|
||||
When you send an email, you will most likely want to build it from a template you wrote.
|
||||
The email plugin provides the service `sendTemplatedEmail` that compile the email and then sends it. The function have the following params:
|
||||
|
||||
| param | description | type | default |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------ | ------ | ------- |
|
||||
| `emailOptions` | Object that contains email options (`to`, `from`, `replyTo`, `cc`, `bcc`) except `subject`, `text` and `html` | object | `{}` |
|
||||
| `emailTemplate` | Object that contains `subject`, `text` and `html` as [lodash string templates](https://lodash.com/docs/4.17.15#template) | object | `{}` |
|
||||
| `data` | Object that contains the data used to compile the templates | object | `{}` |
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
const emailTemplate = {
|
||||
subject: 'Welcome <%= user.firstname %>',
|
||||
text: `Welcome on mywebsite.fr!
|
||||
Your account is now linked with: <%= user.email %>.`,
|
||||
html: `<h1>Welcome on mywebsite.fr!</h1>
|
||||
<p>Your account is now linked with: <%= user.email %>.<p>`,
|
||||
},
|
||||
|
||||
await strapi.plugins.email.services.email.sendTemplatedEmail(
|
||||
{
|
||||
to: user.email,
|
||||
// from: is not specified, so it's the defaultFrom that will be used instead
|
||||
},
|
||||
emailTemplate,
|
||||
{
|
||||
user: _.pick(user, ['username', 'email', 'firstname', 'lastname']),
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
## Configure the plugin
|
||||
|
||||
### Install the provider you want
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
const subject = `Reset password`;
|
||||
|
||||
const html = `<p>We heard that you lost your password. Sorry about that!</p>
|
||||
|
||||
<p>But don’t worry! You can use the following link to reset your password:</p>
|
||||
|
||||
<p><%= url %></p>
|
||||
|
||||
<p>Thanks.</p>`;
|
||||
|
||||
const text = `We heard that you lost your password. Sorry about that!
|
||||
|
||||
But don’t worry! You can use the following link to reset your password:
|
||||
|
||||
<%= url %>
|
||||
|
||||
Thanks.`;
|
||||
|
||||
module.exports = {
|
||||
subject,
|
||||
text,
|
||||
html,
|
||||
};
|
||||
7
packages/strapi-admin/config/settings.js
Normal file
7
packages/strapi-admin/config/settings.js
Normal file
@ -0,0 +1,7 @@
|
||||
const forgotPasswordTemplate = require('./email-templates/forgot-password');
|
||||
|
||||
module.exports = {
|
||||
forgotPassword: {
|
||||
emailTemplate: forgotPasswordTemplate,
|
||||
},
|
||||
};
|
||||
@ -1,6 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const bcrypt = require('bcryptjs');
|
||||
const _ = require('lodash');
|
||||
const { getAbsoluteAdminUrl } = require('strapi-utils');
|
||||
|
||||
/**
|
||||
* hashes a password
|
||||
@ -43,15 +45,6 @@ const checkCredentials = async ({ email, password }) => {
|
||||
return [null, user];
|
||||
};
|
||||
|
||||
const resetEmailTemplate = url => `
|
||||
<p>We heard that you lost your password. Sorry about that!</p>
|
||||
|
||||
<p>But don’t worry! You can use the following link to reset your password:</p>
|
||||
|
||||
<p>${url}</p>
|
||||
|
||||
<p>Thanks.</p>`;
|
||||
|
||||
/**
|
||||
* Send an email to the user if it exists or do nothing
|
||||
* @param {Object} param params
|
||||
@ -67,17 +60,23 @@ const forgotPassword = async ({ email } = {}) => {
|
||||
const resetPasswordToken = strapi.admin.services.token.createToken();
|
||||
await strapi.admin.services.user.updateById(user.id, { resetPasswordToken });
|
||||
|
||||
const url = `${strapi.config.admin.url}/auth/reset-password?code=${resetPasswordToken}`;
|
||||
const body = resetEmailTemplate(url);
|
||||
|
||||
// Send an email to the admin.
|
||||
return strapi.plugins['email'].services.email
|
||||
.send({
|
||||
to: user.email,
|
||||
subject: 'Reset password',
|
||||
text: body,
|
||||
html: body,
|
||||
})
|
||||
const url = `${getAbsoluteAdminUrl(
|
||||
strapi.config
|
||||
)}/auth/reset-password?code=${resetPasswordToken}`;
|
||||
return strapi.plugins.email.services.email
|
||||
.sendTemplatedEmail(
|
||||
{
|
||||
to: user.email,
|
||||
from: strapi.config.get('server.admin.forgotPassword', {}).from,
|
||||
replyTo: strapi.config.get('server.admin.forgotPassword', {}).replyTo,
|
||||
},
|
||||
strapi.config.get('server.admin.forgotPassword', {}).emailTemplate,
|
||||
{
|
||||
url,
|
||||
user: _.pick(user, ['email', 'firstname', 'lastname', 'username']),
|
||||
}
|
||||
)
|
||||
.catch(err => {
|
||||
// log error server side but do not disclose it to the user to avoid leaking informations
|
||||
strapi.log.error(err);
|
||||
|
||||
@ -1,12 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const getProviderConfig = () => {
|
||||
return strapi.plugins.email.config;
|
||||
};
|
||||
|
||||
const send = async options => {
|
||||
return strapi.plugins.email.provider.send(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* fill subject, text and html using lodash template
|
||||
* @param {object} emailOptions - to, from and replyto...
|
||||
* @param {object} emailTemplate - object containing attributes to fill
|
||||
* @param {object} data - data used to fill the template
|
||||
* @returns {{ subject, text, subject }}
|
||||
*/
|
||||
const sendTemplatedEmail = (emailOptions = {}, emailTemplate = {}, data = {}) => {
|
||||
const attributes = ['subject', 'text', 'html'];
|
||||
const missingAttributes = _.difference(attributes, Object.keys(emailTemplate));
|
||||
if (missingAttributes.length > 0) {
|
||||
throw new Error(
|
||||
`Following attributes are missing from your email template : ${missingAttributes.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
const templatedAttributes = {};
|
||||
for (let attribute of attributes) {
|
||||
if (emailTemplate[attribute]) {
|
||||
templatedAttributes[attribute] = _.template(emailTemplate[attribute])(data);
|
||||
}
|
||||
}
|
||||
|
||||
return strapi.plugins.email.provider.send({ ...emailOptions, ...templatedAttributes });
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getProviderConfig,
|
||||
async send(options) {
|
||||
return strapi.plugins.email.provider.send(options);
|
||||
},
|
||||
send,
|
||||
sendTemplatedEmail,
|
||||
};
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
const findPackagePath = require('../load/package-path');
|
||||
const loadFiles = require('../load/load-files');
|
||||
const loadConfig = require('../load/load-config-files');
|
||||
@ -8,13 +9,18 @@ const loadConfig = require('../load/load-config-files');
|
||||
const mergeRoutes = (a, b, key) =>
|
||||
_.isArray(a) && _.isArray(b) && key === 'routes' ? a.concat(b) : undefined;
|
||||
|
||||
module.exports = async () => {
|
||||
module.exports = async strapi => {
|
||||
const adminPath = findPackagePath('strapi-admin');
|
||||
const [files, config] = await Promise.all([
|
||||
loadFiles(adminPath, '!(config|node_modules|test|ee|scripts)/*.*(js|json)'),
|
||||
loadConfig(adminPath),
|
||||
]);
|
||||
|
||||
// set admin config in strapi.config.server.admin
|
||||
const userAdminConfig = strapi.config.get('server.admin');
|
||||
strapi.config.set('server.admin', _.merge(config.config, userAdminConfig));
|
||||
|
||||
// load ee files if they exist
|
||||
let eeFiles = {};
|
||||
let eeConfig = {};
|
||||
if (process.env.STRAPI_DISABLE_EE !== 'true') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user