Skip to content

1.0.6

Choose a tag to compare

@bordoni bordoni released this 11 Jun 20:49
· 23 commits to main since this release
4669742

Added

  • Change email (WorkOS-verified, conflict-guarded) (#22) — self-service and admin-triggered email-change flow. Self-service [workos:change-email] shortcode, a "Change email" row action under the WorkOS column on wp-admin/users.php, and a "Change Email" panel on the user-edit screen. The new address is confirmed via hashed (HMAC-SHA256 + wp_salt('auth')) single-use, expiry-bounded tokens stored as _workos_pending_email_change user_meta and validated with hash_equals (WorkOS's email_verification endpoints can't verify a pending address); the old address simultaneously gets a one-click cancel link. Three new REST endpoints (initiate / confirm / cancel) are capability-gated, per-IP + per-user rate-limited, and enumeration-safe. Configurable conflict policy (block default, allow_orphan, merge_request) prevents silently overwriting another local WP user. Commits to WorkOS first (update_user) then mirrors into WordPress, guarded by a 60-second in-progress transient that short-circuits the webhook fan-back. Adds 8 filters, 5 actions, 7 activity-log event types, and 40 WPUnit tests. See docs/change-email.md.
  • Per-form magic-code registration toggles (CONS-350) (#25) — two independent per-environment checkboxes on the WorkOS settings page gate whether an unknown email signing in with a magic code provisions a new account. Email Code Registration controls the default sign-in form (/login/); Legacy Email Code Registration controls the legacy form (/login/legacy/, slug filterable via workos_legacy_profile_slug). When a form's toggle is off, POST /auth/magic/send skips the WorkOS call for unknown addresses and still returns 200 ok: true, and POST /auth/magic/verify early-returns a generic 400 workos_authkit_invalid_code instead of proceeding to LoginCompleter/UserSync — closing the account-enumeration leak where send previously returned 404 workos_authkit_no_account. Both options (allow_magic_code_registration, allow_legacy_magic_code_registration) default to true, preserving historical behavior.

Fixed

  • Username generation could exhaust memory and block provisioning (CONS-513) (#27) — when a popular email local part (e.g. info@) already had a deep info_1, info_2, … collision chain, generate_username() probed it one username_exists() call at a time, hydrating a WP_User into the object cache per probe until the request OOM'd — so those users could log in via WorkOS but never got a WordPress account. Collisions are now resolved with a suffix derived from sha256( email ) (e.g. info_48f25), which is unique by construction: at most 2 lookups regardless of chain depth, and the same email always derives the same username, so crash retries and replayed webhooks converge instead of minting new names. Existing accounts keep their current usernames.
  • WorkOS → Users settings would not save — the "Sync Roles to WorkOS" button rendered its own <form> inside the Settings API <form action="options.php">. Browsers don't allow nested forms: the inner </form> closed the outer settings form early, leaving the "Save Settings" submit button outside the form, so saving did nothing. The sync form is now deferred to admin_footer (body level, like the Create Organization modal) and its button is wired back via the HTML5 form="workos-role-sync-form" attribute, so the settings form stays intact and saves normally.

Full Changelog: 1.0.5...1.0.6