'Custom SMTP', self::SendGrid => 'SendGrid', self::Mailgun => 'Mailgun', self::Postmark => 'Postmark', self::AmazonSes => 'Amazon SES', self::Microsoft365 => 'Microsoft 365 (OAuth)', self::Gmail => 'Google / Gmail (OAuth)', }; } public function defaultHost(): ?string { return match ($this) { self::Custom, self::Microsoft365, self::Gmail => null, self::SendGrid => 'smtp.sendgrid.net', self::Mailgun => 'smtp.mailgun.org', self::Postmark => 'smtp.postmarkapp.com', self::AmazonSes => 'email-smtp.us-east-1.amazonaws.com', }; } public function defaultPort(): ?int { return match ($this) { self::Custom, self::Microsoft365, self::Gmail => null, self::SendGrid, self::Mailgun, self::Postmark, self::AmazonSes => 587, }; } /** * Whether this provider sends through a vendor HTTP API authorized by * an admin-connected mailbox (MailOAuthConnection) rather than through * the generic SMTP transport. */ public function isOAuth(): bool { return $this === self::Microsoft365 || $this === self::Gmail; } /** * The custom Laravel mailer this provider sends through — the name * registered via Mail::extend() and declared in config/mail.php. */ public function oauthMailer(): ?string { return match ($this) { self::Microsoft365 => 'microsoft-graph', self::Gmail => 'gmail-api', default => null, }; } /** * Whether the connect flow needs a directory/tenant to build its * endpoints. Microsoft's authorize/token URLs are tenant-scoped; * blank falls back to 'common', which admits work/school accounts of * any tenant plus personal accounts — the inclusive default for this * app's audience. Unlike social login's tenant pinning this is not a * security control: the flow is started by an administrator and the * resulting token can only send as the one mailbox that consented. */ public function needsTenant(): bool { return $this === self::Microsoft365; } }