diff --git a/docker-compose.yml b/docker-compose.yml index a05e04a..9eaf68e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,11 +17,13 @@ services: - HOST=0.0.0.0 - PORT=4321 - NODE_ENV=production - # --- E-Mail SMTP Konfiguration (für Login Codes) --- - # Entferne die Rauten (#) und trage deine echten Mail-Daten ein, - # damit die App E-Mails versenden kann: - # - SMTP_HOST=smtp.dein-provider.de - # - SMTP_PORT=587 - # - SMTP_USER=deine_email@domain.de - # - SMTP_PASS=dein_passwort - # - SMTP_FROM=Lebenslauf App + # Diese Variablen werden dynamisch aus dem Portainer 'Env'-Tab gelesen: + - SESSION_SECRET=${SESSION_SECRET} + - APP_URL=${APP_URL} + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_SECURE=${SMTP_SECURE} + - SMTP_USER=${SMTP_USER} + - SMTP_PASS=${SMTP_PASS} + - SMTP_FROM=${SMTP_FROM} + - OTP_EXPIRES_MINUTES=${OTP_EXPIRES_MINUTES:-10} diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 3913562..a449862 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -4,20 +4,34 @@ import { upsertUser, setOTP, consumeOTP, createSession, getSession, deleteSessio const SESSION_COOKIE = 'lv_session'; const SESSION_DAYS = 30; -const OTP_MINUTES = parseInt(import.meta.env.OTP_EXPIRES_MINUTES || '10'); -// ── Mailer ──────────────────────────────────────────────────────────── +function getEnv(key: string, metaFallback?: any): string | undefined { + if (typeof process !== 'undefined' && process.env && process.env[key]) { + return process.env[key]; + } + return metaFallback; +} + +const rawOtp = getEnv('OTP_EXPIRES_MINUTES', import.meta.env.OTP_EXPIRES_MINUTES) || '10'; +const OTP_MINUTES = isNaN(parseInt(rawOtp)) ? 10 : parseInt(rawOtp); + +// ─ Mailer ──────────────────────────────────────────────────────────── let _transport: nodemailer.Transporter | null = null; function getTransport() { if (!_transport) { + const smtpUser = getEnv('SMTP_USER', import.meta.env.SMTP_USER); + const smtpPass = getEnv('SMTP_PASS', import.meta.env.SMTP_PASS); + const rawPort = getEnv('SMTP_PORT', import.meta.env.SMTP_PORT) || '587'; + const smtpPort = isNaN(parseInt(rawPort)) ? 587 : parseInt(rawPort); + _transport = nodemailer.createTransport({ - host: import.meta.env.SMTP_HOST || 'localhost', - port: parseInt(import.meta.env.SMTP_PORT || '587'), - secure: import.meta.env.SMTP_SECURE === 'true', - auth: import.meta.env.SMTP_USER ? { - user: import.meta.env.SMTP_USER, - pass: import.meta.env.SMTP_PASS, + host: getEnv('SMTP_HOST', import.meta.env.SMTP_HOST) || 'localhost', + port: smtpPort, + secure: getEnv('SMTP_SECURE', import.meta.env.SMTP_SECURE) === 'true', + auth: smtpUser ? { + user: smtpUser, + pass: smtpPass || '', } : undefined, tls: { rejectUnauthorized: false @@ -50,7 +64,7 @@ export async function sendOTP(email: string, lang: string = 'de'): Promise<{ ok: `; await getTransport().sendMail({ - from: import.meta.env.SMTP_FROM || 'Lebenslauf-App ', + from: getEnv('SMTP_FROM', import.meta.env.SMTP_FROM) || 'Lebenslauf-App ', to: email, subject, html, diff --git a/src/lib/db.ts b/src/lib/db.ts index cd323b2..d2d4622 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -5,7 +5,7 @@ import { fileURLToPath } from 'url'; import type { CV, CVData, CVSettings } from '../types'; import { DEFAULT_DATA, DEFAULT_SETTINGS } from '../types'; -const DB_PATH = import.meta.env.DB_PATH || join(process.cwd(), 'data', 'lebenslauf.db'); +const DB_PATH = process.env.DB_PATH || import.meta.env.DB_PATH || join(process.cwd(), 'data', 'lebenslauf.db'); const dir = dirname(DB_PATH); if (!existsSync(dir)) mkdirSync(dir, { recursive: true });