<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
  <!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
  <!ENTITY tos "Terms of Service">
  <!ENTITY pp "Privacy Policy">
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
  <title>Terms of Services</title>
  <abstract>This specification provides an in-band, unauthenticated way to request the Terms of Service of an XMPP service.</abstract>
  &LEGALNOTICE;
  <number>xxxx</number>
  <status>ProtoXEP</status>
  <type>Standards Track</type>
  <sig>Standards</sig>
  <approver>Council</approver>
  <dependencies>
    <spec>XMPP Core</spec>
    <spec>XEP-0004</spec>
    <spec>XEP-0030</spec>
    <spec>XEP-0050</spec>
    <spec>XEP-0082</spec>
  </dependencies>
  <supersedes/>
  <supersededby/>
  <shortname>TOS</shortname>
  &jonaswielicki;
  <revision>
    <version>0.0.1</version>
    <date>2018-05-22</date>
    <initials>jwi</initials>
    <remark><p>First draft.</p></remark>
  </revision>
</header>
<section1 topic='Introduction' anchor='intro'>
  <p>The XMPP ecosystem has no way to allow clients to display or refer the user to the &tos; and &pp; of any given server.</p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
  <p>The specification shall allow to satisfy the following requirements:</p>
  <ol>
    <li>Provide a way to query a URL to a text version of the &tos; and &pp; of a service.</li>
    <li>Provide an extensible way to convey key points of the &tos; and &pp; in a machine-readable format in-band.</li>
    <li>Allow to query all information before authentication.</li>
    <li>It should be possible to achieve the same effect with a client supporting &xep0050; and a web browser.</li>
  </ol>
</section1>
<section1 topic='Glossary' anchor='glossary'>
  <p>OPTIONAL.</p>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
  <section2 topic='Announcing support' anchor='usecase-announce'>
    <p>A server which supports the &tos; protocol announces support via both stream features and &xep0030;.</p>
    <example caption='Stream feature which indicates support'><![CDATA[
<stream:features>
  ...
  <tos xmlns='urn:xmpp:tos:0'/>
</stream:features>
]]></example>
    <example caption='XEP-0030 disco#info feature to indicate support'><![CDATA[
<iq type='result'
    from='service.example'
    to='requester@service.example'
    id='req1'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='urn:xmpp:tos:0'/>
    ...
  </query>
</iq>
]]></example>
  </section2>
  <section2 topic='Interact with Terms of Service' anchor='usecase-interaction'>
    <p>The interaction with the Terms of Service is handled using &xep0050;.</p>
    <p>To request the current Terms of Service and Opt-ins/Opt-outs, the client starts an Ad-Hoc command session with the 'urn:xmpp:tos:0' node at its server:</p>
    <example caption='Client initiates Ad-Hoc Command session'><![CDATA[
<iq type='set'
    from='requester@service.example'
    to='service.example'
    id='cmd1'
    xml:lang='en'>
  <command xmlns='http://jabber.org/protocol/commands'
           node='urn:xmpp:tos:0'
           action='execute'>
    <tos-support xmlns='urn:xmpp:tos:0'/>
  </command>
</iq>
]]></example>
    <p>The client MUST include a &lt;tos-support/&gt; child in the initial request to inform the server that it fully supports the protocol. A server MAY reject the Ad-Hoc command from a client which does not fully support the protocol if the form would likely not render correctly or completely. In that case, a &lt;not-acceptable/&gt; type='cancel' error MUST be returned.</p>
    <p>The server SHOULD use the value of xml:lang at the &lt;command/&gt; element to determine the language of returned texts.</p>
    <p>If the server allows the request, it starts the command session and returns the payload:</p>
    <example caption='Server returns Terms of Service payload'><![CDATA[
<iq type='result'
    to='requester@service.example'
    from='service.example'
    id='cmd1'
    xml:lang='en'>
  <command xmlns='http://jabber.org/protocol/commands'
           node='urn:xmpp:tos:0'
           sessionid='dlW81nadFUAS7VSWOOJ4e1J1'
           status='executing'>
    <actions execute='complete'>
      <complete/>
    </actions>
    <x xmlns='jabber:iq:data'>
      <field var='FORM_TYPE' type='hidden'>
        <value>urn:xmpp:tos:0</value>
      </field>
      <field var='urn:xmpp:tos:0#version' type='hidden'>
        <value>0.1.0</value>
      </field>
      <field var='urn:xmpp:tos:0#documents-header' type='fixed'>
        <value>Terms of Use</value>
      </field>
      <field var='urn:xmpp:tos:0#documents' type='text-multi'>
        <desc>
          The Terms of Use for this service are defined by the following
          documents. Please read them carefully.
        </desc>
        <value>https://service.example/tos</value>
        <value>https://service.example/privacy</value>
      </field>
      <field type='fixed'>
        <value>Opt-ins</value>
      </field>
      <field var='https://service.example/privacy' type='boolean'>
        <required/>
        <desc>
          I have read and understood the Privacy Policy document
          linked above.
        </desc>
        <value>false</value>
      </field>
      <field var='https://service.example/privacy#12.3-marketing' type='boolean'>
        <required/>
        <desc>
          I allow analysis of my messages under Art. 9.1a for marketing
          purposes (see Privacy Policy ยง12.3).
        </desc>
        <value>false</value>
      </field>
    </x>
    <tos xmlns='urn:xmpp:tos:0' version='0.1.0'>
      <document>
        <title>Terms of Service</title>
        <source url='https://service.example/tos' type='text/html' />
        <source url='https://service.example/tos.txt' type='text/plain' />
      </document>
      <document>
        <title>Privacy Policy</title>
        <source url='https://service.example/privacy' type='text/html' />
        <source url='https://service.example/privacy.txt' type='text/plain' />
      </document>
      <required-flags>
        <required-flag var='https://service.example/privacy'/>
      </required-flags>
    </tos>
  </command>
</iq>
]]></example>
    <p>The command payload consists of two parts: The data form for legacy clients and additional opt-ins/opt-outs, and the machine-readable &tos; data. The machine-readable &tos; data is carried by a &lt;tos/&gt; element.</p>
    <p>The &lt;tos/&gt; element has the following format:</p>
    <dl>
      <di><dt>version attribute</dt><dd>(exactly once) carries the opaque version identifier of the terms.</dd></di>
      <di><dt>&lt;document/&gt; element</dt><dd>(at least once) carries one of the possibly multiple documents which comprise the full terms of use (see below for details).</dd></di>
      <di><dt>&lt;required-flags/&gt; element</dt><dd>(at most once) carries a set of data form field var values which the user has to accept (set to true) in order to use the service.</dd></di>
    </dl>
    <p>In the future, more children may be added to the &lt;tos/&gt; element. Conforming clients thus MUST ignore all children they do not understand.</p>
    <p>The &lt;document/&gt; element has the following format:</p>
    <dl>
      <di><dt>&lt;title/&gt; element</dt><dd>(at most once) a human-readable title of the document in the language requested by the client.</dd></di>
      <di><dt>&lt;source/&gt; element</dt><dd>(at least once) a pair of url and MIME type. The same URL may be given multiple times with different MIME types. Duplicate MIME types MUST NOT occur.</dd></di>
    </dl>
    <p>The &lt;required-flags/&gt; element contains zero or more &lt;required-flag/&gt; elements. The &lt;required-flag/&gt; elements have a var attribute which refers to one of the fields in the data form. Note that this is semantically different from &lt;require/&gt; in the data form (see &xep0004;)</p>
    <p>The data form has the FORM_TYPE 'urn:xmpp:tos:0'. The fields 'urn:xmpp:tos:0#version' and 'urn:xmpp:tos:0#documents' are mandatory. If the value of the 'urn:xmpp:tos:0#version' data form field and the version attribute of the &lt;tos/&gt; element differ, the response is invalid.</p>
    <p>The data form MAY contain arbitrary fields after the 'urn:xmpp:tos:0#documents' field.</p>
    <p>A client supporting the &tos; protocol should remove the fields prefixed with 'urn:xmpp:tos:0#' from the form when displaying the form and use a richer representation obtained from the &lt;tos/&gt; element for the same data.</p>
    <p>The 'urn:xmpp:tos:0#documents' MUST contain exactly one URL from each &lt;document/&gt; advertised in the &lt;tos/&gt; element. It is used to inform users of legacy clients of the terms.</p>
    <p>The server MAY include &lt;instruction/&gt; and &lt;title/&gt; elements in the data form.</p>
    <p>Once the user has filled out the form, the client submits it to the server:</p>
    <example caption='Client submits filled-out form'><![CDATA[
<iq type='set'
    to='service.example'
    from='requester@service.example'
    id='cmd2'
    xml:lang='en'>
  <command xmlns='http://jabber.org/protocol/commands'
           node='urn:xmpp:tos:0'
           sessionid='dlW81nadFUAS7VSWOOJ4e1J1'
           action='complete'>
    <x xmlns='jabber:iq:data'>
      <field var='FORM_TYPE' type='hidden'>
        <value>urn:xmpp:tos:0</value>
      </field>
      <field var='urn:xmpp:tos:0#version' type='hidden'>
        <value>0.1.0</value>
      </field>
      <field var='urn:xmpp:tos:0#documents-header' type='fixed'>
        <value>Terms of Use</value>
      </field>
      <field var='urn:xmpp:tos:0#documents' type='text-multi'>
        <value>https://service.example/tos</value>
        <value>https://service.example/privacy</value>
      </field>
      <field type='fixed'>
        <value>Opt-ins</value>
      </field>
      <field var='https://service.example/privacy' type='boolean'>
        <value>true</value>
      </field>
      <field var='https://service.example/privacy#12.3-marketing' type='boolean'>
        <value>false</value>
      </field>
    </x>
  </command>
</iq>
]]></example>
    <p>The client does not include the &lt;tos/&gt; element in its response.</p>
    <p>The server acknowledges the reception as usual:</p>
    <example caption='Server acknowledges submission'><![CDATA[
<iq type='result'
    to='requester@service.example'
    from='service.example'
    id='cmd2'
    xml:lang='en'>
  <command xmlns='http://jabber.org/protocol/commands'
           node='urn:xmpp:tos:0'
           sessionid='dlW81nadFUAS7VSWOOJ4e1J1'
           status='completed'>
    <note type='info'>The privacy settings have been updated.</note>
  </command>
</iq>
]]></example>
    <section3 topic='Error cases' anchor='usecase-interaction-errors'>
      <section4 topic='Protocol support required' anchor='usecase-interaction-error-support-required'>
        <p>If the client did not include a &lt;tos-support/&gt; element in the initiating request and the server requires support for the &tos; protocol, it replies with an error:</p>
        <example caption='Server requests request because of lack of protocol support'><![CDATA[
<iq type='error'
    from='service.example'
    to='requester@service.example'
    id='cmd1'>
  <error type='cancel'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>
      Your client does not support the Terms of Service protocol.
      Please review the Terms of Service online at
      https://service.example/tos.
    </text>
  </error>
</iq>
]]></example>
        <p>The server SHOULD include a human readable error text which MAY include a URL to a website where the user can agree to the terms and manage the opt-ins/opt-outs.</p>
      </section4>
      <section4 topic='Required opt-ins not selected' anchor='usecase-interaction-error-required-flag-unset'>
        <p>If the user did not opt in into options required by the service, the service returns the original data to the client and adds an error note to the command:</p>
        <example caption='Server rejects submission because required options have not been selected'><![CDATA[
<iq type='result'
    to='requester@service.example'
    from='service.example'
    id='cmd2'
    xml:lang='en'>
  <command xmlns='http://jabber.org/protocol/commands'
           node='urn:xmpp:tos:0'
           sessionid='dlW81nadFUAS7VSWOOJ4e1J1'
           status='executing'>
    <note type='error'>
      You have to confirm that you read and
      understood the Privacy Policy document below.
    </note>
    <actions execute='complete'>
      <complete/>
    </actions>
    <x xmlns='jabber:iq:data'>
      <field var='FORM_TYPE' type='hidden'>
        <value>urn:xmpp:tos:0</value>
      </field>
      <field var='urn:xmpp:tos:0#version' type='hidden'>
        <value>0.1.0</value>
      </field>
      <field var='urn:xmpp:tos:0#documents-header' type='fixed'>
        <value>Terms of Use</value>
      </field>
      <field var='urn:xmpp:tos:0#documents' type='text-multi'>
        <desc>
          The Terms of Use for this service are defined by the following
          documents. Please read them carefully.
        </desc>
        <value>https://service.example/tos</value>
        <value>https://service.example/privacy</value>
      </field>
      ...
    </x>
    <tos xmlns='urn:xmpp:tos:0' version='0.1.0'>
      <document>
        <title>Terms of Service</title>
        <source url='https://service.example/tos' type='text/html' />
        <source url='https://service.example/tos.txt' type='text/plain' />
      </document>
      ...
    </tos>
  </command>
</iq>
]]></example>
      </section4>
    </section3>
  </section2>
  <section2 topic='Notify entity about new policies' anchor='usecase-notify'>
    <p>If a server updates its &tos;, it may inform its users with a notification. For this, a 'headline' &lt;message/&gt; is used:</p>
    <example caption='Server notifies user about policy update'><![CDATA[
<message type='headline'
         from='service.example'
         to='user@service.example'>
  <body>
    We have updated our Terms of Service. Please refer to the current
    version at https://service.example/tos. You have to review and agree to
    the new version by the 25th of May 2018 to continue to use the service.
  </body>
  <tos-push xmlns='urn:xmpp:tos:0'>
    <tos xmlns='urn:xmpp:tos:0' version='0.2.0'>
      <document>
        <title>Terms of Service</title>
        <source url='https://service.example/tos-0.2.0' type='text/html' />
        <source url='https://service.example/tos-0.2.0.txt' type='text/plain' />
      </document>
      <document>
        <title>Privacy Policy</title>
        <source url='https://service.example/privacy-0.2.0'
                type='text/html' />
        <source url='https://service.example/privacy-0.2.0.txt'
                type='text/plain' />
      </document>
    </tos>
    <deadline>2018-05-25T00:00:00Z</deadline>
  </tos-push>
</iq>]]></example>
    <p>The &lt;body/&gt; is included for clients not supporting the protocol. The user can then review the Terms of Service by themselves. In addition to the &lt;body/&gt;, a &lt;tos-push/&gt; element which contains the &lt;tos/&gt; element of the new terms and an optional &lt;deadline/&gt; element.</p>
    <p>The &lt;deadline/&gt; element includes a &xep0082; DateTime value which indicates at which point in time the user must have agreed to the new &tos; to be allowed to continue to use the service.</p>
  </section2>
  <section2 topic='Inform client about Terms of Service expiry after authentication' anchor='usecase-expired'>
    <p>If a user does not agree to an update of the &tos;, a service may lock down the account. In this case, authentication is handled as normal. In the post-authentication stream features, the server then MUST include a &lt;tos/&gt; element with a &lt;agreement-required/&gt; child:</p>
    <example caption='Stream feature which indicates requirement to agree'><![CDATA[
<stream:features>
  ...
  <tos xmlns='urn:xmpp:tos:0'>
    <agreement-required/>
  </tos>
</stream:features>
]]></example>
    <p>If the &lt;agreement-required/&gt; element is included in the &lt;tos/&gt; stream feature, the client must first agree to the &tos; as described in <link url='#usecase-interaction'>Interact with Terms of Service</link>.</p>
    <section3 topic='Reject bind attempt before agreement' anchor='usecase-expired-reject-bind'>
      <p>If a client attempts to bind a resource before agreeing to the &tos;, the server rejects the request with a &lt;policy-violation/&gt; type 'cancel' error including an application defined condition of &lt;agreement-required&gt; in the namespace of this protocol.</p>
      <p>A human readable error MUST be included for legacy clients. The human readable version SHOULD contain a URL to a web page where the user can agree to the &tos; without client support.</p>
      <example caption='Server rejects attempt to bind to a resource'><![CDATA[
<iq type='error'
    id='bind'>
  <error type='cancel'>
    <policy-violation xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>
      You need to agree to the current version of the Terms of
      Service before continuing.
      </text>
    <agreement-required xmlns='urn:xmpp:tos:0'/>
  </error>
</iq>]]></example>
    </section3>
  </section2>
</section1>
<section1 topic='Business Rules' anchor='rules'>
  <ul>
    <li>A server which supports the protocol MUST announce support via both stream features and &xep0030; as described in <link url='#usecase-announce'>Announcing support</link>.</li>
    <li>The version of the &tos; document as transferred in-band SHOULD NOT be shown to users and MUST be treated as opaque by entities. The version can be used to detect if a version of the document has already been seen by the user and skip displaying it in this case.</li>
    <li>The version identifiers generated by servers MUST NOT be longer than 128 characters.</li>
    <li>The version identifiers generated by servers MUST be unique for the domain of the server.</li>
    <li>Entities MUST NOT compare two version numbers obtained from two different entities.</li>
    <li>Servers MAY store notifications about &tos; changes in the users server-side archive.</li>
    <li>Servers MAY re-send notifications about &tos; changes on each login of a client.</li>
    <li>Servers SHOULD NOT both re-send notifications about &tos; changes on login and store them in the archive.</li>
    <li>Servers MAY re-send notifications about &tos; changes periodically, but SHOULD NOT re-send them more often than once per day.</li>
  </ul>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
  <ul>
    <li>Implementations MUST ignore unknown children of the &lt;tos/&gt; element.</li>
  </ul>
</section1>
<section1 topic='Accessibility Considerations' anchor='access'>
  <p>OPTIONAL.</p>
</section1>
<section1 topic='Internationalization Considerations' anchor='i18n'>
  <p>The service SHOULD honor the xml:lang value of the &xep0050; &lt;command/&gt; in the initial request and choose its translations according to that.</p>
  <p>When pushing a notification about a terms of service update, the service SHOULD use the stream-level xml:lang attribute to determine the locale used for the announcement.</p>
</section1>
<section1 topic='Security Considerations' anchor='security'>
  <p>This specification allows another type of interaction before authentication. Server implementations MUST ensure that this protocol cannot be abused for pre-authentication attacks (e.g. Denial of Service).</p>
  <p>Servers MUST NOT allow entities to query the &tos; of another server unless they are authenticated.</p>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
  <p>REQUIRED.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
  <p>REQUIRED.</p>
</section1>
<section1 topic='XML Schema' anchor='schema'>
  <p>REQUIRED for protocol specifications.</p>
</section1>
</xep>