diff --git a/CHANGELOG.md b/CHANGELOG.md index ad01554..00a7802 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,5 +15,6 @@ All notable changes to this project are documented in this file. The format foll - Account binding to the Microsoft object ID, e-mail domain allow-list. - Entra group restriction with a Graph-powered group picker; membership verified via the `groups` claim or Microsoft Graph `checkMemberGroups`. - Button-only mode that hides the password form and blocks password sign-in on `wp-login.php`, with a secret, rate-limited fallback link and a `wp-config.php` emergency constant. -- `[m365_login_button]` shortcode and developer hooks. +- Custom login page support: automatic button in `wp_login_form()` forms, `m365_login_button()` / `m365_login_messages()` template functions, custom login URL for error messages, fallback link and logout redirect. +- `[m365_login_button]` shortcode (with `divider` and `messages` attributes) and developer hooks. - German translation. diff --git a/README.md b/README.md index a8385fb..8a03aca 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ - [Sicherheit](#sicherheit) - [Gruppen-Beschränkung](#gruppen-beschränkung) - [Nur-Button-Modus & Fallback](#nur-button-modus--fallback) + - [Eigene Login-Seite](#eigene-login-seite) - [Sicherheitskonzept](#sicherheitskonzept) - [Shortcode & Hooks](#shortcode--hooks) - [Fehlerbehebung](#fehlerbehebung) @@ -230,8 +231,8 @@ Leere Liste = keine Beschränkung. 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. +- **Sperrt Passwort-Logins serverseitig**, nicht nur per CSS – auf `wp-login.php` und in jedem eigenen Login-Formular (`authenticate`-Filter). +- Application Passwords, REST API, XML-RPC, WP-CLI und Cron sind nicht betroffen. Einzelne Ausnahmen per Filter `m365_login_block_password_login`. - 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: @@ -254,6 +255,20 @@ schaltet den Modus komplett ab. Alternativ das Plugin-Verzeichnis per FTP umbene > ⚠️ Vor dem Aktivieren sicherstellen, dass dein eigenes Admin-Konto per Microsoft funktioniert, und den Fallback-Link sicher ablegen. +### Eigene Login-Seite + +Das Plugin funktioniert auch, wenn die Anmeldung nicht über `wp-login.php` läuft. + +| Baustein | Was passiert | +| --- | --- | +| **`wp_login_form()`** (Themes, viele Login-Plugins) | Der Button wird automatisch unter dem Formular eingefügt, inklusive Fehlermeldungen darüber. Im Nur-Button-Modus werden die Passwortfelder ausgeblendet. Abschaltbar im Tab *Button*. | +| **Shortcode** | `[m365_login_button redirect="/dashboard/" divider="yes" messages="yes"]` für Block-Editor und Page Builder (Elementor, Divi, …). | +| **Template-Funktion** | `m365_login_button( array( 'redirect' => '/dashboard/' ) );` in Theme-Dateien, `m365_login_messages();` für die Meldungen an anderer Stelle. | +| **URL der Login-Seite** (Tab *Button* → *Eigene Login-Seite*) | Fehlermeldungen nach einem gescheiterten Microsoft-Login, der Fallback-Link und die Weiterleitung nach dem Abmelden zeigen auf diese Seite statt auf `wp-login.php`. | +| **Nur-Button-Modus** | Greift serverseitig für alle Passwort-Logins, also auch für Formulare von Page Buildern, die das Plugin nicht ausblenden kann. | + +Plugins, die `wp-login.php` umbenennen (z. B. WPS Hide Login), sind kompatibel, weil das Plugin durchgehend `wp_login_url()` verwendet. + --- ## Sicherheitskonzept @@ -315,6 +330,11 @@ add_action( 'm365_login_success', function ( WP_User $user, array $claims ) { } }, 10, 2 ); +// Ein vertrauenswürdiges Plugin darf trotz Nur-Button-Modus per Passwort anmelden +add_filter( 'm365_login_block_password_login', function ( $block, WP_User $user ) { + return doing_action( 'my_membership_plugin_login' ) ? false : $block; +}, 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' ); ``` diff --git a/assets/css/login.css b/assets/css/login.css index 9fba99d..5ad87a8 100644 --- a/assets/css/login.css +++ b/assets/css/login.css @@ -134,3 +134,45 @@ body.m365-button-only .m365-login--above { border: 1px solid #c3c4c7; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04); } + +/* Custom login pages: wp_login_form() injection, shortcode and template function. */ +.m365-login--form { + margin: 16px 0 0; + padding: 0; + border: 0; + background: transparent; +} + +.m365-login--form .m365-login__divider span, +.m365-login--shortcode .m365-login__divider span { + background: transparent; +} + +.m365-login--form .m365-login__divider, +.m365-login--shortcode .m365-login__divider { + margin: 0 0 16px; +} + +.m365-login__notice { + box-sizing: border-box; + margin: 0 0 16px; + padding: 12px 14px; + border-left: 4px solid #72aee6; + background: #fff; + color: #1d2327; + font-size: 14px; + line-height: 1.5; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); +} + +.m365-login__notice--error { + border-left-color: #d63638; +} + +.m365-login__notice--message { + border-left-color: #00a32a; +} + +.m365-login__hidden-fields { + display: none !important; +} diff --git a/includes/class-m365-login-admin.php b/includes/class-m365-login-admin.php index 1fbd0f0..b5d143b 100644 --- a/includes/class-m365-login-admin.php +++ b/includes/class-m365-login-admin.php @@ -408,6 +408,33 @@ class M365_Login_Admin { +
+

+

+ +
+ + +

+
+ + + +
+ +

+ [m365_login_button redirect="/dashboard/" divider="yes"] +

+ <?php m365_login_button( array( 'redirect' => '/dashboard/' ) ); ?> +

+
+
@@ -483,7 +510,7 @@ class M365_Login_Admin {

-

+