@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/?post_type=lh-portfolio-doc&#038;p=150400>
  a sioc:Post ;
  dc:title "Changelog" ;
  dcterms:identifier 150400 ;
  dc:modified "2026-10-15T12:32:58Z"^^xsd:dateTime ;
  dc:created "2026-10-15T12:19:35Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-site-privacy/changelog/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded "<ul class=\"lh_portfolio-meta\"><li><strong>Part of:</strong> <a href=\"https://lhero.org/portfolio/lh-site-privacy/\">LH Site Privacy</a></li></ul><ul class=\"lh_portfolio-changelog\"><li><strong>0.4.1:</strong> Shorter MCP ability description. The opening sentence of get-privacy now says what the ability returns in under 70 characters, because discover-abilities lists only that sentence. The list of fields follows unchanged in the next sentence. Wording only: no change to behaviour, inputs or outputs.</li><li><strong>0.4.0:</strong> Mastodon apps can now sign in to private sites when Enable Mastodon Apps is active. The gate refused the requests a Mastodon client makes before it has logged in, so no app could connect to a private site. Instance and nodeinfo discovery, app registration, Enable Mastodon Apps&#039; own diagnostic check and token revocation are now let through. These are the same routes logged-out visitors can reach on public sites, and none return posts or members. Signing in still needs someone with access to the site: the authorize page sends visitors to log in first and refuses anyone without access. Timelines, accounts and posts stay private. The list of routes can be changed with the new lh_site_privacy_return_mastodon_signin_routes filter.</li><li><strong>0.3.4:</strong> get-privacy and set-privacy now reach other sites through LH MCP Adapter Extensions instead of their own site_id handling. site_id works as before where that plugin is active, but the target site must now be live and you must belong to it (super admins can reach any site), and manage_options is checked on that site. Archived, spam and deleted sites can no longer be read or changed from another site. Setting the members level from another site is still refused.</li><li><strong>0.3.3:</strong> Logged-in users with access are no longer refused on a private site&#039;s REST API when a request carries no REST nonce. WordPress treats such a request as logged out, which every navigator.sendBeacon() call is (the LH Log User Data pixel, for example), so the gate answered it with a 401. The gate now decides who may see the site from the logged-in cookie as well, while the request itself still runs as the user WordPress decided, so endpoints gain no access they would not have on a public site.</li><li><strong>0.3.2:</strong> Fix a redirect loop on private sites whose login page is on the front end. Plugins such as LH Membership move the login, registration and lost-password forms onto front-end pages by filtering login_url, register_url and lostpassword_url; the gate then protected the login page itself, so visitors who were not logged in were redirected to it forever and the site appeared to hang. The pages those three URLs point to are now always reachable, so visitors land on the login form with the explanation that the site is private. Other pages can be let through with the new lh_site_privacy_is_exempt_front_end_request filter.</li><li><strong>0.3.1:</strong> Sites hidden from search engines are now flagged to administrators too, not just private sites. Any site that is not fully public shows a marker in the admin bar on every screen, reading Hidden from search engines for a site set to discourage search engines and Private: followed by the level for a private site, and a notice on the Dashboard and Settings &gt; Reading saying so.</li><li><strong>0.3.0:</strong> Every site can now use every privacy level: the network setting for which private levels sites may choose has been removed, along with the lh_site_privacy_available_levels filter and the lh_site_privacy_return_available_levels_option_name filter. The members level still appears only where a membership plugin answers who is a member. Network Admin &gt; Settings keeps one privacy setting, the level for new sites.</li><li><strong>0.2.2:</strong> The password access cookie now falls back to the root path whenever WordPress has not defined COOKIEPATH, rather than relying on the constant always being defined. No change in behaviour on a normal WordPress request.</li><li><strong>0.2.1:</strong> Coding standards fixes. The password form and the no-access page now pass their HTML through wp_kses with a fixed list of allowed tags before it is shown, so markup added by the lh_site_privacy_password_form and lh_site_privacy_no_access_message filters is limited to what those pages need. The network setting for the privacy of new sites is sanitised before it is saved. admin-ajax and admin-post requests no longer read the action name: a plugin whose handler must work for visitors on a private site now answers the new lh_site_privacy_is_exempt_admin_request filter for its own action, replacing lh_site_privacy_return_exempt_admin_actions.</li><li><strong>0.2.0:</strong> First working release. LH Site Privacy makes a site private by adding five levels to Settings &gt; Reading, stored in core&#039;s blog_public option alongside core&#039;s public and hidden-from-search-engines settings: logged-in users (anyone with an account on the network), site users (anyone with a role on the site), administrators only, a shared site password (plus site users), and true members only, which is offered when a membership plugin answers the lh_site_privacy_user_is_member filter. Super admins and site administrators can always visit. Visitors who are not logged in are sent to the login form, which explains why; at the password level they see a password form instead. Logged-in users without access see a no-access page with a link to log in as someone else. The gate covers the front end (pages, feeds, embeds, Markdown and llms.txt), the REST API (with OAuth discovery and token endpoints left reachable so AI clients can still connect), and admin-ajax and admin-post requests; uploaded files are not covered. Private sites are marked noindex, disallow everything in robots.txt, have core sitemaps turned off and are never page cached, and LiteSpeed Cache is purged when a level changes. The site password is stored hashed; entering it sets a signed cookie for that site (never a URL token), attempts are rate limited, and changing the password signs out everyone who entered the old one. On a network, Network Admin &gt; Settings chooses which private levels sites may use and the level for new sites, and Network Admin &gt; Sites gains a Privacy column. Administrators see a notice on the Dashboard and Reading screens and a Private marker in the admin bar. Two MCP abilities, lh-site-privacy/get-privacy and lh-site-privacy/set-privacy, read and change a site&#039;s level and password, for the current site or another by site_id, and require manage_options on that site. Existing sites already set to an extra privacy level by LH Multisite Privacy Options keep it and are enforced as soon as this plugin is active. This replaces LH Multisite Privacy Options, LH Private Site and LH Extra Multisite Privacy.</li><li><strong>0.1.0:</strong> Initial scaffold.</li></ul>"^^rdf:XMLLiteral ;
  sioc:content "Part of: LH Site Privacy0.4.1: Shorter MCP ability description. The opening sentence of get-privacy now says what the ability returns in under 70 characters, because discover-abilities lists only that sentence. The list of fields follows unchanged in the next sentence. Wording only: no change to behaviour, inputs or outputs.0.4.0: Mastodon apps can now sign in to private sites when Enable Mastodon Apps is active. The gate refused the requests a Mastodon client makes before it has logged in, so no app could connect to a private site. Instance and nodeinfo discovery, app registration, Enable Mastodon Apps&#039; own diagnostic check and token revocation are now let through. These are the same routes logged-out visitors can reach on public sites, and none return posts or members. Signing in still needs someone with access to the site: the authorize page sends visitors to log in first and refuses anyone without access. Timelines, accounts and posts stay private. The list of routes can be changed with the new lh_site_privacy_return_mastodon_signin_routes filter.0.3.4: get-privacy and set-privacy now reach other sites through LH MCP Adapter Extensions instead of their own site_id handling. site_id works as before where that plugin is active, but the target site must now be live and you must belong to it (super admins can reach any site), and manage_options is checked on that site. Archived, spam and deleted sites can no longer be read or changed from another site. Setting the members level from another site is still refused.0.3.3: Logged-in users with access are no longer refused on a private site&#039;s REST API when a request carries no REST nonce. WordPress treats such a request as logged out, which every navigator.sendBeacon() call is (the LH Log User Data pixel, for example), so the gate answered it with a 401. The gate now decides who may see the site from the logged-in cookie as well, while the request itself still runs as the user WordPress decided, so endpoints gain no access they would not have on a public site.0.3.2: Fix a redirect loop on private sites whose login page is on the front end. Plugins such as LH Membership move the login, registration and lost-password forms onto front-end pages by filtering login_url, register_url and lostpassword_url; the gate then protected the login page itself, so visitors who were not logged in were redirected to it forever and the site appeared to hang. The pages those three URLs point to are now always reachable, so visitors land on the login form with the explanation that the site is private. Other pages can be let through with the new lh_site_privacy_is_exempt_front_end_request filter.0.3.1: Sites hidden from search engines are now flagged to administrators too, not just private sites. Any site that is not fully public shows a marker in the admin bar on every screen, reading Hidden from search engines for a site set to discourage search engines and Private: followed by the level for a private site, and a notice on the Dashboard and Settings &gt; Reading saying so.0.3.0: Every site can now use every privacy level: the network setting for which private levels sites may choose has been removed, along with the lh_site_privacy_available_levels filter and the lh_site_privacy_return_available_levels_option_name filter. The members level still appears only where a membership plugin answers who is a member. Network Admin &gt; Settings keeps one privacy setting, the level for new sites.0.2.2: The password access cookie now falls back to the root path whenever WordPress has not defined COOKIEPATH, rather than relying on the constant always being defined. No change in behaviour on a normal WordPress request.0.2.1: Coding standards fixes. The password form and the no-access page now pass their HTML through wp_kses with a fixed list of allowed tags before it is shown, so markup added by the lh_site_privacy_password_form and lh_site_privacy_no_access_message filters is limited to what those pages need. The network setting for the privacy of new sites is sanitised before it is saved. admin-ajax and admin-post requests no longer read the action name: a plugin whose handler must work for visitors on a private site now answers the new lh_site_privacy_is_exempt_admin_request filter for its own action, replacing lh_site_privacy_return_exempt_admin_actions.0.2.0: First working release. LH Site Privacy makes a site private by adding five levels to Settings &gt; Reading, stored in core&#039;s blog_public option alongside core&#039;s public and hidden-from-search-engines settings: logged-in users (anyone with an account on the network), site users (anyone with a role on the site), administrators only, a shared site password (plus site users), and true members only, which is offered when a membership plugin answers the lh_site_privacy_user_is_member filter. Super admins and site administrators can always visit. Visitors who are not logged in are sent to the login form, which explains why; at the password level they see a password form instead. Logged-in users without access see a no-access page with a link to log in as someone else. The gate covers the front end (pages, feeds, embeds, Markdown and llms.txt), the REST API (with OAuth discovery and token endpoints left reachable so AI clients can still connect), and admin-ajax and admin-post requests; uploaded files are not covered. Private sites are marked noindex, disallow everything in robots.txt, have core sitemaps turned off and are never page cached, and LiteSpeed Cache is purged when a level changes. The site password is stored hashed; entering it sets a signed cookie for that site (never a URL token), attempts are rate limited, and changing the password signs out everyone who entered the old one. On a network, Network Admin &gt; Settings chooses which private levels sites may use and the level for new sites, and Network Admin &gt; Sites gains a Privacy column. Administrators see a notice on the Dashboard and Reading screens and a Private marker in the admin bar. Two MCP abilities, lh-site-privacy/get-privacy and lh-site-privacy/set-privacy, read and change a site&#039;s level and password, for the current site or another by site_id, and require manage_options on that site. Existing sites already set to an extra privacy level by LH Multisite Privacy Options keep it and are enforced as soon as this plugin is active. This replaces LH Multisite Privacy Options, LH Private Site and LH Extra Multisite Privacy.0.1.0: Initial scaffold." ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
