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
New "User sync" tab that imports Microsoft 365 / Entra ID users as WordPress accounts and keeps them up to date: - Scope: whole tenant or the (nested) members of selected groups, guests optional, e-mail domain allow-list respected. Existing accounts are linked by e-mail address. - Roles: selectable default role plus a group -> role mapping (in addition to or instead of the default role, first match wins). Roles of pre-existing accounts are only managed on request. - Profile: selectable Graph attributes (names, job title, department, phones, address, language, ...) and the profile photo as avatar. - Deprovisioning: accounts disabled or deleted in Microsoft 365 (or removed from the sync groups) are deactivated or deleted; accounts deactivated by the sync are reactivated automatically. Deactivated accounts lose every sign-in path and all sessions. - Safeguards: dry run, safety stop above 20 % (min. 5) deprovisioning, abort on any Graph error, "deleted" only on a 404 for the object ID, protected pre-existing administrators and own account, content reassignment required for deletion, run lock. - Runs manually, via WP-Cron or `wp m365-login sync [--dry-run]`. - Users screen column with deactivate/reactivate row actions and a read-only Microsoft 365 section on the profile screen. The Graph client gains paging, retry on throttling and user, group member and photo endpoints. The group picker is now reusable. Version 1.1.0, German translations (du/Sie), docs and audit addendum. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
41 lines
3.9 KiB
Markdown
41 lines
3.9 KiB
Markdown
# 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.
|
||
- 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.
|