mirror of
https://github.com/immich-app/immich.git
synced 2025-11-02 21:27:39 +09:00
feat(server): Option to configure SMTPS transport (#22833)
* feat(server): Option to configure SMTPS transport This commit adds a boolean option in the SMTP transport configuration to enable the so-called "secure" mode. What it does is use SMTP over TLS instead of relying on the more common STARTTLS option over plain SMTP. * Add missing field in dto * Add missing field * Use a switch instead of text field * Add field in spec * chore: regen open-api --------- Co-authored-by: Jason Rasmussen <jason@rasm.me>
This commit is contained in:
@@ -211,6 +211,8 @@
|
|||||||
"notification_email_ignore_certificate_errors_description": "Ignore TLS certificate validation errors (not recommended)",
|
"notification_email_ignore_certificate_errors_description": "Ignore TLS certificate validation errors (not recommended)",
|
||||||
"notification_email_password_description": "Password to use when authenticating with the email server",
|
"notification_email_password_description": "Password to use when authenticating with the email server",
|
||||||
"notification_email_port_description": "Port of the email server (e.g 25, 465, or 587)",
|
"notification_email_port_description": "Port of the email server (e.g 25, 465, or 587)",
|
||||||
|
"notification_email_secure": "SMTPS",
|
||||||
|
"notification_email_secure_description": "Use SMTPS (SMTP over TLS)",
|
||||||
"notification_email_sent_test_email_button": "Send test email and save",
|
"notification_email_sent_test_email_button": "Send test email and save",
|
||||||
"notification_email_setting_description": "Settings for sending email notifications",
|
"notification_email_setting_description": "Settings for sending email notifications",
|
||||||
"notification_email_test_email": "Send test email",
|
"notification_email_test_email": "Send test email",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class SystemConfigSmtpTransportDto {
|
|||||||
required this.ignoreCert,
|
required this.ignoreCert,
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.port,
|
required this.port,
|
||||||
|
required this.secure,
|
||||||
required this.username,
|
required this.username,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ class SystemConfigSmtpTransportDto {
|
|||||||
/// Maximum value: 65535
|
/// Maximum value: 65535
|
||||||
num port;
|
num port;
|
||||||
|
|
||||||
|
bool secure;
|
||||||
|
|
||||||
String username;
|
String username;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -38,6 +41,7 @@ class SystemConfigSmtpTransportDto {
|
|||||||
other.ignoreCert == ignoreCert &&
|
other.ignoreCert == ignoreCert &&
|
||||||
other.password == password &&
|
other.password == password &&
|
||||||
other.port == port &&
|
other.port == port &&
|
||||||
|
other.secure == secure &&
|
||||||
other.username == username;
|
other.username == username;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -47,10 +51,11 @@ class SystemConfigSmtpTransportDto {
|
|||||||
(ignoreCert.hashCode) +
|
(ignoreCert.hashCode) +
|
||||||
(password.hashCode) +
|
(password.hashCode) +
|
||||||
(port.hashCode) +
|
(port.hashCode) +
|
||||||
|
(secure.hashCode) +
|
||||||
(username.hashCode);
|
(username.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SystemConfigSmtpTransportDto[host=$host, ignoreCert=$ignoreCert, password=$password, port=$port, username=$username]';
|
String toString() => 'SystemConfigSmtpTransportDto[host=$host, ignoreCert=$ignoreCert, password=$password, port=$port, secure=$secure, username=$username]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -58,6 +63,7 @@ class SystemConfigSmtpTransportDto {
|
|||||||
json[r'ignoreCert'] = this.ignoreCert;
|
json[r'ignoreCert'] = this.ignoreCert;
|
||||||
json[r'password'] = this.password;
|
json[r'password'] = this.password;
|
||||||
json[r'port'] = this.port;
|
json[r'port'] = this.port;
|
||||||
|
json[r'secure'] = this.secure;
|
||||||
json[r'username'] = this.username;
|
json[r'username'] = this.username;
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
@@ -75,6 +81,7 @@ class SystemConfigSmtpTransportDto {
|
|||||||
ignoreCert: mapValueOfType<bool>(json, r'ignoreCert')!,
|
ignoreCert: mapValueOfType<bool>(json, r'ignoreCert')!,
|
||||||
password: mapValueOfType<String>(json, r'password')!,
|
password: mapValueOfType<String>(json, r'password')!,
|
||||||
port: num.parse('${json[r'port']}'),
|
port: num.parse('${json[r'port']}'),
|
||||||
|
secure: mapValueOfType<bool>(json, r'secure')!,
|
||||||
username: mapValueOfType<String>(json, r'username')!,
|
username: mapValueOfType<String>(json, r'username')!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -127,6 +134,7 @@ class SystemConfigSmtpTransportDto {
|
|||||||
'ignoreCert',
|
'ignoreCert',
|
||||||
'password',
|
'password',
|
||||||
'port',
|
'port',
|
||||||
|
'secure',
|
||||||
'username',
|
'username',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16726,6 +16726,9 @@
|
|||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
|
"secure": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -16735,6 +16738,7 @@
|
|||||||
"ignoreCert",
|
"ignoreCert",
|
||||||
"password",
|
"password",
|
||||||
"port",
|
"port",
|
||||||
|
"secure",
|
||||||
"username"
|
"username"
|
||||||
],
|
],
|
||||||
"type": "object"
|
"type": "object"
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export type SystemConfigSmtpTransportDto = {
|
|||||||
ignoreCert: boolean;
|
ignoreCert: boolean;
|
||||||
password: string;
|
password: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
secure: boolean;
|
||||||
username: string;
|
username: string;
|
||||||
};
|
};
|
||||||
export type SystemConfigSmtpDto = {
|
export type SystemConfigSmtpDto = {
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ export interface SystemConfig {
|
|||||||
ignoreCert: boolean;
|
ignoreCert: boolean;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
|
secure: boolean;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
};
|
};
|
||||||
@@ -356,6 +357,7 @@ export const defaults = Object.freeze<SystemConfig>({
|
|||||||
ignoreCert: false,
|
ignoreCert: false,
|
||||||
host: '',
|
host: '',
|
||||||
port: 587,
|
port: 587,
|
||||||
|
secure: false,
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -463,6 +463,9 @@ class SystemConfigSmtpTransportDto {
|
|||||||
@Max(65_535)
|
@Max(65_535)
|
||||||
port!: number;
|
port!: number;
|
||||||
|
|
||||||
|
@ValidateBoolean()
|
||||||
|
secure!: boolean;
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
username!: string;
|
username!: string;
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export type SendEmailOptions = {
|
|||||||
export type SmtpOptions = {
|
export type SmtpOptions = {
|
||||||
host: string;
|
host: string;
|
||||||
port?: number;
|
port?: number;
|
||||||
|
secure?: boolean;
|
||||||
username?: string;
|
username?: string;
|
||||||
password?: string;
|
password?: string;
|
||||||
ignoreCert?: boolean;
|
ignoreCert?: boolean;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const smtpTransport = Object.freeze<SystemConfig>({
|
|||||||
ignoreCert: false,
|
ignoreCert: false,
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 587,
|
port: 587,
|
||||||
|
secure: false,
|
||||||
username: 'test',
|
username: 'test',
|
||||||
password: 'test',
|
password: 'test',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ const configs = {
|
|||||||
ignoreCert: false,
|
ignoreCert: false,
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: 587,
|
port: 587,
|
||||||
|
secure: false,
|
||||||
username: 'test',
|
username: 'test',
|
||||||
password: 'test',
|
password: 'test',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
|||||||
transport: {
|
transport: {
|
||||||
host: '',
|
host: '',
|
||||||
port: 587,
|
port: 587,
|
||||||
|
secure: false,
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
ignoreCert: false,
|
ignoreCert: false,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
transport: {
|
transport: {
|
||||||
host: config.notifications.smtp.transport.host,
|
host: config.notifications.smtp.transport.host,
|
||||||
port: config.notifications.smtp.transport.port,
|
port: config.notifications.smtp.transport.port,
|
||||||
|
secure: config.notifications.smtp.transport.secure,
|
||||||
username: config.notifications.smtp.transport.username,
|
username: config.notifications.smtp.transport.username,
|
||||||
password: config.notifications.smtp.transport.password,
|
password: config.notifications.smtp.transport.password,
|
||||||
ignoreCert: config.notifications.smtp.transport.ignoreCert,
|
ignoreCert: config.notifications.smtp.transport.ignoreCert,
|
||||||
@@ -128,6 +129,13 @@
|
|||||||
savedConfig.notifications.smtp.transport.password}
|
savedConfig.notifications.smtp.transport.password}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<SettingSwitch
|
||||||
|
title={$t('admin.notification_email_secure')}
|
||||||
|
subtitle={$t('admin.notification_email_secure_description')}
|
||||||
|
disabled={disabled || !config.notifications.smtp.enabled}
|
||||||
|
bind:checked={config.notifications.smtp.transport.secure}
|
||||||
|
/>
|
||||||
|
|
||||||
<SettingSwitch
|
<SettingSwitch
|
||||||
title={$t('admin.notification_email_ignore_certificate_errors')}
|
title={$t('admin.notification_email_ignore_certificate_errors')}
|
||||||
subtitle={$t('admin.notification_email_ignore_certificate_errors_description')}
|
subtitle={$t('admin.notification_email_ignore_certificate_errors_description')}
|
||||||
|
|||||||
Reference in New Issue
Block a user