mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-16 16:30:15 +01:00
📧 feat: Allow usage of custom SMTP server (#1219)
Co-authored-by: David Reis <post@d-reis.com>
This commit is contained in:
parent
3838ff4617
commit
ae03267d9b
5 changed files with 155 additions and 85 deletions
22
.env.example
22
.env.example
|
|
@ -151,6 +151,9 @@ DEBUG_OPENAI=false # Set to true to enable debug mode for the OpenAI endpoint
|
|||
# https://github.com/spdustin/ChatGPT-AutoExpert/blob/main/_system-prompts/dall-e.md
|
||||
# DALLE3_SYSTEM_PROMPT="Your System Prompt here"
|
||||
|
||||
# OpenAI API key for DALL-E / DALL-E-3. Set to user_provided to have the user provide their own key when installing the pluigin.
|
||||
# DALLE_API_KEY=user_provided
|
||||
|
||||
# (Advanced) DALL-E Proxy settings
|
||||
# This is separate from its OpenAI counterpart for customization purposes
|
||||
|
||||
|
|
@ -451,9 +454,16 @@ DOMAIN_SERVER=http://localhost:3080
|
|||
# Email
|
||||
###########################
|
||||
|
||||
# Email is used for password reset. Note that all 4 values must be set for email to work.
|
||||
# Failing to set the 4 values will result in LibreChat using the unsecured password reset!
|
||||
EMAIL_SERVICE= # eg. gmail
|
||||
EMAIL_USERNAME= # eg. your email address if using gmail
|
||||
EMAIL_PASSWORD= # eg. this is the "app password" if using gmail
|
||||
EMAIL_FROM=noreply@librechat.ai # email address for from field, it is required to set a value here even in the cases where it's not porperly working.
|
||||
# Email is used for password reset. Note that all either service or host, username and password and the From address must be set for email to work.
|
||||
# Do NOT set the extended connection parameters (HOST, PORT, ENCRYPTION, ENCRYPTION_HOSTNAME, ALLOW_SELFSIGNED) if using EMAIL_SERVICE.
|
||||
# Failing to set valid values here will result in LibreChat using the unsecured password reset!
|
||||
EMAIL_SERVICE= # eg. gmail - see https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/
|
||||
EMAIL_HOST= # eg. example.com - if EMAIL_SERVICE is not set, connect to this server.
|
||||
EMAIL_PORT=25 # eg. 25 - mail server port to connect to with EMAIL_HOST (usually 25, 465, 587)
|
||||
EMAIL_ENCRYPTION= # eg. starttls - valid values: starttls (force STARTTLS), tls (obligatory TLS), anything else (use STARTTLS if available)
|
||||
EMAIL_ENCRYPTION_HOSTNAME= # eg. example.com - check the name in the certificate against this instead of EMAIL_HOST
|
||||
EMAIL_ALLOW_SELFSIGNED= # eg. true - valid values: true (allow self-signed), anything else (disallow self-signed)
|
||||
EMAIL_USERNAME= # eg. me@gmail.com - the username used for authentication. For consumer services, this MUST usually match EMAIL_FROM.
|
||||
EMAIL_PASSWORD= # eg. password - the password used for authentication
|
||||
EMAIL_FROM_NAME= # eg. LibreChat - the human-readable address in the From is constructed as "EMAIL_FROM_NAME <EMAIL_FROM>". Defaults to APP_TITLE.
|
||||
EMAIL_FROM=noreply@librechat.ai # eg. noreply@librechat.ai - mail address for from field. It is REQUIRED to set a value here even in if it's not porperly working!
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ router.get('/', async function (req, res) {
|
|||
registrationEnabled: isEnabled(process.env.ALLOW_REGISTRATION),
|
||||
socialLoginEnabled: isEnabled(process.env.ALLOW_SOCIAL_LOGIN),
|
||||
emailEnabled:
|
||||
!process.env.EMAIL_SERVICE &&
|
||||
(!!process.env.EMAIL_SERVICE || !!process.env.EMAIL_HOST) &&
|
||||
!!process.env.EMAIL_USERNAME &&
|
||||
!!process.env.EMAIL_PASSWORD &&
|
||||
!!process.env.EMAIL_FROM,
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ const requestPasswordReset = async (email) => {
|
|||
const link = `${domains.client}/reset-password?token=${resetToken}&userId=${user._id}`;
|
||||
|
||||
const emailEnabled =
|
||||
!!process.env.EMAIL_SERVICE &&
|
||||
(!!process.env.EMAIL_SERVICE || !!process.env.EMAIL_HOST) &&
|
||||
!!process.env.EMAIL_USERNAME &&
|
||||
!!process.env.EMAIL_PASSWORD &&
|
||||
!!process.env.EMAIL_FROM;
|
||||
|
|
|
|||
|
|
@ -5,20 +5,50 @@ const path = require('path');
|
|||
|
||||
const sendEmail = async (email, subject, payload, template) => {
|
||||
try {
|
||||
const transporter = nodemailer.createTransport({
|
||||
service: process.env.EMAIL_SERVICE,
|
||||
const transporterOptions = {
|
||||
// Use STARTTLS by default instead of obligatory TLS
|
||||
secure: process.env.EMAIL_ENCRYPTION === "tls",
|
||||
// If explicit STARTTLS is set, require it when connecting
|
||||
requireTls: process.env.EMAIL_ENCRYPTION === "starttls",
|
||||
tls: {
|
||||
// Whether to accept unsigned certificates
|
||||
rejectUnauthorized: process.env.EMAIL_ALLOW_SELFSIGNED === "true"
|
||||
},
|
||||
auth: {
|
||||
user: process.env.EMAIL_USERNAME,
|
||||
pass: process.env.EMAIL_PASSWORD,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (process.env.EMAIL_ENCRYPTION_HOSTNAME) {
|
||||
// Check the certificate against this name explicitly
|
||||
transporterOptions.tls.servername = process.env.EMAIL_ENCRYPTION_HOSTNAME;
|
||||
}
|
||||
|
||||
// Mailer service definition has precedence
|
||||
if (process.env.EMAIL_SERVICE) {
|
||||
transporterOptions.service = process.env.EMAIL_SERVICE;
|
||||
} else {
|
||||
transporterOptions.host = process.env.EMAIL_HOST;
|
||||
transporterOptions.port = process.env.EMAIL_PORT ?? 25;
|
||||
}
|
||||
|
||||
const transporter = nodemailer.createTransport(transporterOptions);
|
||||
|
||||
const source = fs.readFileSync(path.join(__dirname, 'emails', template), 'utf8');
|
||||
const compiledTemplate = handlebars.compile(source);
|
||||
const options = () => {
|
||||
return {
|
||||
from: process.env.EMAIL_FROM,
|
||||
to: email,
|
||||
// Header address should contain name-addr
|
||||
from: `"${process.env.EMAIL_FROM_NAME || process.env.APP_TITLE}"` +
|
||||
`<${process.env.EMAIL_FROM}>`,
|
||||
to: `"${payload.name}" <${email}>`,
|
||||
envelope: {
|
||||
// Envelope from should contain addr-spec
|
||||
// Mistake in the Nodemailer documentation?
|
||||
from: process.env.EMAIL_FROM,
|
||||
to: email,
|
||||
},
|
||||
subject: subject,
|
||||
html: compiledTemplate(payload),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -173,19 +173,37 @@ DISCORD_CALLBACK_URL=/oauth/discord/callback # this should be the same for every
|
|||
|
||||
### General setup
|
||||
|
||||
in the .env file modify this 4 variables:
|
||||
in the .env file modify these variables:
|
||||
|
||||
```
|
||||
EMAIL_SERVICE= # eg. gmail
|
||||
EMAIL_USERNAME= # eg. your email address if using gmail
|
||||
EMAIL_PASSWORD= # eg. this is the "app password" if using gmail
|
||||
EMAIL_FROM= # eg. email address for from field like noreply@librechat.ai
|
||||
EMAIL_SERVICE= # eg. gmail - see https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/
|
||||
EMAIL_HOST= # eg. example.com - if EMAIL_SERVICE is not set, connect to this server.
|
||||
EMAIL_PORT=25 # eg. 25 - mail server port to connect to with EMAIL_HOST (usually 25, 465, 587)
|
||||
EMAIL_ENCRYPTION= # eg. starttls - valid values: starttls (force STARTTLS), tls (obligatory TLS), anything else (use STARTTLS if available)
|
||||
EMAIL_ENCRYPTION_HOSTNAME= # eg. example.com - check the name in the certificate against this instead of EMAIL_HOST
|
||||
EMAIL_ALLOW_SELFSIGNED= # eg. true - valid values: true (allow self-signed), anything else (disallow self-signed)
|
||||
EMAIL_USERNAME= # eg. me@gmail.com - the username used for authentication. For consumer services, this MUST usually match EMAIL_FROM.
|
||||
EMAIL_PASSWORD= # eg. password - the password used for authentication
|
||||
EMAIL_FROM_NAME= # eg. LibreChat - the human-readable address in the From is constructed as "EMAIL_FROM_NAME <EMAIL_FROM>". Defaults to APP_TITLE.
|
||||
```
|
||||
|
||||
EMAIL_SERVICE is the name of the email service you are using (Gmail, Outlook, Yahoo Mail, ProtonMail, iCloud Mail, etc.).
|
||||
EMAIL_USERNAME is the username of the email service (usually, it will be the email address, but in some cases, it can be an actual username used to access the account).
|
||||
EMAIL_PASSWORD is the password used to access the email service. This is not the password to access the email account directly, but a password specifically generated for this service.
|
||||
EMAIL_FROM is the email address that will appear in the "from" field when a user receives an email.
|
||||
If you want to use one of the predefined services, configure only these variables:
|
||||
|
||||
EMAIL\_SERVICE is the name of the email service you are using (Gmail, Outlook, Yahoo Mail, ProtonMail, iCloud Mail, etc.) as defined in the NodeMailer well-known services linked above.
|
||||
EMAIL\_USERNAME is the username of the email service (usually, it will be the email address, but in some cases, it can be an actual username used to access the account).
|
||||
EMAIL\_PASSWORD is the password used to access the email service. This is not the password to access the email account directly, but a password specifically generated for this service.
|
||||
EMAIL\_FROM is the email address that will appear in the "from" field when a user receives an email.
|
||||
EMAIL\_FROM\_NAME is the name that will appear in the "from" field when a user receives an email. If left unset, it defaults to the app title.
|
||||
|
||||
If you want to use a generic SMTP service or need advanced configuration for one of the predefined providers, configure these variables:
|
||||
|
||||
EMAIL\_HOST is the hostname to connect to, or an IP address.
|
||||
EMAIL\_PORT is the port to connect to. Be aware that different ports usually come with different requirements - 25 is for mailserver-to-mailserver, 465 requires encryption at the start of the connection, and 587 allows submission of mail as a user.
|
||||
EMAIL\_ENCRYPTION defines if encryption is required at the start (`tls`) or started after the connection is set up (`starttls`). If either of these values are set, they are enforced. If they are not set, an encrypted connection is started if available.
|
||||
EMAIL\_ENCRYPTION\_HOSTNAME allows specification of a hostname against which the certificate is validated. Use this if the mail server does have a valid certificate, but you are connecting with an IP or a different name for some reason.
|
||||
EMAIL\_ALLOW\_SELFSIGNED defines whether self-signed certificates can be accepted from the server. As the mails being sent contain sensitive information, ONLY use this for testing.
|
||||
|
||||
NOTE: ⚠️ **Failing to perform either of the below setups will result in LibreChat using the unsecured password reset! This allows anyone to reset any password on your server immediately, without mail being sent at all!** The variable EMAIL\_FROM does not support all email providers **but is still required**. To stay updated, check the bug fixes [here](https://github.com/danny-avila/LibreChat/tags).
|
||||
|
||||
### Setup with Gmail
|
||||
|
||||
|
|
@ -200,11 +218,23 @@ EMAIL_SERVICE=gmail
|
|||
EMAIL_USERNAME=your-email
|
||||
EMAIL_PASSWORD=your-app-password
|
||||
EMAIL_FROM=email address for the from field, e.g., noreply@librechat.ai
|
||||
EMAIL_FROM_NAME="My LibreChat Server"
|
||||
```
|
||||
|
||||
NOTE: ⚠️ **Failing to set the 4 values will result in LibreChat using the unsecured password reset!** The variable EMAIL_FROM does not support all email providers **but is still required**. To stay updated, check the bug fixes [here](https://github.com/danny-avila/LibreChat/tags).
|
||||
### Setup with custom mail server
|
||||
|
||||
1. Gather your SMTP login data from your provider. The steps are different for each, but they will usually list values for all variables.
|
||||
2. In the .env file, modify the variables as follows, assuming some sensible example values:
|
||||
|
||||
```
|
||||
EMAIL_HOST=mail.example.com
|
||||
EMAIL_PORT=587
|
||||
EMAIL_ENCRYPTION=starttls
|
||||
EMAIL_USERNAME=your-email
|
||||
EMAIL_PASSWORD=your-app-password
|
||||
EMAIL_FROM=email address for the from field, e.g., noreply@librechat.ai
|
||||
EMAIL_FROM_NAME="My LibreChat Server"
|
||||
```
|
||||
|
||||
## **Disable User Registration**
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue