<remark>Accepted by vote of Council on 2022-04-13.</remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2022-03-30</date>
<initials>jp</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1topic='Introduction'anchor='intro'>
<p>&xep0060; as its name states has a mechanism to subscribe to a node. Only the owner of the node can retrieve the list of subscribers</p>
<p>It may be interesting for users to share publicly the nodes they have subscribed to, or who is subscribed to theirs: it's a quick way to discover center of interest of a user, or to discover new accounts/nodes related to a specific center of interest. This kind of feature is common in modern social networks and often named "following" and "followers". This XEP proposes a solution to implement this feature in XMPP while respecting privacy of users.</p>
<p>There is currently a XEP partially covering this problem with &xep0330;. This XEP has the advantage to be usable with a generic Pubsub service, but it has 2 flaws:</p>
<ul>
<li>it's only covering half of the problem: we get the pubsub nodes to which an entity is subscribed, but we don't know who is subscribed to a node</li>
<li>clients need to keep the 'urn:xmpp:pubsub:subscription' node synchronized with subscriptions: if a subscription is removed from a node, it may stay present by mistake in 'urn:xmpp:pubsub:subscription' node.</li>
</ul>
<p>This XEP fixes both issues.</p>
</section1>
<section1topic='Requirements'anchor='reqs'>
<p>The design goal of this XEP are:</p>
<ul>
<li>let a user discover to which node an other user is publicly subscribed</li>
<li>let a user discover who is publicly subscribed to a node</li>
<li>take care of privacy: a user must declare a subscription public on purpose</li>
<li>keep public subscription synchronized with nodes subscriptions</li>
</ul>
<p>This XEP uses &xep0376; as only way to subscribe to a node and unsubscribe from a node, as it is necessary to keep track of subscriptions.</p>
</section1>
<section1topic='Glossary'anchor='glossary'>
<p>In this documentation, <strong>PAM service</strong> refers to a PEP service implementing &xep0376;.</p>
<p>Romeo wants to subscribe to the blog of his cousin Benvolio and he wants to make it public, so other peoples can discover Benvolio blog more easily.</p>
<p>He does that as usual by sending a subscription request as explained in <linkurl="https://xmpp.org/extensions/xep-0376.html#subs">XEP-0376 §Subscribing</link> but he adds a <public> element with the 'urn:xmpp:pps:0' namespace:</p>
<examplecaption="Romeo Makes a Public Subscription to Benvolio Blog"><![CDATA[
<p>Romeo also wants to follow the blog of this girl that he met at the ball, however, he doesn't want yet to make it public for political reasons. He then does the subscription as usual and <strong>does not</strong> include the <public> element:</p>
<examplecaption="Romeo Makes a Non Public Subscription to Juliet Blog"><![CDATA[
<section2topic="Retrieving Public Subscriptions"anchor="retrieving_subs">
<p>Mercutio is a friend of Romeo and he wants to know which nodes Romeo is subscribed to, as it may be a way to discover new and interesting peoples. To do this, Romeo's PAM service manages a special node named 'urn:xmpp:pps:subscriptions:0'. This node is created and managed by the PAM service itself, it can be subscribed to and unsubscribed from as an usual PubSub node, and it contains an item for each public subscription that has been made by node owner (Romeo in our example). Each items payload is a <subscription> element with the 'urn:xmpp:pps:0' namespace containing a 'node' attribute with the name of the subscribed node, and a 'jid' attribute with the JID of the pubsub service containing the subscribed node.</p>
<p>The node owner can't add or retract items directly on the node: if Romeo wants to add or public subscription, it does this by doing a public subscription as explained in <linkurl="public_subscription">Public Subscription</link>, and if he wants to retract a public subscription, he can do as explained in the <linkurl="#retracting_public_subs">next section</link>. &xep0059; and &xep0442; apply normally if they are implemented.</p>
<examplecaption="Mercutio Get Public Subscriptions of Romeo"><![CDATA[
<iqtype='get'
from='mercutio@escalus.lit/play.456'
to='romeo@montague.lit'
id='get_pub_sub1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<itemsnode='urn:xmpp:pps:subscriptions:0'/>
</pubsub>
</iq>
]]></example>
<examplecaption="Romeo's PAM Service Replies With Public Subscriptions"><![CDATA[
<section2topic="Retracting Public Subscriptions"anchor="retracting_public_subs">
<p>Romeo can retract a public subscription in 2 ways:</p>
<ul>
<li>by unsubscribing entirely from the node as explained in <linkurl="https://xmpp.org/extensions/xep-0376.html#unsub">XEP-0376 §Unsubscribing</link>. In this case the PAM service remove the node from public subscriptions (it won't appear anymore if somebody <linkurl="#retrieving_subs">retrieves subscriptions</link>) and unsubscribe from the node.</li>
<li>by subscribing again to the node <strong>without</strong> the <public> element, as explained in <linkurl="XEP-0376 §Subscribing">https://xmpp.org/extensions/xep-0376.html#subs</link>. In this case the PAM service remove the node from public subscriptions, and forward the request to the pubsub service (so the pubsub service also knows that the subscription is not public anymore).</li>
</ul>
</section2>
<section2topic="Retrieving Public Subscribers to a node"anchor="retrieving_public_subscribers">
<p>If Mercutio wants to know who is publicly subscribing to Romeo's blog, he request the PAM Service by using a special node managed by the service in a similar way as 'urn:xmpp:pps:0' node from <linkurl="retrieving_subs">Retrieving Public Subscriptions section</link> (i.e. a node which can be subscribed to normally, but whose items can't be publised or retracted directly). This node is named by prefixing the name of the target node with 'urn:xmpp:pps:subscribers:0/'. So to check who is subscribed to Romeo's blog, Mercutio must request 'urn:xmpp:pps:subscribers:0/urn:xmpp:microblog:0' node. The service will answer with items whose payload is a <subscriber> element with the 'urn:xmpp:pps:0' namespace, and a 'jid' attribute whose value is the JID of the public subscriber:</p>
<examplecaption="Mercutio Get Public Subscribers of Romeo's blog"><![CDATA[
<p><strong>note:</strong>Public subscribers is not restricted to PAM service, if a generic pubsub service implements this XEP, it MUST also returns the public subscribers when the special node is requested.</p>
</section2>
</section1>
<section1topic='Business Rules'anchor='rules'>
<p>If a user wants to create, purge or delete a special node used in this XEP, or if they want to manually publish or retract items, the service MUST return a &forbidden; error to the user.</p>
<p>If a PEP or Pubsub service supports the "Pubsub Public Subscriptions" protocol, it must advertize it by including the "urn:xmpp:pps:0" discovery feature &NSNOTE; in response to a &xep0030; information request:</p>
<examplecaption="service discovery information request"><![CDATA[
<p>Publishing publicly subscriptions of a user has pricacy implications: those public subscriptions may be used by someone to get a user interests or to know they network of contacts.</p>
<p>It may be used by bad actors for many reasons like advertising, or it may even be life threating in some countries/situation as it may be used to known political opinion, religion, sexual orientation, etc. A client SHOULD make the subscription public only if there is no doubt that this is what the user wants, by using an opt-in system, and SHOULD display a well visible warning about the consequences of making a subscription public.</p>
<p>By having subscription public, an entity JID can be checked or harvested by doing a request on the public subscriptions node. A client SHOULD display a warning clearly indicating that making subscriptions public makes its JID discoverable.</p>
<p>For the same reason, a server SHOULD respond identically to a pubsub request to public subscriptions node if the user doesn't exist or if they exist but they don't have any public subscriptions.</p>