mirror of
				https://github.com/immich-app/immich
				synced 2025-10-17 18:19:27 +00: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:
		
							parent
							
								
									81554e5ad1
								
							
						
					
					
						commit
						95889a69c9
					
				
					 11 changed files with 33 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -211,6 +211,8 @@
 | 
			
		|||
    "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_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_setting_description": "Settings for sending email notifications",
 | 
			
		||||
    "notification_email_test_email": "Send test email",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
    required this.ignoreCert,
 | 
			
		||||
    required this.password,
 | 
			
		||||
    required this.port,
 | 
			
		||||
    required this.secure,
 | 
			
		||||
    required this.username,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,8 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
  /// Maximum value: 65535
 | 
			
		||||
  num port;
 | 
			
		||||
 | 
			
		||||
  bool secure;
 | 
			
		||||
 | 
			
		||||
  String username;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
| 
						 | 
				
			
			@ -38,6 +41,7 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
    other.ignoreCert == ignoreCert &&
 | 
			
		||||
    other.password == password &&
 | 
			
		||||
    other.port == port &&
 | 
			
		||||
    other.secure == secure &&
 | 
			
		||||
    other.username == username;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
| 
						 | 
				
			
			@ -47,10 +51,11 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
    (ignoreCert.hashCode) +
 | 
			
		||||
    (password.hashCode) +
 | 
			
		||||
    (port.hashCode) +
 | 
			
		||||
    (secure.hashCode) +
 | 
			
		||||
    (username.hashCode);
 | 
			
		||||
 | 
			
		||||
  @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() {
 | 
			
		||||
    final json = <String, dynamic>{};
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +63,7 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
      json[r'ignoreCert'] = this.ignoreCert;
 | 
			
		||||
      json[r'password'] = this.password;
 | 
			
		||||
      json[r'port'] = this.port;
 | 
			
		||||
      json[r'secure'] = this.secure;
 | 
			
		||||
      json[r'username'] = this.username;
 | 
			
		||||
    return json;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +81,7 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
        ignoreCert: mapValueOfType<bool>(json, r'ignoreCert')!,
 | 
			
		||||
        password: mapValueOfType<String>(json, r'password')!,
 | 
			
		||||
        port: num.parse('${json[r'port']}'),
 | 
			
		||||
        secure: mapValueOfType<bool>(json, r'secure')!,
 | 
			
		||||
        username: mapValueOfType<String>(json, r'username')!,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -127,6 +134,7 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
    'ignoreCert',
 | 
			
		||||
    'password',
 | 
			
		||||
    'port',
 | 
			
		||||
    'secure',
 | 
			
		||||
    'username',
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16726,6 +16726,9 @@
 | 
			
		|||
            "minimum": 0,
 | 
			
		||||
            "type": "number"
 | 
			
		||||
          },
 | 
			
		||||
          "secure": {
 | 
			
		||||
            "type": "boolean"
 | 
			
		||||
          },
 | 
			
		||||
          "username": {
 | 
			
		||||
            "type": "string"
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -16735,6 +16738,7 @@
 | 
			
		|||
          "ignoreCert",
 | 
			
		||||
          "password",
 | 
			
		||||
          "port",
 | 
			
		||||
          "secure",
 | 
			
		||||
          "username"
 | 
			
		||||
        ],
 | 
			
		||||
        "type": "object"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,6 +71,7 @@ export type SystemConfigSmtpTransportDto = {
 | 
			
		|||
    ignoreCert: boolean;
 | 
			
		||||
    password: string;
 | 
			
		||||
    port: number;
 | 
			
		||||
    secure: boolean;
 | 
			
		||||
    username: string;
 | 
			
		||||
};
 | 
			
		||||
export type SystemConfigSmtpDto = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,6 +159,7 @@ export interface SystemConfig {
 | 
			
		|||
        ignoreCert: boolean;
 | 
			
		||||
        host: string;
 | 
			
		||||
        port: number;
 | 
			
		||||
        secure: boolean;
 | 
			
		||||
        username: string;
 | 
			
		||||
        password: string;
 | 
			
		||||
      };
 | 
			
		||||
| 
						 | 
				
			
			@ -356,6 +357,7 @@ export const defaults = Object.freeze<SystemConfig>({
 | 
			
		|||
        ignoreCert: false,
 | 
			
		||||
        host: '',
 | 
			
		||||
        port: 587,
 | 
			
		||||
        secure: false,
 | 
			
		||||
        username: '',
 | 
			
		||||
        password: '',
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -463,6 +463,9 @@ class SystemConfigSmtpTransportDto {
 | 
			
		|||
  @Max(65_535)
 | 
			
		||||
  port!: number;
 | 
			
		||||
 | 
			
		||||
  @ValidateBoolean()
 | 
			
		||||
  secure!: boolean;
 | 
			
		||||
 | 
			
		||||
  @IsString()
 | 
			
		||||
  username!: string;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ export type SendEmailOptions = {
 | 
			
		|||
export type SmtpOptions = {
 | 
			
		||||
  host: string;
 | 
			
		||||
  port?: number;
 | 
			
		||||
  secure?: boolean;
 | 
			
		||||
  username?: string;
 | 
			
		||||
  password?: string;
 | 
			
		||||
  ignoreCert?: boolean;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ const smtpTransport = Object.freeze<SystemConfig>({
 | 
			
		|||
        ignoreCert: false,
 | 
			
		||||
        host: 'localhost',
 | 
			
		||||
        port: 587,
 | 
			
		||||
        secure: false,
 | 
			
		||||
        username: 'test',
 | 
			
		||||
        password: 'test',
 | 
			
		||||
      },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ const configs = {
 | 
			
		|||
          ignoreCert: false,
 | 
			
		||||
          host: 'localhost',
 | 
			
		||||
          port: 587,
 | 
			
		||||
          secure: false,
 | 
			
		||||
          username: 'test',
 | 
			
		||||
          password: 'test',
 | 
			
		||||
        },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,6 +197,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
 | 
			
		|||
      transport: {
 | 
			
		||||
        host: '',
 | 
			
		||||
        port: 587,
 | 
			
		||||
        secure: false,
 | 
			
		||||
        username: '',
 | 
			
		||||
        password: '',
 | 
			
		||||
        ignoreCert: false,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,7 @@
 | 
			
		|||
          transport: {
 | 
			
		||||
            host: config.notifications.smtp.transport.host,
 | 
			
		||||
            port: config.notifications.smtp.transport.port,
 | 
			
		||||
            secure: config.notifications.smtp.transport.secure,
 | 
			
		||||
            username: config.notifications.smtp.transport.username,
 | 
			
		||||
            password: config.notifications.smtp.transport.password,
 | 
			
		||||
            ignoreCert: config.notifications.smtp.transport.ignoreCert,
 | 
			
		||||
| 
						 | 
				
			
			@ -128,6 +129,13 @@
 | 
			
		|||
                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
 | 
			
		||||
              title={$t('admin.notification_email_ignore_certificate_errors')}
 | 
			
		||||
              subtitle={$t('admin.notification_email_ignore_certificate_errors_description')}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue