mailer = new PHPMailer(true); $this->configureSMTP(); Log::info('PHPMailerService initialized with NTLM/GSSAPI support'); } /** * Konfigurasi SMTP dengan dukungan NTLM/GSSAPI dan fallback untuk development */ protected function configureSMTP(): void { try { // Server settings $this->mailer->isSMTP(); $this->mailer->Host = config('mail.mailers.phpmailer.host', env('MAIL_HOST')); $this->mailer->Port = config('mail.mailers.phpmailer.port', env('MAIL_PORT', 587)); // Deteksi apakah perlu autentikasi berdasarkan username $username = config('mail.mailers.phpmailer.username', env('MAIL_USERNAME')); $password = config('mail.mailers.phpmailer.password', env('MAIL_PASSWORD')); // Hanya aktifkan autentikasi jika username dan password tersedia if (!empty($username) && $username !== 'null' && !empty($password) && $password !== 'null') { $this->mailer->SMTPAuth = true; $this->mailer->Username = $username; $this->mailer->Password = $password; Log::info('SMTP authentication enabled', [ 'username' => $username, 'host' => $this->mailer->Host ]); // Dukungan NTLM/GSSAPI untuk production $authType = config('mail.mailers.phpmailer.auth_type', env('MAIL_AUTH_TYPE', 'NTLM')); if (strtoupper($authType) === 'NTLM') { $this->mailer->AuthType = 'NTLM'; $this->mailer->Realm = config('mail.mailers.phpmailer.realm', env('MAIL_REALM', '')); $this->mailer->Workstation = config('mail.mailers.phpmailer.workstation', env('MAIL_WORKSTATION', '')); Log::info('NTLM authentication configured', [ 'realm' => $this->mailer->Realm, 'workstation' => $this->mailer->Workstation ]); } elseif (strtoupper($authType) === 'GSSAPI') { $this->mailer->AuthType = 'XOAUTH2'; Log::info('GSSAPI authentication configured'); } } else { // Untuk development server seperti Mailpit $this->mailer->SMTPAuth = false; Log::info('SMTP authentication disabled for development', [ 'host' => $this->mailer->Host, 'port' => $this->mailer->Port ]); } // Encryption configuration $encryption = config('mail.mailers.phpmailer.encryption', env('MAIL_ENCRYPTION')); $port = $this->mailer->Port; if (!empty($encryption) && $encryption !== 'null') { if ($encryption === 'tls' && ($port == 587 || $port == 25)) { $this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; Log::info('Using STARTTLS encryption', ['port' => $port]); } elseif ($encryption === 'ssl' && ($port == 465 || $port == 993)) { $this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; Log::info('Using SSL encryption', ['port' => $port]); } } else { // Untuk development/testing server $this->mailer->SMTPSecure = false; $this->mailer->SMTPAutoTLS = false; Log::info('Using no encryption (plain text)', ['port' => $port]); } // Tambahan konfigurasi untuk kompatibilitas $this->mailer->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) ); // --- TAMBAHKAN BAGIAN INI UNTUK MENGABAIKAN VALIDASI SERTIFIKAT --- if (isset($config['ignore_certificate_errors']) && $config['ignore_certificate_errors']) { $this->mailer->SMTPOptions = [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true, ], ]; } // --- AKHIR TAMBAHAN --- // Debug mode if (config('app.debug')) { $this->mailer->SMTPDebug = SMTP::DEBUG_SERVER; } // Timeout settings $this->mailer->Timeout = config('mail.mailers.phpmailer.timeout', 30); $this->mailer->SMTPKeepAlive = true; Log::info('SMTP configured successfully', [ 'host' => $this->mailer->Host, 'port' => $this->mailer->Port, 'auth_enabled' => $this->mailer->SMTPAuth, 'encryption' => $encryption ?: 'none', 'smtp_secure' => $this->mailer->SMTPSecure ?: 'none' ]); } catch (Exception $e) { Log::error('Failed to configure SMTP', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); throw $e; } } /** * Kirim email dengan attachment * * @param string $to Email tujuan * @param string $subject Subjek email * @param string $body Body email (HTML) * @param string|null $attachmentPath Path file attachment * @param string|null $attachmentName Nama file attachment * @param string|null $mimeType MIME type attachment * @return bool */ /** * Kirim email dengan handling khusus untuk development dan production * * @param string $to Email tujuan * @param string $subject Subjek email * @param string $body Body email (HTML) * @param string|null $attachmentPath Path file attachment * @param string|null $attachmentName Nama file attachment * @param string|null $mimeType MIME type attachment * @return bool */ public function sendEmail( string $to, string $subject, string $body, ?string $attachmentPath = null, ?string $attachmentName = null, ?string $mimeType = 'application/pdf' ): bool { try { // Reset recipients dan attachments $this->mailer->clearAddresses(); $this->mailer->clearAttachments(); // Set sender $fromAddress = config('mail.from.address', env('MAIL_FROM_ADDRESS')); $fromName = config('mail.from.name', env('MAIL_FROM_NAME')); if (!empty($fromAddress)) { $this->mailer->setFrom($fromAddress, $fromName); } else { // Fallback untuk development $this->mailer->setFrom('noreply@localhost', 'Development Server'); } // Add recipient $this->mailer->addAddress($to); // Content $this->mailer->isHTML(true); $this->mailer->Subject = $subject; $this->mailer->Body = $body; $this->mailer->AltBody = strip_tags($body); // Attachment if ($attachmentPath && file_exists($attachmentPath)) { $this->mailer->addAttachment( $attachmentPath, $attachmentName ?: basename($attachmentPath), 'base64', $mimeType ); Log::info('Attachment added to email', [ 'path' => $attachmentPath, 'name' => $attachmentName, 'mime_type' => $mimeType, 'file_size' => filesize($attachmentPath) ]); } // Attempt to send $result = $this->mailer->send(); Log::info('Email sent successfully via PHPMailer', [ 'to' => $to, 'subject' => $subject, 'has_attachment' => !is_null($attachmentPath), 'host' => $this->mailer->Host, 'port' => $this->mailer->Port, 'auth_enabled' => $this->mailer->SMTPAuth ]); return $result; } catch (Exception $e) { Log::error('Failed to send email via PHPMailer', [ 'to' => $to, 'subject' => $subject, 'host' => $this->mailer->Host, 'port' => $this->mailer->Port, 'auth_enabled' => $this->mailer->SMTPAuth, 'error' => $e->getMessage(), 'error_code' => $e->getCode(), 'trace' => $e->getTraceAsString() ]); return false; } } /** * Test koneksi SMTP dengan fallback encryption * * @return bool */ public function testConnection(): bool { try { // Coba koneksi dengan konfigurasi saat ini $this->mailer->smtpConnect(); $this->mailer->smtpClose(); Log::info('SMTP connection test successful with current config'); return true; } catch (Exception $e) { Log::warning('SMTP connection failed, trying fallback', [ 'error' => $e->getMessage() ]); // Fallback: coba tanpa encryption try { $this->mailer->SMTPSecure = false; $this->mailer->SMTPAutoTLS = false; $this->mailer->smtpConnect(); $this->mailer->smtpClose(); Log::info('SMTP connection successful with fallback (no encryption)'); return true; } catch (Exception $fallbackError) { Log::error('SMTP connection test failed completely', [ 'original_error' => $e->getMessage(), 'fallback_error' => $fallbackError->getMessage() ]); return false; } } } /** * Dapatkan instance PHPMailer * * @return PHPMailer */ public function getMailer(): PHPMailer { return $this->mailer; } }