'boolean', 'signature_enabled' => 'boolean', 'last_sync_at' => 'datetime', 'google_oauth_connection_id' => 'integer', ]; public function folders(): HasMany { return $this->hasMany(EmailFolder::class)->orderBy('sort_order'); } public function googleOAuthConnection(): BelongsTo { return $this->belongsTo(GoogleOAuthConnection::class); } public function getImapConfig(): array { if ($this->auth_method === 'oauth') { $token = $this->resolveOAuthToken(); return [ 'host' => $this->imap_host, 'port' => $this->imap_port, 'encryption' => $this->imap_encryption, 'username' => $this->imap_username, 'authentication' => 'oauth', 'password' => $token, ]; } return [ 'host' => $this->imap_host, 'port' => $this->imap_port, 'encryption' => $this->imap_encryption, 'username' => $this->imap_username, 'password' => $this->imap_password, ]; } public function getDecryptedPassword(): string { if ($this->auth_method === 'oauth') { return $this->resolveOAuthToken(); } if (empty($this->imap_password)) { return ''; } try { return Crypt::decryptString($this->imap_password); } catch (\Exception $e) { return $this->imap_password; } } public function getDecryptedSmtpPassword(): string { if ($this->auth_method === 'oauth') { return $this->resolveOAuthToken(); } if (empty($this->smtp_password)) { return $this->getDecryptedPassword(); } try { return Crypt::decryptString($this->smtp_password); } catch (\Exception $e) { return $this->smtp_password; } } protected function resolveOAuthToken(): string { if (!$this->relationLoaded('googleOAuthConnection')) { $this->load('googleOAuthConnection'); } $connection = $this->googleOAuthConnection; if (!$connection) { return ''; } try { return app(GoogleOAuthService::class)->getAccessToken($connection); } catch (\Exception $e) { return ''; } } public function getSmtpConfig(): array { return [ 'host' => $this->smtp_host ?? $this->imap_host, 'port' => $this->smtp_port ?? 587, 'encryption' => $this->smtp_encryption ?? 'tls', 'username' => $this->smtp_username ?? $this->imap_username, 'password' => $this->smtp_password ?? $this->imap_password, ]; } public function getImapClient(): ?\DirectoryTree\ImapEngine\Mailbox { if (!$this->imap_host || !$this->imap_username) { return null; } try { $encryption = match ($this->imap_encryption) { 'ssl' => 'ssl', 'tls' => 'tls', default => 'none', }; $config = [ 'host' => $this->imap_host, 'port' => $this->imap_port ?? 993, 'encryption' => $encryption, 'validate_cert' => false, 'username' => $this->imap_username, 'password' => $this->getDecryptedPassword(), ]; if ($this->auth_method === 'oauth') { $config['authentication'] = 'oauth'; } return new \DirectoryTree\ImapEngine\Mailbox($config); } catch (\Exception $e) { return null; } } public function getSmtpMailer(): ?\Symfony\Component\Mailer\Mailer { if ($this->auth_method === 'oauth') { return $this->buildOAuthSmtpMailer(); } $dsn = $this->buildSmtpDsn(); if (!$dsn) { return null; } try { $transport = \Symfony\Component\Mailer\Transport::fromDsn($dsn); return new \Symfony\Component\Mailer\Mailer($transport); } catch (\Exception $e) { return null; } } protected function buildOAuthSmtpMailer(): ?\Symfony\Component\Mailer\Mailer { $token = $this->resolveOAuthToken(); if (empty($token)) { return null; } $username = $this->smtp_username ?? $this->email_address; $host = $this->smtp_host ?? 'smtp.gmail.com'; $port = $this->smtp_port ?? 587; $transport = new \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport($host, $port, true); $transport->setUsername($username); $transport->setPassword($token); $transport->setAuthenticators([ new \Symfony\Component\Mailer\Transport\Smtp\Auth\XOAuth2Authenticator(), ]); return new \Symfony\Component\Mailer\Mailer($transport); } public function buildSmtpDsn(): ?string { $password = $this->getDecryptedSmtpPassword(); if (empty($password)) { return null; } $username = $this->smtp_username ?? $this->email_address; $encryption = $this->smtp_encryption ?? 'tls'; $scheme = ($encryption === 'ssl') ? 'smtps' : 'smtp'; return sprintf( '%s://%s:%s@%s:%d?encryption=%s', $scheme, rawurlencode($username), rawurlencode($password), $this->smtp_host ?? 'smtp.gmail.com', $this->smtp_port ?? 587, $encryption ); } public function testConnection(): array { try { $mailbox = $this->getImapClient(); if (!$mailbox) { return ['success' => false, 'message' => 'Configurazione IMAP non valida']; } $mailbox->connect(); $mailbox->disconnect(); return [ 'success' => true, 'message' => 'Connessione IMAP riuscita! Server: ' . $this->imap_host ]; } catch (\Exception $e) { $message = $e->getMessage(); if (strpos($message, 'Undefined property') !== false) { return ['success' => true, 'message' => 'Connessione IMAP riuscita! (Server: ' . $this->imap_host . ')']; } return ['success' => false, 'message' => $message]; } } public static function getActive() { return self::where('is_active', true)->first(); } public function getSignature(): ?string { return $this->signature; } public function getEffectiveFromAddress(): string { return $this->from_email ?: $this->email_address; } public function getEffectiveFromName(): string { $name = $this->from_name ?: $this->email_name; if (filter_var($name, FILTER_VALIDATE_EMAIL)) { return 'Glastree'; } $name = preg_replace('/[^\p{L}\p{N}\s]/u', '', $name); $name = trim($name); return empty($name) ? 'Glastree' : $name; } public function getEffectiveReplyTo(): ?string { if ($this->from_email) { return $this->from_email; } return $this->reply_to ?: null; } public function firme(): HasMany { return $this->hasMany(Firma::class); } public function firmaPredefinita(): ?Firma { return $this->firme()->where('is_default', true)->first() ?? $this->firme()->first(); } }