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

43 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
All notable changes to this project are documented in this file. The format follows
[Keep a Changelog](https://keepachangelog.com/) and the plugin adheres to
[Semantic Versioning](https://semver.org/).
## [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.