wp-m365-login/CHANGELOG.md
Friederich Loheide 9f77e9027f
Some checks are pending
CI / PHP lint (7.4) (pull_request) Waiting to run
CI / PHP lint (8.0) (pull_request) Waiting to run
CI / PHP lint (8.1) (pull_request) Waiting to run
CI / PHP lint (8.2) (pull_request) Waiting to run
CI / PHP lint (8.3) (pull_request) Waiting to run
CI / PHP lint (8.4) (pull_request) Waiting to run
CI / WordPress Coding Standards (pull_request) Waiting to run
CI / WordPress.org Plugin Check (pull_request) Waiting to run
Keep profile photos and fields in line with Microsoft 365 on every run
- Photo versions are compared on every sync run via Graph $batch
  (20 users per request); only changed photos are downloaded, the old
  file is deleted and the avatar URL changes. Photos deleted in
  Microsoft 365 are deleted in WordPress. Graph errors never delete a
  photo. Download limit per run (500) with deferral to the next run.
- Switching the photo sync off removes all stored photos; deselected
  m365_* profile fields are removed from the profiles.
- A user's photo is deleted together with the user (delete_user hook).
- Dry run reports photo changes without downloading.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 16:40:45 +00:00

4.3 KiB
Raw Blame History

Changelog

All notable changes to this project are documented in this file. The format follows Keep a Changelog and the plugin adheres to Semantic Versioning.

[1.1.0] 2026-09-23

Added

  • User sync (new "User sync" tab): imports Microsoft 365 / Entra ID users as WordPress accounts the whole tenant or the (nested) members of selected groups, guests optional and links existing accounts by e-mail address.
  • Default role plus group → role mapping with a Graph-powered group picker; mapped roles either added to or replacing the default role (first match wins, reorderable). Roles of accounts that existed before the sync are only managed on request.
  • Selectable profile attributes (display name, first/last name, job title, department, company, office, employee ID, phones, address, language) and the profile photo, which replaces the Gravatar.
  • Profile photos follow Microsoft 365 on every run: versions are compared via Graph $batch (20 users per request), changed photos are downloaded again (old file deleted, new URL), photos deleted in Microsoft 365 are deleted in WordPress. Errors never delete a photo.
  • Deselected profile fields (m365_*) and photos are removed from the profiles on the next run; fields cleared in Microsoft 365 are cleared in WordPress; a user's photo is deleted together with the user.
  • Deactivation or deletion of WordPress accounts whose Microsoft 365 account was disabled, deleted or removed from the sync groups; automatic reactivation. Deactivated accounts cannot sign in at all (Microsoft, password, application passwords) and lose all sessions.
  • Safeguards: dry run, safety stop above 20 % deprovisioning (at least 5 accounts), abort on any Graph error, deletion only on a 404 for the object ID, protected pre-existing administrators and own account, content reassignment required for deletion, run lock.
  • Scheduled sync via WP-Cron (hourly, twice daily, daily), wp m365-login sync [--dry-run], report of the last run in the settings.
  • "Microsoft 365" column and deactivate/reactivate row actions on the users screen; read-only Microsoft 365 section on the profile screen.
  • Graph client: paging, retry on throttling (429/503/504), user, group member and photo endpoints.
  • Filters and actions for the sync (m365_login_sync_*, m365_login_user_disabled, m365_login_user_enabled).

Changed

  • The group picker is reusable (security groups, sync groups, role mapping).

Fixed

  • "Generate certificate" and removing the certificate did not keep the change and encrypted a stored client secret a second time (internal settings writes ran through the form sanitiser).

[1.0.0] 2026-09-22

Added

  • "Sign in with Microsoft" button on wp-login.php (OpenID Connect authorization code flow with PKCE).
  • Matching of existing WordPress users by e-mail address (optional UPN fallback), no user provisioning.
  • Settings screen (own top-level menu entry "M365 Login") with connection, button and security tabs, live button preview, colour presets, media-library icon picker, redirect-URI copy button and tenant connectivity test.
  • ID token verification against Microsoft's JWKS (RS256, issuer, audience, tenant, expiry, nonce).
  • Encrypted client secret storage (AES-256-GCM).
  • Certificate based client authentication (RFC 7523 private_key_jwt): one-click generation of a 3072-bit RSA key pair with self-signed certificate, .cer download, own PEM upload, expiry display; step-by-step guides for both methods in the settings.
  • Security audit (docs/security-audit.md) with fixes: unverified email claim ignored in multi-tenant mode, login-start rate limit, trusted proxy IP header.
  • 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.
  • 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.