Password email not sent (#34)
* Sending mails from password reset now we are really sending the mail * Must set Mail configuration
This commit is contained in:
@@ -32,6 +32,13 @@ type Config struct {
|
|||||||
// PDF Templates
|
// PDF Templates
|
||||||
TemplatesDir string // Directory where PDF templates are stored
|
TemplatesDir string // Directory where PDF templates are stored
|
||||||
ExportTempDir string // Directory for temporary PDF exports
|
ExportTempDir string // Directory for temporary PDF exports
|
||||||
|
|
||||||
|
// Mail Configuration
|
||||||
|
MailHost string // SMTP server host
|
||||||
|
MailPort int // SMTP server port
|
||||||
|
MailUsername string // SMTP username
|
||||||
|
MailPassword string // SMTP password
|
||||||
|
MailFrom string // Default sender email address
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cfg ist die globale Konfigurationsvariable
|
// Cfg ist die globale Konfigurationsvariable
|
||||||
@@ -56,6 +63,11 @@ func defaultConfig() *Config {
|
|||||||
FrontendURL: "http://localhost:5173", // Default frontend URL for development
|
FrontendURL: "http://localhost:5173", // Default frontend URL for development
|
||||||
TemplatesDir: "./templates", // Default templates directory
|
TemplatesDir: "./templates", // Default templates directory
|
||||||
ExportTempDir: "./xporttemp", // Default export temp directory
|
ExportTempDir: "./xporttemp", // Default export temp directory
|
||||||
|
MailHost: "", // No default, must be configured
|
||||||
|
MailPort: 465, // Default SMTP SSL port
|
||||||
|
MailUsername: "", // No default, must be configured
|
||||||
|
MailPassword: "", // No default, must be configured
|
||||||
|
MailFrom: "", // No default, must be configured
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +148,28 @@ func LoadConfig() *Config {
|
|||||||
config.ExportTempDir = exportTempDir
|
config.ExportTempDir = exportTempDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mail Configuration
|
||||||
|
if mailHost := os.Getenv("MAIL_HOST"); mailHost != "" {
|
||||||
|
config.MailHost = mailHost
|
||||||
|
}
|
||||||
|
if mailPort := os.Getenv("MAIL_PORT"); mailPort != "" {
|
||||||
|
if port, err := strconv.Atoi(mailPort); err == nil {
|
||||||
|
config.MailPort = port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mailUsername := os.Getenv("MAIL_USERNAME"); mailUsername != "" {
|
||||||
|
config.MailUsername = mailUsername
|
||||||
|
}
|
||||||
|
if mailPassword := os.Getenv("MAIL_PASSWORD"); mailPassword != "" {
|
||||||
|
config.MailPassword = mailPassword
|
||||||
|
}
|
||||||
|
if mailFrom := os.Getenv("MAIL_FROM"); mailFrom != "" {
|
||||||
|
config.MailFrom = mailFrom
|
||||||
|
} else if config.MailUsername != "" {
|
||||||
|
// Fallback: Verwende Username als From-Adresse
|
||||||
|
config.MailFrom = config.MailUsername
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("DEBUG LoadConfig - Finale Config: Environment='%s', DevTesting='%s', DatabaseType='%s'\n Complete: %v\n",
|
fmt.Printf("DEBUG LoadConfig - Finale Config: Environment='%s', DevTesting='%s', DatabaseType='%s'\n Complete: %v\n",
|
||||||
config.Environment, config.DevTesting, config.DatabaseType, config)
|
config.Environment, config.DevTesting, config.DatabaseType, config)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"net/smtp"
|
||||||
|
|
||||||
|
"bamort/config"
|
||||||
|
"bamort/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client represents an SMTP mail client
|
||||||
|
type Client struct {
|
||||||
|
host string
|
||||||
|
port int
|
||||||
|
username string
|
||||||
|
password string
|
||||||
|
from string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message represents an email message
|
||||||
|
type Message struct {
|
||||||
|
To string
|
||||||
|
Subject string
|
||||||
|
Body string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient creates a new SMTP mail client from config
|
||||||
|
func NewClient() *Client {
|
||||||
|
cfg := config.Cfg
|
||||||
|
return &Client{
|
||||||
|
host: cfg.MailHost,
|
||||||
|
port: cfg.MailPort,
|
||||||
|
username: cfg.MailUsername,
|
||||||
|
password: cfg.MailPassword,
|
||||||
|
from: cfg.MailFrom,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send sends an email message via SMTP
|
||||||
|
func (c *Client) Send(msg Message) error {
|
||||||
|
if c.host == "" {
|
||||||
|
logger.Warn("SMTP Host nicht konfiguriert - E-Mail-Versand übersprungen")
|
||||||
|
return fmt.Errorf("SMTP host not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Debug("Sende E-Mail an %s via SMTP %s:%d", msg.To, c.host, c.port)
|
||||||
|
|
||||||
|
// Prepare email headers and body
|
||||||
|
headers := make(map[string]string)
|
||||||
|
headers["From"] = c.from
|
||||||
|
headers["To"] = msg.To
|
||||||
|
headers["Subject"] = msg.Subject
|
||||||
|
headers["MIME-Version"] = "1.0"
|
||||||
|
headers["Content-Type"] = "text/html; charset=\"UTF-8\""
|
||||||
|
|
||||||
|
// Build message
|
||||||
|
message := ""
|
||||||
|
for key, value := range headers {
|
||||||
|
message += fmt.Sprintf("%s: %s\r\n", key, value)
|
||||||
|
}
|
||||||
|
message += "\r\n" + msg.Body
|
||||||
|
|
||||||
|
// Connect to SMTP server
|
||||||
|
serverAddr := fmt.Sprintf("%s:%d", c.host, c.port)
|
||||||
|
|
||||||
|
// Create TLS config
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
ServerName: c.host,
|
||||||
|
InsecureSkipVerify: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var client *smtp.Client
|
||||||
|
|
||||||
|
// Port 465 requires direct TLS connection, port 587 uses STARTTLS
|
||||||
|
if c.port == 465 {
|
||||||
|
// Direct TLS connection (implicit SSL)
|
||||||
|
conn, err := tls.Dial("tcp", serverAddr, tlsConfig)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Verbinden mit SMTP-Server (TLS): %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to connect to SMTP server: %w", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
client, err = smtp.NewClient(conn, c.host)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Erstellen des SMTP-Clients: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to create SMTP client: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Port 587 or other - use STARTTLS
|
||||||
|
client, err = smtp.Dial(serverAddr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Verbinden mit SMTP-Server: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to dial SMTP server: %w", err)
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
// Start TLS if available
|
||||||
|
if ok, _ := client.Extension("STARTTLS"); ok {
|
||||||
|
if err = client.StartTLS(tlsConfig); err != nil {
|
||||||
|
logger.Error("Fehler beim STARTTLS: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to start TLS: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate
|
||||||
|
if c.username != "" && c.password != "" {
|
||||||
|
auth := smtp.PlainAuth("", c.username, c.password, c.host)
|
||||||
|
if err = client.Auth(auth); err != nil {
|
||||||
|
logger.Error("Fehler bei der SMTP-Authentifizierung: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to authenticate: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sender
|
||||||
|
if err = client.Mail(c.from); err != nil {
|
||||||
|
logger.Error("Fehler beim Setzen des Absenders: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to set sender: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set recipient
|
||||||
|
if err = client.Rcpt(msg.To); err != nil {
|
||||||
|
logger.Error("Fehler beim Setzen des Empfängers: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to set recipient: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send message body
|
||||||
|
writer, err := client.Data()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Öffnen des Data-Writers: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to open data writer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = writer.Write([]byte(message))
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Schreiben der Nachricht: %s", err.Error())
|
||||||
|
writer.Close()
|
||||||
|
return fmt.Errorf("failed to write message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = writer.Close()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Fehler beim Schließen des Data-Writers: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to close data writer: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quit
|
||||||
|
if err = client.Quit(); err != nil {
|
||||||
|
logger.Error("Fehler beim Beenden der SMTP-Verbindung: %s", err.Error())
|
||||||
|
return fmt.Errorf("failed to quit SMTP connection: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("E-Mail erfolgreich an %s versendet", msg.To)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsConfigured returns true if the mail client is properly configured
|
||||||
|
func (c *Client) IsConfigured() bool {
|
||||||
|
return c.host != "" && c.port > 0 && c.from != ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"bamort/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// setupTestEnvironment setzt die Test-Umgebung auf
|
||||||
|
func setupTestEnvironment(t *testing.T) {
|
||||||
|
original := os.Getenv("ENVIRONMENT")
|
||||||
|
os.Setenv("ENVIRONMENT", "test")
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if original != "" {
|
||||||
|
os.Setenv("ENVIRONMENT", original)
|
||||||
|
} else {
|
||||||
|
os.Unsetenv("ENVIRONMENT")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Reload config with test environment
|
||||||
|
config.Cfg = config.LoadConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewClient(t *testing.T) {
|
||||||
|
setupTestEnvironment(t)
|
||||||
|
|
||||||
|
// Set test mail config
|
||||||
|
os.Setenv("MAIL_HOST", "smtp.example.com")
|
||||||
|
os.Setenv("MAIL_PORT", "465")
|
||||||
|
os.Setenv("MAIL_USERNAME", "test@example.com")
|
||||||
|
os.Setenv("MAIL_PASSWORD", "testpass")
|
||||||
|
os.Setenv("MAIL_FROM", "sender@example.com")
|
||||||
|
|
||||||
|
// Reload config
|
||||||
|
config.Cfg = config.LoadConfig()
|
||||||
|
|
||||||
|
client := NewClient()
|
||||||
|
|
||||||
|
if client.host != "smtp.example.com" {
|
||||||
|
t.Errorf("Expected host 'smtp.example.com', got '%s'", client.host)
|
||||||
|
}
|
||||||
|
if client.port != 465 {
|
||||||
|
t.Errorf("Expected port 465, got %d", client.port)
|
||||||
|
}
|
||||||
|
if client.username != "test@example.com" {
|
||||||
|
t.Errorf("Expected username 'test@example.com', got '%s'", client.username)
|
||||||
|
}
|
||||||
|
if client.from != "sender@example.com" {
|
||||||
|
t.Errorf("Expected from 'sender@example.com', got '%s'", client.from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsConfigured(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
client *Client
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Fully configured",
|
||||||
|
client: &Client{
|
||||||
|
host: "smtp.example.com",
|
||||||
|
port: 465,
|
||||||
|
from: "test@example.com",
|
||||||
|
},
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Missing host",
|
||||||
|
client: &Client{
|
||||||
|
host: "",
|
||||||
|
port: 465,
|
||||||
|
from: "test@example.com",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Missing port",
|
||||||
|
client: &Client{
|
||||||
|
host: "smtp.example.com",
|
||||||
|
port: 0,
|
||||||
|
from: "test@example.com",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Missing from",
|
||||||
|
client: &Client{
|
||||||
|
host: "smtp.example.com",
|
||||||
|
port: 465,
|
||||||
|
from: "",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty client",
|
||||||
|
client: &Client{
|
||||||
|
host: "",
|
||||||
|
port: 0,
|
||||||
|
from: "",
|
||||||
|
},
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := tt.client.IsConfigured()
|
||||||
|
if result != tt.expected {
|
||||||
|
t.Errorf("Expected IsConfigured() to return %v, got %v", tt.expected, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSend_NotConfigured(t *testing.T) {
|
||||||
|
setupTestEnvironment(t)
|
||||||
|
|
||||||
|
// Create client without config
|
||||||
|
client := &Client{
|
||||||
|
host: "",
|
||||||
|
port: 0,
|
||||||
|
from: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := Message{
|
||||||
|
To: "recipient@example.com",
|
||||||
|
Subject: "Test",
|
||||||
|
Body: "Test body",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.Send(msg)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected error when sending with unconfigured client, got nil")
|
||||||
|
}
|
||||||
|
if err.Error() != "SMTP host not configured" {
|
||||||
|
t.Errorf("Expected error 'SMTP host not configured', got '%s'", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
+75
-19
@@ -7,6 +7,7 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bamort/logger"
|
"bamort/logger"
|
||||||
|
"bamort/mail"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@@ -239,8 +240,7 @@ func generateResetHash() (string, error) {
|
|||||||
return hex.EncodeToString(bytes), nil
|
return hex.EncodeToString(bytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendResetEmail simuliert das Senden einer E-Mail (hier nur Logging)
|
// sendResetEmail sends a password reset email via SMTP
|
||||||
// In einer echten Implementierung würde hier ein E-Mail-Service verwendet
|
|
||||||
func sendResetEmail(email, username, resetHash, frontendURL string) error {
|
func sendResetEmail(email, username, resetHash, frontendURL string) error {
|
||||||
// Verwende die mitgegebene Frontend-URL oder fallback auf Standard
|
// Verwende die mitgegebene Frontend-URL oder fallback auf Standard
|
||||||
baseURL := frontendURL
|
baseURL := frontendURL
|
||||||
@@ -250,25 +250,81 @@ func sendResetEmail(email, username, resetHash, frontendURL string) error {
|
|||||||
|
|
||||||
resetLink := fmt.Sprintf("%s/reset-password?token=%s", baseURL, resetHash)
|
resetLink := fmt.Sprintf("%s/reset-password?token=%s", baseURL, resetHash)
|
||||||
|
|
||||||
logger.Info("=== PASSWORD RESET EMAIL ===")
|
// Create mail client
|
||||||
logger.Info("An: %s", email)
|
mailClient := mail.NewClient()
|
||||||
logger.Info("Betreff: Passwort zurücksetzen für %s", username)
|
|
||||||
logger.Info("Nachricht:")
|
|
||||||
logger.Info("Hallo %s,", username)
|
|
||||||
logger.Info("")
|
|
||||||
logger.Info("Sie haben eine Passwort-Zurücksetzung angefordert.")
|
|
||||||
logger.Info("Klicken Sie auf den folgenden Link, um Ihr Passwort zurückzusetzen:")
|
|
||||||
logger.Info("")
|
|
||||||
logger.Info("%s", resetLink)
|
|
||||||
logger.Info("")
|
|
||||||
logger.Info("Dieser Link ist 14 Tage gültig.")
|
|
||||||
logger.Info("Falls Sie diese Anfrage nicht gestellt haben, ignorieren Sie diese E-Mail.")
|
|
||||||
logger.Info("")
|
|
||||||
logger.Info("=== END EMAIL ===")
|
|
||||||
|
|
||||||
// TODO: Hier echte E-Mail-Integration hinzufügen
|
// If mail is not configured, fallback to logging
|
||||||
// z.B. SendGrid, SMTP, etc.
|
if !mailClient.IsConfigured() {
|
||||||
|
logger.Warn("SMTP nicht konfiguriert - E-Mail wird nur geloggt")
|
||||||
|
logger.Info("=== PASSWORD RESET EMAIL ===")
|
||||||
|
logger.Info("An: %s", email)
|
||||||
|
logger.Info("Betreff: Passwort zurücksetzen für %s", username)
|
||||||
|
logger.Info("Nachricht:")
|
||||||
|
logger.Info("Hallo %s,", username)
|
||||||
|
logger.Info("")
|
||||||
|
logger.Info("Sie haben eine Passwort-Zurücksetzung angefordert.")
|
||||||
|
logger.Info("Klicken Sie auf den folgenden Link, um Ihr Passwort zurückzusetzen:")
|
||||||
|
logger.Info("")
|
||||||
|
logger.Info("%s", resetLink)
|
||||||
|
logger.Info("")
|
||||||
|
logger.Info("Dieser Link ist 14 Tage gültig.")
|
||||||
|
logger.Info("Falls Sie diese Anfrage nicht gestellt haben, ignorieren Sie diese E-Mail.")
|
||||||
|
logger.Info("")
|
||||||
|
logger.Info("=== END EMAIL ===")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build HTML email body
|
||||||
|
htmlBody := fmt.Sprintf(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
||||||
|
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||||
|
.header { background-color: #4CAF50; color: white; padding: 20px; text-align: center; }
|
||||||
|
.content { background-color: #f9f9f9; padding: 30px; margin-top: 20px; }
|
||||||
|
.button { display: inline-block; padding: 12px 30px; margin: 20px 0; background-color: #4CAF50; color: white; text-decoration: none; border-radius: 5px; }
|
||||||
|
.footer { margin-top: 20px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 12px; color: #666; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>Passwort zurücksetzen</h1>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<p>Hallo %s,</p>
|
||||||
|
<p>Sie haben eine Passwort-Zurücksetzung für Ihren Bamort-Account angefordert.</p>
|
||||||
|
<p>Klicken Sie auf den folgenden Button, um Ihr Passwort zurückzusetzen:</p>
|
||||||
|
<p style="text-align: center;">
|
||||||
|
<a href="%s" class="button">Passwort zurücksetzen</a>
|
||||||
|
</p>
|
||||||
|
<p>Oder kopieren Sie diesen Link in Ihren Browser:</p>
|
||||||
|
<p style="word-break: break-all; color: #666;">%s</p>
|
||||||
|
<p><strong>Dieser Link ist 14 Tage gültig.</strong></p>
|
||||||
|
<p>Falls Sie diese Anfrage nicht gestellt haben, können Sie diese E-Mail ignorieren. Ihr Passwort bleibt unverändert.</p>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p>Dies ist eine automatisch generierte E-Mail. Bitte antworten Sie nicht auf diese Nachricht.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>`, username, resetLink, resetLink)
|
||||||
|
|
||||||
|
// Send email
|
||||||
|
msg := mail.Message{
|
||||||
|
To: email,
|
||||||
|
Subject: "Passwort zurücksetzen - Bamort",
|
||||||
|
Body: htmlBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mailClient.Send(msg); err != nil {
|
||||||
|
logger.Error("Fehler beim Versenden der Reset-E-Mail an %s: %s", email, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Password-Reset-E-Mail erfolgreich an %s versendet", email)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -18,4 +18,10 @@ API_URL=http://192.168.0.48:8180
|
|||||||
API_PORT=8180
|
API_PORT=8180
|
||||||
BASE_URL=http://localhost:5173
|
BASE_URL=http://localhost:5173
|
||||||
TEMPLATES_DIR=./templates
|
TEMPLATES_DIR=./templates
|
||||||
EXPORT_TEMP_DIR=./export_temp
|
EXPORT_TEMP_DIR=./export_temp
|
||||||
|
|
||||||
|
# Mail Configuration (for development)
|
||||||
|
MAIL_HOST=mail.wuenscheonline.de
|
||||||
|
MAIL_PORT=465
|
||||||
|
MAIL_USERNAME=bamort@trokan.de
|
||||||
|
MAIL_PASSWORD=XXXmhqbv.DW+XXX
|
||||||
|
|||||||
@@ -18,3 +18,9 @@ API_PORT=8180
|
|||||||
BASE_URL=https://bamort.trokan.de
|
BASE_URL=https://bamort.trokan.de
|
||||||
TEMPLATES_DIR=./templates
|
TEMPLATES_DIR=./templates
|
||||||
EXPORT_TEMP_DIR=./export_temp
|
EXPORT_TEMP_DIR=./export_temp
|
||||||
|
|
||||||
|
# Mail Configuration (for production)
|
||||||
|
MAIL_HOST=mail.wuenscheonline.de
|
||||||
|
MAIL_PORT=465
|
||||||
|
MAIL_USERNAME=bamort@trokan.de
|
||||||
|
MAIL_PASSWORD=XXXXmhqbv.DW+XXX
|
||||||
|
|||||||
Reference in New Issue
Block a user