=== VisualEyes Login ===
Contributors: aqa-visualeyes
Tags: login, passwordless, authentication, security, mfa
Requires at least: 6.0
Requires PHP: 7.4
Stable tag: 0.5.0
License: GPLv2 or later

Passwordless login for WordPress — users sign in by recognising their own photographs.

== Description ==

VisualEyes Login adds a "Sign in with VisualEyes" option to your WordPress login form — and,
if you run WooCommerce, to the my-account login form as well. You can also drop the button on
any page with the `[visualeyes_login]` shortcode or the "VisualEyes Login" block. Instead of a
password, a user proves who they are by picking their own photographs out of a grid of
look-alikes. You choose the security level for your site — quick for a shop ("pizza"), strict
for high-value accounts ("bank").

The plugin never sees the user's photos and stores no secret about them. It makes a signed
server-to-server call to the VisualEyes service to run the challenge, then verifies the result.

== Installation ==

1. You need a VisualEyes **client account**: a Client ID, a Client secret, and your site's login
   URL registered as the allowed callback. Get these in a minute at **https://aqa.com/client/register**
   — confirm your email and your Client ID + secret are issued on screen (the secret is shown once).
2. Upload the `visualeyes` folder to `/wp-content/plugins/`, or install the zip via Plugins → Add New.
3. Activate the plugin.
4. Go to **Settings → VisualEyes Login** and enter your VisualEyes server URL, Client ID, secret,
   and choose the security level.
5. The "Sign in with VisualEyes" option now appears on your login form.

== How it works ==

1. User clicks "Sign in with VisualEyes" and enters their email.
2. The plugin binds the attempt to this browser and email (an HttpOnly cookie plus a short-lived
   server-side token), then asks the VisualEyes server (signed request) for a challenge at your
   chosen tier.
3. Known user → sent to VisualEyes to pick their pictures, then returned here and logged in.
   Unknown user → shown a clear "Enrol with VisualEyes" call to action; normal password login
   still works.
4. On return the plugin checks the browser-bound state, verifies the result server-to-server,
   confirms the verified email matches the one the flow started for, and only then logs in.

== Security ==

- The callback is bound to the initiating browser and email with a signed, single-use state
  token. This prevents login-CSRF (a victim's browser cannot be made to complete a sign-in it
  did not start) and result replay across sessions (a stolen callback URL is useless without the
  browser's cookie, and each state is consumed exactly once).
- Form/entry actions are protected with WordPress nonces, and all output is escaped.

== Notes ==

- The WordPress user is matched to the VisualEyes identity by email address.
- Roadmap includes corporate/SSO domain handling and push-to-phone for high-assurance actions.

== Changelog ==

= 0.5.0 =
* New-user auto-provisioning: the first time someone signs in with VisualEyes and has no
  WordPress account yet, one is created automatically (verified email → new user with the
  admin-chosen role, defaulting to Subscriber; a random unused password, since login is
  passwordless). Controlled by a new "New users" setting — turn it off to keep the old
  "ask an administrator" behaviour. Fires a `visualeyes_user_provisioned` action so sites
  can tailor the new account (profile fields, memberships, welcome email).

= 0.3.0 =
* UI: the "Sign in with VisualEyes" affordance now presents a small recognizable eye-check icon
  as the primary clickable sign-in control, sitting next to the email field, with a one-line
  instruction underneath ("Click the eye to sign in with your pictures — no password."). The
  original text button remains as an accessible fallback. Consistent everywhere the plugin
  renders a sign-in affordance: the wp-login form, the WooCommerce my-account form, the
  `[visualeyes_login]` shortcode, and the "VisualEyes Login" block.
* The icon is an inline SVG (no external assets); its gradient id is made unique per render so
  multiple sign-in affordances can appear safely on the same page.

= 0.4.0 =
* Integrity tripwires: the plugin now ships a signed checksum manifest (`checksums.json`) and
  re-hashes its own PHP/JS files on load (cached hourly) to detect modified or corrupted
  installs. If a file no longer matches the official release, the site owner sees a WordPress
  admin notice ("plugin files have been modified — reinstall from the official source"), and the
  Settings → VisualEyes Login screen shows a Verified / Modified status.
* Attestation: every signed server-to-server request now carries a plugin-integrity attestation
  (version, API version, manifest digest, self-check result) INSIDE the HMAC-signed body, so the
  VisualEyes server can confirm which build is genuine, current, and unmodified. It rides inside
  the existing signature, so an older VisualEyes server simply ignores it — no flow change.
* Honest scope: this is tamper-evidence + version-assurance, not a guarantee against a fully
  compromised host (which holds the signing secret). It catches injected/modified code, corrupted
  installs and outdated/forked builds, and feeds the VisualEyes trust signal.

= 0.2.0 =
* Security: bind the login callback to the initiating browser + email with a signed, single-use
  state (cookie + transient); reject mismatched or replayed results. Adds nonce checks on the
  start action and confirms the verified email equals the one the flow began for.
* WooCommerce: add "Sign in with VisualEyes" to the my-account login form.
* Enrolment: clearer not-enrolled handling with an "Enrol with VisualEyes" call to action.
* New `[visualeyes_login]` shortcode and a "VisualEyes Login" block for custom pages.
* UX: friendlier, translatable messages; consistent escaping and sanitization.
* Refactor: split into includes/ (settings, signed API client, state, controller); no new
  server endpoints.

= 0.1.0 =
* First release: settings page + "Sign in with VisualEyes" on the login form, signed challenge/
  verify flow, tiered security (standard/high), auto-login of the matching WordPress user.
