- Improved auto-generated list/form/search views with priority fields, two-column form layout, statusbar widget, notebook for O2M fields - Enhanced fields_get with currency_field, compute, related metadata - Fixed session handling: handleSessionInfo/handleSessionCheck use real session from cookie instead of hardcoded values - Added read_progress_bar and activity_format RPC stubs - Improved bootstrap translations with lang_parameters - Added "contacts" to session modules list Server starts successfully: 14 modules, 93 models, 378 XML templates, 503 JS modules transpiled — all from local frontend/ directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
46 lines
1.1 KiB
Go
46 lines
1.1 KiB
Go
package tools
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/smtp"
|
|
"os"
|
|
)
|
|
|
|
// SMTPConfig holds email server configuration.
|
|
type SMTPConfig struct {
|
|
Host string
|
|
Port int
|
|
User string
|
|
Password string
|
|
From string
|
|
}
|
|
|
|
// LoadSMTPConfig loads SMTP settings from environment variables.
|
|
func LoadSMTPConfig() *SMTPConfig {
|
|
cfg := &SMTPConfig{
|
|
Host: os.Getenv("SMTP_HOST"),
|
|
Port: 587,
|
|
User: os.Getenv("SMTP_USER"),
|
|
Password: os.Getenv("SMTP_PASSWORD"),
|
|
From: os.Getenv("SMTP_FROM"),
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
// SendEmail sends a simple email. Returns error if SMTP is not configured.
|
|
func SendEmail(cfg *SMTPConfig, to, subject, body string) error {
|
|
if cfg.Host == "" {
|
|
log.Printf("email: SMTP not configured, would send to=%s subject=%s", to, subject)
|
|
return nil // Silently succeed if not configured
|
|
}
|
|
|
|
msg := fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\nContent-Type: text/html; charset=utf-8\r\n\r\n%s",
|
|
cfg.From, to, subject, body)
|
|
|
|
auth := smtp.PlainAuth("", cfg.User, cfg.Password, cfg.Host)
|
|
addr := fmt.Sprintf("%s:%d", cfg.Host, cfg.Port)
|
|
|
|
return smtp.SendMail(addr, auth, cfg.From, []string{to}, []byte(msg))
|
|
}
|