{"id":352967,"date":"2026-08-24T17:48:04","date_gmt":"2026-08-24T17:48:04","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/logliy-login-protect-passkey-email-code\/"},"modified":"2026-10-22T08:57:28","modified_gmt":"2026-10-22T08:57:28","slug":"logliy","status":"publish","type":"plugin","link":"https:\/\/dsb.wordpress.org\/plugins\/logliy\/","author":23540762,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.2.0","stable_tag":"0.2.0","tested":"7.1.3","requires":"6.4","requires_php":"8.1","requires_plugins":null,"header_name":"Logliy - Login Protect (Passkey, Email, SSO)","header_author":"FloBa Media","header_description":"Passwordless WordPress login with Passkeys and Email OTP. Optional password fallback.","assets_banners_color":"6da1f3","last_updated":"2026-10-22 08:57:28","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/github.com\/FloBaMedia\/logliy","header_author_uri":"https:\/\/www.floba-media.de","rating":0,"author_block_rating":0,"active_installs":10,"downloads":469,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.0.9":{"tag":"0.0.9","author":"flobamedia","date":"2026-08-24 17:47:17","revision":3664048},"0.1.0":{"tag":"0.1.0","author":"flobamedia","date":"2026-09-07 08:51:42","revision":3684507},"0.1.1":{"tag":"0.1.1","author":"flobamedia","date":"2026-09-08 23:27:56","revision":3687379},"0.2.0":{"tag":"0.2.0","author":"flobamedia","date":"2026-10-22 08:57:28","revision":3759593}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3664046,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3664046,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3664046,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3664046,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.0.9","0.1.0","0.1.1","0.2.0"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[602,9210,218738,9223,2469],"plugin_category":[38,45],"plugin_contributors":[274901],"plugin_business_model":[],"class_list":["post-352967","plugin","type-plugin","status-publish","hentry","plugin_tags-login","plugin_tags-otp","plugin_tags-passkey","plugin_tags-passwordless","plugin_tags-sso","plugin_category-authentication","plugin_category-ecommerce","plugin_contributors-flobamedia","plugin_committers-flobamedia"],"banners":{"banner":"https:\/\/ps.w.org\/logliy\/assets\/banner-772x250.png?rev=3664046","banner_2x":"https:\/\/ps.w.org\/logliy\/assets\/banner-1544x500.png?rev=3664046","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/logliy\/assets\/icon-128x128.png?rev=3664046","icon_2x":"https:\/\/ps.w.org\/logliy\/assets\/icon-256x256.png?rev=3664046","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Logliy - Login Protect controls <strong>how<\/strong> users sign in: Passkeys (WebAuthn) first, with Email one-time codes and Magic Links as fallback, plus optional SSO (OpenID Connect) and an optional password path.<\/p>\n\n<p>It is <strong>not<\/strong> a security suite and <strong>not<\/strong> a generic OTP plugin. Keep <a href=\"https:\/\/www.wordfence.com\/\">Wordfence<\/a> (or similar) for WAF, brute-force lockouts, CAPTCHA, malware scanning, and classic TOTP 2FA. Logliy is the login-method layer on top.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Passkey login and registration (discoverable credentials, Conditional UI where available)<\/li>\n<li>Email OTP login via <code>wp_mail<\/code><\/li>\n<li>Optional email address\/domain allowlists with local-part wildcards for Email Code \/ Magic Link<\/li>\n<li>Shared account, IP and site email limits; atomic single-use codes and links<\/li>\n<li>Optional SSO email and signed group\/role restrictions<\/li>\n<li>Security log with configurable retention and up to 10000 events<\/li>\n<li>Opt-in notifications for account, plugin, user and Logliy settings changes<\/li>\n<li>Magic link (one-click email) login<\/li>\n<li>Optional SSO via OpenID Connect (shown on the login form only when fully configured)<\/li>\n<li>Password login <strong>off by default<\/strong>, re-enable site-wide and\/or per role \/ per user<\/li>\n<li>Role-based login\/logout redirects<\/li>\n<li>Optional custom login URL (auto-disabled if WPS Hide Login or similar is active)<\/li>\n<li>Session length, Remember-me duration, admin idle timeout, session list and individual\/all-session revocation<\/li>\n<li>Passkey count and last login in the standard WordPress Users list<\/li>\n<li>Optional custom login logo, brand, background, and footer<\/li>\n<li>Modern login UI on <code>wp-login.php<\/code><\/li>\n<li>WooCommerce classic + Blocks My Account\/Checkout login forms<\/li>\n<li>Cloudflare Turnstile compatible (verifies tokens on Passkey \/ Email OTP \/ Magic Link \/ SSO login)<\/li>\n<li>REST API namespace <code>logliy\/v1<\/code><\/li>\n<li>Rate limits for OTP, Passkey, and SSO auth<\/li>\n<li>Wordfence-friendly: fires <code>wp_login_failed<\/code> \/ <code>wp_login<\/code> and uses normal auth cookies<\/li>\n<li>Emergency override: <code>define( 'LOGLIY_ALLOW_PASSWORD', true );<\/code> in <code>wp-config.php<\/code><\/li>\n<\/ul>\n\n<h4>Wordfence compatibility<\/h4>\n\n<ul>\n<li>Failed Logliy attempts trigger <code>wp_login_failed<\/code> so Wordfence lockouts still apply<\/li>\n<li>Successful Logliy logins use <code>wp_set_auth_cookie<\/code> + <code>wp_login<\/code> like a normal <code>wp_signon<\/code><\/li>\n<li>Wordfence IP lockouts still run during passwordless login; Wordfence Login Security 2FA is skipped for Passkey \/ Email OTP \/ Magic Link \/ SSO (those methods already replace the password)<\/li>\n<li>Wordfence TOTP 2FA continues to apply on the classic password path<\/li>\n<li>Logliy does <strong>not<\/strong> remove Wordfence hooks globally \u2014 only suspends LS 2FA for the passwordless completion step<\/li>\n<\/ul>\n\n<h4>Cloudflare Turnstile<\/h4>\n\n<p>When <a href=\"https:\/\/wordpress.org\/plugins\/simple-cloudflare-turnstile\/\">Simple CAPTCHA with Cloudflare Turnstile<\/a> (or equivalent) is enabled on the WordPress login form, Logliy requires a valid Turnstile token for Email OTP, Passkey, Magic Link, and SSO login. The password path continues to use the Turnstile plugin's own <code>authenticate<\/code> check.<\/p>\n\n<h4>WooCommerce<\/h4>\n\n<ul>\n<li>Classic My Account and Checkout login templates<\/li>\n<li>Guest checkout unchanged<\/li>\n<li>Does not block WooCommerce REST \/ Store API authentication<\/li>\n<li>Optional panel above Checkout and Customer Account blocks for guests<\/li>\n<\/ul>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>PHP 8.1+<\/li>\n<li>WordPress 6.4+<\/li>\n<li>HTTPS for Passkeys (localhost allowed for development)<\/li>\n<li>Composer production dependencies are vendored in release builds (<code>vendor-prefixed\/<\/code>)<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin can contact Cloudflare Turnstile only when a compatible Turnstile plugin is active and configured for the WordPress login form. Logliy does not load Turnstile by itself.<\/p>\n\n<p>When a visitor completes passwordless login (Passkey, Email OTP, Magic Link, or SSO) while Turnstile is required, Logliy sends the Turnstile response token and the visitor IP to Cloudflare\u2019s siteverify API so the challenge can be validated. No other personal data is sent to Cloudflare by Logliy.<\/p>\n\n<p>This service is provided by Cloudflare: <a href=\"https:\/\/www.cloudflare.com\/website-terms\/\">Terms of Use<\/a> and <a href=\"https:\/\/www.cloudflare.com\/privacypolicy\/\">Privacy Policy<\/a>.<\/p>\n\n<p>When SSO (OpenID Connect) is enabled, Logliy contacts the OpenID Provider you configure (Issuer \/ discovery, token, and JWKS URLs) so visitors can sign in with that identity provider. Logliy does not send login data to FloBa Media. The identity provider receives standard OpenID Connect authentication data (such as the authorization request and, after sign-in, token exchange). Which personal data that provider stores is defined by that provider.<\/p>\n\n<p>You must register this site\u2019s Redirect URI at the provider and accept that provider\u2019s own terms of service and privacy policy before enabling SSO.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>logliy<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate <strong>Logliy - Login Protect (Passkey, Email, SSO)<\/strong><\/li>\n<li>Open <strong>Settings \u2192 Logliy<\/strong><\/li>\n<li>Register a Passkey on your profile and\/or test Email OTP <strong>before<\/strong> relying on passwordless-only mode<\/li>\n<li>Optionally enable SSO under the SSO tab (login form shows it only when fully configured)<\/li>\n<li>Optionally set a custom login logo \/ brand name under General<\/li>\n<li>Optionally enable password login again under General<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20email%20access%20rules%20work%3F\"><h3>How do email access rules work?<\/h3><\/dt>\n<dd><p>On Email, under General email settings, enable the allowlist and enter one rule per line: <code>@example.org<\/code>, <code>staff-*@example.net<\/code> or <code>person@example.org<\/code>. Rules are case-insensitive. A domain rule does not include subdomains; wildcards are allowed only before <code>@<\/code>. An enabled empty list denies all email login. Rules apply to the account email even when the user enters a username. Both sending and redemption check the current rules. Passkeys and SSO have separate policies. Public request responses do not reveal whether an account is eligible.<\/p><\/dd>\n<dt id=\"are%20login%20codes%20and%20links%20single-use%3F\"><h3>Are login codes and links single-use?<\/h3><\/dt>\n<dd><p>Yes. Email challenges are stored in a dedicated database table and consumed atomically. A new request replaces the previous challenge of the same method. Codes allow at most five attempts without extending their original expiry. Changes to the account email invalidate outstanding challenges. Upgrading to 0.2.0 invalidates pending codes\/links from older versions; request a new one.<\/p><\/dd>\n<dt id=\"how%20can%20i%20restrict%20sso%3F\"><h3>How can I restrict SSO?<\/h3><\/dt>\n<dd><p>On SSO, configure a separate email allowlist and\/or permitted values from a signed ID-token claim such as <code>groups<\/code>, <code>roles<\/code> or <code>realm_access.roles<\/code>. At least one group must match exactly. When both restrictions are enabled, both must pass, including for existing linked accounts. Rules run before account linking or creation and never assign WordPress roles. Verified email is required by default in 0.2.0. Your provider must return boolean <code>email_verified: true<\/code>; an administrator can disable this requirement for a trusted provider that does not support the claim.<\/p><\/dd>\n<dt id=\"what%20does%20the%20security%20log%20store%3F\"><h3>What does the security log store?<\/h3><\/dt>\n<dd><p>Event type, UTC time, actor\/account IDs and plugin file names only. No raw IP addresses, email addresses, codes, links, user agents or tokens are recorded. IDs can still identify users; include the log in your privacy assessment. The log is enabled by default, capped at 10000 events, and retained for 30 days (configurable 1\u2013365). Expired entries are hidden immediately; hourly WordPress cron deletes them. Administrators can inspect it on Security log. It is a local operational log, not a tamper-proof audit service.<\/p><\/dd>\n<dt id=\"which%20security%20emails%20are%20available%3F\"><h3>Which security emails are available?<\/h3><\/dt>\n<dd><p>All categories are off by default. Enable account security, plugin changes, user changes and\/or Logliy settings changes on Security. Plugin installations, updates (including automatic updates), activations, deactivations and deletions each have their own notification switch. Existing all-plugin notification choices are preserved. User notifications cover creation, deletion and role changes. Account security notices cover Passkeys, SSO links, session revocation and email\/password changes. Administration notices go to the configured recipient or the WordPress administration email; account notices also go to the affected account. At most 20 messages per recipient per hour are sent; failures and suppressed messages are logged. WordPress may send its own notices independently. Delivery uses <code>wp_mail<\/code> and depends on your site's mail setup.<\/p><\/dd>\n<dt id=\"can%20i%20revoke%20individual%20sessions%3F\"><h3>Can I revoke individual sessions?<\/h3><\/dt>\n<dd><p>Profiles show active sessions with individual and all-session revoke buttons. Users can manage their own sessions; administrators need permission to edit the target user. With custom session storage, only all-session revocation is supported here. Revoking the current session signs you out.<\/p><\/dd>\n<dt id=\"how%20do%20i%20enable%20sso%3F\"><h3>How do I enable SSO?<\/h3><\/dt>\n<dd><p>Open <strong>Settings \u2192 Logliy \u2192 SSO<\/strong>. Enable SSO and enter your OpenID Provider Issuer URL, Client ID, and Client Secret. Register the shown Redirect URI at the provider. The SSO tab appears on the login form only when those three fields are set. ID tokens must be signed with RS256. New WordPress users are not created unless you turn on <strong>Create users<\/strong>.<\/p><\/dd>\n<dt id=\"i%20locked%20myself%20out\"><h3>I locked myself out<\/h3><\/dt>\n<dd><p>Add to <code>wp-config.php<\/code>:<\/p>\n\n<pre><code>define( 'LOGLIY_ALLOW_PASSWORD', true );\n<\/code><\/pre>\n\n<p>Then sign in with your password and adjust Logliy settings.<\/p><\/dd>\n<dt id=\"does%20this%20replace%20wordfence%3F\"><h3>Does this replace Wordfence?<\/h3><\/dt>\n<dd><p>No. Logliy is the login <strong>method<\/strong> layer. Wordfence remains your WAF \/ lockout \/ scanner layer.<\/p><\/dd>\n<dt id=\"application%20passwords%20%2F%20wp-cli%20%2F%20xml-rpc\"><h3>Application Passwords \/ WP-CLI \/ XML-RPC<\/h3><\/dt>\n<dd><p>Application Passwords and WP-CLI are not blocked by the password policy.\nWith password login off, XML-RPC authentication with the <strong>account password<\/strong> is blocked by default (affects the WordPress mobile app, Jetpack, and some backup tools). Enable <strong>Allow XML-RPC passwords<\/strong> under Logliy \u2192 General if a tool still requires it. Prefer Application Passwords when the client supports them.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Always-on Auto-save with a top-right Save settings action, debounced edits, sequential requests and visible failure status.<\/li>\n<li>Content-based admin asset versions prevent stale CSS\/JS during repeated ZIP installs; sidebar stays alongside settings on desktop.<\/li>\n<li>Wider responsive settings layout with clearly labelled ServerMetry and CookiePeak promotions using local assets.<\/li>\n<li>Neutral example.com addresses in email rule help.<\/li>\n<li>Plugin notifications can be selected separately by event; shared email rules and limits are grouped above method-specific settings.<\/li>\n<li>Passkey count and last login appear in the WordPress Users list instead of a duplicate users tab.<\/li>\n<li>Added optional address\/domain\/wildcard rules for Email Code and Magic Link, checked at request and redemption.<\/li>\n<li>Shared email request limits across methods, plus a site-wide limit and atomic cooldowns.<\/li>\n<li>Hardened single-use challenges against concurrent redemption; fixed expiry and attempt counting; new links replace older links.<\/li>\n<li>Added SSO verified-email, address and signed group\/role policies before linking or provisioning.<\/li>\n<li>Added bounded security log, configurable retention and opt-in account\/plugin\/user\/settings notifications.<\/li>\n<li>Added active session list and individual\/all-session revocation with capability and nonce checks.<\/li>\n<li>Pending codes and links from earlier versions must be requested again. SSO now requires verified email by default; review provider settings before upgrading.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Fix: SSO no longer fails with \u201cdenied\u201d when Cloudflare Turnstile is enabled on the login form<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Optional SSO login via OpenID Connect (authorization code + PKCE). Shown on the login form only when fully configured.<\/li>\n<li>Plugin name updated to include SSO<\/li>\n<\/ul>\n\n<h4>0.0.9<\/h4>\n\n<ul>\n<li>Tested up to WordPress 7.1<\/li>\n<\/ul>\n\n<h4>0.0.8<\/h4>\n\n<ul>\n<li>Remove arbitrary custom CSS from settings (use Additional CSS instead)<\/li>\n<li>Enqueue remember-me check via login.js; drop inline script tag<\/li>\n<li>Document Cloudflare Turnstile as an external service (terms + privacy)<\/li>\n<li>Stop bundling .po\/.mo and vendor PHPUnit helpers; include composer.json<\/li>\n<li>WordPress.org loads translations automatically (no load_plugin_textdomain)<\/li>\n<li>Limit admin notices to Logliy settings \/ profile screens<\/li>\n<\/ul>\n\n<h4>0.0.7<\/h4>\n\n<ul>\n<li>Ignore leftover Turnstile DB options when the Captcha plugin is not active (fixes false CAPTCHA block)<\/li>\n<li>Show plugin version on settings page; remove duplicate \u201csettings saved\u201d notice<\/li>\n<\/ul>\n\n<h4>0.0.6<\/h4>\n\n<ul>\n<li>Captcha only required when Cloudflare Turnstile is enabled and configured; sites without Captcha are not blocked<\/li>\n<li>Fix Advanced settings save (nested import form) and add Save button at top<\/li>\n<\/ul>\n\n<h4>0.0.5<\/h4>\n\n<ul>\n<li>Settings import\/export (JSON) for cloning config between sites<\/li>\n<li>Vendor namespaces prefixed with Strauss (Logliy) to avoid Symfony conflicts<\/li>\n<li>Passwordless login skips Wordfence 2FA (lockouts still apply); Wordfence 2FA remains on password path<\/li>\n<li>Optional \u201cAllow XML-RPC passwords\u201d (off by default) when password login is disabled<\/li>\n<li>Atomic rate-limit DB table (no option-lock); OTP HMAC bound to user; safer settings import<\/li>\n<\/ul>\n\n<h4>0.0.4<\/h4>\n\n<ul>\n<li>Security: password policy applies to XML-RPC; REST exemption limited to Application Passwords<\/li>\n<li>Security: passwordless login runs authenticate \/ wp_authenticate_user before cookies (Wordfence lockouts)<\/li>\n<li>Privacy: system font stack instead of Google Fonts CDN<\/li>\n<li>Hardening: account cooldown\/rate-limit responses no longer enumerate users; atomic rate-limit buckets; OTP HMAC<\/li>\n<\/ul>\n\n<h4>0.0.3<\/h4>\n\n<ul>\n<li>Fix: Divi fatal when hiding wp-admin (no theme 404 template during early init)<\/li>\n<\/ul>\n\n<h4>0.0.2<\/h4>\n\n<ul>\n<li>Magic link, custom login URL, redirects, sessions, users overview, WC blocks, branding extras<\/li>\n<\/ul>\n\n<h4>0.0.1<\/h4>\n\n<ul>\n<li>Initial pre-release: Passkeys, Email OTP, password policy (default off), wp-login + WooCommerce classic<\/li>\n<li>Admin settings, profile Passkey management, Cloudflare Turnstile compatibility<\/li>\n<li>Optional login branding (logo \/ name \/ tagline); DE\/EN i18n<\/li>\n<li>Auth hardening: no OTP enumeration, redirect validation, Turnstile token verify, rate limits<\/li>\n<\/ul>","raw_excerpt":"Passwordless login with Passkeys, Email Code, Magic Link and SSO. Email access rules, shared rate limits, security log and alerts.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/352967","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=352967"}],"author":[{"embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/flobamedia"}],"wp:attachment":[{"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=352967"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=352967"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=352967"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=352967"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=352967"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/dsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=352967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}