{"id":350324,"date":"2026-08-11T16:05:19","date_gmt":"2026-08-11T16:05:19","guid":{"rendered":"https:\/\/ja.wordpress.org\/plugins\/rapls-passkey\/"},"modified":"2026-08-20T07:37:08","modified_gmt":"2026-08-20T07:37:08","slug":"rapls-passkey","status":"publish","type":"plugin","link":"https:\/\/bal.wordpress.org\/plugins\/rapls-passkey\/","author":23425763,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.13.74","stable_tag":"0.13.74","tested":"7.1","requires":"6.0","requires_php":"8.2","requires_plugins":null,"header_name":"Rapls Passkey \u2013 Passwordless Login with WebAuthn","header_author":"Rapls","header_description":"Passwordless authentication for WordPress using passkeys (WebAuthn \/ FIDO2).","assets_banners_color":"0146d8","last_updated":"2026-08-20 07:37:08","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/raplsworks.com\/plugins\/rapls-passkey\/","header_author_uri":"https:\/\/raplsworks.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":186,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.13.68":{"tag":"0.13.68","author":"rapls","date":"2026-08-11 16:04:53"},"0.13.69":{"tag":"0.13.69","author":"rapls","date":"2026-08-12 02:25:57"},"0.13.70":{"tag":"0.13.70","author":"rapls","date":"2026-08-12 07:45:47"},"0.13.71":{"tag":"0.13.71","author":"rapls","date":"2026-08-18 10:58:17"},"0.13.73":{"tag":"0.13.73","author":"rapls","date":"2026-08-20 06:13:48"},"0.13.74":{"tag":"0.13.74","author":"rapls","date":"2026-08-20 07:37:08"}},"upgrade_notice":{"0.13.70":"<p>On PHP older than 8.2 the previous release took the whole site down, front end included. The plugin now steps aside with an admin notice instead.<\/p>","0.13.66":"<p>Administrator enrolment is on by default instead of being unlocked by the Pro add-on. Translations now come from translate.wordpress.org rather than a bundled catalogue.<\/p>","0.13.63":"<p>Every file in the previous package failed the WordPress Plugin Check direct-access test: the guard was rewritten by the build into a form the tool does not recognise. Fixed, along with the code-standard findings that were hidden behind misplaced exemptions.<\/p>","0.13.53":"<p>Fixes CSV injection in the audit-log export: a formula preceded by whitespace was not neutralised. Update if you export audit logs.<\/p>","0.13.28":"<p>Security (multisite): a user marked as spam on the network could still sign in with a passkey, a QR approval, a magic link or a recovery code. Update immediately on multisite.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3642248,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3642248,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3642248,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3642248,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"rapls-passkey\/login":{"name":"rapls-passkey\/login","title":"Sign in with a passkey"},"rapls-passkey\/register":{"name":"rapls-passkey\/register","title":"Manage passkeys"}},"tagged_versions":["0.13.68","0.13.69","0.13.70","0.13.71","0.13.73","0.13.74"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3642248,"resolution":"1","location":"assets","locale":"","width":1002,"height":1132},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3642248,"resolution":"2","location":"assets","locale":"","width":876,"height":1288},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3642248,"resolution":"3","location":"assets","locale":"","width":1770,"height":600},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3642248,"resolution":"4","location":"assets","locale":"","width":876,"height":672},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3642248,"resolution":"5","location":"assets","locale":"","width":1000,"height":690},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3642248,"resolution":"6","location":"assets","locale":"","width":886,"height":870},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3642248,"resolution":"7","location":"assets","locale":"","width":1842,"height":838},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3642248,"resolution":"8","location":"assets","locale":"","width":2350,"height":1336}},"screenshots":{"1":"Sign in with a passkey from the normal WordPress login screen.","2":"The browser offers the passkeys saved for this site.","3":"Your registered passkeys: rename, suspend or delete each one.","4":"Registering a passkey from your profile screen.","5":"Touch ID confirms before the passkey is saved.","6":"Choose where the passkey is stored.","7":"The first-run check: HTTPS, the relying-party ID, and the WebAuthn library.","8":"Every registration, sign-in and removal, exportable as CSV."}},"plugin_section":[262246],"plugin_tags":[602,218738,9223,9217,183349],"plugin_category":[38],"plugin_contributors":[253146],"plugin_business_model":[],"class_list":["post-350324","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-login","plugin_tags-passkey","plugin_tags-passwordless","plugin_tags-two-factor","plugin_tags-webauthn","plugin_category-authentication","plugin_contributors-rapls","plugin_committers-rapls"],"banners":{"banner":"https:\/\/ps.w.org\/rapls-passkey\/assets\/banner-772x250.png?rev=3642248","banner_2x":"https:\/\/ps.w.org\/rapls-passkey\/assets\/banner-1544x500.png?rev=3642248","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/rapls-passkey\/assets\/icon-128x128.png?rev=3642248","icon_2x":"https:\/\/ps.w.org\/rapls-passkey\/assets\/icon-256x256.png?rev=3642248","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-1.png?rev=3642248","caption":"Sign in with a passkey from the normal WordPress login screen."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-2.png?rev=3642248","caption":"The browser offers the passkeys saved for this site."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-3.png?rev=3642248","caption":"Your registered passkeys: rename, suspend or delete each one."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-4.png?rev=3642248","caption":"Registering a passkey from your profile screen."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-5.png?rev=3642248","caption":"Touch ID confirms before the passkey is saved."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-6.png?rev=3642248","caption":"Choose where the passkey is stored."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-7.png?rev=3642248","caption":"The first-run check: HTTPS, the relying-party ID, and the WebAuthn library."},{"src":"https:\/\/ps.w.org\/rapls-passkey\/assets\/screenshot-8.png?rev=3642248","caption":"Every registration, sign-in and removal, exportable as CSV."}],"raw_content":"<!--section=description-->\n<p>Rapls Passkey adds passkey sign-in to WordPress. Touch ID, Windows Hello, Face\nID or a security key takes the place of the password, and your server never\nholds a shared secret \u2014 only a public key, which is useless to anyone who\nsteals it.<\/p>\n\n<p>It is built to run where most WordPress sites actually run:<\/p>\n\n<ul>\n<li><strong>No PHP extension to install.<\/strong> Nothing beyond what WordPress itself already needs. In particular <code>gmp<\/code> is not required, so there is nothing to ask your shared host for and nothing that stops working when the server's PHP is upgraded.<\/li>\n<li><strong>Nothing leaves your site.<\/strong> The passkey ceremony happens between the browser and your own server. No account, no API key, no third-party service in the login path.<\/li>\n<li><strong>Passwords keep working.<\/strong> Password login is never switched off in the free plugin. Nobody gets locked out while a site moves across.<\/li>\n<li><strong>Japanese UI included.<\/strong> Fully translated, alongside the English source.<\/li>\n<\/ul>\n\n<h4>What the free plugin does<\/h4>\n\n<ul>\n<li>Passwordless, phishing-resistant sign-in (WebAuthn \/ FIDO2)<\/li>\n<li>Same-device passkeys (Touch ID \/ Windows Hello \/ Face ID)<\/li>\n<li>Cross-device sign-in using the browser's native passkey flow when the browser offers it (scan with your phone). A custom QR approval flow is available in Pro.<\/li>\n<li>Shortcodes and Gutenberg blocks (login \/ passkey management) you can embed on any page<\/li>\n<li>Rename, suspend and resume individual passkeys \u2014 a device that is temporarily out of reach can be cut off without destroying the credential<\/li>\n<li>A site-wide passkey list for administrators (Users -&gt; Passkeys), searchable by owner or name<\/li>\n<li>Works with two-factor plugins (Wordfence Login Security, Two-Factor, ...): a passkey counts as the second factor, while weaker alternative logins must still pass the site's 2FA<\/li>\n<li>An audit log of registrations, sign-ins and removals, exportable as CSV<\/li>\n<li>WP-CLI commands, a first-run configuration check, and an emergency bypass constant<\/li>\n<li>Fully translatable UI (English source; translations come from translate.wordpress.org)<\/li>\n<\/ul>\n\n<h4>Shortcodes<\/h4>\n\n<p>Embed them in any page, post, or widget. In the block editor they are also available as the \"Sign in with a passkey\" and \"Manage passkeys\" blocks.<\/p>\n\n<ul>\n<li><code>[rapls_passkey_login]<\/code> \u2014 a passkey sign-in button for logged-out visitors. Supports the <code>redirect<\/code> (URL to go to after success) and <code>label<\/code> (button text) attributes.<\/li>\n<li><code>[rapls_passkey_register]<\/code> \u2014 a management UI where logged-in users can register and remove their own passkeys.<\/li>\n<\/ul>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>WordPress 6.0 or later<\/li>\n<li>PHP 8.2 or later<\/li>\n<li>HTTPS, except on localhost \u2014 browsers refuse WebAuthn without it<\/li>\n<\/ul>\n\n<p>No PHP extension beyond WordPress's own requirements.<\/p>\n\n<h4>Rapls Passkey Pro<\/h4>\n\n<p>Everything above is free, and stays free. Pro is a separate add-on for the part\nthat comes after the first passkey: moving a whole site across, and keeping a\nway in when a device goes missing.<\/p>\n\n<ul>\n<li><strong>Sign in from another device<\/strong> \u2014 approve a login on your computer from your phone, with a QR code and a four-digit confirmation code so a relayed code cannot be used elsewhere<\/li>\n<li><strong>A way back in that is not a password<\/strong> \u2014 one-time recovery codes and email magic-link sign-in<\/li>\n<li><strong>Roll out by role<\/strong> \u2014 require passkeys for the roles you choose, with a grace period, then turn password login off once everyone is across<\/li>\n<li><strong>Adaptive step-up<\/strong> \u2014 ask for a passkey again after a password sign-in from somewhere unfamiliar<\/li>\n<li><strong>Authenticator policy<\/strong> \u2014 FIDO Metadata Service checks, AAGUID allow and deny lists, trusted-device management<\/li>\n<li><strong>Operations<\/strong> \u2014 security webhooks, adoption reports, multisite network settings, WP-CLI<\/li>\n<\/ul>\n\n<p>One-time purchase, no subscription, with a year of updates and a 14-day refund.\n<a href=\"https:\/\/raplsworks.com\/rapls-passkey-pro\/\">Details and pricing<\/a><\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin sends nothing to any external service by default. One optional\nintegration, off unless you turn it on, contacts a third party:<\/p>\n\n<p><strong>Google reCAPTCHA v3<\/strong> \u2014 used only when you enable reCAPTCHA for password\nlogins. When it is on, the visitor's browser loads\n    https:\/\/www.google.com\/recaptcha\/api.js, and the plugin sends the resulting\ntoken together with the request IP address to\n    https:\/\/www.google.com\/recaptcha\/api\/siteverify so that Google can score the\nrequest. Nothing is sent while the option is off. This service is provided by\nGoogle and its use is governed by Google's terms and privacy policy:<\/p>\n\n<ul>\n<li>Terms of Service: https:\/\/policies.google.com\/terms<\/li>\n<li>Privacy Policy: https:\/\/policies.google.com\/privacy<\/li>\n<\/ul>\n\n<p>No other host is contacted. The plugin bundles the public suffix list it needs\n(<code>data\/public_suffix_list.dat<\/code>) rather than fetching it, and passkey ceremonies\nhappen between the browser and your own site.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>Authentication data is stored on your own site.<\/p>\n\n<p>What is stored:<\/p>\n\n<ul>\n<li>Passkey credential records (public key, credential ID, sign counter, a label and timestamps) in a custom database table.<\/li>\n<li>A per-user WebAuthn user handle in user meta, plus one row in the options table recording that the account has one. The handle carries nothing about the person: for accounts created from this version it is derived from the account id and a site secret, and accounts that already had a random handle keep it.<\/li>\n<li>An optional audit log of passkey events (registration, sign-in, removal) with the acting user, IP address and timestamp.<\/li>\n<\/ul>\n\n<p>Retention and removal:<\/p>\n\n<ul>\n<li>Passkey records remain until the user or an administrator deletes them; deleting a user removes their passkey records.<\/li>\n<li>The plugin integrates with WordPress's built-in personal-data export and erase tools, so a user's passkey and audit data are included in export\/erase requests.<\/li>\n<li>Uninstalling the plugin (delete from the Plugins screen) drops its custom table and options.<\/li>\n<\/ul>\n\n<p>This plugin does not use cookies for tracking. It sets only short-lived, functional cookies during a login ceremony (for example the pending second-factor login), which expire within minutes.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Place the plugin in <code>wp-content\/plugins\/rapls-passkey<\/code>.<\/li>\n<li>Activate \"Rapls Passkey\" from the Plugins screen.<\/li>\n<li>Register a passkey from your profile screen.<\/li>\n<\/ol>\n\n<p>Nothing else is required: no account, no API key, no configuration before the\nfirst passkey. The settings screen shows a first-run check (HTTPS, the\nrelying-party ID, the WebAuthn library) so you can see the site is ready.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20need%20any%20php%20extensions%3F\"><h3>Does this need any PHP extensions?<\/h3><\/dt>\n<dd><p>No. It runs on what WordPress itself already requires. Some WebAuthn plugins\nneed <code>gmp<\/code> compiled into PHP, which is not present on every shared host and can\ndisappear when the host upgrades PHP; this plugin does not use it.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20shared%20hosting%3F\"><h3>Does it work on shared hosting?<\/h3><\/dt>\n<dd><p>Yes. There is no extension to install, no persistent process, and nothing\nwritten outside the plugin's own table and options.<\/p><\/dd>\n<dt id=\"which%20browsers%20and%20devices%20work%3F\"><h3>Which browsers and devices work?<\/h3><\/dt>\n<dd><p>Any current browser with a built-in authenticator \u2014 Touch ID, Windows Hello,\nFace ID \u2014 or a FIDO2 security key. If the machine in front of you has no\npasskey for the site, the browser's own cross-device flow lets you scan with\nyour phone instead.<\/p><\/dd>\n<dt id=\"is%20the%20free%20version%20limited%3F\"><h3>Is the free version limited?<\/h3><\/dt>\n<dd><p>No. Passkey sign-in, registration, management, the shortcodes and blocks, the\nadministrator's passkey list and the two-factor integrations are all in the free\nplugin, without a cap, a trial period or a licence key. Rapls Passkey Pro is a\nseparate add-on that adds different features \u2014 cross-device QR login, recovery\ncodes, enforcement by role \u2014 and installing it is not required for anything\ndescribed above to work.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20my%20security%20plugin%3F\"><h3>Does it work with my security plugin?<\/h3><\/dt>\n<dd><p>It is built to sit alongside them rather than replace them. Plugins that change\nthe login URL or add an image CAPTCHA keep doing so; the passkey button appears\non whatever login screen your site actually serves. With Wordfence Login\nSecurity or Two-Factor, a passkey satisfies the second factor, and a weaker\nalternative login still has to pass the site's own 2FA.<\/p><\/dd>\n<dt id=\"is%20the%20plugin%20available%20in%20japanese%3F\"><h3>Is the plugin available in Japanese?<\/h3><\/dt>\n<dd><p>Yes. The Japanese translation is complete, and WordPress.org serves it as a\nlanguage pack \u2014 no bundled catalogue, so it updates independently of the\nplugin.<\/p><\/dd>\n<dt id=\"what%20if%20i%20lose%20my%20passkey%20and%20cannot%20sign%20in%3F\"><h3>What if I lose my passkey and cannot sign in?<\/h3><\/dt>\n<dd><p>Password login still works alongside passkeys, so sign in with your password as usual and then remove or re-register passkeys from your profile screen.<\/p>\n\n<p>You can also manage passkeys from the server with WP-CLI:<\/p>\n\n<pre><code>wp rapls-passkey list --user=admin\nwp rapls-passkey remove &lt;id&gt;\n<\/code><\/pre>\n\n<p>In an emergency, add the following to wp-config.php to temporarily disable passkey enforcement (remove it once you have recovered):<\/p>\n\n<pre><code>define( 'RAPLS_PASSKEY_BYPASS', true );\n<\/code><\/pre><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.13.74<\/h4>\n\n<ul>\n<li>Passkey sign-in no longer depends on the object cache. A sign-in is two requests \u2014 the browser asks for a challenge, then sends back the answer \u2014 and the challenge was kept in a transient, which WordPress stores in the object cache whenever one is installed. WordPress then assumes the cache will hand the second request what the first one wrote, and that is up to the host, not the plugin: separate PHP-FPM instances and separate servers do not share an APCu segment, and any cache can evict an entry or lose the counter a drop-in namespaces its keys by. Seen on a live site, the challenge was not what came back seconds later, and a correct passkey was refused as expired \u2014 which is why the same passkey worked, then did not, then worked again. Challenges and parked two-factor logins now go straight to the database.<\/li>\n<li>A challenge can no longer be spent twice on such a host. Single use was enforced with an atomic add on the object cache, which decides a winner only among callers the cache actually serializes; where it does not, two requests could both be told they had won. It is now decided by the database.<\/li>\n<li>Site Health reports an object cache that does not return what an earlier request wrote. It affects far more than this plugin, and nothing else says so.<\/li>\n<\/ul>\n\n<h4>0.13.72<\/h4>\n\n<ul>\n<li>Signing in with a passkey no longer fails at random. The browser allows one credential request at a time, and the page keeps a background one open so passkeys appear in the username field. Pressing the button while that one was still being cancelled was answered with \"a request is already pending\", which is why the same passkey worked one moment and failed the next; the button now waits for the background request to actually be released, and cannot be pressed twice into the same prompt.<\/li>\n<li>A passkey chosen from the username field's autofill list no longer fails silently. Once the authenticator has answered, the sign-in is finished and reported instead of being cancelled halfway or abandoned without a word \u2014 the case where touching the sensor appeared to do nothing at all.<\/li>\n<li>A login page left open for a long time still works. The sign-in attempt the page holds open is refreshed before the server stops recognising it, rather than failing the next time a passkey is picked.<\/li>\n<li>Failures now say what went wrong: a connection problem, a cancelled prompt, or a site that is not on HTTPS each get their own message instead of a single \"authentication failed\", and internal browser text is no longer shown.<\/li>\n<\/ul>\n\n<h4>0.13.71<\/h4>\n\n<ul>\n<li>Display name updated: the plugin is listed as \"Rapls Passkey \u2013 Passwordless Login with WebAuthn\" so that the directory search finds it by what it does, not only by its brand name. The short description on the Plugins screen now names Touch ID, Windows Hello and security keys instead of repeating the title. No functional change.<\/li>\n<\/ul>\n\n<h4>0.13.70<\/h4>\n\n<ul>\n<li><strong>Fixed: on PHP older than 8.2 the whole site went down, front end included.<\/strong> The bundled dependencies require 8.2, and Composer's platform check throws the moment the autoloader is read \u2014 inside WordPress's plugin loading, where nothing catches it. The plugin now checks the version first and steps aside with an admin notice, leaving the rest of the site alone. The <code>Requires PHP<\/code> header does not cover this on its own: WordPress reads it when activating and when offering an update, so a server whose PHP is lowered afterwards, or a WP-CLI running an older PHP than the web server, went straight past it.<\/li>\n<\/ul>\n\n<h4>0.13.69<\/h4>\n\n<ul>\n<li>The Rapls Passkey Pro panel moved into a sidebar that follows the page down. It sat at the very bottom of a single column, below the audit table, where nobody scrolls. It also says what the add-on is for rather than listing features, the Plugins screen gains \"Settings\" and \"Go Pro\" row links, and the adoption figure names what closes the gap. Nothing on the page is gated: the readme now has a Pro section and an FAQ entry saying plainly that the free version has no cap, trial or licence key.<\/li>\n<li>Asks for a WordPress.org review, once. After a week of use, and only if a passkey has actually been registered, a notice on this plugin's own two screens asks for one. Every button \u2014 including the close button \u2014 settles it for good, and rapls_passkey\/show_review_prompt turns it off entirely. It never appears anywhere else in wp-admin and never comes back.<\/li>\n<li>Corrected: the readme claimed a bundled Japanese translation, which has not been true since 0.13.62. Translations come from translate.wordpress.org.<\/li>\n<\/ul>\n\n<h4>0.13.68<\/h4>\n\n<ul>\n<li>Screenshots for the plugin directory listing, and the readme section that names them. No change to the plugin.<\/li>\n<\/ul>\n\n<h4>0.13.67<\/h4>\n\n<ul>\n<li>Tests only, and one that was worth finding: nothing asserted that registering a passkey for another user is on by default. The stub in the enrolment test answered the filter itself, so the shipped default was never read \u2014 flip it back to off and every test still passed. The default is now under test, on both call sites, and the source is checked for wording that ties the feature to the paid add-on.<\/li>\n<\/ul>\n\n<h4>0.13.66<\/h4>\n\n<ul>\n<li><strong>Registering a passkey for another user is on by default.<\/strong> It was implemented but switched off, and the Pro add-on turned it on \u2014 which made a built-in feature depend on a licence, and that is not allowed here. The capability check was always the real bound and it has not changed: only someone who can already edit that user, and could therefore reset their password and sign in as them, can enrol for them. Pro's setting now only turns the feature off.<\/li>\n<li>The second-factor screen filters the markup its 2FA provider prints, to the form controls such a screen needs. The two bundled adapters are unaffected, byte for byte; inline JavaScript from a provider is dropped, and a provider that needs it should enqueue it.<\/li>\n<li>The package no longer carries the Japanese catalogue or <code>load_plugin_textdomain()<\/code>. WordPress.org builds translations for every locale from translate.wordpress.org and loads them on demand, and a bundled copy would only shadow that.<\/li>\n<li>Dropped two test-only directories that Composer installs inside third-party packages (<code>doctrine\/deprecations<\/code>, <code>symfony\/clock<\/code>).<\/li>\n<\/ul>\n\n<h4>0.13.65<\/h4>\n\n<ul>\n<li>Clears the last of the WordPress Plugin Check warnings against the shipped package. <code>$_SERVER['REQUEST_METHOD']<\/code>, a <code>redirect_to<\/code> from the query string and the \"seen device\" cookie are now unslashed and sanitised on the way in rather than only validated afterwards; the uninstall script's two loop variables are prefixed, since a file that runs at global scope defines globals; and the exemption on the DROP TABLE in uninstall named the wrong rule.<\/li>\n<li><code>composer.json<\/code> ships with the package again. WordPress.org's scan asks for it wherever a <code>vendor\/<\/code> directory is present, and it is the manifest that says what is in there. <code>composer.lock<\/code> stays out. Note for anyone reading the package: <code>vendor\/<\/code> has already been namespace-prefixed by the build, so do not run <code>composer install<\/code> inside an installed copy.<\/li>\n<li>No functional change.<\/li>\n<\/ul>\n\n<h4>0.13.64<\/h4>\n\n<ul>\n<li>Readme only: <code>Tested up to<\/code> named a patch release (7.0.2). WordPress.org's automated scan requires the major version alone, and rejected the upload over it. It reads 7.0 now; the plugin is unchanged and was tested against 7.0.2.<\/li>\n<\/ul>\n\n<h4>0.13.63<\/h4>\n\n<ul>\n<li><strong>Direct-access protection was missing from every file in the distributed package.<\/strong> The plugin guards each file with <code>if ( ! defined( 'ABSPATH' ) )<\/code>, which the build rewrites to <code>if ( ! \\defined( 'ABSPATH' ) )<\/code> \u2014 a form the WordPress Plugin Check tool does not recognise. Every shipped file therefore read as unprotected to the tooling, while the repository looked correct. The guard is now written in the form that survives the build.<\/li>\n<li><strong>The code-standard exemptions in the shipped files were pointing at the wrong lines.<\/strong> They were written at the end of the line they applied to, and the build moves a trailing comment onto the following line \u2014 so each one silenced the line after the one it was meant to cover. All of them are now written above the line they apply to.<\/li>\n<li>Fixes the findings these two hid: an unescaped exception message, a missing translators comment, a database call whose exemption named the wrong rule, and the CSV export's file handle. Behaviour is unchanged; the audit-log CSV, the two-factor integrations and the passkey cap all work exactly as before.<\/li>\n<li>Also: <code>Plugin URI<\/code> pointed at this plugin's WordPress.org page, which the plugin header documentation does not allow, and <code>Author URI<\/code> was missing. The readme's external-service disclosure (optional reCAPTCHA) is now its own section, and releases older than 0.13.46 have moved to changelog.txt.<\/li>\n<\/ul>\n\n<p>For the change history of 0.13.62 and earlier releases, see changelog.txt.<\/p>","raw_excerpt":"Touch ID, Windows Hello and security keys sign users in. No extra PHP extension, no external service, and password sign-in keeps working.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/350324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=350324"}],"author":[{"embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/rapls"}],"wp:attachment":[{"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=350324"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=350324"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=350324"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=350324"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=350324"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/bal.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=350324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}