Add M365 Login plugin: Microsoft Entra ID sign-in for existing users

Adds a WordPress plugin that places a customisable "Sign in with
Microsoft" button on wp-login.php and signs existing users in via the
OpenID Connect authorization code flow with PKCE. Users are matched by
e-mail address only; no accounts are created.

Security: single-use state/nonce bound to an HttpOnly cookie, ID token
signature verification against Microsoft's JWKS (RS256 only) with
issuer/audience/tenant/expiry/nonce checks, optional tenant pinning,
account binding to the Microsoft object ID, e-mail domain allow-list,
client secret encrypted at rest (AES-256-GCM).

Admin: settings screen with connection, button and security tabs, live
button preview, colour presets, media-library icon picker, redirect URI
copy button and tenant connectivity test.

Packaging for WordPress.org: readme.txt with External services section,
GPL-2.0 license, uninstall.php, POT + German translations, .distignore,
build script, PHPCS config and CI running Plugin Check.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JJxAHYdMfKPoN4koRc4Ci2
This commit is contained in:
friloo 2026-09-22 14:21:10 +00:00
commit 3e3e87b399
No known key found for this signature in database
35 changed files with 5413 additions and 0 deletions

View file

@ -0,0 +1,460 @@
# German translation for M365 Login.
# This file is distributed under the GPL-2.0-or-later.
msgid ""
msgstr ""
"Project-Id-Version: M365 Login 1.0.0\n"
"Report-Msgid-Bugs-To: https://github.com/friloo/wp-m365-login/issues\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2026-09-22T00:00:00+00:00\n"
"PO-Revision-Date: 2026-09-22 12:00+0000\n"
"Last-Translator: friloo\n"
"Language-Team: German\n"
"Language: de_DE_formal\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: bin/make-pot.py\n"
"X-Domain: m365-login\n"
#: includes/class-m365-login-admin.php:63 includes/class-m365-login-admin.php:64 includes/class-m365-login-admin.php:203
msgid "M365 Login"
msgstr "M365 Login"
#: includes/class-m365-login-admin.php:102
msgid "M365 Login is active but not connected to Microsoft Entra ID yet."
msgstr "M365 Login ist aktiv, aber noch nicht mit Microsoft Entra ID verbunden."
#: includes/class-m365-login-admin.php:104
msgid "Open the settings"
msgstr "Einstellungen öffnen"
#: includes/class-m365-login-admin.php:132
msgid "Choose button icon"
msgstr "Button-Icon auswählen"
#: includes/class-m365-login-admin.php:133
msgid "Use this icon"
msgstr "Dieses Icon verwenden"
#: includes/class-m365-login-admin.php:134
msgid "Copied!"
msgstr "Kopiert!"
#: includes/class-m365-login-admin.php:135 includes/class-m365-login-admin.php:427
msgid "Copy"
msgstr "Kopieren"
#: includes/class-m365-login-admin.php:136
msgid "Testing…"
msgstr "Wird geprüft …"
#: includes/class-m365-login-admin.php:137
msgid "The tenant could not be reached. Check the tenant ID and the servers outgoing connections."
msgstr "Der Tenant ist nicht erreichbar. Bitte Tenant-ID und ausgehende Verbindungen des Servers prüfen."
#: includes/class-m365-login-admin.php:149
msgid "You are not allowed to do this."
msgstr "Dafür fehlt die Berechtigung."
#: includes/class-m365-login-admin.php:154
msgid "Please enter a valid tenant ID first."
msgstr "Bitte zuerst eine gültige Tenant-ID eingeben."
#. translators: %d: HTTP status code
#: includes/class-m365-login-admin.php:168
msgid "Microsoft answered with HTTP %d. Is the tenant ID correct?"
msgstr "Microsoft hat mit HTTP %d geantwortet. Ist die Tenant-ID korrekt?"
#. translators: %d: HTTP status code
#: includes/class-m365-login-admin.php:177
msgid "Tenant reachable. The OpenID configuration was loaded successfully."
msgstr "Tenant erreichbar. Die OpenID-Konfiguration wurde erfolgreich geladen."
#: includes/class-m365-login-admin.php:187
msgid "You are not allowed to access this page."
msgstr "Für diese Seite fehlt die Berechtigung."
#: includes/class-m365-login-admin.php:204
msgid "Let existing users sign in with their Microsoft 365 / Entra ID account."
msgstr "Bestehende Benutzer melden sich mit ihrem Microsoft 365 / Entra ID-Konto an."
#: includes/class-m365-login-admin.php:209
msgid "Connected"
msgstr "Verbunden"
#: includes/class-m365-login-admin.php:209
msgid "Setup incomplete"
msgstr "Einrichtung unvollständig"
#: includes/class-m365-login-admin.php:217
msgid "Connection"
msgstr "Verbindung"
#: includes/class-m365-login-admin.php:218
msgid "Button"
msgstr "Button"
#: includes/class-m365-login-admin.php:219
msgid "Security"
msgstr "Sicherheit"
#: includes/class-m365-login-admin.php:228
msgid "Microsoft Entra ID app registration"
msgstr "App-Registrierung in Microsoft Entra ID"
#: includes/class-m365-login-admin.php:229
msgid "Enter the values from your app registration in the Microsoft Entra admin center."
msgstr "Tragen Sie hier die Werte aus Ihrer App-Registrierung im Microsoft Entra Admin Center ein."
#: includes/class-m365-login-admin.php:232
msgid "Directory (tenant) ID"
msgstr "Verzeichnis-ID (Mandant/Tenant)"
#: includes/class-m365-login-admin.php:235
msgid "Test tenant"
msgstr "Tenant testen"
#: includes/class-m365-login-admin.php:237
msgid "Recommended: the GUID of your tenant. Only sign-ins from this tenant are accepted. \"organizations\" allows any work or school account."
msgstr "Empfohlen: die GUID Ihres Tenants. Dann werden nur Anmeldungen aus diesem Tenant akzeptiert. „organizations“ erlaubt beliebige Geschäfts-, Schul- oder Unikonten."
#: includes/class-m365-login-admin.php:242
msgid "Application (client) ID"
msgstr "Anwendungs-ID (Client)"
#: includes/class-m365-login-admin.php:247
msgid "Client secret"
msgstr "Geheimer Clientschlüssel (Client Secret)"
#: includes/class-m365-login-admin.php:249
msgid "•••••••••••• (stored, leave empty to keep)"
msgstr "•••••••••••• (gespeichert leer lassen, um zu behalten)"
#: includes/class-m365-login-admin.php:249
msgid "Paste the secret value"
msgstr "Wert des Secrets einfügen"
#: includes/class-m365-login-admin.php:250
msgid "Show secret"
msgstr "Secret anzeigen"
#: includes/class-m365-login-admin.php:255
msgid "Remove the stored secret"
msgstr "Gespeichertes Secret entfernen"
#: includes/class-m365-login-admin.php:258
msgid "Stored encrypted (AES-256-GCM, key derived from your WordPress salts) and never displayed again. Client secrets expire note the expiry date in Entra ID."
msgstr "Wird verschlüsselt gespeichert (AES-256-GCM, Schlüssel aus den WordPress-Salts abgeleitet) und nie wieder angezeigt. Client Secrets laufen ab Ablaufdatum in Entra ID notieren."
#: includes/class-m365-login-admin.php:262
msgid "Account prompt"
msgstr "Kontoauswahl"
#: includes/class-m365-login-admin.php:264
msgid "Always let the user pick an account (recommended)"
msgstr "Benutzer wählt immer ein Konto aus (empfohlen)"
#: includes/class-m365-login-admin.php:265
msgid "Use the current Microsoft session if available"
msgstr "Vorhandene Microsoft-Sitzung verwenden, falls vorhanden"
#: includes/class-m365-login-admin.php:266
msgid "Always require re-entering credentials"
msgstr "Immer erneute Eingabe der Anmeldedaten verlangen"
#: includes/class-m365-login-admin.php:275
msgid "Appearance"
msgstr "Darstellung"
#: includes/class-m365-login-admin.php:278
msgid "Live preview"
msgstr "Live-Vorschau"
#: includes/class-m365-login-admin.php:292
msgid "Button text"
msgstr "Button-Text"
#: includes/class-m365-login-admin.php:296
msgid "Divider text"
msgstr "Trennlinien-Text"
#: includes/class-m365-login-admin.php:298
msgid "Leave empty to hide the divider line."
msgstr "Leer lassen, um die Trennlinie auszublenden."
#: includes/class-m365-login-admin.php:303
msgid "Icon"
msgstr "Icon"
#: includes/class-m365-login-admin.php:306
msgid "Show an icon on the button"
msgstr "Icon auf dem Button anzeigen"
#: includes/class-m365-login-admin.php:317
msgid "Default: Microsoft logo"
msgstr "Standard: Microsoft-Logo"
#: includes/class-m365-login-admin.php:319
msgid "Choose from media library"
msgstr "Aus Mediathek wählen"
#: includes/class-m365-login-admin.php:320
msgid "Use Microsoft logo"
msgstr "Microsoft-Logo verwenden"
#: includes/class-m365-login-admin.php:322
msgid "PNG, SVG, JPG or WebP. Square images (e.g. 64×64 px) work best."
msgstr "PNG, SVG, JPG oder WebP. Quadratische Bilder (z. B. 64×64 px) eignen sich am besten."
#: includes/class-m365-login-admin.php:330
msgid "Background"
msgstr "Hintergrund"
#: includes/class-m365-login-admin.php:331
msgid "Background (hover)"
msgstr "Hintergrund (Hover)"
#: includes/class-m365-login-admin.php:332
msgid "Text colour"
msgstr "Textfarbe"
#: includes/class-m365-login-admin.php:333
msgid "Border"
msgstr "Rahmen"
#: includes/class-m365-login-admin.php:346
msgid "Corner radius"
msgstr "Eckenradius"
#: includes/class-m365-login-admin.php:350
msgid "Position on the login page"
msgstr "Position auf der Login-Seite"
#: includes/class-m365-login-admin.php:352
msgid "Below the login form"
msgstr "Unter dem Login-Formular"
#: includes/class-m365-login-admin.php:353
msgid "Above the login form"
msgstr "Über dem Login-Formular"
#: includes/class-m365-login-admin.php:359
msgid "Quick presets"
msgstr "Schnellauswahl"
#: includes/class-m365-login-admin.php:360
msgid "Microsoft dark"
msgstr "Microsoft dunkel"
#: includes/class-m365-login-admin.php:361
msgid "Microsoft light"
msgstr "Microsoft hell"
#: includes/class-m365-login-admin.php:362
msgid "Azure blue"
msgstr "Azure-Blau"
#: includes/class-m365-login-admin.php:363
msgid "WordPress blue"
msgstr "WordPress-Blau"
#: includes/class-m365-login-admin.php:371
msgid "User matching & hardening"
msgstr "Benutzerzuordnung & Härtung"
#: includes/class-m365-login-admin.php:372
msgid "Users are never created automatically. A Microsoft sign-in only succeeds when a WordPress user with the same e-mail address already exists."
msgstr "Benutzer werden nie automatisch angelegt. Eine Microsoft-Anmeldung gelingt nur, wenn bereits ein WordPress-Benutzer mit derselben E-Mail-Adresse existiert."
#: includes/class-m365-login-admin.php:377
msgid "Bind WordPress accounts to the Microsoft object ID"
msgstr "WordPress-Konten an die Microsoft-Objekt-ID binden"
#: includes/class-m365-login-admin.php:378
msgid "On first sign-in the immutable Microsoft object ID is stored with the user. Later sign-ins with the same e-mail but a different Microsoft identity are rejected. Strongly recommended."
msgstr "Bei der ersten Anmeldung wird die unveränderliche Microsoft-Objekt-ID am Benutzer gespeichert. Spätere Anmeldungen mit gleicher E-Mail, aber anderer Microsoft-Identität werden abgelehnt. Dringend empfohlen."
#: includes/class-m365-login-admin.php:385
msgid "Fall back to the user principal name (UPN)"
msgstr "Auf den User Principal Name (UPN) zurückgreifen"
#: includes/class-m365-login-admin.php:386
msgid "If the token contains no \"email\" claim, use the UPN (e.g. jane@contoso.com) when it is a valid e-mail address. Usually required for work accounts."
msgstr "Enthält das Token keinen „email“-Claim, wird der UPN (z. B. jane@contoso.com) verwendet, sofern er eine gültige E-Mail-Adresse ist. Für Geschäftskonten meist erforderlich."
#: includes/class-m365-login-admin.php:393
msgid "Keep users signed in (\"Remember me\")"
msgstr "Benutzer angemeldet lassen („Angemeldet bleiben“)"
#: includes/class-m365-login-admin.php:394
msgid "Issues a 14-day WordPress session instead of a browser session."
msgstr "Erstellt eine 14-tägige WordPress-Sitzung statt einer Browser-Sitzung."
#: includes/class-m365-login-admin.php:399
msgid "Allowed e-mail domains (optional)"
msgstr "Erlaubte E-Mail-Domains (optional)"
#: includes/class-m365-login-admin.php:401
msgid "One or more domains separated by commas or new lines. Leave empty to allow any domain of your tenant."
msgstr "Eine oder mehrere Domains, getrennt durch Kommas oder Zeilenumbrüche. Leer lassen, um alle Domains des Tenants zuzulassen."
#: includes/class-m365-login-admin.php:406
msgid "What the plugin does to keep sign-ins safe"
msgstr "So schützt das Plugin die Anmeldung"
#: includes/class-m365-login-admin.php:408
msgid "OpenID Connect authorization code flow with PKCE (S256) no tokens ever pass through the browser."
msgstr "OpenID Connect Authorization Code Flow mit PKCE (S256) Tokens laufen nie durch den Browser."
#: includes/class-m365-login-admin.php:409
msgid "Single-use state and nonce values bound to the browser via an HttpOnly cookie (CSRF and replay protection)."
msgstr "Einmalige State- und Nonce-Werte, per HttpOnly-Cookie an den Browser gebunden (CSRF- und Replay-Schutz)."
#: includes/class-m365-login-admin.php:410
msgid "ID token signature verified against Microsofts published signing keys; issuer, audience, tenant, expiry and nonce are checked."
msgstr "Signatur des ID-Tokens wird gegen Microsofts veröffentlichte Signaturschlüssel geprüft; Issuer, Audience, Tenant, Ablauf und Nonce werden kontrolliert."
#: includes/class-m365-login-admin.php:411
msgid "Client secret encrypted at rest; no accounts are created, no passwords are changed."
msgstr "Client Secret verschlüsselt gespeichert; es werden keine Konten angelegt und keine Passwörter geändert."
#: includes/class-m365-login-admin.php:417
msgid "Save changes"
msgstr "Änderungen speichern"
#: includes/class-m365-login-admin.php:423
msgid "Redirect URI"
msgstr "Umleitungs-URI (Redirect URI)"
#: includes/class-m365-login-admin.php:424
msgid "Register this URI in your app registration under Authentication → Web → Redirect URIs:"
msgstr "Diese URI in der App-Registrierung unter Authentifizierung → Web → Umleitungs-URIs eintragen:"
#: includes/class-m365-login-admin.php:430
msgid "Plain permalinks are active, so the callback uses a query string. If you enable pretty permalinks later, the redirect URI changes and must be updated in Entra ID."
msgstr "Einfache Permalinks sind aktiv, daher verwendet der Callback einen Query-String. Werden später sprechende Permalinks aktiviert, ändert sich die Umleitungs-URI und muss in Entra ID angepasst werden."
#: includes/class-m365-login-admin.php:433
msgid "Your site does not use HTTPS. Microsoft only accepts http:// redirect URIs for localhost; production sites must use HTTPS."
msgstr "Diese Website nutzt kein HTTPS. Microsoft akzeptiert http://-Umleitungs-URIs nur für localhost; produktive Websites benötigen HTTPS."
#: includes/class-m365-login-admin.php:438
msgid "Setup in 5 steps"
msgstr "Einrichtung in 5 Schritten"
#: includes/class-m365-login-admin.php:440
msgid "Open the Microsoft Entra admin center → App registrations → New registration."
msgstr "Microsoft Entra Admin Center öffnen → App-Registrierungen → Neue Registrierung."
#: includes/class-m365-login-admin.php:441
msgid "Choose \"Accounts in this organizational directory only\", set the platform to Web and paste the redirect URI above."
msgstr "„Nur Konten in diesem Organisationsverzeichnis“ wählen, Plattform „Web“ auswählen und die Umleitungs-URI von oben einfügen."
#: includes/class-m365-login-admin.php:442
msgid "Copy the Application (client) ID and Directory (tenant) ID from the overview page."
msgstr "Anwendungs-ID (Client) und Verzeichnis-ID (Mandant) von der Übersichtsseite kopieren."
#: includes/class-m365-login-admin.php:443
msgid "Under Certificates & secrets create a client secret and copy its value (not the ID)."
msgstr "Unter „Zertifikate & Geheimnisse“ einen geheimen Clientschlüssel erstellen und dessen Wert (nicht die ID) kopieren."
#: includes/class-m365-login-admin.php:444
msgid "Under Token configuration add the optional claim \"email\" for ID tokens (recommended), then save this page."
msgstr "Unter „Tokenkonfiguration“ den optionalen Anspruch „email“ für ID-Tokens hinzufügen (empfohlen), dann diese Seite speichern."
#: includes/class-m365-login-admin.php:446
msgid "Required API permission: openid, profile, email (delegated) granted by default."
msgstr "Benötigte API-Berechtigungen: openid, profile, email (delegiert) standardmäßig vorhanden."
#: includes/class-m365-login-admin.php:450
msgid "Shortcode"
msgstr "Shortcode"
#: includes/class-m365-login-admin.php:451
msgid "Place the button on a custom login page:"
msgstr "Button auf einer eigenen Login-Seite platzieren:"
#: includes/class-m365-login-auth.php:593
msgid "Microsoft login is not configured yet."
msgstr "Die Microsoft-Anmeldung ist noch nicht eingerichtet."
#: includes/class-m365-login-auth.php:594
msgid "The login request expired or was invalid. Please try again."
msgstr "Die Anmeldeanfrage ist abgelaufen oder ungültig. Bitte erneut versuchen."
#: includes/class-m365-login-auth.php:595
msgid "Microsoft sign-in was cancelled."
msgstr "Die Microsoft-Anmeldung wurde abgebrochen."
#: includes/class-m365-login-auth.php:596
msgid "Microsoft returned an error. Please try again."
msgstr "Microsoft hat einen Fehler gemeldet. Bitte erneut versuchen."
#: includes/class-m365-login-auth.php:597
msgid "Could not complete the sign-in with Microsoft. Please try again or contact an administrator."
msgstr "Die Anmeldung über Microsoft konnte nicht abgeschlossen werden. Bitte erneut versuchen oder einen Administrator kontaktieren."
#: includes/class-m365-login-auth.php:598
msgid "The Microsoft sign-in could not be verified."
msgstr "Die Microsoft-Anmeldung konnte nicht verifiziert werden."
#: includes/class-m365-login-auth.php:599
msgid "Your Microsoft account did not provide an e-mail address."
msgstr "Das Microsoft-Konto hat keine E-Mail-Adresse übermittelt."
#: includes/class-m365-login-auth.php:600
msgid "Your e-mail domain is not allowed to sign in here."
msgstr "Diese E-Mail-Domain ist hier nicht zur Anmeldung zugelassen."
#: includes/class-m365-login-auth.php:601
msgid "No WordPress account exists for your Microsoft e-mail address."
msgstr "Für die E-Mail-Adresse des Microsoft-Kontos existiert kein WordPress-Konto."
#: includes/class-m365-login-auth.php:602
msgid "This WordPress account is linked to a different Microsoft account. Please contact an administrator."
msgstr "Dieses WordPress-Konto ist mit einem anderen Microsoft-Konto verknüpft. Bitte einen Administrator kontaktieren."
#: includes/class-m365-login-auth.php:603
msgid "You are not allowed to sign in with this account."
msgstr "Die Anmeldung mit diesem Konto ist nicht erlaubt."
#: includes/class-m365-login-settings.php:40
msgid "Sign in with Microsoft"
msgstr "Login mit Microsoft"
#: includes/class-m365-login-settings.php:49
msgid "or"
msgstr "oder"
#: includes/class-m365-login-settings.php:176
msgid "The tenant ID must be a GUID (e.g. 1a2b3c4d-…) or one of \"organizations\", \"common\", \"consumers\"."
msgstr "Die Tenant-ID muss eine GUID (z. B. 1a2b3c4d-…) oder einer der Werte „organizations“, „common“, „consumers“ sein."
#: includes/class-m365-login-settings.php:184
msgid "The application (client) ID must be a GUID."
msgstr "Die Anwendungs-ID (Client) muss eine GUID sein."
#: includes/class-m365-login-settings.php:196
msgid "The client secret contains invalid characters."
msgstr "Das Client Secret enthält ungültige Zeichen."
#: includes/class-m365-login-settings.php:200
msgid "The client secret could not be encrypted. Is the OpenSSL extension available?"
msgstr "Das Client Secret konnte nicht verschlüsselt werden. Ist die OpenSSL-Erweiterung verfügbar?"
#: includes/class-m365-login.php:94
msgid "Settings"
msgstr "Einstellungen"
#: includes/class-m365-login.php:105
msgid "M365 Login requires PHP 7.4 or newer."
msgstr "M365 Login benötigt PHP 7.4 oder neuer."
#: includes/class-m365-login.php:106 includes/class-m365-login.php:115
msgid "Plugin activation failed"
msgstr "Plugin-Aktivierung fehlgeschlagen"
#: includes/class-m365-login.php:114
msgid "M365 Login requires the PHP OpenSSL extension (needed to verify Microsoft token signatures and to encrypt the client secret)."
msgstr "M365 Login benötigt die PHP-Erweiterung OpenSSL (zur Prüfung der Microsoft-Token-Signaturen und zur Verschlüsselung des Client Secrets)."