Login page (default and button-only mode) and the three settings tabs, rendered from the plugin's own markup and CSS inside a mock WordPress admin shell. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2
416 lines
20 KiB
Markdown
416 lines
20 KiB
Markdown
<div align="center">
|
||
|
||
<img src=".wordpress-org/icon.svg" width="96" height="96" alt="">
|
||
|
||
# M365 Login
|
||
|
||
**Anmeldung an WordPress mit dem Microsoft 365 / Entra ID-Konto – sicher, schlank, gestaltbar.**
|
||
|
||
[](https://wordpress.org/)
|
||
[](https://www.php.net/)
|
||
[](LICENSE)
|
||
[](https://github.com/friloo/wp-m365-login/actions/workflows/ci.yml)
|
||
[](docs/wordpress-org-einreichung.md)
|
||
|
||
<img src=".github/assets/button-preview.svg" width="720" alt="Login-Seite mit Microsoft-Button, Farb-Presets und Sicherheitsmerkmalen">
|
||
|
||
</div>
|
||
|
||
---
|
||
|
||
## Inhalt
|
||
|
||
- [Auf einen Blick](#auf-einen-blick)
|
||
- [Screenshots](#screenshots)
|
||
- [So funktioniert es](#so-funktioniert-es)
|
||
- [Installation](#installation)
|
||
- [Einrichtung in Microsoft Entra ID](#einrichtung-in-microsoft-entra-id)
|
||
- [Einstellungen im Backend](#einstellungen-im-backend)
|
||
- [Verbindung](#verbindung)
|
||
- [Button](#button)
|
||
- [Sicherheit](#sicherheit)
|
||
- [Gruppen-Beschränkung](#gruppen-beschränkung)
|
||
- [Nur-Button-Modus & Fallback](#nur-button-modus--fallback)
|
||
- [Sicherheitskonzept](#sicherheitskonzept)
|
||
- [Shortcode & Hooks](#shortcode--hooks)
|
||
- [Fehlerbehebung](#fehlerbehebung)
|
||
- [Entwicklung](#entwicklung)
|
||
- [Einreichung bei WordPress.org](#einreichung-bei-wordpressorg)
|
||
- [FAQ](#faq)
|
||
- [Lizenz](#lizenz)
|
||
|
||
---
|
||
|
||
## Auf einen Blick
|
||
|
||
| | |
|
||
| --- | --- |
|
||
| 🔑 **Login per Microsoft** | Ein Klick auf der Anmeldeseite, Anmeldung bei Microsoft, zurück in WordPress – fertig. |
|
||
| 📧 **Zuordnung über die E-Mail-Adresse** | Es werden **keine Benutzer angelegt**. Nur wer schon ein WordPress-Konto mit derselben E-Mail hat, kommt rein. |
|
||
| 🎨 **Gestaltbarer Button** | Text, Icon (Microsoft-Logo oder eigenes Bild), Farben, Hover-Farbe, Rahmen, Eckenradius, Position – mit Live-Vorschau und Presets. |
|
||
| 👥 **Entra-Gruppen** | Optional nur Mitglieder ausgewählter Gruppen zulassen. Gruppen werden direkt im Backend gesucht und ausgewählt. |
|
||
| 🚪 **Nur-Button-Modus** | Passwortfelder ausblenden und Passwort-Logins sperren – mit geheimem Fallback-Link als Notausgang. |
|
||
| 🛡️ **Sicher by default** | OpenID Connect + PKCE, Signaturprüfung, Tenant-Pinning, Konto-Bindung, verschlüsseltes Secret. |
|
||
| 🌍 **Übersetzbar** | Englische Basis, deutsche Übersetzung (du & Sie) enthalten. |
|
||
| 📦 **WordPress.org-ready** | readme.txt, Lizenz, Uninstall, Plugin Check in CI, Build-Script. |
|
||
|
||
---
|
||
|
||
## Screenshots
|
||
|
||
> Vorschauen, gerendert aus dem echten Plugin-Markup und -CSS in einer nachgebauten WordPress-Oberfläche.
|
||
|
||
| Login-Seite | Nur-Button-Modus |
|
||
| --- | --- |
|
||
|  |  |
|
||
|
||
| Einstellungen – Verbindung | Einstellungen – Button |
|
||
| --- | --- |
|
||
|  |  |
|
||
|
||
<details>
|
||
<summary><strong>Einstellungen – Sicherheit</strong> (Gruppen-Auswahl, Nur-Button-Modus, Fallback-Link)</summary>
|
||
|
||

|
||
|
||
</details>
|
||
|
||
---
|
||
|
||
## So funktioniert es
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
autonumber
|
||
participant B as Browser
|
||
participant WP as WordPress<br/>(M365 Login)
|
||
participant MS as Microsoft Entra ID
|
||
participant G as Microsoft Graph<br/>(optional)
|
||
|
||
B->>WP: Klick auf „Login mit Microsoft“
|
||
WP->>WP: state, nonce, PKCE-Verifier erzeugen<br/>State-Cookie setzen (HttpOnly)
|
||
WP-->>B: Redirect zu Microsoft (code_challenge, state, nonce)
|
||
B->>MS: Anmeldung beim Microsoft-Konto
|
||
MS-->>B: Redirect zurück mit code + state
|
||
B->>WP: /m365-login/callback?code=…&state=…
|
||
WP->>WP: State einmalig einlösen, Cookie prüfen
|
||
WP->>MS: Code + code_verifier + Client Secret (Server-zu-Server)
|
||
MS-->>WP: ID-Token
|
||
WP->>MS: Signaturschlüssel (JWKS, gecacht)
|
||
WP->>WP: Signatur, Issuer, Audience, Tenant, exp, Nonce prüfen
|
||
opt Gruppen-Beschränkung aktiv
|
||
WP->>G: checkMemberGroups(oid, erlaubte Gruppen)
|
||
G-->>WP: Treffer / kein Treffer
|
||
end
|
||
WP->>WP: Benutzer per E-Mail suchen, Objekt-ID abgleichen
|
||
WP-->>B: WordPress-Session, Redirect ins Dashboard
|
||
```
|
||
|
||
Tokens laufen ausschließlich zwischen deinem Server und Microsoft. Der Browser sieht nur einen Autorisierungscode, der ohne den serverseitigen PKCE-Verifier und das Client Secret wertlos ist.
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
**Variante A – manuell (empfohlen, solange das Plugin nicht im Verzeichnis ist)**
|
||
|
||
```bash
|
||
git clone https://github.com/friloo/wp-m365-login.git
|
||
cd wp-m365-login
|
||
bash bin/build-zip.sh # erzeugt build/m365-login.zip
|
||
```
|
||
|
||
Dann in WordPress unter *Plugins → Installieren → Plugin hochladen* das ZIP hochladen und aktivieren.
|
||
Alternativ den Repo-Inhalt als Ordner `m365-login` nach `wp-content/plugins/` kopieren.
|
||
|
||
**Variante B – WordPress.org** (nach der Freigabe): *Plugins → Installieren → „M365 Login“*.
|
||
|
||
> **Voraussetzungen:** WordPress ≥ 6.0, PHP ≥ 7.4 mit OpenSSL-Erweiterung, HTTPS auf der Website (Microsoft akzeptiert `http://` nur für `localhost`).
|
||
|
||
---
|
||
|
||
## Einrichtung in Microsoft Entra ID
|
||
|
||
<details open>
|
||
<summary><strong>Schritt für Schritt (ca. 5 Minuten)</strong></summary>
|
||
|
||
1. **Redirect-URI kopieren.** In WordPress *Einstellungen → M365 Login* öffnen; die URI steht in der Seitenleiste
|
||
(`https://deine-seite.tld/m365-login/callback`, bei einfachen Permalinks `https://deine-seite.tld/?m365-login=callback`).
|
||
2. **App registrieren.** [Microsoft Entra Admin Center](https://entra.microsoft.com/) → *App-Registrierungen → Neue Registrierung*
|
||
- Name: z. B. „WordPress Login“
|
||
- Unterstützte Kontotypen: **Nur Konten in diesem Organisationsverzeichnis** (Single Tenant)
|
||
- Umleitungs-URI: Plattform **Web**, URI aus Schritt 1
|
||
3. **IDs übernehmen.** Auf der Übersichtsseite **Anwendungs-ID (Client)** und **Verzeichnis-ID (Mandant)** kopieren → in WordPress eintragen.
|
||
4. **Client Secret erstellen.** *Zertifikate & Geheimnisse → Neuer geheimer Clientschlüssel* → den **Wert** (nicht die Geheimnis-ID) in WordPress eintragen.
|
||
Das Ablaufdatum notieren – abgelaufene Secrets müssen erneuert werden.
|
||
5. **E-Mail-Claim aktivieren** (empfohlen). *Tokenkonfiguration → Optionalen Anspruch hinzufügen → ID → `email`*.
|
||
6. **Speichern** und mit *Tenant testen* prüfen, ob Microsoft erreichbar ist.
|
||
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Zusätzlich für die Gruppen-Beschränkung</strong></summary>
|
||
|
||
Damit das Backend Gruppen suchen und beim Login die Mitgliedschaft prüfen kann, braucht die App-Registrierung
|
||
**Anwendungsberechtigungen** (nicht delegiert) für Microsoft Graph, jeweils mit **Administratorzustimmung**:
|
||
|
||
| Berechtigung | Wofür |
|
||
| --- | --- |
|
||
| `GroupMember.Read.All` | Gruppen im Backend suchen |
|
||
| `User.Read.All` | Mitgliedschaft beim Login prüfen (`checkMemberGroups`, inkl. verschachtelter Gruppen) |
|
||
|
||
`Directory.Read.All` deckt beides ab, ist aber weiter gefasst.
|
||
|
||
**Ohne Graph-Berechtigungen** geht es auch: Unter *Tokenkonfiguration → Gruppenanspruch hinzufügen* den `groups`-Claim
|
||
für ID-Tokens aktivieren (am besten *Der Anwendung zugewiesene Gruppen* oder *Sicherheitsgruppen*). Dann prüft das Plugin die
|
||
Mitgliedschaft direkt im Token. Gruppen-IDs lassen sich im Backend auch von Hand einfügen. Bei mehr als 200 Gruppen pro
|
||
Benutzer liefert Microsoft keinen `groups`-Claim mehr („Overage“); dann greift das Plugin automatisch auf Graph zurück.
|
||
|
||
</details>
|
||
|
||
Wichtig: Jeder Benutzer, der sich per Microsoft anmelden soll, braucht in WordPress **dieselbe E-Mail-Adresse** wie in Microsoft 365.
|
||
|
||
---
|
||
|
||
## Einstellungen im Backend
|
||
|
||
*Einstellungen → M365 Login* – drei Tabs, ein Formular, ein Speichern-Button.
|
||
|
||
### Verbindung
|
||
|
||
| Feld | Beschreibung |
|
||
| --- | --- |
|
||
| Verzeichnis-ID (Tenant) | GUID des Tenants (empfohlen, aktiviert Tenant-Pinning) oder `organizations` / `common` / `consumers`. |
|
||
| Anwendungs-ID (Client) | GUID der App-Registrierung. |
|
||
| Client Secret | Wird verschlüsselt gespeichert und nie wieder angezeigt. Leer lassen = behalten. |
|
||
| Kontoauswahl | `select_account` (Standard), `none` (bestehende Microsoft-Sitzung nutzen) oder `login` (immer Anmeldedaten verlangen). |
|
||
| Tenant testen | Lädt die OpenID-Konfiguration des Tenants – prüft ID und ausgehende Verbindung. |
|
||
|
||
### Button
|
||
|
||
| Option | Beschreibung |
|
||
| --- | --- |
|
||
| Button-Text | Standard „Sign in with Microsoft“ / „Login mit Microsoft“ (max. 80 Zeichen). |
|
||
| Trennlinien-Text | Standard „or“ / „oder“; leer = keine Trennlinie. |
|
||
| Icon | Microsoft-Logo (eingebettet) oder eigenes Bild aus der Mediathek (PNG, SVG, JPG, WebP). Ein-/ausblendbar. |
|
||
| Farben | Hintergrund, Hintergrund (Hover), Text, Rahmen – mit Farbwähler. |
|
||
| Eckenradius | 0–50 px. |
|
||
| Position | Unter dem Login-Formular (Standard) oder darüber. |
|
||
| Presets | Microsoft dunkel, Microsoft hell, Azure-Blau, WordPress-Blau. |
|
||
|
||
Alles wird live in der Vorschau angezeigt, bevor du speicherst.
|
||
|
||
### Sicherheit
|
||
|
||
| Option | Standard | Beschreibung |
|
||
| --- | --- | --- |
|
||
| Konto an Microsoft-Objekt-ID binden | an | Beim ersten Login wird die `oid` gespeichert; danach muss sie übereinstimmen. Schützt vor Übernahme, wenn eine E-Mail-Adresse in Microsoft neu vergeben wird. |
|
||
| UPN-Fallback | an | Fehlt der `email`-Claim, wird der User Principal Name verwendet, sofern er eine gültige E-Mail-Adresse ist. |
|
||
| Angemeldet bleiben | aus | 14-Tage-Session statt Browser-Session. |
|
||
| Erlaubte E-Mail-Domains | leer | Kommagetrennte Liste, z. B. `contoso.com, contoso.de`. |
|
||
|
||
### Gruppen-Beschränkung
|
||
|
||
Im Tab *Sicherheit* → **Erlaubte Entra-Gruppen**:
|
||
|
||
1. Gruppenname eintippen (oder Objekt-ID einfügen) → *Suchen*.
|
||
2. Treffer mit *Hinzufügen* übernehmen – sie erscheinen als Chips mit Name und ID.
|
||
3. Speichern. Ab jetzt darf sich nur anmelden, wer in **mindestens einer** dieser Gruppen ist (verschachtelte Mitgliedschaften zählen).
|
||
|
||
Prüfreihenfolge beim Login:
|
||
|
||
1. Enthält das ID-Token einen `groups`-Claim → Abgleich direkt im Token.
|
||
2. Sonst (oder bei Overage) → Microsoft Graph `checkMemberGroups`.
|
||
3. Schlägt beides fehl → **Anmeldung abgelehnt** (fail closed), Meldung „Gruppenmitgliedschaft konnte nicht geprüft werden“.
|
||
|
||
Leere Liste = keine Beschränkung.
|
||
|
||
### Nur-Button-Modus & Fallback
|
||
|
||
Im Tab *Sicherheit* → **Button-only mode**:
|
||
|
||
- Blendet Benutzername/Passwort-Felder und den „Passwort vergessen?“-Link aus.
|
||
- **Sperrt Passwort-Logins** über `wp-login.php` serverseitig – nicht nur per CSS.
|
||
- Application Passwords, REST API und XML-RPC sind nicht betroffen.
|
||
- Wird erst aktiv, wenn die Verbindung vollständig konfiguriert ist.
|
||
|
||
**Fallback (Notausgang):** Beim Speichern erzeugt das Plugin einen geheimen Schlüssel und zeigt den Fallback-Link an:
|
||
|
||
```
|
||
https://deine-seite.tld/wp-login.php?m365_fallback=AbC…xYz
|
||
```
|
||
|
||
Wer den Link öffnet, sieht für **30 Minuten in diesem Browser** wieder das normale Formular und kann sich mit Passwort anmelden.
|
||
Der Schlüssel landet nicht im Cookie (nur ein HMAC davon), Fehlversuche werden pro IP gedrosselt (10 Versuche / 15 Minuten),
|
||
und über die Checkbox *Neuen Schlüssel beim Speichern erzeugen* lässt er sich jederzeit rotieren.
|
||
|
||
**Notschalter ohne Backend-Zugang:** In `wp-config.php`
|
||
|
||
```php
|
||
define( 'M365_LOGIN_DISABLE_BUTTON_ONLY', true );
|
||
```
|
||
|
||
schaltet den Modus komplett ab. Alternativ das Plugin-Verzeichnis per FTP umbenennen.
|
||
|
||
> ⚠️ Vor dem Aktivieren sicherstellen, dass dein eigenes Admin-Konto per Microsoft funktioniert, und den Fallback-Link sicher ablegen.
|
||
|
||
---
|
||
|
||
## Sicherheitskonzept
|
||
|
||
| Bedrohung | Gegenmaßnahme |
|
||
| --- | --- |
|
||
| Abfangen von Tokens im Browser | Authorization Code Flow **mit PKCE (S256)**; ID-Token wird serverseitig geholt, `response_mode=query` ohne Token. |
|
||
| CSRF / Login-CSRF | `state` ist zufällig (256 Bit), **einmalig** verwendbar, 10 Min. gültig und per HttpOnly-/SameSite-Cookie an den startenden Browser gebunden. |
|
||
| Token-Replay | `nonce` wird im ID-Token geprüft und mit dem State-Datensatz verworfen. |
|
||
| Gefälschte Tokens | Signaturprüfung gegen Microsofts JWKS (`RS256` only; `alg=none`/HMAC werden abgelehnt), Schlüssel-Rollover wird automatisch nachgeladen. `iss`, `aud`, `tid`, `exp`, `nbf`, `iat` werden geprüft. |
|
||
| Fremde Tenants | Bei konfigurierter Tenant-GUID **Tenant-Pinning**; sonst Issuer-Konsistenz mit `tid`. |
|
||
| Kontoübernahme per E-Mail-Recycling | **Bindung an die Objekt-ID** (`oid`) beim ersten Login. |
|
||
| Unbefugte Konten | Kein Provisioning, optionale Domain-Allowlist, optionale Gruppen-Beschränkung (fail closed). |
|
||
| Secret-Diebstahl aus der Datenbank | AES-256-GCM, Schlüssel per HKDF aus `AUTH_KEY`/`SECURE_AUTH_KEY`; ohne `wp-config.php` ist der Datensatz wertlos. |
|
||
| Offene Redirects | `redirect_to` läuft durch `wp_validate_redirect`, alle Redirects über `wp_safe_redirect`. |
|
||
| Fehler-Reflektion | Fehlermeldungen sind Codes → feste, übersetzte Texte; Details nur ins Log (`WP_DEBUG_LOG`). |
|
||
| Rate Limiting Fallback-Key | 10 Fehlversuche pro IP / 15 Min. |
|
||
|
||
Die Klassen für JWT-Prüfung und Verschlüsselung haben isolierte Tests (manipulierte Signaturen, abgelaufene Tokens, falsche Audience/Tenant/Issuer, `alg=none`, fremde Schlüssel).
|
||
|
||
---
|
||
|
||
## Shortcode & Hooks
|
||
|
||
**Shortcode** für eigene Login-Seiten:
|
||
|
||
```
|
||
[m365_login_button redirect="/mein-konto/"]
|
||
```
|
||
|
||
**Filter & Actions**
|
||
|
||
```php
|
||
// Button z. B. nur im Intranet zeigen
|
||
add_filter( 'm365_login_show_button', function ( $show ) {
|
||
return $show && 'intranet.example.com' === $_SERVER['HTTP_HOST'];
|
||
} );
|
||
|
||
// domain_hint mitschicken, damit Microsoft direkt die Firmenanmeldung zeigt
|
||
add_filter( 'm365_login_authorize_params', function ( $params ) {
|
||
$params['domain_hint'] = 'contoso.com';
|
||
return $params;
|
||
} );
|
||
|
||
// E-Mail vor dem Lookup umschreiben (z. B. Alias-Domain)
|
||
add_filter( 'm365_login_match_email', function ( $email, $claims ) {
|
||
return str_replace( '@alt.contoso.com', '@contoso.com', $email );
|
||
}, 10, 2 );
|
||
|
||
// Eigene Zusatzprüfung nach allen Plugin-Checks
|
||
add_filter( 'm365_login_allow_user', function ( $allowed, WP_User $user, array $claims ) {
|
||
return $allowed && ! in_array( 'subscriber', $user->roles, true );
|
||
}, 10, 3 );
|
||
|
||
// Nach erfolgreichem Login, z. B. Anzeigenamen synchronisieren
|
||
add_action( 'm365_login_success', function ( WP_User $user, array $claims ) {
|
||
if ( ! empty( $claims['name'] ) ) {
|
||
wp_update_user( array( 'ID' => $user->ID, 'display_name' => $claims['name'] ) );
|
||
}
|
||
}, 10, 2 );
|
||
|
||
// Redirect-URI anpassen (z. B. hinter einem Reverse Proxy)
|
||
add_filter( 'm365_login_redirect_uri', fn( $uri ) => 'https://www.example.com/m365-login/callback' );
|
||
```
|
||
|
||
---
|
||
|
||
## Fehlerbehebung
|
||
|
||
| Meldung auf der Login-Seite | Ursache & Lösung |
|
||
| --- | --- |
|
||
| *Microsoft login is not configured yet.* | Tenant-ID, Client-ID oder Secret fehlt. |
|
||
| *The login request expired or was invalid.* | State abgelaufen (> 10 Min.), Cookie blockiert oder Seite doppelt geladen. Erneut versuchen; Cookies für die Domain erlauben. |
|
||
| *Could not complete the sign-in with Microsoft.* | Token-Tausch fehlgeschlagen – meist falsches/abgelaufenes Client Secret oder Redirect-URI stimmt nicht exakt mit Entra überein. Details im Log. |
|
||
| *The Microsoft sign-in could not be verified.* | ID-Token abgelehnt (Tenant, Audience, Signatur). Tenant-ID prüfen; Serverzeit prüfen (NTP). |
|
||
| *Your Microsoft account did not provide an e-mail address.* | `email`-Claim fehlt und UPN-Fallback ist aus oder UPN ist keine E-Mail. Claim in der Tokenkonfiguration hinzufügen. |
|
||
| *No WordPress account exists for your Microsoft e-mail address.* | E-Mail in WordPress stimmt nicht mit Microsoft überein. |
|
||
| *This WordPress account is linked to a different Microsoft account.* | Objekt-ID weicht ab. Wenn gewollt (neues Microsoft-Konto): User-Meta `_m365_login_oid` beim Benutzer löschen. |
|
||
| *… not a member of a group that is allowed …* | Benutzer ist in keiner der ausgewählten Gruppen. |
|
||
| *Your group membership could not be verified.* | Graph nicht erreichbar oder Berechtigung fehlt (`User.Read.All`) – oder `groups`-Claim aktivieren. |
|
||
|
||
Logging: Mit `WP_DEBUG` und `WP_DEBUG_LOG` schreibt das Plugin Fehlerdetails mit Präfix `[M365 Login]` nach `wp-content/debug.log`. Es werden nie Tokens oder Secrets geloggt.
|
||
|
||
---
|
||
|
||
## Entwicklung
|
||
|
||
```
|
||
m365-login.php Plugin-Header & Bootstrap
|
||
includes/
|
||
class-m365-login.php Verdrahtung der Komponenten
|
||
class-m365-login-settings.php Defaults, Sanitizing, Redirect-URI, Fallback-Key
|
||
class-m365-login-crypto.php AES-256-GCM für das Client Secret
|
||
class-m365-login-jwt.php RS256-Verifikation, JWKS → PEM
|
||
class-m365-login-auth.php OAuth-Flow, Callback, Benutzerzuordnung, Nur-Button-Modus
|
||
class-m365-login-graph.php Client-Credentials-Token, Gruppensuche, checkMemberGroups
|
||
class-m365-login-button.php Ausgabe auf wp-login.php, Shortcode
|
||
class-m365-login-admin.php Einstellungsseite, AJAX
|
||
assets/ CSS/JS für Login-Seite und Backend (unminifiziert)
|
||
languages/ .pot, de_DE, de_DE_formal
|
||
bin/ build-zip.sh, make-pot.py, compile-mo.py
|
||
docs/ Einreichungs-Checkliste
|
||
```
|
||
|
||
```bash
|
||
composer install # PHPCS + WordPress Coding Standards + PHPCompatibility
|
||
composer lint # php -l für alle Dateien
|
||
composer phpcs # Coding-Standards-Prüfung (phpcs.xml.dist)
|
||
python3 bin/make-pot.py # Strings extrahieren (oder: wp i18n make-pot . languages/m365-login.pot)
|
||
python3 bin/compile-mo.py # .po → .mo
|
||
bash bin/build-zip.sh # build/m365-login.zip
|
||
```
|
||
|
||
Die CI (`.github/workflows/ci.yml`) prüft Syntax unter PHP 7.4–8.4, führt PHPCS aus und lässt den offiziellen
|
||
**WordPress Plugin Check** über das Build-Verzeichnis laufen.
|
||
|
||
---
|
||
|
||
## Einreichung bei WordPress.org
|
||
|
||
Das Plugin bringt alles mit, was das Review-Team verlangt: `readme.txt` mit *External services*-Abschnitt, GPL-Lizenz,
|
||
`uninstall.php`, eindeutige Präfixe, keine externen Assets, Übersetzungen, Verzeichnis-Icon. Die komplette Checkliste
|
||
(inkl. Slug-/Marken-Hinweisen und SVN-Schritten nach der Freigabe) steht in
|
||
**[docs/wordpress-org-einreichung.md](docs/wordpress-org-einreichung.md)**.
|
||
|
||
---
|
||
|
||
## FAQ
|
||
|
||
<details>
|
||
<summary><strong>Kann ich Benutzer automatisch anlegen lassen?</strong></summary>
|
||
Nein, bewusst nicht. Der Admin entscheidet, wer ein Konto hat. Wer Auto-Provisioning braucht, kann es über den Hook <code>m365_login_allow_user</code> nicht nachrüsten – das wäre ein anderes Sicherheitsmodell.
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Funktioniert es mit privaten Microsoft-Konten (outlook.com)?</strong></summary>
|
||
Ja, Tenant auf <code>consumers</code> oder <code>common</code> stellen. Microsoft erlaubt dann keine Query-Strings in Redirect-URIs, deshalb müssen sprechende Permalinks aktiv sein (Callback ohne <code>?</code>).
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Multisite?</strong></summary>
|
||
Ja. Einstellungen gelten pro Site; der Benutzer muss Mitglied der Site (oder Super-Admin) sein.
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Was passiert beim Deinstallieren?</strong></summary>
|
||
Einstellungen, Caches (Transients) und die pro Benutzer gespeicherte Objekt-ID werden entfernt – auch in Multisite.
|
||
</details>
|
||
|
||
<details>
|
||
<summary><strong>Ich habe mich ausgesperrt.</strong></summary>
|
||
Fallback-Link öffnen. Kein Link zur Hand? <code>define( 'M365_LOGIN_DISABLE_BUTTON_ONLY', true );</code> in die <code>wp-config.php</code> oder den Plugin-Ordner per FTP umbenennen.
|
||
</details>
|
||
|
||
---
|
||
|
||
## Lizenz
|
||
|
||
GPL-2.0-or-later – siehe [LICENSE](LICENSE). „Microsoft“, „Microsoft 365“ und das Microsoft-Logo sind Marken der Microsoft Corporation;
|
||
das Plugin ist ein unabhängiges Community-Projekt und steht in keiner Verbindung zu Microsoft.
|