=== EUDI Wallet Login ===
Tags: authentication, openid-connect, wallet, login
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.1.7
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect your WordPress site to the EUDI Wallet for sign-in or age verification.

== Description ==
Published by Web3 Digital Wallet (Talao). Available as a ZIP download;
WordPress.org submission is being prepared and directory approval is not claimed.

Adds a Wallet login button to the WordPress login form, WooCommerce login form
when present, and the [eudi_wallet_login] shortcode. Authorization Code, PKCE
S256, signed ID Token validation and browser-bound single-use state are enabled
without extra security settings. PHP OpenSSL and Sodium are required.

Existing accounts are never matched or merged by email. Users can link their
Wallet from their own WordPress profile after confirming their local password.
New account creation is disabled until the administrator explicitly enables it.
New users receive Subscriber, or Customer if that role exists and is selected.
No administrator roles are issued by this plugin.

== Installation ==
1. Upload the ZIP through Plugins > Add New > Upload Plugin and activate it.
2. Open Settings > EUDI Wallet Login. Age verification (18+) is selected by default
   for a new installation; choose Identity verification if you need user sign-in.
3. Copy your return URL using Copy URL, then select Register my site (opens a new tab).
4. Paste the exact return URL into the registration form, complete your details,
   and verify your email address using the code received.
5. On the confirmation page, download the configuration JSON. Keep it private.
6. Return to WordPress and choose the downloaded configuration file. A separate
   screen shows its name and the configuration, with the secret hidden. Select
   Save configuration. No Client ID or secret needs to be typed.
7. After saving, the settings page opens directly on the saved configuration.
   Select Import another configuration to return to setup when needed.

The setup screen uses French or English according to your browser's language
preferences, with English as the fallback. Manual configuration is collapsed by
default. Existing saved settings are preserved. Identity mode can optionally
request verified contact email and create accounts. Age mode creates no account.
After a positive age verification, a one-time confirmation says "Bravo! Your age
has been verified." Select "Continue to the site" to close it. The plugin returns
to the local page that started verification; the five-minute age access remains
active after closing the confirmation. Without JavaScript, a status message is
shown instead. Cancellation and failed checks never display success.

Advanced settings contains Issuer, Callback, Scopes, Token authentication and
new-account role. JSON import validates the exact callback and credentials;
changing verification mode preserves the separate previously saved credentials.

Documentation: https://openid4vc-hub.com/api/docs/bridge.html#86-wordpress-setup
Contact: contact@talao.io

Publisher: Web3 Digital Wallet (Talao), https://talao.io
Source code and build instructions:
https://github.com/TalaoDAO/openid4vc-hub/tree/main/plugins/wordpress

HTTPS is required. Local WordPress login remains available. No network-wide
multisite support, automatic user linking, refresh tokens or provider logout.

== External service ==
This plugin requires an OIDC provider; the default is the EUDI OIDC Bridge at
https://login.openid4vc-hub.com. Saving settings alone makes no provider request.
Starting Wallet login contacts its Discovery endpoint; completing login exchanges
the code server-side, fetches JWKS and UserInfo. The provider receives the client
ID, registered callback, requested scopes, random state/nonce/PKCE challenge and
client authentication at the token endpoint. Identity verification is handled by
the provider and the Wallet. WordPress receives only authorized OIDC attributes.
Contact email, when requested, is verified separately by the bridge after identity verification.

JSON import reads the downloaded credentials locally in the browser; it does
not upload the file to the provider. The file contains a client secret and must
be kept private. Imported values are saved only after the administrator selects
Save configuration. Secrets are encrypted in WordPress storage and not redisplayed.

The free signup button opens the provider's /register page in a new tab; no
WordPress password or local user information is sent by that button. The form
requests company/contact details, a verified developer email, an application name,
an exact callback URL and the identity/age purpose. The client is created only
after email verification.
No shared client credentials, Hub API keys or tracking service are included.

Provider privacy: https://talao.io/privacy.html
Provider terms: https://talao.io/cgu.html
Review service availability, quotas and applicable terms with your provider.

== Storage and recovery ==
The client secret and temporary login data are encrypted using a key derived
from the WordPress auth salt. Rotating salts invalidates encrypted data: re-enter
the client secret and start a new login. The EUDI_WALLET_CLIENT_SECRET constant in
wp-config.php can hold the secret instead of the options table. Do not commit it.

Subject associations are stored as issuer/subject hashes linked to local user
IDs. Account profile attributes are saved only when the account is created;
subsequent Wallet logins do not overwrite local names, email, roles or password.
Expired transactions are rejected immediately and removed by hourly WP-Cron or
on the next login attempt. Deactivation clears transactions and preserves account
associations/settings. No user, identity binding or settings deletion is automatic.

== Changelog ==

= 0.1.7 =
* Add an explicit public demonstration mode: age verification and success feedback work while explanatory pages remain accessible to visitors and search engines. Content protection remains enabled by default.

= 0.1.6 =
* Show a one-time accessible success dialog after a verified positive age result.
* Return to the local page that started age verification; retain the five-minute access.
* Success feedback is bound to the encrypted age proof, with no public URL success flag.


= 0.1.5 =
WordPress.org preparation: escape generated HTML at output, validate and unslash
HTTP inputs, prepare SQL table identifiers, and use a restricted safe provider
redirect. Preserve single-use state, PKCE, account linking and encrypted storage.
Document justified checker exceptions for core hooks and atomic custom SQL.
Include Composer manifests for dependency provenance.

= 0.1.4 =
Cancellation and callback errors return to the calling local page with a one-time
message after browser/state validation. Invalid or expired state uses safe recovery.
The settings page includes a local Talao logo linking to talao.io.
= 0.1.3 =
Configuration import opens a dedicated review screen showing the imported file
name and public settings. Saved sites reopen on the configuration screen.
The client secret remains hidden; import does not save settings automatically.
= 0.1.2 =
Five-step setup with return URL copy and configuration JSON import. French/English
setup follows browser language; manual credentials are collapsed by default.
Existing settings, PKCE and token validation are preserved.
= 0.1.1 =
Simplified active Client ID/secret form, browser-only bridge JSON import, advanced
OIDC settings, documentation/contact links and preserved separate credentials.
= 0.1.0 =
Development preview with isolated WordPress OIDC client and free signup access.
Automated tests are not proof of a complete real Wallet login.

== Age verification mode ==
Choose Age verification (18+) in the bridge signup form and plugin settings.
The dedicated age client uses openid age_verification and never requests email.
Only a signed age_over_18=true result is accepted, with matching UserInfo.
It opens a protected browser age session for five minutes, without creating or
signing into a WordPress account. The ephemeral OIDC sub is discarded.

Age mode gates public WordPress page rendering and public REST access. Keep a
local administrator login for recovery. Configure page/CDN caches to bypass this
site's protected responses and the age cookie: a cache may respond before PHP.
Direct media/file URLs served by your web server are not protected by PHP and
need separate access rules. Disable or redact callback query strings in hosting
access logs; authorization codes must not be retained there.

Age verification is not a regulatory compliance certification and does not prevent
use of a shared browser/device. Test the complete HTTPS Wallet flow on your site
before opening protected content to users.

== Return after cancellation ==
The connector remembers the local page from which Wallet login was started.
Cancel and return to application on the Wallet login screen first returns to the
registered callback; the plugin then returns to that original page with a message.
This also handles callback errors after state and browser validation. A missing,
expired or invalid transaction shows a safe recovery page instead. External return
URLs are rejected. The registered callback remains unchanged.

The message uses a one-time encrypted Secure/HttpOnly cookie lasting at most two
minutes. Configure page/CDN caches to bypass the __Host-eudi_wp_notice cookie,
as well as the protected age cookie. No provider error details or identity data
are stored in that notice.
