Skip to content

feat(mailer): Office365 OAuth2 SMTP support#269

Open
tsgoff wants to merge 25 commits into
OpenXE-org:masterfrom
tsgoff:o365oauth2
Open

feat(mailer): Office365 OAuth2 SMTP support#269
tsgoff wants to merge 25 commits into
OpenXE-org:masterfrom
tsgoff:o365oauth2

Conversation

@tsgoff
Copy link
Copy Markdown
Contributor

@tsgoff tsgoff commented Apr 28, 2026

Übersicht

Dieser PR ergänzt OpenXE um vollständige Microsoft Office365 OAuth2-Unterstützung für den Mailversand um den Workaround abzulösen: https://openxe.org/wiki/index.php?entry%2F9-nutzung-von-microsoft-office365-mailadressen-oauth2%2F=

Änderungen

Office365 OAuth2 Mailversand

  • Neues Modul classes/Modules/Office365Api/ (Account-Gateway, Authorization-Service, Credentials-Service, DTOs, Exceptions) — analog zum bestehenden GoogleApi-Modul.
  • Custom-SMTP-Client Office365SmtpTransport, der AUTH XOAUTH2 in Großbuchstaben sendet (Office365 lehnt das von PHPMailer gesendete AUTH xoauth2 mit „Requested auth method not available: xoauth2" ab).
  • Automatischer Token-Refresh, wenn die Restlaufzeit < 30 s beträgt.
  • UI-Integration in emailbackup_edit.tpl (Dropdown-Eintrag „Microsoft Office365 OAuth2" + Authorize-Button) sowie OAuth-Authorize/Callback-Actions in emailbackup.php.

Datenbankstruktur

  • 4 neue Tabellen (office365_account, office365_access_token, office365_account_property, office365_account_scope) ergänzt in:
    • upgrade/data/db_schema.json → wird vom Upgrade-Tool als Soll-Schema verwendet.
  • Bestehende migrations/office365_oauth_tables.sql bleibt für Updates bestehender Installationen erhalten.

CI

  • Neuer Workflow .github/workflows/ci.yml mit PHP 8.4 für jeden Push und jeden Pull Request:
    • PHP-Lint über projektspezifischen Code (ohne vendor/).
    • JSON-Validierung von db_schema.json und composer.json.
    • DB-Schema-Integritätstest: importiert struktur.sql in MariaDB 10.6 und prüft, dass alle Office365-Tabellen erzeugt werden + Cross-Check zwischen db_schema.json und struktur.sql.
    • Office365-Smoke-Test: Lint des Moduls + Verifikation, dass AUTH_OFFICE365 durchgängig in Account, SystemMailer, Factory und UI verdrahtet ist.

Dokumentation

  • Neue konsolidierte Doku OFFICE365_OAUTH2.md (Setup, Architektur, Troubleshooting). Ersetzt die drei vorigen MDs (OFFICE365_OAUTH_SETUP.md, OFFICE365_OAUTH2_DOCUMENTATION.md, OFFICE365_SMTP_CLIENT_TESTING.md).

Testdurchführung

  • Manuell auf produktiver VM gegen echtes Office365-Postfach erfolgreich verifiziert (Authorize-Flow + Testmail-Versand).
  • DB-Schema-Check und JSON-Validierung lokal grün.

Setup für bestehende Installationen

  1. git pull
  2. mysql -u … -p … openxe < migrations/office365_oauth_tables.sql
  3. Apache / PHP-FPM neu starten (OPcache).
  4. Azure App Registration durchführen und in den OpenXE-Systemeinstellungen office365_client_id, office365_client_secret, office365_redirect_uri, office365_tenant_id hinterlegen.

Details siehe OFFICE365_OAUTH2.md.

tsgoff added 25 commits April 28, 2026 11:49
Implement direct SMTP client that sends uppercase AUTH XOAUTH2 (matching
Office365 server advertisement) instead of lowercase, resolving XOAUTH2
authentication failures.

Changes:
- Office365SmtpTransport: Custom SMTP implementation with:
  * Direct stream socket connection to smtp.office365.com:587
  * TLS STARTTLS encryption negotiation
  * Uppercase AUTH XOAUTH2 command (critical fix)
  * MIME multipart support for attachments
  * Automatic OAuth2 token refresh (TTL < 30 seconds)
  * Full error handling and logging

- Office365SmtpException: SMTP-specific exception class

- MailerTransportFactory: Route Office365 accounts to new custom
  transport instead of PhpMailerOAuth

Result: Office365 OAuth2 email sending now works without external proxy.
XOAUTH2 authentication no longer fails due to case sensitivity.
…e::fetchRow() returns empty array [] when no rows found, not null. All null checks changed to empty() to properly handle empty arrays. Fixes: - getAccount() - null check - getAccountByEmailAddress() - null check - getAccountByUserId() - null check - getAccessToken() - null check - getAccountProperties() - null check - getScopes() - null check This was preventing Office365 OAuth accounts from being found by email address.
…dd database schema for Office365 integration including tables for access tokens, accounts, account properties, and scopes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant