diff --git a/backend/internal/dto/app_config_dto.go b/backend/internal/dto/app_config_dto.go index d3c0a7eb..dbb7a6ad 100644 --- a/backend/internal/dto/app_config_dto.go +++ b/backend/internal/dto/app_config_dto.go @@ -21,7 +21,7 @@ type AppConfigUpdateDto struct { SmtpFrom string `json:"smtpFrom" binding:"omitempty,email"` SmtpUser string `json:"smtpUser"` SmtpPassword string `json:"smtpPassword"` - SmtpTls string `json:"smtpTls"` + SmtpTls string `json:"smtpTls" binding:"required,oneof=none starttls tls"` SmtpSkipCertVerify string `json:"smtpSkipCertVerify"` LdapEnabled string `json:"ldapEnabled" binding:"required"` LdapUrl string `json:"ldapUrl"` diff --git a/backend/internal/service/app_config_service.go b/backend/internal/service/app_config_service.go index 50562015..1aea718b 100644 --- a/backend/internal/service/app_config_service.go +++ b/backend/internal/service/app_config_service.go @@ -27,6 +27,7 @@ func NewAppConfigService(db *gorm.DB) *AppConfigService { if err := service.InitDbConfig(); err != nil { log.Fatalf("Failed to initialize app config service: %v", err) } + return service } @@ -96,8 +97,8 @@ var defaultDbConfig = model.AppConfig{ }, SmtpTls: model.AppConfigVariable{ Key: "smtpTls", - Type: "bool", - DefaultValue: "true", + Type: "string", + DefaultValue: "none", }, SmtpSkipCertVerify: model.AppConfigVariable{ Key: "smtpSkipCertVerify", diff --git a/backend/internal/service/email_service.go b/backend/internal/service/email_service.go index 2aa6cb69..33f3e6bb 100644 --- a/backend/internal/service/email_service.go +++ b/backend/internal/service/email_service.go @@ -115,18 +115,22 @@ func (srv *EmailService) getSmtpClient() (client *smtp.Client, err error) { } // Connect to the SMTP server - if srv.appConfigService.DbConfig.SmtpTls.Value == "false" { + // Connect to the SMTP server based on TLS setting + switch srv.appConfigService.DbConfig.SmtpTls.Value { + case "none": client, err = srv.connectToSmtpServer(smtpAddress) - } else if port == "465" { + case "tls": client, err = srv.connectToSmtpServerUsingImplicitTLS( smtpAddress, tlsConfig, ) - } else { + case "starttls": client, err = srv.connectToSmtpServerUsingStartTLS( smtpAddress, tlsConfig, ) + default: + return nil, fmt.Errorf("invalid SMTP TLS setting: %s", srv.appConfigService.DbConfig.SmtpTls.Value) } if err != nil { return nil, fmt.Errorf("failed to connect to SMTP server: %w", err) diff --git a/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.down.sql b/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.down.sql new file mode 100644 index 00000000..bab75a60 --- /dev/null +++ b/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.down.sql @@ -0,0 +1 @@ +UPDATE app_config_variables SET value = 'true' WHERE key = 'smtpTls'; \ No newline at end of file diff --git a/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.up.sql b/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.up.sql new file mode 100644 index 00000000..b8cb1b4d --- /dev/null +++ b/backend/resources/migrations/postgres/20250225182112_manual_smtp_tls_selection.up.sql @@ -0,0 +1,7 @@ +UPDATE app_config_variables AS target +SET value = CASE + WHEN target.value = 'true' AND (SELECT value FROM app_config_variables WHERE key = 'smtpPort' LIMIT 1) = '587' THEN 'starttls' + WHEN target.value = 'true' THEN 'tls' + ELSE 'none' +END + WHERE target.key = 'smtpTls'; \ No newline at end of file diff --git a/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.down.sql b/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.down.sql new file mode 100644 index 00000000..bab75a60 --- /dev/null +++ b/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.down.sql @@ -0,0 +1 @@ +UPDATE app_config_variables SET value = 'true' WHERE key = 'smtpTls'; \ No newline at end of file diff --git a/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.up.sql b/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.up.sql new file mode 100644 index 00000000..ace19a90 --- /dev/null +++ b/backend/resources/migrations/sqlite/20250225182112_manual_smtp_tls_selection.up.sql @@ -0,0 +1,7 @@ +UPDATE app_config_variables +SET value = CASE + WHEN value = 'true' AND (SELECT value FROM app_config_variables WHERE key = 'smtpPort' LIMIT 1) = '587' THEN 'starttls' + WHEN value = 'true' THEN 'tls' + ELSE 'none' + END +WHERE key = 'smtpTls'; \ No newline at end of file diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c8c842f5..bd87c076 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "pocket-id-frontend", - "version": "0.30.0", + "version": "0.35.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pocket-id-frontend", - "version": "0.30.0", + "version": "0.35.2", "dependencies": { "@simplewebauthn/browser": "^13.1.0", "@tailwindcss/vite": "^4.0.0", diff --git a/frontend/src/lib/types/application-configuration.ts b/frontend/src/lib/types/application-configuration.ts index a5ea06d0..b6a8053f 100644 --- a/frontend/src/lib/types/application-configuration.ts +++ b/frontend/src/lib/types/application-configuration.ts @@ -15,7 +15,7 @@ export type AllAppConfig = AppConfig & { smtpFrom: string; smtpUser: string; smtpPassword: string; - smtpTls: boolean; + smtpTls: 'none' | 'starttls' | 'tls'; smtpSkipCertVerify: boolean; emailLoginNotificationEnabled: boolean; // LDAP diff --git a/frontend/src/routes/settings/admin/application-configuration/forms/app-config-email-form.svelte b/frontend/src/routes/settings/admin/application-configuration/forms/app-config-email-form.svelte index 9745e0d5..20f88c6c 100644 --- a/frontend/src/routes/settings/admin/application-configuration/forms/app-config-email-form.svelte +++ b/frontend/src/routes/settings/admin/application-configuration/forms/app-config-email-form.svelte @@ -1,9 +1,11 @@