From 4e493c268eb49e1b0ded7d6c4618dcc1fe462e58 Mon Sep 17 00:00:00 2001 From: Lai Power Date: Thu, 27 Jun 2024 12:10:38 +0000 Subject: [PATCH] updated plugin `ActivityPub` version 2.4.0 --- wp-content/plugins/activitypub/.distignore | 42 --- .../plugins/activitypub/activitypub.php | 11 +- .../assets/css/activitypub-admin.css | 5 + .../activitypub/build/follow-me/index.js | 2 +- .../activitypub/build/follow-me/view.js | 2 +- .../build/followers/index.asset.php | 2 +- .../activitypub/build/followers/index.js | 6 +- .../build/followers/view.asset.php | 2 +- .../activitypub/build/followers/view.js | 6 +- .../activitypub/build/remote-reply/index.js | 2 +- .../includes/activity/class-activity.php | 8 +- .../includes/class-activity-dispatcher.php | 24 +- .../includes/class-activitypub.php | 33 +-- .../activitypub/includes/class-admin.php | 71 ++++- .../activitypub/includes/class-comment.php | 2 +- .../activitypub/includes/class-handler.php | 2 + .../activitypub/includes/class-http.php | 94 +++++++ .../activitypub/includes/class-mention.php | 14 +- .../activitypub/includes/class-migration.php | 2 +- .../includes/class-notification.php | 58 +++++ .../includes/collection/class-users.php | 59 +++-- .../activitypub/includes/functions.php | 115 ++++++++ .../includes/handler/class-announce.php | 69 +++++ .../includes/handler/class-follow.php | 10 + .../includes/model/class-application-user.php | 79 ------ .../includes/model/class-application.php | 200 ++++++++++++++ .../{class-blog-user.php => class-blog.php} | 169 ++++++++++-- .../activitypub/includes/model/class-post.php | 12 +- .../activitypub/includes/model/class-user.php | 41 +-- .../{class-users.php => class-actors.php} | 8 +- .../includes/rest/class-collection.php | 19 +- .../includes/rest/class-comment.php | 2 +- .../includes/rest/class-followers.php | 6 +- .../includes/rest/class-following.php | 6 +- .../activitypub/includes/rest/class-inbox.php | 6 +- .../includes/rest/class-outbox.php | 16 +- .../includes/rest/class-server.php | 27 +- .../includes/transformer/class-base.php | 5 +- .../includes/transformer/class-comment.php | 55 ++-- .../includes/transformer/class-factory.php | 12 +- .../includes/transformer/class-post.php | 208 ++++++++++----- .../class-enable-mastodon-apps.php | 246 ++++++++++++------ .../activitypub/integration/class-jetpack.php | 21 ++ wp-content/plugins/activitypub/readme.txt | 28 +- .../activitypub/templates/blog-json.php | 2 +- .../activitypub/templates/comment-json.php | 33 +-- .../activitypub/templates/post-json.php | 13 +- .../activitypub/templates/settings.php | 2 +- .../plugins/activitypub/templates/welcome.php | 2 +- 49 files changed, 1368 insertions(+), 491 deletions(-) delete mode 100644 wp-content/plugins/activitypub/.distignore create mode 100644 wp-content/plugins/activitypub/includes/class-notification.php create mode 100644 wp-content/plugins/activitypub/includes/handler/class-announce.php delete mode 100644 wp-content/plugins/activitypub/includes/model/class-application-user.php create mode 100644 wp-content/plugins/activitypub/includes/model/class-application.php rename wp-content/plugins/activitypub/includes/model/{class-blog-user.php => class-blog.php} (57%) rename wp-content/plugins/activitypub/includes/rest/{class-users.php => class-actors.php} (95%) create mode 100644 wp-content/plugins/activitypub/integration/class-jetpack.php diff --git a/wp-content/plugins/activitypub/.distignore b/wp-content/plugins/activitypub/.distignore deleted file mode 100644 index e864dd8d..00000000 --- a/wp-content/plugins/activitypub/.distignore +++ /dev/null @@ -1,42 +0,0 @@ -.DS_Store -.editorconfig -.git -.gitignore -.github -.travis.yml -.codeclimate.yml -.data -.svnignore -.wordpress-org -.php_cs -Gruntfile.js -LINGUAS -Makefile -README.md -readme.md -CHANGELOG.md -CODE_OF_CONDUCT.md -FEDERATION.md -SECURITY.md -LICENSE.md -_site -_config.yml -bin -composer.json -composer.lock -docker-compose.yml -docker-compose-test.yml -Dockerfile -gulpfile.js -package.json -node_modules -npm-debug.log -phpcs.xml -package.json -package-lock.json -phpunit.xml -phpunit.xml.dist -tests -node_modules -vendor -src diff --git a/wp-content/plugins/activitypub/activitypub.php b/wp-content/plugins/activitypub/activitypub.php index 9c163161..ace3ff44 100644 --- a/wp-content/plugins/activitypub/activitypub.php +++ b/wp-content/plugins/activitypub/activitypub.php @@ -3,7 +3,7 @@ * Plugin Name: ActivityPub * Plugin URI: https://github.com/pfefferle/wordpress-activitypub/ * Description: The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. - * Version: 2.3.1 + * Version: 2.4.0 * Author: Matthias Pfefferle & Automattic * Author URI: https://automattic.com/ * License: MIT @@ -21,7 +21,7 @@ use function Activitypub\site_supports_blocks; require_once __DIR__ . '/includes/compat.php'; require_once __DIR__ . '/includes/functions.php'; -\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.3.1' ); +\define( 'ACTIVITYPUB_PLUGIN_VERSION', '2.4.0' ); /** * Initialize the plugin constants. @@ -50,7 +50,7 @@ require_once __DIR__ . '/includes/functions.php'; * Initialize REST routes. */ function rest_init() { - Rest\Users::init(); + Rest\Actors::init(); Rest\Outbox::init(); Rest\Inbox::init(); Rest\Followers::init(); @@ -100,6 +100,11 @@ function plugin_init() { require_once __DIR__ . '/integration/class-enable-mastodon-apps.php'; Integration\Enable_Mastodon_Apps::init(); + + if ( \defined( 'JETPACK__VERSION' ) && ! \defined( 'IS_WPCOM' ) ) { + require_once __DIR__ . '/integration/class-jetpack.php'; + Integration\Jetpack::init(); + } } \add_action( 'plugins_loaded', __NAMESPACE__ . '\plugin_init' ); diff --git a/wp-content/plugins/activitypub/assets/css/activitypub-admin.css b/wp-content/plugins/activitypub/assets/css/activitypub-admin.css index 07aadcad..7c7589e4 100644 --- a/wp-content/plugins/activitypub/assets/css/activitypub-admin.css +++ b/wp-content/plugins/activitypub/assets/css/activitypub-admin.css @@ -197,3 +197,8 @@ input.blog-user-identifier { border-bottom: none; margin-bottom: 0; } + +#dashboard_right_now li a.activitypub-followers::before { + content: "\f307"; + font-family: dashicons; +} diff --git a/wp-content/plugins/activitypub/build/follow-me/index.js b/wp-content/plugins/activitypub/build/follow-me/index.js index 12897d8b..55bc6759 100644 --- a/wp-content/plugins/activitypub/build/follow-me/index.js +++ b/wp-content/plugins/activitypub/build/follow-me/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={647:(e,t,n)=>{const o=window.wp.blocks,r=window.React,l=window.wp.primitives,a=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),i=window.wp.blockEditor,c=window.wp.i18n,u=window.wp.components,s=window.wp.data,p=window.wp.element,d=window._activityPubOptions?.enabled,v=window.wp.apiFetch;var m=n.n(v);function f(e){return`var(--wp--preset--color--${e})`}function w(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return f(t)}function b(e,t,n=null,o=""){return n?`${e}${o} { ${t}: ${n}; }\n`:""}function y(e,t,n,o){return b(e,"background-color",t)+b(e,"color",n)+b(e,"background-color",o,":hover")+b(e,"background-color",o,":focus")}function _({selector:e,style:t,backgroundColor:n}){const o=function(e,t,n){const o=`${e} .components-button`,r=("string"==typeof(l=n)?f(l):l?.color?.background||null)||t?.color?.background;var l;return y(o,w(t?.elements?.link?.color?.text),r,w(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,n);return(0,r.createElement)("style",null,o)}const h=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})),g=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),E=(0,p.forwardRef)((function({icon:e,size:t=24,...n},o){return(0,p.cloneElement)(e,{width:t,height:t,...n,ref:o})})),k=window.wp.compose;function x(e){try{return new URL(e),!0}catch(e){return!1}}function C({actionText:e,copyDescription:t,handle:n,resourceUrl:o}){const l=(0,c.__)("Loading...","activitypub"),a=(0,c.__)("Opening...","activitypub"),i=(0,c.__)("Error","activitypub"),s=(0,c.__)("Invalid","activitypub"),[d,v]=(0,p.useState)(e),[f,w]=(0,p.useState)(h),b=(0,k.useCopyToClipboard)(n,(()=>{w(g),setTimeout((()=>w(h)),1e3)})),[y,_]=(0,p.useState)(""),C=(0,p.useCallback)((()=>{let t;if(!x(y)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&x(`https://${t[1]}`)}(y))return v(s),t=setTimeout((()=>v(e)),2e3),()=>clearTimeout(t);const n=o+y;v(l),m()({path:n}).then((({url:t})=>{v(a),setTimeout((()=>{window.open(t,"_blank"),v(e)}),200)})).catch((()=>{v(i),setTimeout((()=>v(e)),2e3)}))}),[y]);return(0,r.createElement)("div",{className:"activitypub__dialog"},(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,c.__)("My Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog-description"},t),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:n,readOnly:!0}),(0,r.createElement)(u.Button,{ref:b},(0,r.createElement)(E,{icon:f}),(0,c.__)("Copy","activitypub")))),(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,c.__)("Your Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog__description"},(0,p.createInterpolateElement)((0,c.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,r.createElement)("code",null)})),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:y,onKeyDown:e=>{"Enter"===e?.code&&C()},onChange:e=>_(e.target.value)}),(0,r.createElement)(u.Button,{onClick:C},d))))}const{namespace:O}=window._activityPubOptions,S={avatar:"",webfinger:"@well@hello.dolly",name:(0,c.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function N(e){if(!e)return S;const t={...S,...e};return t.avatar=t?.icon?.url,t}function $({profile:e,popupStyles:t,userId:n}){const{avatar:o,name:l,webfinger:a}=e;return(0,r.createElement)("div",{className:"activitypub-profile"},(0,r.createElement)("img",{className:"activitypub-profile__avatar",src:o,alt:l}),(0,r.createElement)("div",{className:"activitypub-profile__content"},(0,r.createElement)("div",{className:"activitypub-profile__name"},l),(0,r.createElement)("div",{className:"activitypub-profile__handle",title:a},a)),(0,r.createElement)(P,{profile:e,popupStyles:t,userId:n}))}function P({profile:e,popupStyles:t,userId:n}){const[o,l]=(0,p.useState)(!1),a=(0,c.sprintf)((0,c.__)("Follow %s","activitypub"),e?.name);return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(u.Button,{className:"activitypub-profile__follow",onClick:()=>l(!0)},(0,c.__)("Follow","activitypub")),o&&(0,r.createElement)(u.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>l(!1),title:a},(0,r.createElement)(T,{profile:e,userId:n}),(0,r.createElement)("style",null,t)))}function T({profile:e,userId:t}){const{webfinger:n}=e,o=(0,c.__)("Follow","activitypub"),l=`/${O}/users/${t}/remote-follow?resource=`,a=(0,c.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub");return(0,r.createElement)(C,{actionText:o,copyDescription:a,handle:n,resourceUrl:l})}function I({selectedUser:e,style:t,backgroundColor:n,id:o,useId:l=!1,profileData:a=!1}){const[i,c]=(0,p.useState)(N()),u="site"===e?0:e,s=function(e){return y(".apfmd__button-group .components-button",w(e?.elements?.link?.color?.text)||"#111","#fff",w(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),d=l?{id:o}:{};function v(e){c(N(e))}return(0,p.useEffect)((()=>{if(a)return v(a);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${O}/users/${e}`};return m()(t)})(u).then(v)}),[u,a]),(0,r.createElement)("div",{...d},(0,r.createElement)(_,{selector:`#${o}`,style:t,backgroundColor:n}),(0,r.createElement)($,{profile:i,userId:u,popupStyles:s}))}(0,o.registerBlockType)("activitypub/follow-me",{edit:function({attributes:e,setAttributes:t}){const n=(0,i.useBlockProps)({className:"activitypub-follow-me-block-wrapper"}),o=function(){const e=d?.users?(0,s.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,p.useMemo)((()=>{if(!e)return[];const t=d?.site?[{label:(0,c.__)("Whole Site","activitypub"),value:"site"}]:[];return e.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),t)}),[e])}(),{selectedUser:l}=e;return(0,p.useEffect)((()=>{o.length&&(o.find((({value:e})=>e===l))||t({selectedUser:o[0].value}))}),[l,o]),(0,r.createElement)("div",{...n},o.length>1&&(0,r.createElement)(i.InspectorControls,{key:"setting"},(0,r.createElement)(u.PanelBody,{title:(0,c.__)("Followers Options","activitypub")},(0,r.createElement)(u.SelectControl,{label:(0,c.__)("Select User","activitypub"),value:e.selectedUser,options:o,onChange:e=>t({selectedUser:e})}))),(0,r.createElement)(I,{...e,id:n.id}))},save:()=>null,icon:a})}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var l=n[e]={exports:{}};return t[e](l,l.exports,o),l.exports}o.m=t,e=[],o.O=(t,n,r,l)=>{if(!n){var a=1/0;for(s=0;s=l)&&Object.keys(o.O).every((e=>o.O[e](n[c])))?n.splice(c--,1):(i=!1,l0&&e[s-1][2]>l;s--)e[s]=e[s-1];e[s]=[n,r,l]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={338:0,301:0};o.O.j=t=>0===e[t];var t=(t,n)=>{var r,l,[a,i,c]=n,u=0;if(a.some((t=>0!==e[t]))){for(r in i)o.o(i,r)&&(o.m[r]=i[r]);if(c)var s=c(o)}for(t&&t(n);uo(647)));r=o.O(r)})(); \ No newline at end of file +(()=>{"use strict";var e,t={147:(e,t,n)=>{const o=window.wp.blocks,r=window.wp.element,l=window.wp.primitives,i=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),a=window.wp.blockEditor,c=window.wp.i18n,u=window.wp.components,s=window.wp.data,p=window._activityPubOptions?.enabled,v=window.wp.apiFetch;var m=n.n(v);function d(e){return`var(--wp--preset--color--${e})`}function f(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return d(t)}function y(e,t,n=null,o=""){return n?`${e}${o} { ${t}: ${n}; }\n`:""}function b(e,t,n,o){return y(e,"background-color",t)+y(e,"color",n)+y(e,"background-color",o,":hover")+y(e,"background-color",o,":focus")}function w({selector:e,style:t,backgroundColor:n}){const o=function(e,t,n){const o=`${e} .components-button`,r=("string"==typeof(l=n)?d(l):l?.color?.background||null)||t?.color?.background;var l;return b(o,f(t?.elements?.link?.color?.text),r,f(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,n);return(0,r.createElement)("style",null,o)}const _=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{d:"M20.2 8v11c0 .7-.6 1.2-1.2 1.2H6v1.5h13c1.5 0 2.7-1.2 2.7-2.8V8zM18 16.4V4.6c0-.9-.7-1.6-1.6-1.6H4.6C3.7 3 3 3.7 3 4.6v11.8c0 .9.7 1.6 1.6 1.6h11.8c.9 0 1.6-.7 1.6-1.6zm-13.5 0V4.6c0-.1.1-.1.1-.1h11.8c.1 0 .1.1.1.1v11.8c0 .1-.1.1-.1.1H4.6l-.1-.1z"})),h=(0,r.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(l.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),g=function({icon:e,size:t=24,...n}){return(0,r.cloneElement)(e,{width:t,height:t,...n})},E=window.wp.compose;function k(e){try{return new URL(e),!0}catch(e){return!1}}function x({actionText:e,copyDescription:t,handle:n,resourceUrl:o}){const l=(0,c.__)("Loading...","activitypub"),i=(0,c.__)("Opening...","activitypub"),a=(0,c.__)("Error","activitypub"),s=(0,c.__)("Invalid","activitypub"),[p,v]=(0,r.useState)(e),[d,f]=(0,r.useState)(_),y=(0,E.useCopyToClipboard)(n,(()=>{f(h),setTimeout((()=>f(_)),1e3)})),[b,w]=(0,r.useState)(""),x=(0,r.useCallback)((()=>{let t;if(!k(b)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&k(`https://${t[1]}`)}(b))return v(s),t=setTimeout((()=>v(e)),2e3),()=>clearTimeout(t);const n=o+b;v(l),m()({path:n}).then((({url:t})=>{v(i),setTimeout((()=>{window.open(t,"_blank"),v(e)}),200)})).catch((()=>{v(a),setTimeout((()=>v(e)),2e3)}))}),[b]);return(0,r.createElement)("div",{className:"activitypub__dialog"},(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,c.__)("My Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog-description"},t),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:n,readOnly:!0}),(0,r.createElement)(u.Button,{ref:y},(0,r.createElement)(g,{icon:d}),(0,c.__)("Copy","activitypub")))),(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,c.__)("Your Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog__description"},(0,r.createInterpolateElement)((0,c.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,r.createElement)("code",null)})),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:b,onKeyDown:e=>{"Enter"===e?.code&&x()},onChange:e=>w(e.target.value)}),(0,r.createElement)(u.Button,{onClick:x},p))))}const{namespace:C}=window._activityPubOptions,O={avatar:"",webfinger:"@well@hello.dolly",name:(0,c.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function S(e){if(!e)return O;const t={...O,...e};return t.avatar=t?.icon?.url,t}function N({profile:e,popupStyles:t,userId:n}){const{avatar:o,name:l,webfinger:i}=e;return(0,r.createElement)("div",{className:"activitypub-profile"},(0,r.createElement)("img",{className:"activitypub-profile__avatar",src:o,alt:l}),(0,r.createElement)("div",{className:"activitypub-profile__content"},(0,r.createElement)("div",{className:"activitypub-profile__name"},l),(0,r.createElement)("div",{className:"activitypub-profile__handle",title:i},i)),(0,r.createElement)($,{profile:e,popupStyles:t,userId:n}))}function $({profile:e,popupStyles:t,userId:n}){const[o,l]=(0,r.useState)(!1),i=(0,c.sprintf)((0,c.__)("Follow %s","activitypub"),e?.name);return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(u.Button,{className:"activitypub-profile__follow",onClick:()=>l(!0)},(0,c.__)("Follow","activitypub")),o&&(0,r.createElement)(u.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>l(!1),title:i},(0,r.createElement)(z,{profile:e,userId:n}),(0,r.createElement)("style",null,t)))}function z({profile:e,userId:t}){const{webfinger:n}=e,o=(0,c.__)("Follow","activitypub"),l=`/${C}/actors/${t}/remote-follow?resource=`,i=(0,c.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub");return(0,r.createElement)(x,{actionText:o,copyDescription:i,handle:n,resourceUrl:l})}function P({selectedUser:e,style:t,backgroundColor:n,id:o,useId:l=!1,profileData:i=!1}){const[a,c]=(0,r.useState)(S()),u="site"===e?0:e,s=function(e){return b(".apfmd__button-group .components-button",f(e?.elements?.link?.color?.text)||"#111","#fff",f(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),p=l?{id:o}:{};function v(e){c(S(e))}return(0,r.useEffect)((()=>{if(i)return v(i);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${C}/actors/${e}`};return m()(t)})(u).then(v)}),[u,i]),(0,r.createElement)("div",{...p},(0,r.createElement)(w,{selector:`#${o}`,style:t,backgroundColor:n}),(0,r.createElement)(N,{profile:a,userId:u,popupStyles:s}))}(0,o.registerBlockType)("activitypub/follow-me",{edit:function({attributes:e,setAttributes:t}){const n=(0,a.useBlockProps)({className:"activitypub-follow-me-block-wrapper"}),o=function(){const e=p?.users?(0,s.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,r.useMemo)((()=>{if(!e)return[];const t=p?.site?[{label:(0,c.__)("Whole Site","activitypub"),value:"site"}]:[];return e.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),t)}),[e])}(),{selectedUser:l}=e;return(0,r.useEffect)((()=>{o.length&&(o.find((({value:e})=>e===l))||t({selectedUser:o[0].value}))}),[l,o]),(0,r.createElement)("div",{...n},o.length>1&&(0,r.createElement)(a.InspectorControls,{key:"setting"},(0,r.createElement)(u.PanelBody,{title:(0,c.__)("Followers Options","activitypub")},(0,r.createElement)(u.SelectControl,{label:(0,c.__)("Select User","activitypub"),value:e.selectedUser,options:o,onChange:e=>t({selectedUser:e})}))),(0,r.createElement)(P,{...e,id:n.id}))},save:()=>null,icon:i})}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var l=n[e]={exports:{}};return t[e](l,l.exports,o),l.exports}o.m=t,e=[],o.O=(t,n,r,l)=>{if(!n){var i=1/0;for(s=0;s=l)&&Object.keys(o.O).every((e=>o.O[e](n[c])))?n.splice(c--,1):(a=!1,l0&&e[s-1][2]>l;s--)e[s]=e[s-1];e[s]=[n,r,l]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={127:0,740:0};o.O.j=t=>0===e[t];var t=(t,n)=>{var r,l,i=n[0],a=n[1],c=n[2],u=0;if(i.some((t=>0!==e[t]))){for(r in a)o.o(a,r)&&(o.m[r]=a[r]);if(c)var s=c(o)}for(t&&t(n);uo(147)));r=o.O(r)})(); \ No newline at end of file diff --git a/wp-content/plugins/activitypub/build/follow-me/view.js b/wp-content/plugins/activitypub/build/follow-me/view.js index 3ebc7eab..690ccb48 100644 --- a/wp-content/plugins/activitypub/build/follow-me/view.js +++ b/wp-content/plugins/activitypub/build/follow-me/view.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={421:(e,t,o)=>{const r=window.React,n=window.wp.element,a=window.wp.domReady;var i=o.n(a);const l=window.wp.apiFetch;var c=o.n(l);const u=window.wp.components,s=window.wp.i18n;function p(e){return`var(--wp--preset--color--${e})`}function d(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return p(t)}function m(e,t,o=null,r=""){return o?`${e}${r} { ${t}: ${o}; }\n`:""}function v(e,t,o,r){return m(e,"background-color",t)+m(e,"color",o)+m(e,"background-color",r,":hover")+m(e,"background-color",r,":focus")}function f({selector:e,style:t,backgroundColor:o}){const n=function(e,t,o){const r=`${e} .components-button`,n=("string"==typeof(a=o)?p(a):a?.color?.background||null)||t?.color?.background;var a;return v(r,d(t?.elements?.link?.color?.text),n,d(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,o);return(0,r.createElement)("style",null,n)}const y=window.wp.primitives,b=(0,r.createElement)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(y.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})),w=(0,r.createElement)(y.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(y.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),_=(0,n.forwardRef)((function({icon:e,size:t=24,...o},r){return(0,n.cloneElement)(e,{width:t,height:t,...o,ref:r})})),h=window.wp.compose;function g(e){try{return new URL(e),!0}catch(e){return!1}}function E({actionText:e,copyDescription:t,handle:o,resourceUrl:a}){const i=(0,s.__)("Loading...","activitypub"),l=(0,s.__)("Opening...","activitypub"),p=(0,s.__)("Error","activitypub"),d=(0,s.__)("Invalid","activitypub"),[m,v]=(0,n.useState)(e),[f,y]=(0,n.useState)(b),E=(0,h.useCopyToClipboard)(o,(()=>{y(w),setTimeout((()=>y(b)),1e3)})),[k,x]=(0,n.useState)(""),O=(0,n.useCallback)((()=>{let t;if(!g(k)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&g(`https://${t[1]}`)}(k))return v(d),t=setTimeout((()=>v(e)),2e3),()=>clearTimeout(t);const o=a+k;v(i),c()({path:o}).then((({url:t})=>{v(l),setTimeout((()=>{window.open(t,"_blank"),v(e)}),200)})).catch((()=>{v(p),setTimeout((()=>v(e)),2e3)}))}),[k]);return(0,r.createElement)("div",{className:"activitypub__dialog"},(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,s.__)("My Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog-description"},t),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:o,readOnly:!0}),(0,r.createElement)(u.Button,{ref:E},(0,r.createElement)(_,{icon:f}),(0,s.__)("Copy","activitypub")))),(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,s.__)("Your Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog__description"},(0,n.createInterpolateElement)((0,s.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,r.createElement)("code",null)})),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:k,onKeyDown:e=>{"Enter"===e?.code&&O()},onChange:e=>x(e.target.value)}),(0,r.createElement)(u.Button,{onClick:O},m))))}const{namespace:k}=window._activityPubOptions,x={avatar:"",webfinger:"@well@hello.dolly",name:(0,s.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function O(e){if(!e)return x;const t={...x,...e};return t.avatar=t?.icon?.url,t}function N({profile:e,popupStyles:t,userId:o}){const{avatar:n,name:a,webfinger:i}=e;return(0,r.createElement)("div",{className:"activitypub-profile"},(0,r.createElement)("img",{className:"activitypub-profile__avatar",src:n,alt:a}),(0,r.createElement)("div",{className:"activitypub-profile__content"},(0,r.createElement)("div",{className:"activitypub-profile__name"},a),(0,r.createElement)("div",{className:"activitypub-profile__handle",title:i},i)),(0,r.createElement)(C,{profile:e,popupStyles:t,userId:o}))}function C({profile:e,popupStyles:t,userId:o}){const[a,i]=(0,n.useState)(!1),l=(0,s.sprintf)((0,s.__)("Follow %s","activitypub"),e?.name);return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(u.Button,{className:"activitypub-profile__follow",onClick:()=>i(!0)},(0,s.__)("Follow","activitypub")),a&&(0,r.createElement)(u.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>i(!1),title:l},(0,r.createElement)(S,{profile:e,userId:o}),(0,r.createElement)("style",null,t)))}function S({profile:e,userId:t}){const{webfinger:o}=e,n=(0,s.__)("Follow","activitypub"),a=`/${k}/users/${t}/remote-follow?resource=`,i=(0,s.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub");return(0,r.createElement)(E,{actionText:n,copyDescription:i,handle:o,resourceUrl:a})}function $({selectedUser:e,style:t,backgroundColor:o,id:a,useId:i=!1,profileData:l=!1}){const[u,s]=(0,n.useState)(O()),p="site"===e?0:e,m=function(e){return v(".apfmd__button-group .components-button",d(e?.elements?.link?.color?.text)||"#111","#fff",d(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),y=i?{id:a}:{};function b(e){s(O(e))}return(0,n.useEffect)((()=>{if(l)return b(l);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${k}/users/${e}`};return c()(t)})(p).then(b)}),[p,l]),(0,r.createElement)("div",{...y},(0,r.createElement)(f,{selector:`#${a}`,style:t,backgroundColor:o}),(0,r.createElement)(N,{profile:u,userId:p,popupStyles:m}))}let I=1;i()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follow-me-block-wrapper"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,n.render)((0,r.createElement)($,{...t,id:"activitypub-follow-me-block-"+I++,useId:!0}),e)}))}))}},o={};function r(e){var n=o[e];if(void 0!==n)return n.exports;var a=o[e]={exports:{}};return t[e](a,a.exports,r),a.exports}r.m=t,e=[],r.O=(t,o,n,a)=>{if(!o){var i=1/0;for(s=0;s=a)&&Object.keys(r.O).every((e=>r.O[e](o[c])))?o.splice(c--,1):(l=!1,a0&&e[s-1][2]>a;s--)e[s]=e[s-1];e[s]=[o,n,a]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={41:0,301:0};r.O.j=t=>0===e[t];var t=(t,o)=>{var n,a,[i,l,c]=o,u=0;if(i.some((t=>0!==e[t]))){for(n in l)r.o(l,n)&&(r.m[n]=l[n]);if(c)var s=c(r)}for(t&&t(o);ur(421)));n=r.O(n)})(); \ No newline at end of file +(()=>{"use strict";var e,t={792:(e,t,o)=>{const r=window.wp.element,n=window.wp.domReady;var a=o.n(n);const c=window.wp.apiFetch;var i=o.n(c);const l=window.wp.components,u=window.wp.i18n;function s(e){return`var(--wp--preset--color--${e})`}function p(e){if("string"!=typeof e)return null;if(e.match(/^#/))return e.substring(0,7);const[,,t]=e.split("|");return s(t)}function m(e,t,o=null,r=""){return o?`${e}${r} { ${t}: ${o}; }\n`:""}function d(e,t,o,r){return m(e,"background-color",t)+m(e,"color",o)+m(e,"background-color",r,":hover")+m(e,"background-color",r,":focus")}function v({selector:e,style:t,backgroundColor:o}){const n=function(e,t,o){const r=`${e} .components-button`,n=("string"==typeof(a=o)?s(a):a?.color?.background||null)||t?.color?.background;var a;return d(r,p(t?.elements?.link?.color?.text),n,p(t?.elements?.link?.[":hover"]?.color?.text))}(e,t,o);return(0,r.createElement)("style",null,n)}const f=window.wp.primitives,y=(0,r.createElement)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(f.Path,{d:"M20.2 8v11c0 .7-.6 1.2-1.2 1.2H6v1.5h13c1.5 0 2.7-1.2 2.7-2.8V8zM18 16.4V4.6c0-.9-.7-1.6-1.6-1.6H4.6C3.7 3 3 3.7 3 4.6v11.8c0 .9.7 1.6 1.6 1.6h11.8c.9 0 1.6-.7 1.6-1.6zm-13.5 0V4.6c0-.1.1-.1.1-.1h11.8c.1 0 .1.1.1.1v11.8c0 .1-.1.1-.1.1H4.6l-.1-.1z"})),b=(0,r.createElement)(f.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,r.createElement)(f.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),w=function({icon:e,size:t=24,...o}){return(0,r.cloneElement)(e,{width:t,height:t,...o})},_=window.wp.compose;function h(e){try{return new URL(e),!0}catch(e){return!1}}function g({actionText:e,copyDescription:t,handle:o,resourceUrl:n}){const a=(0,u.__)("Loading...","activitypub"),c=(0,u.__)("Opening...","activitypub"),s=(0,u.__)("Error","activitypub"),p=(0,u.__)("Invalid","activitypub"),[m,d]=(0,r.useState)(e),[v,f]=(0,r.useState)(y),g=(0,_.useCopyToClipboard)(o,(()=>{f(b),setTimeout((()=>f(y)),1e3)})),[E,k]=(0,r.useState)(""),x=(0,r.useCallback)((()=>{let t;if(!h(E)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&h(`https://${t[1]}`)}(E))return d(p),t=setTimeout((()=>d(e)),2e3),()=>clearTimeout(t);const o=n+E;d(a),i()({path:o}).then((({url:t})=>{d(c),setTimeout((()=>{window.open(t,"_blank"),d(e)}),200)})).catch((()=>{d(s),setTimeout((()=>d(e)),2e3)}))}),[E]);return(0,r.createElement)("div",{className:"activitypub__dialog"},(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,u.__)("My Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog-description"},t),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:o,readOnly:!0}),(0,r.createElement)(l.Button,{ref:g},(0,r.createElement)(w,{icon:v}),(0,u.__)("Copy","activitypub")))),(0,r.createElement)("div",{className:"activitypub-dialog__section"},(0,r.createElement)("h4",null,(0,u.__)("Your Profile","activitypub")),(0,r.createElement)("div",{className:"activitypub-dialog__description"},(0,r.createInterpolateElement)((0,u.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,r.createElement)("code",null)})),(0,r.createElement)("div",{className:"activitypub-dialog__button-group"},(0,r.createElement)("input",{type:"text",value:E,onKeyDown:e=>{"Enter"===e?.code&&x()},onChange:e=>k(e.target.value)}),(0,r.createElement)(l.Button,{onClick:x},m))))}const{namespace:E}=window._activityPubOptions,k={avatar:"",webfinger:"@well@hello.dolly",name:(0,u.__)("Hello Dolly Fan Account","activitypub"),url:"#"};function x(e){if(!e)return k;const t={...k,...e};return t.avatar=t?.icon?.url,t}function O({profile:e,popupStyles:t,userId:o}){const{avatar:n,name:a,webfinger:c}=e;return(0,r.createElement)("div",{className:"activitypub-profile"},(0,r.createElement)("img",{className:"activitypub-profile__avatar",src:n,alt:a}),(0,r.createElement)("div",{className:"activitypub-profile__content"},(0,r.createElement)("div",{className:"activitypub-profile__name"},a),(0,r.createElement)("div",{className:"activitypub-profile__handle",title:c},c)),(0,r.createElement)(C,{profile:e,popupStyles:t,userId:o}))}function C({profile:e,popupStyles:t,userId:o}){const[n,a]=(0,r.useState)(!1),c=(0,u.sprintf)((0,u.__)("Follow %s","activitypub"),e?.name);return(0,r.createElement)(r.Fragment,null,(0,r.createElement)(l.Button,{className:"activitypub-profile__follow",onClick:()=>a(!0)},(0,u.__)("Follow","activitypub")),n&&(0,r.createElement)(l.Modal,{className:"activitypub-profile__confirm activitypub__modal",onRequestClose:()=>a(!1),title:c},(0,r.createElement)(N,{profile:e,userId:o}),(0,r.createElement)("style",null,t)))}function N({profile:e,userId:t}){const{webfinger:o}=e,n=(0,u.__)("Follow","activitypub"),a=`/${E}/actors/${t}/remote-follow?resource=`,c=(0,u.__)("Copy and paste my profile into the search field of your favorite fediverse app or server.","activitypub");return(0,r.createElement)(g,{actionText:n,copyDescription:c,handle:o,resourceUrl:a})}function S({selectedUser:e,style:t,backgroundColor:o,id:n,useId:a=!1,profileData:c=!1}){const[l,u]=(0,r.useState)(x()),s="site"===e?0:e,m=function(e){return d(".apfmd__button-group .components-button",p(e?.elements?.link?.color?.text)||"#111","#fff",p(e?.elements?.link?.[":hover"]?.color?.text)||"#333")}(t),f=a?{id:n}:{};function y(e){u(x(e))}return(0,r.useEffect)((()=>{if(c)return y(c);(function(e){const t={headers:{Accept:"application/activity+json"},path:`/${E}/actors/${e}`};return i()(t)})(s).then(y)}),[s,c]),(0,r.createElement)("div",{...f},(0,r.createElement)(v,{selector:`#${n}`,style:t,backgroundColor:o}),(0,r.createElement)(O,{profile:l,userId:s,popupStyles:m}))}let $=1;a()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follow-me-block-wrapper"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,r.render)((0,r.createElement)(S,{...t,id:"activitypub-follow-me-block-"+$++,useId:!0}),e)}))}))}},o={};function r(e){var n=o[e];if(void 0!==n)return n.exports;var a=o[e]={exports:{}};return t[e](a,a.exports,r),a.exports}r.m=t,e=[],r.O=(t,o,n,a)=>{if(!o){var c=1/0;for(s=0;s=a)&&Object.keys(r.O).every((e=>r.O[e](o[l])))?o.splice(l--,1):(i=!1,a0&&e[s-1][2]>a;s--)e[s]=e[s-1];e[s]=[o,n,a]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var o in t)r.o(t,o)&&!r.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={529:0,740:0};r.O.j=t=>0===e[t];var t=(t,o)=>{var n,a,c=o[0],i=o[1],l=o[2],u=0;if(c.some((t=>0!==e[t]))){for(n in i)r.o(i,n)&&(r.m[n]=i[n]);if(l)var s=l(r)}for(t&&t(o);ur(792)));n=r.O(n)})(); \ No newline at end of file diff --git a/wp-content/plugins/activitypub/build/followers/index.asset.php b/wp-content/plugins/activitypub/build/followers/index.asset.php index b9383244..067872e2 100644 --- a/wp-content/plugins/activitypub/build/followers/index.asset.php +++ b/wp-content/plugins/activitypub/build/followers/index.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-url'), 'version' => '536d43b3eaab93a5c9ef'); + array('react', 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-url'), 'version' => 'a351235e5feab398a954'); diff --git a/wp-content/plugins/activitypub/build/followers/index.js b/wp-content/plugins/activitypub/build/followers/index.js index f10e58ff..4a56a22c 100644 --- a/wp-content/plugins/activitypub/build/followers/index.js +++ b/wp-content/plugins/activitypub/build/followers/index.js @@ -1,3 +1,3 @@ -(()=>{var e={942:(e,t)=>{var a;!function(){"use strict";var n={}.hasOwnProperty;function r(){for(var e="",t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";const e=window.wp.blocks,t=window.React,n=window.wp.primitives,r=(0,t.createElement)(n.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,t.createElement)(n.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),l=window.wp.components,o=window.wp.element,i=window.wp.blockEditor,c=window.wp.i18n,s=window.wp.apiFetch;var p=a.n(s);const u=window.wp.url;var v=a(942),m=a.n(v);function w({active:e,children:a,page:n,pageClick:r,className:l}){const o=m()("wp-block activitypub-pager",l,{current:e});return(0,t.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&r(n)}},a)}const b={outlined:"outlined",minimal:"minimal"};function d({compact:e,nextLabel:a,page:n,pageClick:r,perPage:l,prevLabel:o,total:i,variant:c=b.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,n)=>e>=1&&e<=t&&n.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(n,Math.ceil(i/l)),p=m()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,t.createElement)("nav",{className:p},o&&(0,t.createElement)(w,{key:"prev",page:n-1,pageClick:r,active:1===n,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,t.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,t.createElement)(w,{key:e,page:e,pageClick:r,active:e===n,className:"page-numbers"},e)))),a&&(0,t.createElement)(w,{key:"next",page:n+1,pageClick:r,active:n===Math.ceil(i/l),"aria-label":a,className:"wp-block-query-pagination-next block-editor-block-list__block"},a))}const{namespace:f}=window._activityPubOptions;function g({selectedUser:e,per_page:a,order:n,title:r,page:l,setPage:i,className:s="",followLinks:v=!0,followerData:m=!1}){const w="site"===e?0:e,[b,g]=(0,t.useState)([]),[k,h]=(0,t.useState)(0),[E,_]=(0,t.useState)(0),[x,C]=function(){const[e,a]=(0,t.useState)(1);return[e,a]}(),S=l||x,N=i||C,P=(0,o.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ -(0,c.__)(" Less","activitypub"),{span:(0,t.createElement)("span",{class:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,o.createInterpolateElement)(/* translators: arrow for next followers link */ /* translators: arrow for next followers link */ -(0,c.__)("More ","activitypub"),{span:(0,t.createElement)("span",{class:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),O=(e,t)=>{g(e),_(t),h(Math.ceil(t/a))};return(0,t.useEffect)((()=>{if(m&&1===S)return O(m.followers,m.total);const e=function(e,t,a,n){const r=`/${f}/users/${e}/followers`,l={per_page:t,order:a,page:n,context:"full"};return(0,u.addQueryArgs)(r,l)}(w,a,n,S);p()({path:e}).then((e=>O(e.orderedItems,e.totalItems))).catch((()=>{}))}),[w,a,n,S,m]),(0,t.createElement)("div",{className:"activitypub-follower-block "+s},(0,t.createElement)("h3",null,r),(0,t.createElement)("ul",null,b&&b.map((e=>(0,t.createElement)("li",{key:e.url},(0,t.createElement)(y,{...e,followLinks:v}))))),k>1&&(0,t.createElement)(d,{page:S,perPage:a,total:E,pageClick:N,nextLabel:L,prevLabel:P,compact:"is-style-compact"===s}))}function y({name:e,icon:a,url:n,preferredUsername:r,followLinks:o=!0}){const i=`@${r}`,c={};return o||(c.onClick=e=>e.preventDefault()),(0,t.createElement)(l.ExternalLink,{className:"activitypub-link",href:n,title:i,...c},(0,t.createElement)("img",{width:"40",height:"40",src:a.url,class:"avatar activitypub-avatar",alt:e}),(0,t.createElement)("span",{class:"activitypub-actor"},(0,t.createElement)("strong",{className:"activitypub-name"},e),(0,t.createElement)("span",{class:"sep"},"/"),(0,t.createElement)("span",{class:"activitypub-handle"},i)))}const k=window.wp.data,h=window._activityPubOptions?.enabled;(0,e.registerBlockType)("activitypub/followers",{edit:function({attributes:e,setAttributes:a}){const{order:n,per_page:r,selectedUser:s,title:p}=e,u=(0,i.useBlockProps)(),[v,m]=(0,o.useState)(1),w=[{label:(0,c.__)("New to old","activitypub"),value:"desc"},{label:(0,c.__)("Old to new","activitypub"),value:"asc"}],b=function(){const e=h?.users?(0,k.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,o.useMemo)((()=>{if(!e)return[];const t=h?.site?[{label:(0,c.__)("Whole Site","activitypub"),value:"site"}]:[];return e.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),t)}),[e])}(),d=e=>t=>{m(1),a({[e]:t})};return(0,o.useEffect)((()=>{b.length&&(b.find((({value:e})=>e===s))||a({selectedUser:b[0].value}))}),[s,b]),(0,t.createElement)("div",{...u},(0,t.createElement)(i.InspectorControls,{key:"setting"},(0,t.createElement)(l.PanelBody,{title:(0,c.__)("Followers Options","activitypub")},(0,t.createElement)(l.TextControl,{label:(0,c.__)("Title","activitypub"),help:(0,c.__)("Title to display above the list of followers. Blank for none.","activitypub"),value:p,onChange:e=>a({title:e})}),b.length>1&&(0,t.createElement)(l.SelectControl,{label:(0,c.__)("Select User","activitypub"),value:s,options:b,onChange:d("selectedUser")}),(0,t.createElement)(l.SelectControl,{label:(0,c.__)("Sort","activitypub"),value:n,options:w,onChange:d("order")}),(0,t.createElement)(l.RangeControl,{label:(0,c.__)("Number of Followers","activitypub"),value:r,onChange:d("per_page"),min:1,max:10}))),(0,t.createElement)(g,{...e,page:v,setPage:m,followLinks:!1}))},save:()=>null,icon:r})})()})(); \ No newline at end of file +(()=>{var e={184:(e,t)=>{var a;!function(){"use strict";var l={}.hasOwnProperty;function n(){for(var e=[],t=0;t{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var l in t)a.o(t,l)&&!a.o(e,l)&&Object.defineProperty(e,l,{enumerable:!0,get:t[l]})},a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";const e=window.wp.blocks,t=window.wp.element,l=window.wp.primitives,n=(0,t.createElement)(l.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,t.createElement)(l.Path,{d:"M15.5 9.5a1 1 0 100-2 1 1 0 000 2zm0 1.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5zm-2.25 6v-2a2.75 2.75 0 00-2.75-2.75h-4A2.75 2.75 0 003.75 15v2h1.5v-2c0-.69.56-1.25 1.25-1.25h4c.69 0 1.25.56 1.25 1.25v2h1.5zm7-2v2h-1.5v-2c0-.69-.56-1.25-1.25-1.25H15v-1.5h2.5A2.75 2.75 0 0120.25 15zM9.5 8.5a1 1 0 11-2 0 1 1 0 012 0zm1.5 0a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0z",fillRule:"evenodd"})),r=window.wp.components,o=window.wp.blockEditor,i=window.wp.i18n,c=window.React,s=window.wp.apiFetch;var p=a.n(s);const u=window.wp.url;var v=a(184),m=a.n(v);function w({active:e,children:a,page:l,pageClick:n,className:r}){const o=m()("wp-block activitypub-pager",r,{current:e});return(0,t.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&n(l)}},a)}const b={outlined:"outlined",minimal:"minimal"};function d({compact:e,nextLabel:a,page:l,pageClick:n,perPage:r,prevLabel:o,total:i,variant:c=b.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,l)=>e>=1&&e<=t&&l.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(l,Math.ceil(i/r)),p=m()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,t.createElement)("nav",{className:p},o&&(0,t.createElement)(w,{key:"prev",page:l-1,pageClick:n,active:1===l,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,t.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,t.createElement)(w,{key:e,page:e,pageClick:n,active:e===l,className:"page-numbers"},e)))),a&&(0,t.createElement)(w,{key:"next",page:l+1,pageClick:n,active:l===Math.ceil(i/r),"aria-label":a,className:"wp-block-query-pagination-next block-editor-block-list__block"},a))}const{namespace:g}=window._activityPubOptions;function f({selectedUser:e,per_page:a,order:l,title:n,page:r,setPage:o,className:s="",followLinks:v=!0,followerData:m=!1}){const w="site"===e?0:e,[b,f]=(0,c.useState)([]),[h,k]=(0,c.useState)(0),[E,_]=(0,c.useState)(0),[x,C]=function(){const[e,t]=(0,c.useState)(1);return[e,t]}(),S=r||x,N=o||C,P=(0,t.createInterpolateElement)(/* translators: arrow for previous followers link */ +(0,i.__)(" Less","activitypub"),{span:(0,t.createElement)("span",{class:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,t.createInterpolateElement)(/* translators: arrow for next followers link */ +(0,i.__)("More ","activitypub"),{span:(0,t.createElement)("span",{class:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),O=(e,t)=>{f(e),_(t),k(Math.ceil(t/a))};return(0,c.useEffect)((()=>{if(m&&1===S)return O(m.followers,m.total);const e=function(e,t,a,l){const n=`/${g}/actors/${e}/followers`,r={per_page:t,order:a,page:l,context:"full"};return(0,u.addQueryArgs)(n,r)}(w,a,l,S);p()({path:e}).then((e=>O(e.orderedItems,e.totalItems))).catch((()=>{}))}),[w,a,l,S,m]),(0,t.createElement)("div",{className:"activitypub-follower-block "+s},(0,t.createElement)("h3",null,n),(0,t.createElement)("ul",null,b&&b.map((e=>(0,t.createElement)("li",{key:e.url},(0,t.createElement)(y,{...e,followLinks:v}))))),h>1&&(0,t.createElement)(d,{page:S,perPage:a,total:E,pageClick:N,nextLabel:L,prevLabel:P,compact:"is-style-compact"===s}))}function y({name:e,icon:a,url:l,preferredUsername:n,followLinks:o=!0}){const i=`@${n}`,c={};return o||(c.onClick=e=>e.preventDefault()),(0,t.createElement)(r.ExternalLink,{className:"activitypub-link",href:l,title:i,...c},(0,t.createElement)("img",{width:"40",height:"40",src:a.url,class:"avatar activitypub-avatar",alt:e}),(0,t.createElement)("span",{class:"activitypub-actor"},(0,t.createElement)("strong",{className:"activitypub-name"},e),(0,t.createElement)("span",{class:"sep"},"/"),(0,t.createElement)("span",{class:"activitypub-handle"},i)))}const h=window.wp.data,k=window._activityPubOptions?.enabled;(0,e.registerBlockType)("activitypub/followers",{edit:function({attributes:e,setAttributes:a}){const{order:l,per_page:n,selectedUser:c,title:s}=e,p=(0,o.useBlockProps)(),[u,v]=(0,t.useState)(1),m=[{label:(0,i.__)("New to old","activitypub"),value:"desc"},{label:(0,i.__)("Old to new","activitypub"),value:"asc"}],w=function(){const e=k?.users?(0,h.useSelect)((e=>e("core").getUsers({who:"authors"}))):[];return(0,t.useMemo)((()=>{if(!e)return[];const t=k?.site?[{label:(0,i.__)("Whole Site","activitypub"),value:"site"}]:[];return e.reduce(((e,t)=>(e.push({label:t.name,value:`${t.id}`}),e)),t)}),[e])}(),b=e=>t=>{v(1),a({[e]:t})};return(0,t.useEffect)((()=>{w.length&&(w.find((({value:e})=>e===c))||a({selectedUser:w[0].value}))}),[c,w]),(0,t.createElement)("div",{...p},(0,t.createElement)(o.InspectorControls,{key:"setting"},(0,t.createElement)(r.PanelBody,{title:(0,i.__)("Followers Options","activitypub")},(0,t.createElement)(r.TextControl,{label:(0,i.__)("Title","activitypub"),help:(0,i.__)("Title to display above the list of followers. Blank for none.","activitypub"),value:s,onChange:e=>a({title:e})}),w.length>1&&(0,t.createElement)(r.SelectControl,{label:(0,i.__)("Select User","activitypub"),value:c,options:w,onChange:b("selectedUser")}),(0,t.createElement)(r.SelectControl,{label:(0,i.__)("Sort","activitypub"),value:l,options:m,onChange:b("order")}),(0,t.createElement)(r.RangeControl,{label:(0,i.__)("Number of Followers","activitypub"),value:n,onChange:b("per_page"),min:1,max:10}))),(0,t.createElement)(f,{...e,page:u,setPage:v,followLinks:!1}))},save:()=>null,icon:n})})()})(); \ No newline at end of file diff --git a/wp-content/plugins/activitypub/build/followers/view.asset.php b/wp-content/plugins/activitypub/build/followers/view.asset.php index c11c39ca..b85c9d71 100644 --- a/wp-content/plugins/activitypub/build/followers/view.asset.php +++ b/wp-content/plugins/activitypub/build/followers/view.asset.php @@ -1 +1 @@ - array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '23bc54443801976420cd'); + array('react', 'wp-api-fetch', 'wp-components', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '8c01e26171636c3b698f'); diff --git a/wp-content/plugins/activitypub/build/followers/view.js b/wp-content/plugins/activitypub/build/followers/view.js index 97227046..5b6083d4 100644 --- a/wp-content/plugins/activitypub/build/followers/view.js +++ b/wp-content/plugins/activitypub/build/followers/view.js @@ -1,3 +1,3 @@ -(()=>{var e,t={250:(e,t,a)=>{"use strict";const r=window.React,n=window.wp.apiFetch;var l=a.n(n);const o=window.wp.url,i=window.wp.element,c=window.wp.i18n;var s=a(942),p=a.n(s);function u({active:e,children:t,page:a,pageClick:n,className:l}){const o=p()("wp-block activitypub-pager",l,{current:e});return(0,r.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&n(a)}},t)}const m={outlined:"outlined",minimal:"minimal"};function f({compact:e,nextLabel:t,page:a,pageClick:n,perPage:l,prevLabel:o,total:i,variant:c=m.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(i/l)),f=p()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,r.createElement)("nav",{className:f},o&&(0,r.createElement)(u,{key:"prev",page:a-1,pageClick:n,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,r.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,r.createElement)(u,{key:e,page:e,pageClick:n,active:e===a,className:"page-numbers"},e)))),t&&(0,r.createElement)(u,{key:"next",page:a+1,pageClick:n,active:a===Math.ceil(i/l),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const v=window.wp.components,{namespace:b}=window._activityPubOptions;function d({selectedUser:e,per_page:t,order:a,title:n,page:s,setPage:p,className:u="",followLinks:m=!0,followerData:v=!1}){const d="site"===e?0:e,[g,y]=(0,r.useState)([]),[k,h]=(0,r.useState)(0),[E,x]=(0,r.useState)(0),[_,O]=function(){const[e,t]=(0,r.useState)(1);return[e,t]}(),N=s||_,S=p||O,C=(0,i.createInterpolateElement)(/* translators: arrow for previous followers link */ /* translators: arrow for previous followers link */ -(0,c.__)(" Less","activitypub"),{span:(0,r.createElement)("span",{class:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,i.createInterpolateElement)(/* translators: arrow for next followers link */ /* translators: arrow for next followers link */ -(0,c.__)("More ","activitypub"),{span:(0,r.createElement)("span",{class:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),q=(e,a)=>{y(e),x(a),h(Math.ceil(a/t))};return(0,r.useEffect)((()=>{if(v&&1===N)return q(v.followers,v.total);const e=function(e,t,a,r){const n=`/${b}/users/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,o.addQueryArgs)(n,l)}(d,t,a,N);l()({path:e}).then((e=>q(e.orderedItems,e.totalItems))).catch((()=>{}))}),[d,t,a,N,v]),(0,r.createElement)("div",{className:"activitypub-follower-block "+u},(0,r.createElement)("h3",null,n),(0,r.createElement)("ul",null,g&&g.map((e=>(0,r.createElement)("li",{key:e.url},(0,r.createElement)(w,{...e,followLinks:m}))))),k>1&&(0,r.createElement)(f,{page:N,perPage:t,total:E,pageClick:S,nextLabel:L,prevLabel:C,compact:"is-style-compact"===u}))}function w({name:e,icon:t,url:a,preferredUsername:n,followLinks:l=!0}){const o=`@${n}`,i={};return l||(i.onClick=e=>e.preventDefault()),(0,r.createElement)(v.ExternalLink,{className:"activitypub-link",href:a,title:o,...i},(0,r.createElement)("img",{width:"40",height:"40",src:t.url,class:"avatar activitypub-avatar",alt:e}),(0,r.createElement)("span",{class:"activitypub-actor"},(0,r.createElement)("strong",{className:"activitypub-name"},e),(0,r.createElement)("span",{class:"sep"},"/"),(0,r.createElement)("span",{class:"activitypub-handle"},o)))}const g=window.wp.domReady;a.n(g)()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follower-block"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,i.render)((0,r.createElement)(d,{...t}),e)}))}))},942:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e="",t=0;t{if(!a){var o=1/0;for(p=0;p=l)&&Object.keys(r.O).every((e=>r.O[e](a[c])))?a.splice(c--,1):(i=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={996:0,528:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,[o,i,c]=a,s=0;if(o.some((t=>0!==e[t]))){for(n in i)r.o(i,n)&&(r.m[n]=i[n]);if(c)var p=c(r)}for(t&&t(a);sr(250)));n=r.O(n)})(); \ No newline at end of file +(()=>{var e,t={142:(e,t,a)=>{"use strict";const r=window.wp.element,n=window.React,l=window.wp.apiFetch;var o=a.n(l);const i=window.wp.url,c=window.wp.i18n;var s=a(184),p=a.n(s);function u({active:e,children:t,page:a,pageClick:n,className:l}){const o=p()("wp-block activitypub-pager",l,{current:e});return(0,r.createElement)("a",{className:o,onClick:t=>{t.preventDefault(),!e&&n(a)}},t)}const m={outlined:"outlined",minimal:"minimal"};function f({compact:e,nextLabel:t,page:a,pageClick:n,perPage:l,prevLabel:o,total:i,variant:c=m.outlined}){const s=((e,t)=>{let a=[1,e-2,e-1,e,e+1,e+2,t];a.sort(((e,t)=>e-t)),a=a.filter(((e,a,r)=>e>=1&&e<=t&&r.lastIndexOf(e)===a));for(let e=a.length-2;e>=0;e--)a[e]===a[e+1]&&a.splice(e+1,1);return a})(a,Math.ceil(i/l)),f=p()("alignwide wp-block-query-pagination is-content-justification-space-between is-layout-flex wp-block-query-pagination-is-layout-flex",`is-${c}`,{"is-compact":e});return(0,r.createElement)("nav",{className:f},o&&(0,r.createElement)(u,{key:"prev",page:a-1,pageClick:n,active:1===a,"aria-label":o,className:"wp-block-query-pagination-previous block-editor-block-list__block"},o),!e&&(0,r.createElement)("div",{className:"block-editor-block-list__block wp-block wp-block-query-pagination-numbers"},s.map((e=>(0,r.createElement)(u,{key:e,page:e,pageClick:n,active:e===a,className:"page-numbers"},e)))),t&&(0,r.createElement)(u,{key:"next",page:a+1,pageClick:n,active:a===Math.ceil(i/l),"aria-label":t,className:"wp-block-query-pagination-next block-editor-block-list__block"},t))}const v=window.wp.components,{namespace:d}=window._activityPubOptions;function b({selectedUser:e,per_page:t,order:a,title:l,page:s,setPage:p,className:u="",followLinks:m=!0,followerData:v=!1}){const b="site"===e?0:e,[g,k]=(0,n.useState)([]),[y,h]=(0,n.useState)(0),[E,x]=(0,n.useState)(0),[_,O]=function(){const[e,t]=(0,n.useState)(1);return[e,t]}(),N=s||_,S=p||O,C=(0,r.createInterpolateElement)(/* translators: arrow for previous followers link */ +(0,c.__)(" Less","activitypub"),{span:(0,r.createElement)("span",{class:"wp-block-query-pagination-previous-arrow is-arrow-arrow","aria-hidden":"true"})}),L=(0,r.createInterpolateElement)(/* translators: arrow for next followers link */ +(0,c.__)("More ","activitypub"),{span:(0,r.createElement)("span",{class:"wp-block-query-pagination-next-arrow is-arrow-arrow","aria-hidden":"true"})}),j=(e,a)=>{k(e),x(a),h(Math.ceil(a/t))};return(0,n.useEffect)((()=>{if(v&&1===N)return j(v.followers,v.total);const e=function(e,t,a,r){const n=`/${d}/actors/${e}/followers`,l={per_page:t,order:a,page:r,context:"full"};return(0,i.addQueryArgs)(n,l)}(b,t,a,N);o()({path:e}).then((e=>j(e.orderedItems,e.totalItems))).catch((()=>{}))}),[b,t,a,N,v]),(0,r.createElement)("div",{className:"activitypub-follower-block "+u},(0,r.createElement)("h3",null,l),(0,r.createElement)("ul",null,g&&g.map((e=>(0,r.createElement)("li",{key:e.url},(0,r.createElement)(w,{...e,followLinks:m}))))),y>1&&(0,r.createElement)(f,{page:N,perPage:t,total:E,pageClick:S,nextLabel:L,prevLabel:C,compact:"is-style-compact"===u}))}function w({name:e,icon:t,url:a,preferredUsername:n,followLinks:l=!0}){const o=`@${n}`,i={};return l||(i.onClick=e=>e.preventDefault()),(0,r.createElement)(v.ExternalLink,{className:"activitypub-link",href:a,title:o,...i},(0,r.createElement)("img",{width:"40",height:"40",src:t.url,class:"avatar activitypub-avatar",alt:e}),(0,r.createElement)("span",{class:"activitypub-actor"},(0,r.createElement)("strong",{className:"activitypub-name"},e),(0,r.createElement)("span",{class:"sep"},"/"),(0,r.createElement)("span",{class:"activitypub-handle"},o)))}const g=window.wp.domReady;a.n(g)()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-follower-block"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,r.render)((0,r.createElement)(b,{...t}),e)}))}))},184:(e,t)=>{var a;!function(){"use strict";var r={}.hasOwnProperty;function n(){for(var e=[],t=0;t{if(!a){var o=1/0;for(p=0;p=l)&&Object.keys(r.O).every((e=>r.O[e](a[c])))?a.splice(c--,1):(i=!1,l0&&e[p-1][2]>l;p--)e[p]=e[p-1];e[p]=[a,n,l]},r.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return r.d(t,{a:t}),t},r.d=(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={638:0,962:0};r.O.j=t=>0===e[t];var t=(t,a)=>{var n,l,o=a[0],i=a[1],c=a[2],s=0;if(o.some((t=>0!==e[t]))){for(n in i)r.o(i,n)&&(r.m[n]=i[n]);if(c)var p=c(r)}for(t&&t(a);sr(142)));n=r.O(n)})(); \ No newline at end of file diff --git a/wp-content/plugins/activitypub/build/remote-reply/index.js b/wp-content/plugins/activitypub/build/remote-reply/index.js index 5373b0fa..384fa0fa 100644 --- a/wp-content/plugins/activitypub/build/remote-reply/index.js +++ b/wp-content/plugins/activitypub/build/remote-reply/index.js @@ -1 +1 @@ -(()=>{"use strict";var e,t={202:(e,t,a)=>{const n=window.React,o=window.wp.element,r=window.wp.domReady;var i=a.n(r);const c=window.wp.components,l=window.wp.i18n,u=window.wp.apiFetch;var s=a.n(u);const p=window.wp.primitives,m=(0,n.createElement)(p.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(p.Path,{fillRule:"evenodd",clipRule:"evenodd",d:"M5 4.5h11a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V5a.5.5 0 0 1 .5-.5ZM3 5a2 2 0 0 1 2-2h11a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5Zm17 3v10.75c0 .69-.56 1.25-1.25 1.25H6v1.5h12.75a2.75 2.75 0 0 0 2.75-2.75V8H20Z"})),d=(0,n.createElement)(p.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,n.createElement)(p.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),v=(0,o.forwardRef)((function({icon:e,size:t=24,...a},n){return(0,o.cloneElement)(e,{width:t,height:t,...a,ref:n})})),y=window.wp.compose;function w(e){try{return new URL(e),!0}catch(e){return!1}}function _({actionText:e,copyDescription:t,handle:a,resourceUrl:r}){const i=(0,l.__)("Loading...","activitypub"),u=(0,l.__)("Opening...","activitypub"),p=(0,l.__)("Error","activitypub"),_=(0,l.__)("Invalid","activitypub"),[b,h]=(0,o.useState)(e),[f,E]=(0,o.useState)(m),g=(0,y.useCopyToClipboard)(a,(()=>{E(d),setTimeout((()=>E(m)),1e3)})),[O,C]=(0,o.useState)(""),x=(0,o.useCallback)((()=>{let t;if(!w(O)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&w(`https://${t[1]}`)}(O))return h(_),t=setTimeout((()=>h(e)),2e3),()=>clearTimeout(t);const a=r+O;h(i),s()({path:a}).then((({url:t})=>{h(u),setTimeout((()=>{window.open(t,"_blank"),h(e)}),200)})).catch((()=>{h(p),setTimeout((()=>h(e)),2e3)}))}),[O]);return(0,n.createElement)("div",{className:"activitypub__dialog"},(0,n.createElement)("div",{className:"activitypub-dialog__section"},(0,n.createElement)("h4",null,(0,l.__)("My Profile","activitypub")),(0,n.createElement)("div",{className:"activitypub-dialog-description"},t),(0,n.createElement)("div",{className:"activitypub-dialog__button-group"},(0,n.createElement)("input",{type:"text",value:a,readOnly:!0}),(0,n.createElement)(c.Button,{ref:g},(0,n.createElement)(v,{icon:f}),(0,l.__)("Copy","activitypub")))),(0,n.createElement)("div",{className:"activitypub-dialog__section"},(0,n.createElement)("h4",null,(0,l.__)("Your Profile","activitypub")),(0,n.createElement)("div",{className:"activitypub-dialog__description"},(0,o.createInterpolateElement)((0,l.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,n.createElement)("code",null)})),(0,n.createElement)("div",{className:"activitypub-dialog__button-group"},(0,n.createElement)("input",{type:"text",value:O,onKeyDown:e=>{"Enter"===e?.code&&x()},onChange:e=>C(e.target.value)}),(0,n.createElement)(c.Button,{onClick:x},b))))}const{namespace:b}=window._activityPubOptions;function h({selectedComment:e,commentId:t}){const a=(0,l.__)("Reply","activitypub"),o=`/${b}/comments/${t}/remote-reply?resource=`,r=(0,l.__)("Copy and paste the Comment URL into the search field of your favorite fediverse app or server.","activitypub");return(0,n.createElement)(_,{actionText:a,copyDescription:r,handle:e,resourceUrl:o})}function f({selectedComment:e,commentId:t}){const[a,r]=(0,o.useState)(!1),i=(0,l.__)("Remote Reply","activitypub");return(0,n.createElement)(n.Fragment,null,(0,n.createElement)(c.Button,{isLink:!0,className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>r(!0)},(0,l.__)("Reply on the Fediverse","activitypub")),a&&(0,n.createElement)(c.Modal,{className:"activitypub-remote-reply__modal activitypub__modal",onRequestClose:()=>r(!1),title:i},(0,n.createElement)(h,{selectedComment:e,commentId:t})))}let E=1;i()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-remote-reply"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,o.createRoot)(e).render((0,n.createElement)(f,{...t,id:"activitypub-remote-reply-link-"+E++,useId:!0}))}))}))}},a={};function n(e){var o=a[e];if(void 0!==o)return o.exports;var r=a[e]={exports:{}};return t[e](r,r.exports,n),r.exports}n.m=t,e=[],n.O=(t,a,o,r)=>{if(!a){var i=1/0;for(s=0;s=r)&&Object.keys(n.O).every((e=>n.O[e](a[l])))?a.splice(l--,1):(c=!1,r0&&e[s-1][2]>r;s--)e[s]=e[s-1];e[s]=[a,o,r]},n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={227:0,739:0};n.O.j=t=>0===e[t];var t=(t,a)=>{var o,r,[i,c,l]=a,u=0;if(i.some((t=>0!==e[t]))){for(o in c)n.o(c,o)&&(n.m[o]=c[o]);if(l)var s=l(n)}for(t&&t(a);un(202)));o=n.O(o)})(); \ No newline at end of file +(()=>{"use strict";var e,t={667:(e,t,n)=>{const o=window.wp.element,r=window.wp.domReady;var a=n.n(r);const i=window.wp.components,c=window.wp.i18n,l=window.wp.apiFetch;var u=n.n(l);const s=window.wp.primitives,p=(0,o.createElement)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,o.createElement)(s.Path,{d:"M20.2 8v11c0 .7-.6 1.2-1.2 1.2H6v1.5h13c1.5 0 2.7-1.2 2.7-2.8V8zM18 16.4V4.6c0-.9-.7-1.6-1.6-1.6H4.6C3.7 3 3 3.7 3 4.6v11.8c0 .9.7 1.6 1.6 1.6h11.8c.9 0 1.6-.7 1.6-1.6zm-13.5 0V4.6c0-.1.1-.1.1-.1h11.8c.1 0 .1.1.1.1v11.8c0 .1-.1.1-.1.1H4.6l-.1-.1z"})),m=(0,o.createElement)(s.SVG,{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},(0,o.createElement)(s.Path,{d:"M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"})),d=function({icon:e,size:t=24,...n}){return(0,o.cloneElement)(e,{width:t,height:t,...n})},v=window.wp.compose;function y(e){try{return new URL(e),!0}catch(e){return!1}}function _({actionText:e,copyDescription:t,handle:n,resourceUrl:r}){const a=(0,c.__)("Loading...","activitypub"),l=(0,c.__)("Opening...","activitypub"),s=(0,c.__)("Error","activitypub"),_=(0,c.__)("Invalid","activitypub"),[w,b]=(0,o.useState)(e),[h,f]=(0,o.useState)(p),E=(0,v.useCopyToClipboard)(n,(()=>{f(m),setTimeout((()=>f(p)),1e3)})),[g,C]=(0,o.useState)(""),O=(0,o.useCallback)((()=>{let t;if(!y(g)&&!function(e){const t=e.replace(/^@/,"").split("@");return 2===t.length&&y(`https://${t[1]}`)}(g))return b(_),t=setTimeout((()=>b(e)),2e3),()=>clearTimeout(t);const n=r+g;b(a),u()({path:n}).then((({url:t})=>{b(l),setTimeout((()=>{window.open(t,"_blank"),b(e)}),200)})).catch((()=>{b(s),setTimeout((()=>b(e)),2e3)}))}),[g]);return(0,o.createElement)("div",{className:"activitypub__dialog"},(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",null,(0,c.__)("My Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog-description"},t),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("input",{type:"text",value:n,readOnly:!0}),(0,o.createElement)(i.Button,{ref:E},(0,o.createElement)(d,{icon:h}),(0,c.__)("Copy","activitypub")))),(0,o.createElement)("div",{className:"activitypub-dialog__section"},(0,o.createElement)("h4",null,(0,c.__)("Your Profile","activitypub")),(0,o.createElement)("div",{className:"activitypub-dialog__description"},(0,o.createInterpolateElement)((0,c.__)("Or, if you know your own profile, we can start things that way! (eg https://example.com/yourusername or yourusername@example.com)","activitypub"),{code:(0,o.createElement)("code",null)})),(0,o.createElement)("div",{className:"activitypub-dialog__button-group"},(0,o.createElement)("input",{type:"text",value:g,onKeyDown:e=>{"Enter"===e?.code&&O()},onChange:e=>C(e.target.value)}),(0,o.createElement)(i.Button,{onClick:O},w))))}const{namespace:w}=window._activityPubOptions;function b({selectedComment:e,commentId:t}){const n=(0,c.__)("Reply","activitypub"),r=`/${w}/comments/${t}/remote-reply?resource=`,a=(0,c.__)("Copy and paste the Comment URL into the search field of your favorite fediverse app or server.","activitypub");return(0,o.createElement)(_,{actionText:n,copyDescription:a,handle:e,resourceUrl:r})}function h({selectedComment:e,commentId:t}){const[n,r]=(0,o.useState)(!1),a=(0,c.__)("Remote Reply","activitypub");return(0,o.createElement)(o.Fragment,null,(0,o.createElement)(i.Button,{isLink:!0,className:"comment-reply-link activitypub-remote-reply__button",onClick:()=>r(!0)},(0,c.__)("Reply on the Fediverse","activitypub")),n&&(0,o.createElement)(i.Modal,{className:"activitypub-remote-reply__modal activitypub__modal",onRequestClose:()=>r(!1),title:a},(0,o.createElement)(b,{selectedComment:e,commentId:t})))}let f=1;a()((()=>{[].forEach.call(document.querySelectorAll(".activitypub-remote-reply"),(e=>{const t=JSON.parse(e.dataset.attrs);(0,o.createRoot)(e).render((0,o.createElement)(h,{...t,id:"activitypub-remote-reply-link-"+f++,useId:!0}))}))}))}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={exports:{}};return t[e](a,a.exports,o),a.exports}o.m=t,e=[],o.O=(t,n,r,a)=>{if(!n){var i=1/0;for(s=0;s=a)&&Object.keys(o.O).every((e=>o.O[e](n[l])))?n.splice(l--,1):(c=!1,a0&&e[s-1][2]>a;s--)e[s]=e[s-1];e[s]=[n,r,a]},o.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return o.d(t,{a:t}),t},o.d=(e,t)=>{for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={805:0,881:0};o.O.j=t=>0===e[t];var t=(t,n)=>{var r,a,i=n[0],c=n[1],l=n[2],u=0;if(i.some((t=>0!==e[t]))){for(r in c)o.o(c,r)&&(o.m[r]=c[r]);if(l)var s=l(o)}for(t&&t(n);uo(667)));r=o.O(r)})(); \ No newline at end of file diff --git a/wp-content/plugins/activitypub/includes/activity/class-activity.php b/wp-content/plugins/activitypub/includes/activity/class-activity.php index 32aa3988..fcc35e46 100644 --- a/wp-content/plugins/activitypub/includes/activity/class-activity.php +++ b/wp-content/plugins/activitypub/includes/activity/class-activity.php @@ -162,7 +162,13 @@ class Activity extends Base_Object { } if ( $object->get_id() && ! $this->get_id() ) { - $this->set( 'id', $object->get_id() . '#activity' ); + $id = strtok( $object->get_id(), '#' ); + if ( $object->get_updated() ) { + $updated = $object->get_updated(); + } else { + $updated = $object->get_published(); + } + $this->set( 'id', $id . '#activity-' . strtolower( $this->get_type() ) . '-' . $updated ); } } diff --git a/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php b/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php index edc41f37..38ba1858 100644 --- a/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php +++ b/wp-content/plugins/activitypub/includes/class-activity-dispatcher.php @@ -64,7 +64,11 @@ class Activity_Dispatcher { * @return void */ public static function send_activity( $wp_object, $type, $user_id = null ) { - $transformer = Factory::get_transformer( $wp_object ); + $transformer = Factory::get_transformer( $wp_object ); // Could potentially return a `\WP_Error` instance. + + if ( \is_wp_error( $transformer ) ) { + return; + } if ( null !== $user_id ) { $transformer->change_wp_user_id( $user_id ); @@ -98,18 +102,22 @@ class Activity_Dispatcher { return; } - // do not announce replies - if ( $wp_object instanceof WP_Comment ) { + $transformer = Factory::get_transformer( $wp_object ); + + if ( \is_wp_error( $transformer ) ) { return; } - $transformer = Factory::get_transformer( $wp_object ); - $transformer->change_wp_user_id( Users::BLOG_USER_ID ); + $user_id = Users::BLOG_USER_ID; + $activity = $transformer->to_activity( $type ); + $user = Users::get_by_id( Users::BLOG_USER_ID ); - $user_id = $transformer->get_wp_user_id(); - $activity = $transformer->to_activity( 'Announce' ); + $announce = new Activity(); + $announce->set_type( 'Announce' ); + $announce->set_object( $activity ); + $announce->set_actor( $user->get_id() ); - self::send_activity_to_followers( $activity, $user_id, $wp_object ); + self::send_activity_to_followers( $announce, $user_id, $wp_object ); } /** diff --git a/wp-content/plugins/activitypub/includes/class-activitypub.php b/wp-content/plugins/activitypub/includes/class-activitypub.php index 442cdfa5..afef5b71 100644 --- a/wp-content/plugins/activitypub/includes/class-activitypub.php +++ b/wp-content/plugins/activitypub/includes/class-activitypub.php @@ -9,6 +9,7 @@ use Activitypub\Collection\Followers; use function Activitypub\is_comment; use function Activitypub\sanitize_url; use function Activitypub\is_local_comment; +use function Activitypub\is_user_type_disabled; use function Activitypub\is_activitypub_request; use function Activitypub\should_comment_be_federated; @@ -95,35 +96,37 @@ class Activitypub { $json_template = false; - // check if user can publish posts - if ( \is_author() && is_wp_error( Users::get_by_id( \get_the_author_meta( 'ID' ) ) ) ) { - return $template; - } - - // check if blog-user is enabled - if ( \is_home() && is_wp_error( Users::get_by_id( Users::BLOG_USER_ID ) ) ) { - return $template; - } - - if ( \is_author() ) { + if ( \is_author() && ! is_user_disabled( \get_the_author_meta( 'ID' ) ) ) { $json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/author-json.php'; } elseif ( is_comment() ) { $json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/comment-json.php'; } elseif ( \is_singular() ) { $json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/post-json.php'; - } elseif ( \is_home() ) { + } elseif ( \is_home() && ! is_user_type_disabled( 'blog' ) ) { $json_template = ACTIVITYPUB_PLUGIN_DIR . '/templates/blog-json.php'; } - if ( ACTIVITYPUB_AUTHORIZED_FETCH ) { + /* + * Check if the request is authorized. + * + * @see https://www.w3.org/wiki/SocialCG/ActivityPub/Primer/Authentication_Authorization#Authorized_fetch + * @see https://swicg.github.io/activitypub-http-signature/#authorized-fetch + */ + if ( $json_template && ACTIVITYPUB_AUTHORIZED_FETCH ) { $verification = Signature::verify_http_signature( $_SERVER ); if ( \is_wp_error( $verification ) ) { + header( 'HTTP/1.1 401 Unauthorized' ); + // fallback as template_loader can't return http headers return $template; } } - return $json_template; + if ( $json_template ) { + return $json_template; + } + + return $template; } /** @@ -292,7 +295,7 @@ class Activitypub { \add_rewrite_rule( '^@([\w\-\.]+)', - 'index.php?rest_route=/' . ACTIVITYPUB_REST_NAMESPACE . '/users/$matches[1]', + 'index.php?rest_route=/' . ACTIVITYPUB_REST_NAMESPACE . '/actors/$matches[1]', 'top' ); diff --git a/wp-content/plugins/activitypub/includes/class-admin.php b/wp-content/plugins/activitypub/includes/class-admin.php index 5df037d4..e9613415 100644 --- a/wp-content/plugins/activitypub/includes/class-admin.php +++ b/wp-content/plugins/activitypub/includes/class-admin.php @@ -2,8 +2,10 @@ namespace Activitypub; use WP_User_Query; -use Activitypub\Model\Blog_User; +use Activitypub\Model\Blog; +use Activitypub\Collection\Users; +use function Activitypub\count_followers; use function Activitypub\is_user_disabled; use function Activitypub\was_comment_received; use function Activitypub\is_comment_federatable; @@ -37,6 +39,8 @@ class Admin { if ( ! is_user_disabled( get_current_user_id() ) ) { \add_action( 'show_user_profile', array( self::class, 'add_profile' ) ); } + + \add_filter( 'dashboard_glance_items', array( self::class, 'dashboard_glance_items' ) ); } /** @@ -216,7 +220,7 @@ class Admin { 'type' => 'string', 'description' => \esc_html__( 'The Identifier of the Blog-User', 'activitypub' ), 'show_in_rest' => true, - 'default' => Blog_User::get_default_username(), + 'default' => Blog::get_default_username(), 'sanitize_callback' => function ( $value ) { // hack to allow dots in the username $parts = explode( '.', $value ); @@ -247,7 +251,7 @@ class Admin { 'error' ); - return Blog_User::get_default_username(); + return Blog::get_default_username(); } return $sanitized; @@ -313,8 +317,12 @@ class Admin { public static function enqueue_scripts( $hook_suffix ) { if ( false !== strpos( $hook_suffix, 'activitypub' ) ) { - wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), '1.0.0' ); - wp_enqueue_script( 'activitypub-admin-styles', plugins_url( 'assets/js/activitypub-admin.js', ACTIVITYPUB_PLUGIN_FILE ), array( 'jquery' ), '1.0.0', false ); + wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), get_plugin_version() ); + wp_enqueue_script( 'activitypub-admin-script', plugins_url( 'assets/js/activitypub-admin.js', ACTIVITYPUB_PLUGIN_FILE ), array( 'jquery' ), get_plugin_version(), false ); + } + + if ( 'index.php' === $hook_suffix ) { + wp_enqueue_style( 'activitypub-admin-styles', plugins_url( 'assets/css/activitypub-admin.css', ACTIVITYPUB_PLUGIN_FILE ), array(), get_plugin_version() ); } } @@ -469,4 +477,57 @@ class Admin { return $sendback; } + + /** + * Add ActivityPub infos to the dashboard glance items + * + * @param array $items The existing glance items. + * + * @return array The extended glance items. + */ + public static function dashboard_glance_items( $items ) { + \add_filter( 'number_format_i18n', '\Activitypub\custom_large_numbers', 10, 3 ); + + if ( ! is_user_disabled( get_current_user_id() ) ) { + $follower_count = sprintf( + // translators: %s: number of followers + _n( + '%s Follower', + '%s Followers', + count_followers( \get_current_user_id() ), + 'activitypub' + ), + \number_format_i18n( count_followers( \get_current_user_id() ) ) + ); + $items['activitypub-followers-user'] = sprintf( + '%3$s', + \esc_url( \admin_url( 'users.php?page=activitypub-followers-list' ) ), + \esc_attr__( 'Your followers', 'activitypub' ), + \esc_html( $follower_count ) + ); + } + + if ( ! is_user_type_disabled( 'blog' ) && current_user_can( 'manage_options' ) ) { + $follower_count = sprintf( + // translators: %s: number of followers + _n( + '%s Follower (Blog)', + '%s Followers (Blog)', + count_followers( Users::BLOG_USER_ID ), + 'activitypub' + ), + \number_format_i18n( count_followers( Users::BLOG_USER_ID ) ) + ); + $items['activitypub-followers-blog'] = sprintf( + '%3$s', + \esc_url( \admin_url( 'options-general.php?page=activitypub&tab=followers' ) ), + \esc_attr__( 'The Blog\'s followers', 'activitypub' ), + \esc_html( $follower_count ) + ); + } + + \remove_filter( 'number_format_i18n', '\Activitypub\custom_large_numbers', 10, 3 ); + + return $items; + } } diff --git a/wp-content/plugins/activitypub/includes/class-comment.php b/wp-content/plugins/activitypub/includes/class-comment.php index 1d52a9bd..7fa4ebc6 100644 --- a/wp-content/plugins/activitypub/includes/class-comment.php +++ b/wp-content/plugins/activitypub/includes/class-comment.php @@ -379,7 +379,7 @@ class Comment { } // generate URI based on comment ID - return \add_query_arg( 'c', $comment->comment_ID, \home_url() ); + return \add_query_arg( 'c', $comment->comment_ID, \trailingslashit( \home_url() ) ); } /** diff --git a/wp-content/plugins/activitypub/includes/class-handler.php b/wp-content/plugins/activitypub/includes/class-handler.php index fcabd63c..05c65805 100644 --- a/wp-content/plugins/activitypub/includes/class-handler.php +++ b/wp-content/plugins/activitypub/includes/class-handler.php @@ -1,6 +1,7 @@ 404, + 'object' => $url_or_object, + ) + ); + } + } else { + $url = $url_or_object; + } + + if ( preg_match( '/^@?' . ACTIVITYPUB_USERNAME_REGEXP . '$/i', $url ) ) { + $url = Webfinger::resolve( $url ); + } + + if ( ! $url ) { + return new WP_Error( + 'activitypub_no_valid_actor_identifier', + \__( 'The "actor" identifier is not valid', 'activitypub' ), + array( + 'status' => 404, + 'object' => $url, + ) + ); + } + + if ( is_wp_error( $url ) ) { + return $url; + } + + $transient_key = self::generate_cache_key( $url ); + + // only check the cache if needed. + if ( $cached ) { + $data = \get_transient( $transient_key ); + + if ( $data ) { + return $data; + } + } + + if ( ! \wp_http_validate_url( $url ) ) { + return new WP_Error( + 'activitypub_no_valid_object_url', + \__( 'The "object" is/has no valid URL', 'activitypub' ), + array( + 'status' => 400, + 'object' => $url, + ) + ); + } + + $response = self::get( $url ); + + if ( \is_wp_error( $response ) ) { + return $response; + } + + $data = \wp_remote_retrieve_body( $response ); + $data = \json_decode( $data, true ); + + if ( ! $data ) { + return new WP_Error( + 'activitypub_invalid_json', + \__( 'No valid JSON data', 'activitypub' ), + array( + 'status' => 400, + 'object' => $url, + ) + ); + } + + \set_transient( $transient_key, $data, WEEK_IN_SECONDS ); + + return $data; + } } diff --git a/wp-content/plugins/activitypub/includes/class-mention.php b/wp-content/plugins/activitypub/includes/class-mention.php index fee01b20..c2e8792d 100644 --- a/wp-content/plugins/activitypub/includes/class-mention.php +++ b/wp-content/plugins/activitypub/includes/class-mention.php @@ -4,6 +4,8 @@ namespace Activitypub; use WP_Error; use Activitypub\Webfinger; +use function Activitypub\object_to_uri; + /** * ActivityPub Mention Class * @@ -93,7 +95,11 @@ class Mention { public static function replace_with_links( $result ) { $metadata = get_remote_metadata_by_actor( $result[0] ); - if ( ! empty( $metadata ) && ! is_wp_error( $metadata ) && ! empty( $metadata['url'] ) ) { + if ( + ! empty( $metadata ) && + ! is_wp_error( $metadata ) && + ( ! empty( $metadata['id'] ) || ! empty( $metadata['url'] ) ) + ) { $username = ltrim( $result[0], '@' ); if ( ! empty( $metadata['name'] ) ) { $username = $metadata['name']; @@ -102,11 +108,7 @@ class Mention { $username = $metadata['preferredUsername']; } - $url = isset( $metadata['url'] ) ? $metadata['url'] : $metadata['id']; - - if ( \is_array( $url ) ) { - $url = $url[0]; - } + $url = isset( $metadata['url'] ) ? object_to_uri( $metadata['url'] ) : object_to_uri( $metadata['id'] ); return \sprintf( '@%s', esc_url( $url ), esc_html( $username ) ); } diff --git a/wp-content/plugins/activitypub/includes/class-migration.php b/wp-content/plugins/activitypub/includes/class-migration.php index 88737a3c..acfe88a5 100644 --- a/wp-content/plugins/activitypub/includes/class-migration.php +++ b/wp-content/plugins/activitypub/includes/class-migration.php @@ -2,7 +2,7 @@ namespace Activitypub; use Activitypub\Activitypub; -use Activitypub\Model\Blog_User; +use Activitypub\Model\Blog; use Activitypub\Collection\Followers; /** diff --git a/wp-content/plugins/activitypub/includes/class-notification.php b/wp-content/plugins/activitypub/includes/class-notification.php new file mode 100644 index 00000000..72747021 --- /dev/null +++ b/wp-content/plugins/activitypub/includes/class-notification.php @@ -0,0 +1,58 @@ +type = $type; + $this->actor = $actor; + $this->object = $object; + $this->target = $target; + } + + /** + * Send the notification. + */ + public function send() { + do_action( 'activitypub_notification', $this ); + } +} diff --git a/wp-content/plugins/activitypub/includes/collection/class-users.php b/wp-content/plugins/activitypub/includes/collection/class-users.php index 6a9a5dc7..9462a9a1 100644 --- a/wp-content/plugins/activitypub/includes/collection/class-users.php +++ b/wp-content/plugins/activitypub/includes/collection/class-users.php @@ -4,8 +4,8 @@ namespace Activitypub\Collection; use WP_Error; use WP_User_Query; use Activitypub\Model\User; -use Activitypub\Model\Blog_User; -use Activitypub\Model\Application_User; +use Activitypub\Model\Blog; +use Activitypub\Model\Application; use function Activitypub\object_to_uri; use function Activitypub\url_to_authorid; @@ -47,9 +47,9 @@ class Users { } if ( self::BLOG_USER_ID === $user_id ) { - return Blog_User::from_wp_user( $user_id ); + return new Blog(); } elseif ( self::APPLICATION_USER_ID === $user_id ) { - return Application_User::from_wp_user( $user_id ); + return new Application(); } elseif ( $user_id > 0 ) { return User::from_wp_user( $user_id ); } @@ -70,12 +70,12 @@ class Users { */ public static function get_by_username( $username ) { // check for blog user. - if ( Blog_User::get_default_username() === $username ) { - return self::get_by_id( self::BLOG_USER_ID ); + if ( Blog::get_default_username() === $username ) { + return new Blog(); } if ( get_option( 'activitypub_blog_user_identifier' ) === $username ) { - return self::get_by_id( self::BLOG_USER_ID ); + return new Blog(); } // check for application user. @@ -144,24 +144,31 @@ class Users { // try to extract the scheme and the host if ( preg_match( '/^([a-zA-Z^:]+):(.*)$/i', $resource, $match ) ) { // extract the scheme - $scheme = esc_attr( $match[1] ); + $scheme = \esc_attr( $match[1] ); } switch ( $scheme ) { // check for http(s) URIs case 'http': case 'https': - $url_parts = wp_parse_url( $resource ); + $resource_path = \wp_parse_url( $resource, PHP_URL_PATH ); - // check for http(s)://blog.example.com/@username - if ( - isset( $url_parts['path'] ) && - str_starts_with( $url_parts['path'], '/@' ) - ) { - $identifier = str_replace( '/@', '', $url_parts['path'] ); - $identifier = untrailingslashit( $identifier ); + if ( $resource_path ) { + $blog_path = \wp_parse_url( \home_url(), PHP_URL_PATH ); - return self::get_by_username( $identifier ); + if ( $blog_path ) { + $resource_path = \str_replace( $blog_path, '', $resource_path ); + } + + $resource_path = \trim( $resource_path, '/' ); + + // check for http(s)://blog.example.com/@username + if ( str_starts_with( $resource_path, '@' ) ) { + $identifier = \str_replace( '@', '', $resource_path ); + $identifier = \trim( $identifier, '/' ); + + return self::get_by_username( $identifier ); + } } // check for http(s)://blog.example.com/author/username @@ -222,18 +229,26 @@ class Users { * @return \Acitvitypub\Model\User The User. */ public static function get_by_various( $id ) { + $user = null; + if ( is_numeric( $id ) ) { - return self::get_by_id( $id ); + $user = self::get_by_id( $id ); } elseif ( // is URL filter_var( $id, FILTER_VALIDATE_URL ) || // is acct - str_starts_with( $id, 'acct:' ) + str_starts_with( $id, 'acct:' ) || + // is email + filter_var( $id, FILTER_VALIDATE_EMAIL ) ) { - return self::get_by_resource( $id ); - } else { - return self::get_by_username( $id ); + $user = self::get_by_resource( $id ); } + + if ( $user && ! is_wp_error( $user ) ) { + return $user; + } + + return self::get_by_username( $id ); } /** diff --git a/wp-content/plugins/activitypub/includes/functions.php b/wp-content/plugins/activitypub/includes/functions.php index ee6ce46c..d33a2a4f 100644 --- a/wp-content/plugins/activitypub/includes/functions.php +++ b/wp-content/plugins/activitypub/includes/functions.php @@ -854,3 +854,118 @@ function get_masked_wp_version() { return implode( '.', $version ); } + +/** + * Get the enclosures of a post. + * + * @param int $post_id The post ID. + * + * @return array The enclosures. + */ +function get_enclosures( $post_id ) { + $enclosures = get_post_meta( $post_id, 'enclosure' ); + + if ( ! $enclosures ) { + return array(); + } + + $enclosures = array_map( + function ( $enclosure ) { + $attributes = explode( "\n", $enclosure ); + + if ( ! isset( $attributes[0] ) || ! \wp_http_validate_url( $attributes[0] ) ) { + return false; + } + + return array( + 'url' => $attributes[0], + 'length' => isset( $attributes[1] ) ? trim( $attributes[1] ) : null, + 'mediaType' => isset( $attributes[2] ) ? trim( $attributes[2] ) : null, + ); + }, + $enclosures + ); + + return array_filter( $enclosures ); +} + +/** + * Retrieves the IDs of the ancestors of a comment. + * + * Adaption of `get_post_ancestors` from WordPress core. + * + * @see https://developer.wordpress.org/reference/functions/get_post_ancestors/ + * + * @param int|WP_Comment $comment Comment ID or comment object. + * + * @return WP_Comment[] Array of ancestor comments or empty array if there are none. + */ +function get_comment_ancestors( $comment ) { + $comment = \get_comment( $comment ); + + // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual + if ( ! $comment || empty( $comment->comment_parent ) || $comment->comment_parent == $comment->comment_ID ) { + return array(); + } + + $ancestors = array(); + + $id = (int) $comment->comment_parent; + $ancestors[] = $id; + + // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition + while ( $id > 0 ) { + $ancestor = \get_comment( $id ); + $parent_id = (int) $ancestor->comment_parent; + + // Loop detection: If the ancestor has been seen before, break. + if ( empty( $parent_id ) || ( $parent_id === (int) $comment->comment_ID ) || in_array( $parent_id, $ancestors, true ) ) { + break; + } + + $id = $parent_id; + $ancestors[] = $id; + } + + return $ancestors; +} + +/** + * Change the display of large numbers on the site. + * + * @author Jeremy Herve + * + * @see https://wordpress.org/support/topic/abbreviate-numbers-with-k/ + * + * @param string $formatted Converted number in string format. + * @param float $number The number to convert based on locale. + * @param int $decimals Precision of the number of decimal places. + * + * @return string Converted number in string format. + */ +function custom_large_numbers( $formatted, $number, $decimals ) { + global $wp_locale; + + $decimals = 0; + $decimal_point = '.'; + $thousands_sep = ','; + + if ( isset( $wp_locale ) ) { + $decimals = (int) $wp_locale->number_format['decimal_point']; + $decimal_point = $wp_locale->number_format['decimal_point']; + $thousands_sep = $wp_locale->number_format['thousands_sep']; + } + + if ( $number < 1000 ) { // any number less than a Thousand. + return \number_format( $number, $decimals, $decimal_point, $thousands_sep ); + } elseif ( $number < 1000000 ) { // any number less than a million + return \number_format( $number / 1000, $decimals, $decimal_point, $thousands_sep ) . 'K'; + } elseif ( $number < 1000000000 ) { // any number less than a billion + return \number_format( $number / 1000000, $decimals, $decimal_point, $thousands_sep ) . 'M'; + } else { // at least a billion + return \number_format( $number / 1000000000, $decimals, $decimal_point, $thousands_sep ) . 'B'; + } + + // Default fallback. We should not get here. + return $formatted; +} diff --git a/wp-content/plugins/activitypub/includes/handler/class-announce.php b/wp-content/plugins/activitypub/includes/handler/class-announce.php new file mode 100644 index 00000000..46db2a3b --- /dev/null +++ b/wp-content/plugins/activitypub/includes/handler/class-announce.php @@ -0,0 +1,69 @@ +send(); } /** diff --git a/wp-content/plugins/activitypub/includes/model/class-application-user.php b/wp-content/plugins/activitypub/includes/model/class-application-user.php deleted file mode 100644 index 37ff4698..00000000 --- a/wp-content/plugins/activitypub/includes/model/class-application-user.php +++ /dev/null @@ -1,79 +0,0 @@ -get_preferred_username() ); - } - - public function get_name() { - return 'application'; - } - - public function get_preferred_username() { - return $this->get_name(); - } - - public function get_followers() { - return null; - } - - public function get_following() { - return null; - } - - public function get_attachment() { - return null; - } - - public function get_featured() { - return null; - } - - public function get_moderators() { - return null; - } - - public function get_indexable() { - return false; - } -} diff --git a/wp-content/plugins/activitypub/includes/model/class-application.php b/wp-content/plugins/activitypub/includes/model/class-application.php new file mode 100644 index 00000000..7bd3aa5e --- /dev/null +++ b/wp-content/plugins/activitypub/includes/model/class-application.php @@ -0,0 +1,200 @@ + + */ + protected $webfinger; + + public function get_type() { + return 'Application'; + } + + public function get_manually_approves_followers() { + return true; + } + + public function get_id() { + return get_rest_url_by_path( 'application' ); + } + + /** + * Get the User-Url. + * + * @return string The User-Url. + */ + public function get_url() { + return $this->get_id(); + } + + /** + * Returns the User-URL with @-Prefix for the username. + * + * @return string The User-URL with @-Prefix for the username. + */ + public function get_alternate_url() { + return $this->get_url(); + } + + public function get_name() { + return 'application'; + } + + public function get_preferred_username() { + return $this->get_name(); + } + + /** + * Get the User-Icon. + * + * @return array The User-Icon. + */ + public function get_icon() { + // try site icon first + $icon_id = get_option( 'site_icon' ); + + // try custom logo second + if ( ! $icon_id ) { + $icon_id = get_theme_mod( 'custom_logo' ); + } + + $icon_url = false; + + if ( $icon_id ) { + $icon = wp_get_attachment_image_src( $icon_id, 'full' ); + if ( $icon ) { + $icon_url = $icon[0]; + } + } + + if ( ! $icon_url ) { + // fallback to default icon + $icon_url = plugins_url( '/assets/img/wp-logo.png', ACTIVITYPUB_PLUGIN_FILE ); + } + + return array( + 'type' => 'Image', + 'url' => esc_url( $icon_url ), + ); + } + + /** + * Get the User-Header-Image. + * + * @return array|null The User-Header-Image. + */ + public function get_header_image() { + if ( \has_header_image() ) { + return array( + 'type' => 'Image', + 'url' => esc_url( \get_header_image() ), + ); + } + + return null; + } + + public function get_published() { + $first_post = new WP_Query( + array( + 'orderby' => 'date', + 'order' => 'ASC', + 'number' => 1, + ) + ); + + if ( ! empty( $first_post->posts[0] ) ) { + $time = \strtotime( $first_post->posts[0]->post_date_gmt ); + } else { + $time = \time(); + } + + return \gmdate( 'Y-m-d\TH:i:s\Z', $time ); + } + + /** + * Returns the Inbox-API-Endpoint. + * + * @return string The Inbox-Endpoint. + */ + public function get_inbox() { + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) ); + } + + /** + * Returns the Outbox-API-Endpoint. + * + * @return string The Outbox-Endpoint. + */ + public function get_outbox() { + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) ); + } + + /** + * Returns a user@domain type of identifier for the user. + * + * @return string The Webfinger-Identifier. + */ + public function get_webfinger() { + return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); + } + + public function get_public_key() { + return array( + 'id' => $this->get_id() . '#main-key', + 'owner' => $this->get_id(), + 'publicKeyPem' => Signature::get_public_key_for( Users::APPLICATION_USER_ID ), + ); + } + + /** + * Get the User-Description. + * + * @return string The User-Description. + */ + public function get_summary() { + return \wpautop( + \wp_kses( + \get_bloginfo( 'description' ), + 'default' + ) + ); + } +} diff --git a/wp-content/plugins/activitypub/includes/model/class-blog-user.php b/wp-content/plugins/activitypub/includes/model/class-blog.php similarity index 57% rename from wp-content/plugins/activitypub/includes/model/class-blog-user.php rename to wp-content/plugins/activitypub/includes/model/class-blog.php index 579f7ba2..cc515385 100644 --- a/wp-content/plugins/activitypub/includes/model/class-blog-user.php +++ b/wp-content/plugins/activitypub/includes/model/class-blog.php @@ -4,13 +4,38 @@ namespace Activitypub\Model; use WP_Query; use WP_Error; +use Activitypub\Signature; +use Activitypub\Activity\Actor; use Activitypub\Collection\Users; use function Activitypub\is_single_user; use function Activitypub\is_user_disabled; use function Activitypub\get_rest_url_by_path; -class Blog_User extends User { +class Blog extends Actor { + /** + * The Featured-Posts. + * + * @see https://docs.joinmastodon.org/spec/activitypub/#featured + * + * @context { + * "@id": "http://joinmastodon.org/ns#featured", + * "@type": "@id" + * } + * + * @var string + */ + protected $featured; + + /** + * Moderators endpoint. + * + * @see https://join-lemmy.org/docs/contributors/05-federation.html + * + * @var string + */ + protected $moderators; + /** * The User-ID * @@ -18,6 +43,42 @@ class Blog_User extends User { */ protected $_id = Users::BLOG_USER_ID; // phpcs:ignore PSR2.Classes.PropertyDeclaration.Underscore + /** + * If the User is indexable. + * + * @context http://joinmastodon.org/ns#indexable + * + * @var boolean + */ + protected $indexable; + + /** + * The WebFinger Resource. + * + * @var string + */ + protected $webfinger; + + /** + * If the User is discoverable. + * + * @see https://docs.joinmastodon.org/spec/activitypub/#discoverable + * + * @context http://joinmastodon.org/ns#discoverable + * + * @var boolean + */ + protected $discoverable; + + /** + * Restrict posting to mods + * + * @see https://join-lemmy.org/docs/contributors/05-federation.html + * + * @var boolean + */ + protected $posting_restricted_to_mods; + public function get_manually_approves_followers() { return false; } @@ -26,19 +87,13 @@ class Blog_User extends User { return true; } - public static function from_wp_user( $user_id ) { - if ( is_user_disabled( $user_id ) ) { - return new WP_Error( - 'activitypub_user_not_found', - \__( 'User not found', 'activitypub' ), - array( 'status' => 404 ) - ); - } - - $object = new static(); - $object->_id = $user_id; - - return $object; + /** + * Get the User-ID. + * + * @return string The User-ID. + */ + public function get_id() { + return $this->get_url(); } /** @@ -204,10 +259,6 @@ class Blog_User extends User { return \gmdate( 'Y-m-d\TH:i:s\Z', $time ); } - public function get_attachment() { - return array(); - } - public function get_canonical_url() { return \home_url(); } @@ -228,6 +279,14 @@ class Blog_User extends User { return get_rest_url_by_path( 'collections/moderators' ); } + public function get_public_key() { + return array( + 'id' => $this->get_id() . '#main-key', + 'owner' => $this->get_id(), + 'publicKeyPem' => Signature::get_public_key_for( $this->get__id() ), + ); + } + public function get_posting_restricted_to_mods() { if ( 'Group' === $this->get_type() ) { return true; @@ -235,4 +294,78 @@ class Blog_User extends User { return null; } + + /** + * Returns the Inbox-API-Endpoint. + * + * @return string The Inbox-Endpoint. + */ + public function get_inbox() { + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) ); + } + + /** + * Returns the Outbox-API-Endpoint. + * + * @return string The Outbox-Endpoint. + */ + public function get_outbox() { + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) ); + } + + /** + * Returns the Followers-API-Endpoint. + * + * @return string The Followers-Endpoint. + */ + public function get_followers() { + return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) ); + } + + /** + * Returns the Following-API-Endpoint. + * + * @return string The Following-Endpoint. + */ + public function get_following() { + return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) ); + } + + public function get_endpoints() { + $endpoints = null; + + if ( ACTIVITYPUB_SHARED_INBOX_FEATURE ) { + $endpoints = array( + 'sharedInbox' => get_rest_url_by_path( 'inbox' ), + ); + } + + return $endpoints; + } + + /** + * Returns a user@domain type of identifier for the user. + * + * @return string The Webfinger-Identifier. + */ + public function get_webfinger() { + return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); + } + + /** + * Returns the Featured-API-Endpoint. + * + * @return string The Featured-Endpoint. + */ + public function get_featured() { + return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) ); + } + + public function get_indexable() { + if ( \get_option( 'blog_public', 1 ) ) { + return true; + } else { + return false; + } + } } diff --git a/wp-content/plugins/activitypub/includes/model/class-post.php b/wp-content/plugins/activitypub/includes/model/class-post.php index 29aadfc9..a4229539 100644 --- a/wp-content/plugins/activitypub/includes/model/class-post.php +++ b/wp-content/plugins/activitypub/includes/model/class-post.php @@ -2,7 +2,7 @@ namespace Activitypub\Model; use Activitypub\Collection\Users; -use Activitypub\Transformer\Post as Post_Transformer; +use Activitypub\Transformer\Factory; /** * ActivityPub Post Class @@ -32,10 +32,14 @@ class Post { */ // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable public function __construct( $post, $post_author = null ) { - _deprecated_function( __CLASS__, '1.0.0', '\Activitypub\Transformer\Post' ); + _deprecated_function( __METHOD__, '1.0.0', '\Activitypub\Transformer\Factory::get_transformer' ); - $this->post = $post; - $this->object = Post_Transformer::transform( $post )->to_object(); + $transformer = Factory::get_transformer( $post ); + + if ( ! \is_wp_error( $transformer ) ) { + $this->post = $post; + $this->object = $transformer->to_object(); + } } /** diff --git a/wp-content/plugins/activitypub/includes/model/class-user.php b/wp-content/plugins/activitypub/includes/model/class-user.php index a62efb30..c5f91a31 100644 --- a/wp-content/plugins/activitypub/includes/model/class-user.php +++ b/wp-content/plugins/activitypub/includes/model/class-user.php @@ -4,8 +4,9 @@ namespace Activitypub\Model; use WP_Query; use WP_Error; use Activitypub\Signature; -use Activitypub\Collection\Users; +use Activitypub\Model\Blog; use Activitypub\Activity\Actor; +use Activitypub\Collection\Users; use function Activitypub\is_user_disabled; use function Activitypub\get_rest_url_by_path; @@ -32,19 +33,6 @@ class User extends Actor { */ protected $featured; - /** - * Moderators endpoint. - * - * @see https://join-lemmy.org/docs/contributors/05-federation.html - * - * @var string - */ - protected $moderators; - - public function get_type() { - return 'Person'; - } - /** * If the User is discoverable. * @@ -72,14 +60,9 @@ class User extends Actor { */ protected $webfinger; - /** - * Restrict posting to mods - * - * @see https://join-lemmy.org/docs/contributors/05-federation.html - * - * @var boolean - */ - protected $posting_restricted_to_mods = null; + public function get_type() { + return 'Person'; + } public static function from_wp_user( $user_id ) { if ( is_user_disabled( $user_id ) ) { @@ -193,7 +176,7 @@ class User extends Actor { * @return string The Inbox-Endpoint. */ public function get_inbox() { - return get_rest_url_by_path( sprintf( 'users/%d/inbox', $this->get__id() ) ); + return get_rest_url_by_path( sprintf( 'actors/%d/inbox', $this->get__id() ) ); } /** @@ -202,7 +185,7 @@ class User extends Actor { * @return string The Outbox-Endpoint. */ public function get_outbox() { - return get_rest_url_by_path( sprintf( 'users/%d/outbox', $this->get__id() ) ); + return get_rest_url_by_path( sprintf( 'actors/%d/outbox', $this->get__id() ) ); } /** @@ -211,7 +194,7 @@ class User extends Actor { * @return string The Followers-Endpoint. */ public function get_followers() { - return get_rest_url_by_path( sprintf( 'users/%d/followers', $this->get__id() ) ); + return get_rest_url_by_path( sprintf( 'actors/%d/followers', $this->get__id() ) ); } /** @@ -220,7 +203,7 @@ class User extends Actor { * @return string The Following-Endpoint. */ public function get_following() { - return get_rest_url_by_path( sprintf( 'users/%d/following', $this->get__id() ) ); + return get_rest_url_by_path( sprintf( 'actors/%d/following', $this->get__id() ) ); } /** @@ -229,7 +212,7 @@ class User extends Actor { * @return string The Featured-Endpoint. */ public function get_featured() { - return get_rest_url_by_path( sprintf( 'users/%d/collections/featured', $this->get__id() ) ); + return get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $this->get__id() ) ); } public function get_endpoints() { @@ -296,10 +279,6 @@ class User extends Actor { return $this->get_preferred_username() . '@' . \wp_parse_url( \home_url(), \PHP_URL_HOST ); } - public function get_resource() { - return $this->get_webfinger(); - } - public function get_canonical_url() { return $this->get_url(); } diff --git a/wp-content/plugins/activitypub/includes/rest/class-users.php b/wp-content/plugins/activitypub/includes/rest/class-actors.php similarity index 95% rename from wp-content/plugins/activitypub/includes/rest/class-users.php rename to wp-content/plugins/activitypub/includes/rest/class-actors.php index db9d14cf..9455a261 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-users.php +++ b/wp-content/plugins/activitypub/includes/rest/class-actors.php @@ -12,13 +12,13 @@ use Activitypub\Collection\Users as User_Collection; use function Activitypub\is_activitypub_request; /** - * ActivityPub Followers REST-Class + * ActivityPub Actors REST-Class * * @author Matthias Pfefferle * * @see https://www.w3.org/TR/activitypub/#followers */ -class Users { +class Actors { /** * Initialize the class, registering WordPress hooks */ @@ -32,7 +32,7 @@ class Users { public static function register_routes() { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)', + '/(users|actors)/(?P[\w\-\.]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -45,7 +45,7 @@ class Users { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/remote-follow', + '/(users|actors)/(?P[\w\-\.]+)/remote-follow', array( array( 'methods' => WP_REST_Server::READABLE, diff --git a/wp-content/plugins/activitypub/includes/rest/class-collection.php b/wp-content/plugins/activitypub/includes/rest/class-collection.php index 680235ee..296789fb 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-collection.php +++ b/wp-content/plugins/activitypub/includes/rest/class-collection.php @@ -1,13 +1,12 @@ [\w\-\.]+)/collections/tags', + '/(users|actors)/(?P[\w\-\.]+)/collections/tags', array( array( 'methods' => WP_REST_Server::READABLE, @@ -48,7 +47,7 @@ class Collection { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/collections/featured', + '/(users|actors)/(?P[\w\-\.]+)/collections/featured', array( array( 'methods' => WP_REST_Server::READABLE, @@ -104,7 +103,7 @@ class Collection { $response = array( '@context' => Base_Object::JSON_LD_CONTEXT, - 'id' => get_rest_url_by_path( sprintf( 'users/%d/collections/tags', $user->get__id() ) ), + 'id' => get_rest_url_by_path( sprintf( 'actors/%d/collections/tags', $user->get__id() ) ), 'type' => 'Collection', 'totalItems' => is_countable( $tags ) ? count( $tags ) : 0, 'items' => array(), @@ -162,14 +161,20 @@ class Collection { $response = array( '@context' => Base_Object::JSON_LD_CONTEXT, - 'id' => get_rest_url_by_path( sprintf( 'users/%d/collections/featured', $user_id ) ), + 'id' => get_rest_url_by_path( sprintf( 'actors/%d/collections/featured', $user_id ) ), 'type' => 'OrderedCollection', 'totalItems' => is_countable( $posts ) ? count( $posts ) : 0, 'orderedItems' => array(), ); foreach ( $posts as $post ) { - $response['orderedItems'][] = Post::transform( $post )->to_object()->to_array( false ); + $transformer = Factory::get_transformer( $post ); + + if ( \is_wp_error( $transformer ) ) { + continue; + } + + $response['orderedItems'][] = $transformer->to_object()->to_array( false ); } $rest_response = new WP_REST_Response( $response, 200 ); diff --git a/wp-content/plugins/activitypub/includes/rest/class-comment.php b/wp-content/plugins/activitypub/includes/rest/class-comment.php index 6a062d6c..066b52fb 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-comment.php +++ b/wp-content/plugins/activitypub/includes/rest/class-comment.php @@ -29,7 +29,7 @@ class Comment { public static function register_routes() { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/comments/(?P\d+)/remote-reply', + '/(users|actors)/(?P\d+)/remote-reply', array( array( 'methods' => WP_REST_Server::READABLE, diff --git a/wp-content/plugins/activitypub/includes/rest/class-followers.php b/wp-content/plugins/activitypub/includes/rest/class-followers.php index bbddb004..ca882cf3 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-followers.php +++ b/wp-content/plugins/activitypub/includes/rest/class-followers.php @@ -32,7 +32,7 @@ class Followers { public static function register_routes() { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/followers', + '/(users|actors)/(?P[\w\-\.]+)/followers', array( array( 'methods' => WP_REST_Server::READABLE, @@ -74,13 +74,13 @@ class Followers { $json->{'@context'} = \Activitypub\get_context(); - $json->id = get_rest_url_by_path( sprintf( 'users/%d/followers', $user->get__id() ) ); + $json->id = get_rest_url_by_path( sprintf( 'actors/%d/followers', $user->get__id() ) ); $json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version(); $json->actor = $user->get_id(); $json->type = 'OrderedCollectionPage'; $json->totalItems = $data['total']; // phpcs:ignore - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/followers', $user->get__id() ) ); // phpcs:ignore + $json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/followers', $user->get__id() ) ); // phpcs:ignore $json->first = \add_query_arg( 'page', 1, $json->partOf ); // phpcs:ignore $json->last = \add_query_arg( 'page', \ceil ( $json->totalItems / $per_page ), $json->partOf ); // phpcs:ignore diff --git a/wp-content/plugins/activitypub/includes/rest/class-following.php b/wp-content/plugins/activitypub/includes/rest/class-following.php index 5ff29ec0..4e077279 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-following.php +++ b/wp-content/plugins/activitypub/includes/rest/class-following.php @@ -31,7 +31,7 @@ class Following { public static function register_routes() { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/following', + '/(users|actors)/(?P[\w\-\.]+)/following', array( array( 'methods' => \WP_REST_Server::READABLE, @@ -67,12 +67,12 @@ class Following { $json->{'@context'} = \Activitypub\get_context(); - $json->id = get_rest_url_by_path( sprintf( 'users/%d/following', $user->get__id() ) ); + $json->id = get_rest_url_by_path( sprintf( 'actors/%d/following', $user->get__id() ) ); $json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version(); $json->actor = $user->get_id(); $json->type = 'OrderedCollectionPage'; - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/following', $user->get__id() ) ); // phpcs:ignore + $json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/following', $user->get__id() ) ); // phpcs:ignore $items = apply_filters( 'activitypub_rest_following', array(), $user ); // phpcs:ignore diff --git a/wp-content/plugins/activitypub/includes/rest/class-inbox.php b/wp-content/plugins/activitypub/includes/rest/class-inbox.php index b5ea52eb..161fcf19 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-inbox.php +++ b/wp-content/plugins/activitypub/includes/rest/class-inbox.php @@ -48,7 +48,7 @@ class Inbox { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/inbox', + '/(users|actors)/(?P[\w\-\.]+)/inbox', array( array( 'methods' => WP_REST_Server::CREATABLE, @@ -90,10 +90,10 @@ class Inbox { $json = new \stdClass(); $json->{'@context'} = get_context(); - $json->id = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) ); + $json->id = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) ); $json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version(); $json->type = 'OrderedCollectionPage'; - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/inbox', $user->get__id() ) ); // phpcs:ignore + $json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) ); // phpcs:ignore $json->totalItems = 0; // phpcs:ignore $json->orderedItems = array(); // phpcs:ignore $json->first = $json->partOf; // phpcs:ignore diff --git a/wp-content/plugins/activitypub/includes/rest/class-outbox.php b/wp-content/plugins/activitypub/includes/rest/class-outbox.php index 474f1622..e0670301 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-outbox.php +++ b/wp-content/plugins/activitypub/includes/rest/class-outbox.php @@ -5,9 +5,9 @@ use stdClass; use WP_Error; use WP_REST_Server; use WP_REST_Response; -use Activitypub\Transformer\Post; use Activitypub\Activity\Activity; use Activitypub\Collection\Users as User_Collection; +use Activitypub\Transformer\Factory; use function Activitypub\get_context; use function Activitypub\get_rest_url_by_path; @@ -34,7 +34,7 @@ class Outbox { public static function register_routes() { \register_rest_route( ACTIVITYPUB_REST_NAMESPACE, - '/users/(?P[\w\-\.]+)/outbox', + '/(users|actors)/(?P[\w\-\.]+)/outbox', array( array( 'methods' => WP_REST_Server::READABLE, @@ -72,11 +72,11 @@ class Outbox { $json = new stdClass(); $json->{'@context'} = get_context(); - $json->id = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) ); + $json->id = get_rest_url_by_path( sprintf( 'actors/%d/outbox', $user_id ) ); $json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version(); $json->actor = $user->get_id(); $json->type = 'OrderedCollectionPage'; - $json->partOf = get_rest_url_by_path( sprintf( 'users/%d/outbox', $user_id ) ); // phpcs:ignore + $json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/outbox', $user_id ) ); // phpcs:ignore $json->totalItems = 0; // phpcs:ignore if ( $user_id > 0 ) { @@ -111,7 +111,13 @@ class Outbox { ); foreach ( $posts as $post ) { - $post = Post::transform( $post )->to_object(); + $transformer = Factory::get_transformer( $post ); + + if ( \is_wp_error( $transformer ) ) { + continue; + } + + $post = $transformer->to_object(); $activity = new Activity(); $activity->set_type( 'Create' ); $activity->set_object( $post ); diff --git a/wp-content/plugins/activitypub/includes/rest/class-server.php b/wp-content/plugins/activitypub/includes/rest/class-server.php index 13e70736..d03f6c17 100644 --- a/wp-content/plugins/activitypub/includes/rest/class-server.php +++ b/wp-content/plugins/activitypub/includes/rest/class-server.php @@ -5,7 +5,7 @@ use stdClass; use WP_Error; use WP_REST_Response; use Activitypub\Signature; -use Activitypub\Model\Application_User; +use Activitypub\Model\Application; /** * ActivityPub Server REST-Class @@ -47,7 +47,7 @@ class Server { * @return WP_REST_Response The JSON profile of the Application Actor. */ public static function application_actor() { - $user = new Application_User(); + $user = new Application(); $json = $user->to_array(); @@ -62,6 +62,9 @@ class Server { * * @see WP_REST_Request * + * @see https://www.w3.org/wiki/SocialCG/ActivityPub/Primer/Authentication_Authorization#Authorized_fetch + * @see https://swicg.github.io/activitypub-http-signature/#authorized-fetch + * * @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client. * Usually a WP_REST_Response or WP_Error. * @param array $handler Route handler used for the request. @@ -80,7 +83,8 @@ class Server { if ( ! \str_starts_with( $route, '/' . ACTIVITYPUB_REST_NAMESPACE ) || \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'webfinger' ) || - \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'nodeinfo' ) + \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'nodeinfo' ) || + \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'application' ) ) { return $response; } @@ -102,17 +106,12 @@ class Server { return $response; } - // POST-Requets are always signed - if ( 'GET' !== $request->get_method() ) { - $verified_request = Signature::verify_http_signature( $request ); - if ( \is_wp_error( $verified_request ) ) { - return new WP_Error( - 'activitypub_signature_verification', - $verified_request->get_error_message(), - array( 'status' => 401 ) - ); - } - } elseif ( 'GET' === $request->get_method() && ACTIVITYPUB_AUTHORIZED_FETCH ) { // GET-Requests are only signed in secure mode + if ( + // POST-Requests are always signed + 'GET' !== $request->get_method() || + // GET-Requests only require a signature in secure mode + ( 'GET' === $request->get_method() && ACTIVITYPUB_AUTHORIZED_FETCH ) + ) { $verified_request = Signature::verify_http_signature( $request ); if ( \is_wp_error( $verified_request ) ) { return new WP_Error( diff --git a/wp-content/plugins/activitypub/includes/transformer/class-base.php b/wp-content/plugins/activitypub/includes/transformer/class-base.php index b66703fa..5041fa96 100644 --- a/wp-content/plugins/activitypub/includes/transformer/class-base.php +++ b/wp-content/plugins/activitypub/includes/transformer/class-base.php @@ -1,6 +1,7 @@ get_locale() => $this->get_content(), ) ); - $path = sprintf( 'users/%d/followers', intval( $comment->comment_author ) ); + $path = sprintf( 'actors/%d/followers', intval( $comment->comment_author ) ); $object->set_to( array( @@ -90,7 +91,7 @@ class Comment extends Base { */ protected function get_attributed_to() { if ( is_single_user() ) { - $user = new Blog_User(); + $user = new Blog(); return $user->get_url(); } @@ -218,6 +219,23 @@ class Comment extends Base { return apply_filters( 'activitypub_extract_mentions', array(), $this->wp_object->comment_content, $this->wp_object ); } + /** + * Gets the ancestors of the comment, but only the ones that are ActivityPub comments. + * + * @return array The list of ancestors. + */ + protected function get_comment_ancestors() { + $ancestors = get_comment_ancestors( $this->wp_object ); + + // Now that we have the full tree of ancestors, only return the ones received from the fediverse + return array_filter( + $ancestors, + function ( $comment_id ) { + return \get_comment_meta( $comment_id, 'protocol', true ) === 'activitypub'; + } + ); + } + /** * Collect all other Users that participated in this comment-thread * to send them a notification about the new reply. @@ -232,27 +250,18 @@ class Comment extends Base { return $mentions; } - $comment_query = new WP_Comment_Query( - array( - 'post_id' => $this->wp_object->comment_post_ID, - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query - 'meta_query' => array( - array( - 'key' => 'protocol', - 'value' => 'activitypub', - ), - ), - ) - ); + $ancestors = $this->get_comment_ancestors(); + if ( ! $ancestors ) { + return $mentions; + } - if ( $comment_query->comments ) { - foreach ( $comment_query->comments as $comment ) { - if ( ! empty( $comment->comment_author_url ) ) { - $acct = Webfinger::uri_to_acct( $comment->comment_author_url ); - if ( $acct && ! is_wp_error( $acct ) ) { - $acct = str_replace( 'acct:', '@', $acct ); - $mentions[ $acct ] = $comment->comment_author_url; - } + foreach ( $ancestors as $comment_id ) { + $comment = \get_comment( $comment_id ); + if ( $comment && ! empty( $comment->comment_author_url ) ) { + $acct = Webfinger::uri_to_acct( $comment->comment_author_url ); + if ( $acct && ! is_wp_error( $acct ) ) { + $acct = str_replace( 'acct:', '@', $acct ); + $mentions[ $acct ] = $comment->comment_author_url; } } } diff --git a/wp-content/plugins/activitypub/includes/transformer/class-factory.php b/wp-content/plugins/activitypub/includes/transformer/class-factory.php index 33210ca1..b21de7f9 100644 --- a/wp-content/plugins/activitypub/includes/transformer/class-factory.php +++ b/wp-content/plugins/activitypub/includes/transformer/class-factory.php @@ -11,7 +11,11 @@ use Activitypub\Transformer\Attachment; * Transformer Factory */ class Factory { - public static function get_transformer( $object ) { + /** + * @param mixed $object The object to transform + * @return \Activitypub\Transformer|\WP_Error The transformer to use, or an error. + */ + public static function get_transformer( $object ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.objectFound if ( ! \is_object( $object ) ) { return new WP_Error( 'invalid_object', __( 'Invalid object', 'activitypub' ) ); } @@ -41,9 +45,9 @@ class Factory { * return $transformer; * }, 10, 3 ); * - * @param Activitypub\Transformer\Base $transformer The transformer to use. - * @param mixed $object The object to transform. - * @param string $object_class The class of the object to transform. + * @param Base $transformer The transformer to use. + * @param mixed $object The object to transform. + * @param string $object_class The class of the object to transform. * * @return mixed The transformer to use. */ diff --git a/wp-content/plugins/activitypub/includes/transformer/class-post.php b/wp-content/plugins/activitypub/includes/transformer/class-post.php index 3c4905ec..646f45b1 100644 --- a/wp-content/plugins/activitypub/includes/transformer/class-post.php +++ b/wp-content/plugins/activitypub/includes/transformer/class-post.php @@ -3,13 +3,13 @@ namespace Activitypub\Transformer; use WP_Post; use Activitypub\Shortcodes; -use Activitypub\Model\Blog_User; +use Activitypub\Model\Blog; use Activitypub\Transformer\Base; use Activitypub\Collection\Users; -use Activitypub\Activity\Base_Object; use function Activitypub\esc_hashtag; use function Activitypub\is_single_user; +use function Activitypub\get_enclosures; use function Activitypub\get_rest_url_by_path; use function Activitypub\site_supports_blocks; @@ -70,7 +70,7 @@ class Post extends Base { $this->get_locale() => $this->get_content(), ) ); - $path = sprintf( 'users/%d/followers', intval( $post->post_author ) ); + $path = sprintf( 'actors/%d/followers', intval( $post->post_author ) ); $object->set_to( array( @@ -116,7 +116,7 @@ class Post extends Base { * @return string The User-URL. */ protected function get_attributed_to() { - $blog_user = new Blog_User(); + $blog_user = new Blog(); if ( is_single_user() ) { return $blog_user->get_url(); @@ -139,14 +139,34 @@ class Post extends Base { protected function get_attachment() { // Once upon a time we only supported images, but we now support audio/video as well. // We maintain the image-centric naming for backwards compatibility. - $max_media = \intval( \apply_filters( 'activitypub_max_image_attachments', \get_option( 'activitypub_max_image_attachments', ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS ) ) ); + $max_media = \intval( + \apply_filters( + 'activitypub_max_image_attachments', + \get_option( 'activitypub_max_image_attachments', ACTIVITYPUB_MAX_IMAGE_ATTACHMENTS ) + ) + ); - if ( site_supports_blocks() && \has_blocks( $this->wp_object->post_content ) ) { - $media = $this->get_block_attachments( $max_media ); - } else { - $media = $this->get_classic_editor_images( $max_media ); + $media = array( + 'audio' => array(), + 'video' => array(), + 'image' => array(), + ); + $id = $this->wp_object->ID; + + // list post thumbnail first if this post has one + if ( \function_exists( 'has_post_thumbnail' ) && \has_post_thumbnail( $id ) ) { + $media['image'][] = array( 'id' => \get_post_thumbnail_id( $id ) ); } + $media = $this->get_enclosures( $media ); + + if ( site_supports_blocks() && \has_blocks( $this->wp_object->post_content ) ) { + $media = $this->get_block_attachments( $media, $max_media ); + } else { + $media = $this->get_classic_editor_images( $media, $max_media ); + } + + $media = self::filter_media_by_object_type( $media, \get_post_format( $this->wp_object ), $this->wp_object ); $unique_ids = \array_unique( \array_column( $media, 'id' ) ); $media = \array_intersect_key( $media, $unique_ids ); $media = \array_slice( $media, 0, $max_media ); @@ -157,35 +177,21 @@ class Post extends Base { /** * Get media attachments from blocks. They will be formatted as ActivityPub attachments, not as WP attachments. * - * @param int $max_media The maximum number of attachments to return. + * @param array $media The media array grouped by type. + * @param int $max_media The maximum number of attachments to return. * * @return array The attachments. */ - protected function get_block_attachments( $max_media ) { + protected function get_block_attachments( $media, $max_media ) { // max media can't be negative or zero if ( $max_media <= 0 ) { return array(); } - $id = $this->wp_object->ID; + $blocks = \parse_blocks( $this->wp_object->post_content ); + $media = self::get_media_from_blocks( $blocks, $media ); - $media = array( - 'image' => array(), - 'audio' => array(), - 'video' => array(), - ); - - // list post thumbnail first if this post has one - if ( \function_exists( 'has_post_thumbnail' ) && \has_post_thumbnail( $id ) ) { - $media['image'][] = array( 'id' => \get_post_thumbnail_id( $id ) ); - } - - if ( $max_media > 0 ) { - $blocks = \parse_blocks( $this->wp_object->post_content ); - $media = self::get_media_from_blocks( $blocks, $media ); - } - - return self::filter_media_by_object_type( $media, \get_post_format( $this->wp_object ) ); + return $media; } /** @@ -202,8 +208,9 @@ class Post extends Base { if ( $max_images <= 0 ) { return array(); } + $images = array(); - $query = new \WP_Query( + $query = new \WP_Query( array( 'post_parent' => $this->wp_object->ID, 'post_status' => 'inherit', @@ -214,6 +221,7 @@ class Post extends Base { 'posts_per_page' => $max_images, ) ); + foreach ( $query->get_posts() as $attachment ) { if ( ! \in_array( $attachment->ID, $images, true ) ) { $images[] = array( 'id' => $attachment->ID ); @@ -249,7 +257,7 @@ class Post extends Base { // This linter warning is a false positive - we have to // re-count each time here as we modify $images. // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found - while ( $tags->next_tag( 'img' ) && ( \count( $images ) < $max_images ) ) { + while ( $tags->next_tag( 'img' ) && ( \count( $images ) <= $max_images ) ) { $src = $tags->get_attribute( 'src' ); // If the img source is in our uploads dir, get the @@ -292,34 +300,68 @@ class Post extends Base { * Get post images from the classic editor. * Note that audio/video attachments are only supported in the block editor. * - * @param int $max_images The maximum number of images to return. + * @param array $media The media array grouped by type. + * @param int $max_images The maximum number of images to return. * * @return array The attachments. */ - protected function get_classic_editor_images( $max_images ) { + protected function get_classic_editor_images( $media, $max_images ) { // max images can't be negative or zero if ( $max_images <= 0 ) { return array(); } - $id = $this->wp_object->ID; - - $images = array(); - - // list post thumbnail first if this post has one - if ( \function_exists( 'has_post_thumbnail' ) && \has_post_thumbnail( $id ) ) { - $images[] = \get_post_thumbnail_id( $id ); - } - - if ( \count( $images ) < $max_images ) { + if ( \count( $media['image'] ) <= $max_images ) { if ( \class_exists( '\WP_HTML_Tag_Processor' ) ) { - $images = \array_merge( $images, $this->get_classic_editor_image_embeds( $max_images ) ); + $media['image'] = \array_merge( $media['image'], $this->get_classic_editor_image_embeds( $max_images ) ); } else { - $images = \array_merge( $images, $this->get_classic_editor_image_attachments( $max_images ) ); + $media['image'] = \array_merge( $media['image'], $this->get_classic_editor_image_attachments( $max_images ) ); } } - return $images; + return $media; + } + + /** + * Get enclosures for a post. + * + * @param array $media The media array grouped by type. + * + * @return array The media array extended with enclosures. + */ + public function get_enclosures( $media ) { + $enclosures = get_enclosures( $this->wp_object->ID ); + + if ( ! $enclosures ) { + return $media; + } + + foreach ( $enclosures as $enclosure ) { + // check if URL is an attachment + $attachment_id = \attachment_url_to_postid( $enclosure['url'] ); + if ( $attachment_id ) { + $enclosure['id'] = $attachment_id; + $enclosure['url'] = \wp_get_attachment_url( $attachment_id ); + $enclosure['mediaType'] = \get_post_mime_type( $attachment_id ); + } + + $mime_type = $enclosure['mediaType']; + $mime_type_parts = \explode( '/', $mime_type ); + + switch ( $mime_type_parts[0] ) { + case 'image': + $media['image'][] = $enclosure; + break; + case 'audio': + $media['audio'][] = $enclosure; + break; + case 'video': + $media['video'][] = $enclosure; + break; + } + } + + return $media; } /** @@ -331,7 +373,6 @@ class Post extends Base { * @return array The image IDs. */ protected static function get_media_from_blocks( $blocks, $media ) { - foreach ( $blocks as $block ) { // recurse into inner blocks if ( ! empty( $block['innerBlocks'] ) ) { @@ -397,19 +438,19 @@ class Post extends Base { /** * Filter media IDs by object type. * - * @param array $media The media array grouped by type. - * @param array $type The object type. + * @param array $media The media array grouped by type. + * @param string $type The object type. * * @return array The filtered media IDs. */ - protected static function filter_media_by_object_type( $media, $type ) { - $type = \apply_filters( 'filter_media_by_object_type', \strtolower( $type ) ); + protected static function filter_media_by_object_type( $media, $type, $wp_object ) { + $type = \apply_filters( 'filter_media_by_object_type', \strtolower( $type ), $wp_object ); if ( ! empty( $media[ $type ] ) ) { return $media[ $type ]; } - return array_merge( array(), ...array_values( $media ) ); + return array_filter( array_merge( array(), ...array_values( $media ) ) ); } /** @@ -420,6 +461,10 @@ class Post extends Base { * @return array The ActivityPub Attachment. */ public static function wp_attachment_to_activity_attachment( $media ) { + if ( ! isset( $media['id'] ) ) { + return $media; + } + $id = $media['id']; $attachment = array(); $mime_type = \get_post_mime_type( $id ); @@ -427,14 +472,14 @@ class Post extends Base { // switching on image/audio/video switch ( $mime_type_parts[0] ) { case 'image': - $image_size = 'full'; + $image_size = 'large'; /** * Filter the image URL returned for each post. * * @param array|false $thumbnail The image URL, or false if no image is available. * @param int $id The attachment ID. - * @param string $image_size The image size to retrieve. Set to 'full' by default. + * @param string $image_size The image size to retrieve. Set to 'large' by default. */ $thumbnail = apply_filters( 'activitypub_get_image', @@ -488,16 +533,16 @@ class Post extends Base { * Return details about an image attachment. * * @param int $id The attachment ID. - * @param string $image_size The image size to retrieve. Set to 'full' by default. + * @param string $image_size The image size to retrieve. Set to 'large' by default. * * @return array|false Array of image data, or boolean false if no image is available. */ - protected static function get_wordpress_attachment( $id, $image_size = 'full' ) { + protected static function get_wordpress_attachment( $id, $image_size = 'large' ) { /** * Hook into the image retrieval process. Before image retrieval. * * @param int $id The attachment ID. - * @param string $image_size The image size to retrieve. Set to 'full' by default. + * @param string $image_size The image size to retrieve. Set to 'large' by default. */ do_action( 'activitypub_get_image_pre', $id, $image_size ); @@ -507,7 +552,7 @@ class Post extends Base { * Hook into the image retrieval process. After image retrieval. * * @param int $id The attachment ID. - * @param string $image_size The image size to retrieve. Set to 'full' by default. + * @param string $image_size The image size to retrieve. Set to 'large' by default. */ do_action( 'activitypub_get_image_post', $id, $image_size ); @@ -536,7 +581,7 @@ class Post extends Base { } // Default to Article. - $object_type = 'Article'; + $object_type = 'Note'; $post_format = 'standard'; if ( \get_theme_support( 'post-formats' ) ) { @@ -547,18 +592,12 @@ class Post extends Base { switch ( $post_type ) { case 'post': switch ( $post_format ) { - case 'aside': - case 'status': - case 'quote': - case 'note': - case 'gallery': - case 'image': - case 'video': - case 'audio': - $object_type = 'Note'; + case 'standard': + case '': + $object_type = 'Article'; break; default: - $object_type = 'Article'; + $object_type = 'Note'; break; } break; @@ -566,7 +605,7 @@ class Post extends Base { $object_type = 'Page'; break; default: - $object_type = 'Article'; + $object_type = 'Note'; break; } @@ -593,6 +632,16 @@ class Post extends Base { return $cc; } + + public function get_audience() { + if ( is_single_user() ) { + return null; + } else { + $blog = new Blog(); + return $blog->get_id(); + } + } + /** * Returns a list of Tags, used in the Post. * @@ -708,6 +757,8 @@ class Post extends Base { */ do_action( 'activitypub_before_get_content', $post ); + add_filter( 'render_block_core/embed', array( self::class, 'revert_embed_links' ), 10, 2 ); + // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited $post = $this->wp_object; $content = $this->get_post_content_template(); @@ -792,4 +843,21 @@ class Post extends Base { */ return apply_filters( 'activitypub_post_locale', $lang, $post_id, $this->wp_object ); } + + /** + * Transform Embed blocks to block level link. + * + * Remote servers will simply drop iframe elements, rendering incomplete content. + * + * @see https://www.w3.org/TR/activitypub/#security-sanitizing-content + * @see https://www.w3.org/wiki/ActivityPub/Primer/HTML + * + * @param string $block_content The block content (html) + * @param object $block The block object + * + * @return string A block level link + */ + public static function revert_embed_links( $block_content, $block ) { + return '

' . $block['attrs']['url'] . '

'; + } } diff --git a/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php b/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php index 8fe2c3f5..65a78ddf 100644 --- a/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php +++ b/wp-content/plugins/activitypub/integration/class-enable-mastodon-apps.php @@ -28,10 +28,12 @@ class Enable_Mastodon_Apps { public static function init() { \add_filter( 'mastodon_api_account_followers', array( self::class, 'api_account_followers' ), 10, 2 ); \add_filter( 'mastodon_api_account', array( self::class, 'api_account_add_followers' ), 20, 2 ); - \add_filter( 'mastodon_api_account', array( self::class, 'api_account_external' ), 10, 2 ); + \add_filter( 'mastodon_api_account', array( self::class, 'api_account_external' ), 15, 2 ); \add_filter( 'mastodon_api_search', array( self::class, 'api_search' ), 40, 2 ); + \add_filter( 'mastodon_api_search', array( self::class, 'api_search_by_url' ), 40, 2 ); \add_filter( 'mastodon_api_get_posts_query_args', array( self::class, 'api_get_posts_query_args' ) ); \add_filter( 'mastodon_api_statuses', array( self::class, 'api_statuses_external' ), 10, 2 ); + \add_filter( 'mastodon_api_status_context', array( self::class, 'api_get_replies' ), 10, 23 ); } /** @@ -102,11 +104,11 @@ class Enable_Mastodon_Apps { * @return Enable_Mastodon_Apps\Entity\Account The filtered Account */ public static function api_account_add_followers( $account, $user_id ) { - if ( ! $account instanceof Account || ! is_numeric( $user_id ) ) { + if ( ! $account instanceof Account ) { return $account; } - $user = Users::get_by_id( $user_id ); + $user = Users::get_by_various( $user_id ); if ( ! $user || is_wp_error( $user ) ) { return $account; @@ -130,7 +132,7 @@ class Enable_Mastodon_Apps { $account->acct = $user->get_preferred_username(); $account->note = $user->get_summary(); - $account->followers_count = Followers::count_followers( $user_id ); + $account->followers_count = Followers::count_followers( $user->get__id() ); return $account; } @@ -143,7 +145,7 @@ class Enable_Mastodon_Apps { * @return Enable_Mastodon_Apps\Entity\Account The filtered Account */ public static function api_account_external( $user_data, $user_id ) { - if ( $user_data || is_numeric( $user_id ) ) { + if ( $user_data || ( is_numeric( $user_id ) && $user_id ) ) { // Only augment. return $user_data; } @@ -201,12 +203,38 @@ class Enable_Mastodon_Apps { $account->header = $data['image']['url']; $account->header_static = $data['image']['url']; } - + if ( ! isset( $data['published'] ) ) { + $data['published'] = 'now'; + } $account->created_at = new DateTime( $data['published'] ); return $account; } + public static function api_search_by_url( $search_data, $request ) { + $p = \wp_parse_url( $request->get_param( 'q' ) ); + if ( ! $p || ! isset( $p['host'] ) ) { + return $search_data; + } + + $object = Http::get_remote_object( $request->get_param( 'q' ), true ); + if ( is_wp_error( $object ) || ! isset( $object['attributedTo'] ) ) { + return $search_data; + } + + $account = self::get_account_for_actor( $object['attributedTo'] ); + if ( ! $account ) { + return $search_data; + } + + $status = self::activity_to_status( $object, $account ); + if ( $status ) { + $search_data['statuses'][] = $status; + } + + return $search_data; + } + public static function api_search( $search_data, $request ) { $user_id = \get_current_user_id(); if ( ! $user_id ) { @@ -254,7 +282,7 @@ class Enable_Mastodon_Apps { return $search_data; } - public function api_get_posts_query_args( $args ) { + public static function api_get_posts_query_args( $args ) { if ( isset( $args['author'] ) && is_string( $args['author'] ) ) { $uri = Webfinger_Util::resolve( $args['author'] ); if ( $uri && ! is_wp_error( $uri ) ) { @@ -266,6 +294,78 @@ class Enable_Mastodon_Apps { return $args; } + private static function activity_to_status( $item, $account ) { + if ( isset( $item['object'] ) ) { + $object = $item['object']; + } else { + $object = $item; + } + + if ( ! isset( $object['type'] ) || 'Note' !== $object['type'] ) { + return null; + } + + $status = new Status(); + $status->id = $object['id']; + $status->created_at = new DateTime( $object['published'] ); + $status->content = $object['content']; + $status->account = $account; + + if ( ! empty( $object['inReplyTo'] ) ) { + $status->in_reply_to_id = $object['inReplyTo']; + } + + if ( ! empty( $object['visibility'] ) ) { + $status->visibility = $object['visibility']; + } + if ( ! empty( $object['url'] ) ) { + $status->url = $object['url']; + $status->uri = $object['url']; + } else { + $status->uri = $object['id']; + } + + if ( ! empty( $object['attachment'] ) ) { + $status->media_attachments = array_map( + function ( $attachment ) { + $default_attachment = array( + 'url' => null, + 'mediaType' => null, + 'name' => null, + 'width' => 0, + 'height' => 0, + 'blurhash' => null, + ); + + $attachment = array_merge( $default_attachment, $attachment ); + + $media_attachment = new Media_Attachment(); + $media_attachment->id = $attachment['url']; + $media_attachment->type = strtok( $attachment['mediaType'], '/' ); + $media_attachment->url = $attachment['url']; + $media_attachment->preview_url = $attachment['url']; + $media_attachment->description = $attachment['name']; + if ( $attachment['blurhash'] ) { + $media_attachment->blurhash = $attachment['blurhash']; + } + if ( $attachment['width'] > 0 && $attachment['height'] > 0 ) { + $media_attachment->meta = array( + 'original' => array( + 'width' => $attachment['width'], + 'height' => $attachment['height'], + 'size' => $attachment['width'] . 'x' . $attachment['height'], + 'aspect' => $attachment['width'] / $attachment['height'], + ), + );} + return $media_attachment; + }, + $object['attachment'] + ); + } + + return $status; + } + public static function api_statuses_external( $statuses, $args ) { if ( ! isset( $args['activitypub'] ) ) { return $statuses; @@ -277,13 +377,8 @@ class Enable_Mastodon_Apps { return $statuses; } - $response = Http::get( $data['outbox'], true ); - if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { - return $statuses; - } - - $outbox = json_decode( wp_remote_retrieve_body( $response ), true ); - if ( ! $outbox || is_wp_error( $outbox ) || ! isset( $outbox['first'] ) ) { + $outbox = Http::get_remote_object( $data['outbox'], true ); + if ( is_wp_error( $outbox ) || ! isset( $outbox['first'] ) ) { return $statuses; } @@ -291,76 +386,77 @@ class Enable_Mastodon_Apps { if ( ! $account ) { return $statuses; } - - $response = Http::get( $outbox['first'], true ); - if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { - return $statuses; + $limit = 10; + if ( isset( $args['posts_per_page'] ) ) { + $limit = $args['posts_per_page']; } - $posts = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( $limit > 40 ) { + $limit = 40; + } + $activitypub_statuses = array(); + $url = $outbox['first']; + $tries = 0; + while ( $url ) { + if ( ++$tries > 3 ) { + break; + } - $activitypub_statuses = array_map( - function ( $item ) use ( $account ) { - $object = $item['object']; - if ( ! isset( $object['type'] ) || 'Note' !== $object['type'] ) { - return null; - } + $posts = Http::get_remote_object( $url, true ); + if ( is_wp_error( $posts ) ) { + return $statuses; + } - $status = new Status(); - $status->id = Mastodon_API::remap_url( $object['id'] ); - $status->created_at = new DateTime( $object['published'] ); - $status->content = $object['content']; - $status->account = $account; + $new_statuses = array_map( + function ( $item ) use ( $account, $args ) { + if ( $args['exclude_replies'] ) { + if ( isset( $item['object']['inReplyTo'] ) && $item['object']['inReplyTo'] ) { + return null; + } + } + return self::activity_to_status( $item, $account ); + }, + $posts['orderedItems'] + ); + $activitypub_statuses = array_merge( $activitypub_statuses, array_filter( $new_statuses ) ); + $url = $posts['next']; - if ( ! empty( $object['inReplyTo'] ) ) { - $status->in_reply_to_id = $object['inReplyTo']; - } + if ( count( $activitypub_statuses ) >= $limit ) { + break; + } + } - if ( ! empty( $object['visibility'] ) ) { - $status->visibility = $object['visibility']; - } + return array_slice( $activitypub_statuses, 0, $limit ); + } - $status->uri = $object['url']; + public static function api_get_replies( $context, $post_id, $url ) { + $meta = Http::get_remote_object( $url, true ); + if ( is_wp_error( $meta ) || ! isset( $meta['replies']['first']['next'] ) ) { + return $context; + } - if ( ! empty( $object['attachment'] ) ) { - $status->media_attachments = array_map( - function ( $attachment ) { - $default_attachment = array( - 'url' => null, - 'mediaType' => null, - 'name' => null, - 'width' => 0, - 'height' => 0, - 'blurhash' => null, - ); + $replies_url = $meta['replies']['first']['next']; + $replies = Http::get_remote_object( $replies_url, true ); + if ( is_wp_error( $replies ) || ! isset( $replies['items'] ) ) { + return $context; + } - $attachment = array_merge( $default_attachment, $attachment ); + foreach ( $replies['items'] as $url ) { + $response = Http::get( $url, true ); + if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) { + continue; + } + $status = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( ! $status || is_wp_error( $status ) ) { + continue; + } - $media_attachment = new Media_Attachment(); - $media_attachment->id = Mastodon_API::remap_url( $attachment['url'], $attachment ); - $media_attachment->type = strtok( $attachment['mediaType'], '/' ); - $media_attachment->url = $attachment['url']; - $media_attachment->preview_url = $attachment['url']; - $media_attachment->description = $attachment['name']; - $media_attachment->blurhash = $attachment['blurhash']; - $media_attachment->meta = array( - 'original' => array( - 'width' => $attachment['width'], - 'height' => $attachment['height'], - 'size' => $attachment['width'] . 'x' . $attachment['height'], - 'aspect' => $attachment['width'] / $attachment['height'], - ), - ); - return $media_attachment; - }, - $object['attachment'] - ); - } + $account = self::get_account_for_actor( $status['attributedTo'] ); + $status = self::activity_to_status( $status, $account ); + if ( $status ) { + $context['descendants'][ $status->id ] = $status; + } + } - return $status; - }, - $posts['orderedItems'] - ); - - return $activitypub_statuses; + return $context; } } diff --git a/wp-content/plugins/activitypub/integration/class-jetpack.php b/wp-content/plugins/activitypub/integration/class-jetpack.php new file mode 100644 index 00000000..009811e9 --- /dev/null +++ b/wp-content/plugins/activitypub/integration/class-jetpack.php @@ -0,0 +1,21 @@ + \Activitypub\get_context() ), $object->to_object()->to_array() ); - -// filter output -$json = \apply_filters( 'activitypub_json_comment_array', $json ); +if ( \is_wp_error( $transformer ) ) { + \wp_die( + \esc_html( $transformer->get_error_message() ), + 404 + ); +} /* * Action triggerd prior to the ActivityPub profile being created and sent to the client */ \do_action( 'activitypub_json_comment_pre' ); -$options = 0; -// JSON_PRETTY_PRINT added in PHP 5.4 -if ( \get_query_var( 'pretty' ) ) { - $options |= \JSON_PRETTY_PRINT; // phpcs:ignore -} - -$options |= \JSON_HEX_TAG | \JSON_HEX_AMP | \JSON_HEX_QUOT; - -/* - * Options to be passed to json_encode() - * - * @param int $options The current options flags - */ -$options = \apply_filters( 'activitypub_json_comment_options', $options ); - \header( 'Content-Type: application/activity+json' ); -echo \wp_json_encode( $json, $options ); +echo $transformer->to_object()->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /* * Action triggerd after the ActivityPub profile has been created and sent to the client */ -\do_action( 'activitypub_json_comment_comment' ); +\do_action( 'activitypub_json_comment_post' ); diff --git a/wp-content/plugins/activitypub/templates/post-json.php b/wp-content/plugins/activitypub/templates/post-json.php index f90a1bca..a89a7c01 100644 --- a/wp-content/plugins/activitypub/templates/post-json.php +++ b/wp-content/plugins/activitypub/templates/post-json.php @@ -1,8 +1,15 @@ get_error_message() ), + 404 + ); +} -$post_object = \Activitypub\Transformer\Factory::get_transformer( $post )->to_object(); /* * Action triggerd prior to the ActivityPub profile being created and sent to the client @@ -10,7 +17,7 @@ $post_object = \Activitypub\Transformer\Factory::get_transformer( $post )->to_ob \do_action( 'activitypub_json_post_pre' ); \header( 'Content-Type: application/activity+json' ); -echo $post_object->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped +echo $transformer->to_object()->to_json(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped /* * Action triggerd after the ActivityPub profile has been created and sent to the client diff --git a/wp-content/plugins/activitypub/templates/settings.php b/wp-content/plugins/activitypub/templates/settings.php index 071aa1bd..a00a551f 100644 --- a/wp-content/plugins/activitypub/templates/settings.php +++ b/wp-content/plugins/activitypub/templates/settings.php @@ -52,7 +52,7 @@

diff --git a/wp-content/plugins/activitypub/templates/welcome.php b/wp-content/plugins/activitypub/templates/welcome.php index a2663286..e5e9440e 100644 --- a/wp-content/plugins/activitypub/templates/welcome.php +++ b/wp-content/plugins/activitypub/templates/welcome.php @@ -19,7 +19,7 @@