1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-28 04:02:20 -05:00
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1771 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2008-04-18 16:25:28 +00:00
parent 51fdf8c40b
commit 10aca1a268

View File

@ -10,7 +10,7 @@
<abstract>This document defines mechanisms and preferences for the archiving and retrieval of XMPP messages.</abstract> <abstract>This document defines mechanisms and preferences for the archiving and retrieval of XMPP messages.</abstract>
&LEGALNOTICE; &LEGALNOTICE;
<number>0136</number> <number>0136</number>
<status>Experimental</status> <status>Proposed</status>
<type>Standards Track</type> <type>Standards Track</type>
<sig>Standards</sig> <sig>Standards</sig>
<dependencies> <dependencies>
@ -34,6 +34,12 @@
</author> </author>
&stpeter; &stpeter;
&infiniti; &infiniti;
<revision>
<version>0.16</version>
<date>2008-04-15</date>
<initials>psa</initials>
<remark><p>Addressed last call comments; clarified syntax of the pref and chat elements; deferred definition of data forms for attribute association to future specifications; removed registration of field standardization fields.</p></remark>
</revision>
<revision> <revision>
<version>0.15</version> <version>0.15</version>
<date>2008-03-03</date> <date>2008-03-03</date>
@ -130,8 +136,8 @@
<p>Many XMPP clients implement some form of client-side message archiving. However, it is not always convenient or even possible to archive messages locally, e.g., because it is easier to keep all archives in one universally accessible place (not scattered around on multiple computers or devices) or because the client operates in a web browser or resides on a mobile device that does not have sufficient local storage for message archiving. In addition, server-side archiving makes it possible to offer new services such as integration of instant messaging and email. Therefore it is beneficial to define methods for server-side archiving of XMPP messages.</p> <p>Many XMPP clients implement some form of client-side message archiving. However, it is not always convenient or even possible to archive messages locally, e.g., because it is easier to keep all archives in one universally accessible place (not scattered around on multiple computers or devices) or because the client operates in a web browser or resides on a mobile device that does not have sufficient local storage for message archiving. In addition, server-side archiving makes it possible to offer new services such as integration of instant messaging and email. Therefore it is beneficial to define methods for server-side archiving of XMPP messages.</p>
<p>There are two main approaches to this problem:</p> <p>There are two main approaches to this problem:</p>
<ol start='1'> <ol start='1'>
<li>Enable the client to send individual messages or entire conversations to the server for archiving (optionally after encryption); we call this MANUAL ARCHIVING.</li> <li>Enable the client to send individual messages or entire conversations to the server for archiving; we call this MANUAL ARCHIVING.</li>
<li>Enable the server (at the client's request) to archive messages as they pass through the server; we call this AUTOMATED ARCHIVING.</li> <li>Enable the server (at the user's request) to archive messages as they pass through the server; we call this AUTOMATED ARCHIVING.</li>
</ol> </ol>
<p>So that client and server developers can refer to one specification, both approaches are defined in this document. In addition, this document defines common methods for retrieving and managing archived messages.</p> <p>So that client and server developers can refer to one specification, both approaches are defined in this document. In addition, this document defines common methods for retrieving and managing archived messages.</p>
<p>Note: Complying with <strong>XMPP Core</strong>, the server MUST respond to all &IQ; element of type 'get' or 'set'. However, most successful responses have been omitted from this document in the interest of conciseness.</p> <p>Note: Complying with <strong>XMPP Core</strong>, the server MUST respond to all &IQ; element of type 'get' or 'set'. However, most successful responses have been omitted from this document in the interest of conciseness.</p>
@ -141,7 +147,7 @@
<section2 topic='Introduction' anchor='pref-reqs'> <section2 topic='Introduction' anchor='pref-reqs'>
<p>Not all users want to archive messages. A client SHOULD save its user's default archiving preference (or "Save Mode") to its own server (i.e., specify whether by default all conversations should be archived or not). In addition, a client MAY save different preferences for particular contacts.</p> <p>Not all users want to archive messages. A client SHOULD save its user's default archiving preference (or "Save Mode") to its own server (i.e., specify whether by default all conversations should be archived or not). In addition, a client MAY save different preferences for particular contacts.</p>
<p>Some users may also prefer that the messages they exchange with contacts are "<link url='#otr'>Off The Record</link>" (OTR). <note>The "OTR" mode for message archiving is not to be confused with the "OTR" technology for "off-the-record communications" described at &lt;<link url='http://www.cypherpunks.ca/otr/'>http://www.cypherpunks.ca/otr/</link>&gt;.</note> A client SHOULD save its user's default and contact-specific OTR preferences (or "OTR Modes") to its own server.</p> <p>Some users may also prefer that the messages they exchange with contacts are "<link url='#otr'>Off The Record</link>" (OTR). <note>The "OTR" mode for message archiving is not to be confused with the "OTR" technology for "off-the-record communications" described at &lt;<link url='http://www.cypherpunks.ca/otr/'>http://www.cypherpunks.ca/otr/</link>&gt;.</note> A client SHOULD save its user's default and contact-specific OTR preferences (or "OTR Modes") to its own server.</p>
<p>Whichever archiving method a client uses (e.g., local archiving to files or a database, or server-side archiving that happens either automatically or manually), it SHOULD adhere to its user's archiving preferences. However, a client MAY maintain a set of preferences in a local file which takes precedence over the preferences stored on the server for both local archiving and server-side archiving.</p> <p>Whichever archiving method a client uses (e.g., local archiving to files or a database, or server-side archiving that happens either automatically or manually), it SHOULD adhere to its user's archiving preferences as stored on the server. However, a client MAY maintain a set of preferences in a local file which takes precedence over the preferences stored on the server for both local archiving and server-side archiving.</p>
<p>This section addresses the following use cases:</p> <p>This section addresses the following use cases:</p>
<ol start='1'> <ol start='1'>
<li>A client determines its user's current default Save Mode and OTR Mode, and the Modes for particular contacts.</li> <li>A client determines its user's current default Save Mode and OTR Mode, and the Modes for particular contacts.</li>
@ -151,9 +157,30 @@
</section2> </section2>
<section2 topic='Preference Syntax' anchor='pref-syntax'> <section2 topic='Preference Syntax' anchor='pref-syntax'>
<p>Archiving preferences are encapsulated in four children of the &lt;pref/&gt; element: &lt;auto/&gt;, &lt;default/&gt;, &lt;item/&gt;, and &lt;method/&gt;. These are defined in the following sections.</p> <p>Archiving preferences are encapsulated in four children of the &lt;pref/&gt; element: &lt;auto/&gt;, &lt;default/&gt;, &lt;item/&gt;, and &lt;method/&gt;. These are defined in the following sections.</p>
<p>In order to capture a complete set of preferences, when the server returns the user's preferences to the client the &lt;pref/&gt; element:</p>
<ul>
<li>MUST include an &lt;auto/&gt; element that specifies whether automatic archiving is on or off.</li>
<li>MUST include a &lt;default/&gt; element that specifies the user's default settings for OTR Mode and Save Mode.</li>
<li>MAY include one or more &lt;item/&gt; elements that specify preferences related to particular contacts.</li>
<li>MUST include at least three &lt;method/&gt; elements, differentiated by the value of the 'type' attribute (i.e., at least one &lt;method/&gt; element each for "auto", "local", and "manual").</li>
</ul>
<p>An example follows.</p>
<example caption='Complete Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:tmp:archive'>
<auto save='false'/>
<default expire='31536000' otr='concede' save='body'/>
<item jid='romeo@montague.net' otr='require' save='false'/>
<item expire='630720000' jid='benvolio@montague.net' otr='forbid' save='message'/>
<method type='auto' use='forbid'/>
<method type='local' use='concede'/>
<method type='manual' use='prefer'/>
</pref>
</iq>
]]></example>
<section3 topic='Auto Element' anchor='pref-syntax-auto'> <section3 topic='Auto Element' anchor='pref-syntax-auto'>
<p>The &lt;auto/&gt; element specifies the current <link url='#auto'>Automated Archiving</link> settings for <em>this stream</em>.</p> <p>The &lt;auto/&gt; element specifies the current <link url='#auto'>Automatic Archiving</link> settings for <em>this stream</em>.</p>
<p>This element MUST be empty and MUST include a boolean 'save' attribute &BOOLEANNOTE; that specifies whether automated archiving is enabled or disabled for this stream.</p> <p>This element MUST be empty and MUST include a boolean 'save' attribute &BOOLEANNOTE; that specifies whether automatic archiving is enabled or disabled for this stream.</p>
</section3> </section3>
<section3 topic='Default Element' anchor='pref-syntax-default'> <section3 topic='Default Element' anchor='pref-syntax-default'>
<p>The &lt;default/&gt; element specifies the default settings for both OTR Mode and Save Mode. The element MUST be empty and MUST include an 'otr' attribute and a 'save' attribute. The element MAY include an 'expire' attribute.</p> <p>The &lt;default/&gt; element specifies the default settings for both OTR Mode and Save Mode. The element MUST be empty and MUST include an 'otr' attribute and a 'save' attribute. The element MAY include an 'expire' attribute.</p>
@ -217,7 +244,7 @@
</section4> </section4>
</section3> </section3>
<section3 topic='Method Element' anchor='pref-syntax-method'> <section3 topic='Method Element' anchor='pref-syntax-method'>
<p>Each &lt;method/&gt; element specifies the the user's preferences for one available archiving method. The &lt;method/&gt; element MUST be empty and MUST include both the 'type' and 'use' attributes. The &lt;pref/&gt; element MUST include at least three &lt;method/&gt; elements, differentiated by the value of the 'type' attribute.</p> <p>Each &lt;method/&gt; element specifies the the user's preferences for one available archiving method. The &lt;method/&gt; element MUST be empty and MUST include both the 'type' and 'use' attributes.</p>
<section4 topic='type Attribute' anchor='pref-syntax-method-type'> <section4 topic='type Attribute' anchor='pref-syntax-method-type'>
<p>The allowable values of the 'type' attribute are:</p> <p>The allowable values of the 'type' attribute are:</p>
<ul> <ul>
@ -247,13 +274,13 @@
<example caption='Server Returns Preferences'><![CDATA[ <example caption='Server Returns Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'> <iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
<default save='body' otr='concede' expire='31536000'/> <auto save='false'/>
<item jid='romeo@montague.net' save='false' otr='require'/> <default expire='31536000' otr='concede' save='body'/>
<item jid='benvolio@montague.net' save='message' expire='630720000' otr='forbid'/> <item jid='romeo@montague.net' otr='require' save='false'/>
<item expire='630720000' jid='benvolio@montague.net' otr='forbid' save='message'/>
<method type='auto' use='forbid'/> <method type='auto' use='forbid'/>
<method type='local' use='concede'/> <method type='local' use='concede'/>
<method type='manual' use='prefer'/> <method type='manual' use='prefer'/>
<auto save='false'/>
</pref> </pref>
</iq> </iq>
]]></example> ]]></example>
@ -270,7 +297,7 @@
<example caption='Server Returns Service Default Preferences'><![CDATA[ <example caption='Server Returns Service Default Preferences'><![CDATA[
<iq type='result' id='pref1' to='juliet@capulet.com/chamber'> <iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
<default save='false' otr='concede' unset='true'/> <default otr='concede' save='false' unset='true'/>
<method type='auto' use='concede'/> <method type='auto' use='concede'/>
<method type='local' use='concede'/> <method type='local' use='concede'/>
<method type='manual' use='concede'/> <method type='manual' use='concede'/>
@ -285,7 +312,7 @@
<example caption='Client Sets Default Modes'><![CDATA[ <example caption='Client Sets Default Modes'><![CDATA[
<iq type='set' id='pref2'> <iq type='set' id='pref2'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
<default save='false' otr='prefer'/> <default otr='prefer' save='false'/>
</pref> </pref>
</iq> </iq>
]]></example> ]]></example>
@ -297,21 +324,18 @@
<example caption='Server Pushes New Modes'><![CDATA[ <example caption='Server Pushes New Modes'><![CDATA[
<iq type='set' id='push1' to='juliet@capulet.com/chamber'> <iq type='set' id='push1' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
<default save='false' otr='prefer'/> <default otr='prefer' save='false'/>
</pref> </pref>
</iq> </iq>
<iq type='set' id='push2' to='juliet@capulet.com/pda'> <iq type='set' id='push2' to='juliet@capulet.com/pda'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
<default save='false' otr='prefer'/> <default otr='prefer' save='false'/>
</pref> </pref>
</iq> </iq>
]]></example> ]]></example>
<p>The server MAY be configured to return a &lt;feature-not-implemented/&gt; error in the following cases:</p> <p>If the server does not allow the saving of full message stanza content, the client set the value of the 'save' attribute to 'message' or 'stream', and any of the user's connected resources have <link url='#auto'>Automatic Archiving</link> enabled, then the server SHOULD return a &feature; error.</p>
<ul> <p>If administrator policies require that at least the &lt;body/&gt; elements (or the full content) of every message must be logged automatically and the client attempts to set the value of the 'save' attribute to 'false' or 'body', then the server SHOULD return a &notacceptable; error.</p>
<li><p>If it does not allow the saving of full message stanza content, and the client set the value of the 'save' attribute to 'message' or 'stream', and any of the user's connected resources have <link url='#auto'>Automated Archiving</link> enabled.</p></li>
<li><p>If administrator policies require that at least the &lt;body/&gt; elements (or the full content) of every message are logged automatically, and the client sets the value of the 'save' attribute to 'false' (or 'body').</p></li>
</ul>
</section2> </section2>
<section2 topic='Setting Modes for a Contact' anchor='pref-contact'> <section2 topic='Setting Modes for a Contact' anchor='pref-contact'>
<p>A client may use a similar protocol to set the Modes for a particular contact or domain of contacts (bare JID, full JID or domain). Note: It is STRONGLY RECOMMENDED for the value of the 'jid' attribute to be a bare JID &LOCALBARE; rather than a full JID &LOCALFULL;.</p> <p>A client may use a similar protocol to set the Modes for a particular contact or domain of contacts (bare JID, full JID or domain). Note: It is STRONGLY RECOMMENDED for the value of the 'jid' attribute to be a bare JID &LOCALBARE; rather than a full JID &LOCALFULL;.</p>
@ -352,6 +376,7 @@
]]></example> ]]></example>
</section2> </section2>
<section2 topic='Setting Archiving Method Preferences' anchor='pref-archive'> <section2 topic='Setting Archiving Method Preferences' anchor='pref-archive'>
<p>The client can set one or more method preferences by sending an IQ-set containing a &lt;pref/&gt; element that in turn contains one or more &lt;method/&gt; elements.</p>
<example caption='Client Sets Method Preferences'><![CDATA[ <example caption='Client Sets Method Preferences'><![CDATA[
<iq type='set' id='pref4'> <iq type='set' id='pref4'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
@ -364,6 +389,7 @@
<example caption='Server Acknowleges Change'><![CDATA[ <example caption='Server Acknowleges Change'><![CDATA[
<iq type='result' id='pref4' to='juliet@capulet.com/chamber'/> <iq type='result' id='pref4' to='juliet@capulet.com/chamber'/>
]]></example> ]]></example>
<p>If the client includes less than three &lt;method/&gt; elements, the server MUST NOT modify the unspecified methods and MUST leave them as currently stored on the server. However, when the server pushes the method preferences it MUST include all of the preferences, not only those that were set by the client.</p>
<example caption='Server Pushes New Method Preferences'><![CDATA[ <example caption='Server Pushes New Method Preferences'><![CDATA[
<iq type='set' id='push5' to='juliet@capulet.com/chamber'> <iq type='set' id='push5' to='juliet@capulet.com/chamber'>
<pref xmlns='urn:xmpp:tmp:archive'> <pref xmlns='urn:xmpp:tmp:archive'>
@ -388,9 +414,9 @@
<p>A user will sometimes exchange messages with contacts who prefer that their conversations are not archived by either party.</p> <p>A user will sometimes exchange messages with contacts who prefer that their conversations are not archived by either party.</p>
<section2 topic='OTR Negotiation' anchor='otr-nego'> <section2 topic='OTR Negotiation' anchor='otr-nego'>
<p>Any client that archives messages SHOULD support <cite>Stanza Session Negotiation</cite> and its 'logging' field both to give other contacts the opportunity to indicate this preference, and to negotiate an "Off The Record" (OTR) policy that complies with its user's own <link url='#pref'>Archiving Preferences</link>.</p> <p>Any client that archives messages SHOULD support <cite>Stanza Session Negotiation</cite> and its 'logging' field both to give other contacts the opportunity to indicate this preference, and to negotiate an "Off The Record" (OTR) policy that complies with its user's own <link url='#pref'>Archiving Preferences</link>.</p>
<p>Note: A client MUST NOT propose or agree to enable OTR (i.e., disallow message logging) unless it has confirmed that its server will allow it to switch off <link url='#auto'>Automated Archiving</link>.</p> <p>Note: A client MUST NOT propose or agree to enable OTR (i.e., disallow message logging) unless it has confirmed that its server will allow it to switch off <link url='#auto'>Automatic Archiving</link>. The client can do so based on the rules in the <link url='#auto'>Automatic Archiving</link> section of this document. If the client logs in and does not receive a warning message, it can assume that automatic archiving is not on by default. If the client does receive a warning message because automatic archiving is on by default, the client can determine if auto-archiving can be turned off by trying to do so; if the client receives an error, it knows that automatic archiving cannot be turned off.</p>
<p>Both parties to a stanza session negotiation may have OTR preferences (i.e, the initiating party or "user" and the responding party or "contact"). These preferences will interact in the ways specified below, resulting either in a successful negotiation or an unsuccessful negotiation (naturally, an unsuccessful negotiation can lead to a subsequent negotiation attempt by the user or the contact).</p> <p>Both parties to a stanza session negotiation may have OTR preferences (i.e, the initiating party or "user" and the responding party or "contact"). These preferences will interact in the ways specified below, resulting either in a successful negotiation or an unsuccessful negotiation (naturally, an unsuccessful negotiation can lead to a subsequent negotiation attempt by the user or the contact).</p>
<p>The following table shows what stanza session negotiation values the initating party (i.e., the "user") should send for the 'logging' field in the initial data form for a stanza session negotiation (note: 'may' means that the receiving party MAY enable message logging and 'mustnot' means that the receiving party MUST NOT enable logging).</p> <p>The following table shows how to instantiate the user's OTR preference in a stanza session negotiation (SSN) offer. The various OTR preferences map to particular values of the SSN 'logging' field, including the order of values for that field. In particular, an SSN logging value of 'may' means that the receiving party MAY enable message logging and an SSN logging value of 'mustnot' means that the receiving party MUST NOT enable message logging.</p>
<table caption='Stanza Session Negotiation logging options offered by initiating party (user)'> <table caption='Stanza Session Negotiation logging options offered by initiating party (user)'>
<tr> <tr>
<th>User's OTR Preference</th> <th>User's OTR Preference</th>
@ -487,40 +513,56 @@
<p>If a user's OTR preference for a contact changes during a Chat Session that has been negotiated with the contact, and if the new preference would affect the value of the 'logging' field that was previously negotiated, then the client MUST immediately renegotiate the 'logging' field according to the user's new OTR preference (or terminate the Chat Session).</p> <p>If a user's OTR preference for a contact changes during a Chat Session that has been negotiated with the contact, and if the new preference would affect the value of the 'logging' field that was previously negotiated, then the client MUST immediately renegotiate the 'logging' field according to the user's new OTR preference (or terminate the Chat Session).</p>
</section2> </section2>
<section2 topic='Notes' anchor='otr-notes'> <section2 topic='Notes' anchor='otr-notes'>
<p>If a Stanza Session Negotiation agreed to enable OTR then the clients MUST NOT allow messages sent in <em>either</em> direction to be archived in any way (including <link url='#manual'>Manual Archiving</link> and <link url='#auto'>Automated Archiving</link>). <note>If a client (or user) acts in bad faith then its contacts cannot prevent it from archiving conversations.</note></p> <p>If a Stanza Session Negotiation agreed to enable OTR then the clients MUST NOT allow messages sent in <em>either</em> direction to be archived in any way (including <link url='#manual'>Manual Archiving</link> and <link url='#auto'>Automatic Archiving</link>). <note>If a client (or user) acts in bad faith then its contacts cannot prevent it from archiving conversations.</note></p>
<p>If a Stanza Session Negotiation agreed to enable OTR then both clients MUST ensure that the Stanza Session Negotiation messages themselves are not archived. For example, if <link url='#auto'>Automated Archiving</link> was enabled when the client received the initial Stanza Session Negotiation request, then the client MUST immediately ask its server to delete its copy of the request (see <link url='#manage-remove'>Removing a Collection</link> for a description of how to remove the messages currently being recorded by the server).</p> <p>If a Stanza Session Negotiation agreed to enable OTR then both clients MUST ensure that the Stanza Session Negotiation messages themselves are not archived. For example, if <link url='#auto'>Automatic Archiving</link> was enabled when the client received the initial Stanza Session Negotiation request, then the client MUST immediately ask its server to delete its copy of the request (see <link url='#manage-remove'>Removing a Collection</link> for a description of how to remove the messages currently being recorded by the server).</p>
</section2>
</section1>
<section1 topic='Collections: The Chat Element' anchor='collections'>
<p>Whether manual archiving or automatic archiving is used, messages are archived in the form of "collections. A collection is a set of messages to/from the same user that are received near each other in time or as part of the same conversation thread. A collection is intended to mimic the natural flow of human conversations, which in instant messaging (IM) systems tend to occur in bursts (e.g., a five-minute conversation one day, followed by a ten-minute conversation the next).</p>
<p>Each collection of messages and notes is encapsulated in a &lt;chat/&gt; element and is uniquely identified by the combination of the 'start' and 'with' attributes as defined below. The syntax of the &lt;chat/&gt; element is specified in this section.</p>
<section2 topic='start Attribute' anchor='collections-start'>
<p>The 'start' attribute specifies the start time of the conversation thread, which MUST be UTC and adhere to the DateTime format specified in &xep0082;.</p>
</section2>
<section2 topic='subject Attribute' anchor='collections-subject'>
<p>The 'subject' attribute specifies a friendly name for the collection (note the <link url='#security-subject'>Security Considerations</link> regarding the subject attribute). Inclusion of the 'subject' attribute is OPTIONAL.</p>
</section2>
<section2 topic='thread Attribute' anchor='collections-thread'>
<p>A client SHOULD include a thread ID in each &MESSAGE; element it sends that is part of a conversation it expects will be archived (as explained in &xep0201;, a thread ID is captured in the &THREAD; child of the &MESSAGE; element).</p>
<p>If the messages contained in a conversation contain a thread ID, then the server MUST map that thread ID to the 'thread' attribute of the &lt;chat/&gt; element. There MUST be a one-to-one mapping between the &THREAD; element and the 'thread' attribute.</p>
<p>If a thread ID is not included, the server may use its own implementation-specific methods for mapping messages and conversations to collections.</p>
<p>The content of &MESSAGE; elements that have different thread IDs SHOULD be archived in separate collections and the content of &MESSAGE; elements that have the same thread IDs SHOULD be archived in the same collection; this is the responsibility of the client if manual archiving is used and the responsibility of the server if automatic archiving is used. The thread attribute SHOULD NOT be set to any value other than the exact content of the &THREAD; elements. If no &THREAD; elements appeared in the conversation then the &lt;chat/&gt; element SHOULD have no thread attribute. Implementations SHOULD use the thread attribute for cross-referencing purposes only, within the archive each collection MUST be uniquely identified by the combination of its 'with' and 'start' attributes.</p>
<p>Inclusion of the 'thread' attribute is RECOMMENDED.</p>
</section2>
<section2 topic='version Attribute' anchor='collections-version'>
<p>Upon receiving a manually-uploaded collection or creating a collection as a result of auto-archiving, the server MUST assign a version number to the collection, which MUST start at zero (0). Whenever the collection is modified, the server MUST increment the version number by one (1). The server MUST include the version number attribute whenever it sends the collection or information about the collection to the client, by including a 'version' attribute in the &lt;chat/&gt;, &lt;changed/&gt;, or &lt;removed/&gt; element. If the client includes a 'version' attribute in an IQ-set, the server MUST ignore it.</p>
<p>Inclusion of the 'version' attribute is REQUIRED of servers.</p>
</section2>
<section2 topic='with Attribute' anchor='collections-with'>
<p>The 'with' attribute specifies the JID with which the messages were exchanged. If the JID is of the form &LOCALBARE;, any resource matches; if the JID is of the form &DOMAINBARE;, any node matches. If the client or server wishes to match an exact bare JID, the boolean 'exactmatch' attribute MUST be included and MUST be set yo "true" or "0" &BOOLEANNOTE;.</p>
<p>Inclusion of the 'with' attributwe is REQUIRED.</p>
</section2>
<section2 topic='from and to Elements' anchor='collections-fromto'>
<p>The content of each individual message MUST be encapsulated in a &lt;to/&gt; or &lt;from/&gt; element. The time in whole seconds of the message relative to the previous message in the collection (or, for the first message, relative to the start of the collection) SHOULD be specified with a 'secs' attribute. Note: When deciding whether to round up or down to a number of whole seconds, entities MUST ensure that the sum of the 'secs' attribute and the 'secs' attributes of the preceeding messages will accurately reflect the absolute time of the message. (e.g., if a sequence of messages occur at exactly 0.51-second intervals then the 'secs' attributes should generally alternate between '0' or '1'.)</p>
<p>The content of each &lt;to/&gt; or &lt;from/&gt; element SHOULD depend on the user's <link url='#pref'>Archiving Preferences</link>. &lt;to/&gt; or &lt;from/&gt; elements MUST NOT be empty. Note: A server MAY be configured to return a &lt;feature-not-implemented/&gt; error if any &lt;to/&gt; or &lt;from/&gt; element contains anything other than &BODY; elements.</p>
</section2>
<section2 topic='note Element' anchor='collections-note'>
<p>The &lt;note/&gt; element specifies a private note about the conversation. The absolute time the note was created SHOULD be specified with a 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>XEP-0082</cite>). Inclusion of the &lt;note/&gt; element is OPTIONAL.</p>
</section2> </section2>
</section1> </section1>
<section1 topic='Manual Archiving' anchor='manual'> <section1 topic='Manual Archiving' anchor='manual'>
<section2 topic='Introduction' anchor='manual-intro'> <section2 topic='Introduction' anchor='manual-intro'>
<p>While automated archiving is easy for the client and server to implement, there are many contexts in which manual archiving is required. For examples, when:</p> <p>While automatic archiving is easy for the client and server to implement, there are many contexts in which manual archiving is required. For examples, when:</p>
<ul> <ul>
<li>Messages are encrypted using evanescent keys, as in &xep0116;</li> <li>Messages are encrypted using evanescent keys, as in &xep0116;</li>
<li>A client's own server does not support automated archiving but it (or another server) does support manual archiving</li> <li>A client's own server does not support automatic archiving but it (or another server) does support manual archiving</li>
<li>A server does not support encryption of auto-archived collections</li> <li>A server does not support encryption of auto-archived collections</li>
<li>A client wants to maintain a unified archive for messages that were transmitted both in and out-of-band (e.g. SMS or email)</li> <li>A client wants to maintain a unified archive for messages that were transmitted both in and out-of-band (e.g. SMS or email)</li>
<li>A client wants to append private notes to a conversation</li> <li>A client wants to append private notes to a conversation</li>
</ul> </ul>
<p>Therefore, often a client will want to send or receive a sequence of messages, optionally add private notes to the sequence, optionally encrypt the sequence, and then ask the server to archive it. Such messages and notes SHOULD be stored on the server in the form of a "collection".</p> <p>Therefore, often a client will want to send or receive a sequence of messages, optionally add private notes to the sequence, optionally encrypt the sequence, and then ask the server to archive it. Such messages and notes SHOULD be stored on the server in the form of a "collection".</p>
</section2> </section2>
<section2 topic='Collections' anchor='manual-collection'>
<p>A "collection" is a set of messages to/from the same user that are received near each other in time or as part of the same conversation thread. A collection is intended to mimic the natural flow of human conversations, which in instant messaging (IM) systems tend to occur in bursts (e.g., a five-minute conversation one day, followed by a ten-minute conversation the next).</p>
<p>Each collection of messages and notes is encapsulated in a &lt;chat/&gt; element.</p>
<p>The client uniquely specifies a collection using a pair of attributes:</p>
<ul>
<li>'with' (the full JID with which the messages were exchanged)</li>
<li>'start' (the UTC start time of the conversation thread, which MUST be UTC and adhere to the DateTime format specified in &xep0082;)</li>
</ul>
<p>A friendly name for the collection MAY be specified with a 'subject' attribute. Note the <link url='#security-subject'>Security Considerations</link> regarding the subject attribute.</p>
<p>If an opaque thread ID (found in the &THREAD; children of the &MESSAGE; elements whose content is stored in the collection) is associated with the conversation then it MUST be specified with a 'thread' attribute. Clients SHOULD include a &THREAD; child in each &MESSAGE; element they send that is part of a conversation they expect will be archived (see &xep0201;).</p>
<p>Upon receiving a manually-uploaded collection or creating a collection as a result of auto-archiving, the server MUST assign a version number to the collection, which MUST start at zero (0). Whenever the collection is modified, the server MUST increment the version number by one (1). The server MUST include the version number attribute whenever it sends the collection or information about the collection to the client, by including a 'version' attribute in the &lt;chat/&gt;, &lt;changed/&gt;, or &lt;removed/&gt; element. If the client includes a 'version' attribute in an IQ-set, the server MUST ignore it.</p>
<p>Note: The content of &MESSAGE; elements that have different thread IDs SHOULD be archived in separate collections. The content of &MESSAGE; elements that have the same thread IDs SHOULD be archived in the same collection. The thread attribute SHOULD NOT be set to any value other than the exact content of the &THREAD; elements. If no &THREAD; elements appeared in the conversation the &lt;chat/&gt; element SHOULD have no thread attribute. Implementations SHOULD use the thread attribute for cross-referencing purposes only, within the archive each collection MUST be uniquely identified by the combination of its 'with' and 'start' attributes.</p>
<p>Each collection MAY contain &lt;note/&gt;, &lt;to/&gt; or &lt;from/&gt; elements (or &lt;EncryptedData/&gt; and &lt;EncryptedKey/&gt; elements - see the <link url='#crypt'>Encryption</link> section of this document).</p>
<p>The text of each individual private note MUST be encapsulated in a &lt;note/&gt; element. The absolute time the note was created SHOULD be specified with a 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>XEP-0082</cite>).</p>
<p>The content of each individual message MUST be encapsulated in a &lt;to/&gt; or &lt;from/&gt; element. The time in whole seconds of the message relative to the previous message in the collection (or, for the first message, relative to the start of the collection) SHOULD be specified with a 'secs' attribute. Note: When deciding whether to round up or down to a number of whole seconds, entities MUST ensure that the sum of the 'secs' attribute and the 'secs' attributes of the preceeding messages will accurately reflect the absolute time of the message. (e.g., if a sequence of messages occur at exactly 0.51-second intervals then the 'secs' attributes should generally alternate between '0' or '1'.)</p>
<p>The content of each &lt;to/&gt; or &lt;from/&gt; element SHOULD depend on the user's <link url='#pref'>Archiving Preferences</link>. &lt;to/&gt; or &lt;from/&gt; elements MUST NOT be empty. Note: A server MAY be configured to return a &lt;feature-not-implemented/&gt; error if any &lt;to/&gt; or &lt;from/&gt; element contains anything other than &BODY; elements.</p>
</section2>
<section2 topic='Uploading Messages to a Collection' anchor='manual-upload'> <section2 topic='Uploading Messages to a Collection' anchor='manual-upload'>
<p>A collection of messages and notes is uploaded to the server encapsulated in a &lt;save/&gt; element.</p> <p>A collection of messages and notes is uploaded to the server encapsulated in a &lt;save/&gt; element.</p>
<example caption='Storing messages in a collection'><![CDATA[ <example caption='Storing messages in a collection'><![CDATA[
@ -551,7 +593,7 @@
</save> </save>
</iq> </iq>
]]></example> ]]></example>
<p>If the collection already exists then the server MUST append the messages to the existing collection.</p> <p>If the collection already exists then the server MUST append the messages to the existing collection (which MAY involve adding messages that appear to be duplicates, i.e., messages that have identical &lt;from/&gt; elements, &lt;to/&gt; elements, and dateTimes).</p>
<example caption='Messages appended to collection'><![CDATA[ <example caption='Messages appended to collection'><![CDATA[
<iq type='result' id='up1'> <iq type='result' id='up1'>
<save xmlns='urn:xmpp:tmp:archive'> <save xmlns='urn:xmpp:tmp:archive'>
@ -585,7 +627,7 @@
</save> </save>
</iq> </iq>
]]></example> ]]></example>
<example caption='Collection created'><![CDATA[ <example caption='Collection subject updated'><![CDATA[
<iq type='result' id='subject1'> <iq type='result' id='subject1'>
<save xmlns='urn:xmpp:tmp:archive'> <save xmlns='urn:xmpp:tmp:archive'>
<chat with='juliet@capulet.com/chamber' <chat with='juliet@capulet.com/chamber'
@ -598,7 +640,7 @@
]]></example> ]]></example>
</section2> </section2>
<section2 topic='Offline Messages' anchor='impl-offline'> <section2 topic='Offline Messages' anchor='impl-offline'>
<p>The client MAY specify an absolute time for any message by providing a longer 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>XEP-0082</cite>) instead of a 'secs' attribute. The absolute time MAY be earlier than the start time of the collection:</p> <p>The client MAY specify an absolute time for any message by providing a 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in <cite>XEP-0082</cite>) instead of a 'secs' attribute. The absolute time MAY be earlier than the start time of the collection:</p>
<example caption='Storing offline messages in a collection'><![CDATA[ <example caption='Storing offline messages in a collection'><![CDATA[
<iq type='set' id='up2'> <iq type='set' id='up2'>
<save xmlns='urn:xmpp:tmp:archive'> <save xmlns='urn:xmpp:tmp:archive'>
@ -614,7 +656,7 @@
]]></example> ]]></example>
</section2> </section2>
<section2 topic='Groupchat Messages' anchor='impl-muc'> <section2 topic='Groupchat Messages' anchor='impl-muc'>
<p>A client MAY archive messages that it receives from &xep0045; rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each &lt;from/&gt; element to specify the room nickname (and, if available, bare JID) of the message sender:</p> <p>A client MAY archive messages that it receives from &xep0045; rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each &lt;from/&gt; element to specify the room nickname of the message sender and MAY include a 'jid' attribute to specify the full or bare JID of the sender (if available).</p>
<example caption='Storing groupchat messages in a collection'><![CDATA[ <example caption='Storing groupchat messages in a collection'><![CDATA[
<iq type='set' id='up3'> <iq type='set' id='up3'>
<save xmlns='urn:xmpp:tmp:archive'> <save xmlns='urn:xmpp:tmp:archive'>
@ -673,19 +715,20 @@
<section2 topic='Associating Attributes with a Collection' anchor='impl-form'> <section2 topic='Associating Attributes with a Collection' anchor='impl-form'>
<p>A client MAY append attributes to a collection by including an x:data form of type 'submit' (see &xep0004;) when it uploads to a collection.</p> <p>A client MAY append attributes to a collection by including an x:data form of type 'submit' (see &xep0004;) when it uploads to a collection.</p>
<p>A collection MUST NOT contain more than one x:data form. If a form is uploaded to a collection that already contains one then the older form element MUST be discarded. When a collection is retrieved (see <link url='#manage-retrieve'>Retrieving a Collection</link>) the x:data form MUST appear as the first element in the collection after any &lt;previous/&gt; or &lt;next/&gt; elements, whatever order it was uploaded in. Upon retrieval the 'type' attribute of the form MAY be 'submit' or 'form'.</p> <p>A collection MUST NOT contain more than one x:data form. If a form is uploaded to a collection that already contains one then the older form element MUST be discarded. When a collection is retrieved (see <link url='#manage-retrieve'>Retrieving a Collection</link>) the x:data form MUST appear as the first element in the collection after any &lt;previous/&gt; or &lt;next/&gt; elements, whatever order it was uploaded in. Upon retrieval the 'type' attribute of the form MAY be 'submit' or 'form'.</p>
<p>Any data forms for associating attributes are application-specific and are to be defined outside this specification. The following example shows attributes generated by a fictional application.</p>
<example caption='Private chat with attributes form'><![CDATA[ <example caption='Private chat with attributes form'><![CDATA[
<iq type='set' id='form1'> <iq type='set' id='form1'>
<save xmlns='urn:xmpp:tmp:archive'> <save xmlns='urn:xmpp:tmp:archive'>
<chat with='benvolio@capulet.com' <chat with='benvolio@capulet.com'
start='1469-07-21T03:01:54Z'> start='1469-07-21T03:01:54Z'>
<to secs='0'><body>O, I am fortune's fool!</body></to>
<from secs='4'><body>Why dost thou stay?</body></from>
<x xmlns='jabber:x:data' type='submit'> <x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'><value>urn:xmpp:tmp:archive</value></field> <field var='FORM_TYPE'><value>http://example.com/archiving</value></field>
<field var='task'><value>1</value></field> <field var='task'><value>1</value></field>
<field var='important'><value>1</value></field> <field var='important'><value>1</value></field>
<field var='action_before'><value>1469-07-29T12:00:00Z</value></field> <field var='action_before'><value>1469-07-29T12:00:00Z</value></field>
</x> </x>
<to secs='0'><body>O, I am fortune's fool!</body></to>
<from secs='4'><body>Why dost thou stay?</body></from>
</chat> </chat>
</save> </save>
</iq> </iq>
@ -694,42 +737,76 @@
</section2> </section2>
</section1> </section1>
<section1 topic='Automated Archiving' anchor='auto'> <section1 topic='Automatic Archiving' anchor='auto'>
<section2 topic='Toggling Auto-Archiving' anchor='auto-toggle'> <p>If server administration policies <em>require</em> that every message is logged automatically (see <link url='#security'>Security Considerations</link>) then:</p>
<p>If server administration policies <em>require</em> that every message is logged automatically (see <link url='#security'>Security Considerations</link>) then:</p> <ul>
<ul> <li>The server MUST enable automatic archiving when each stream is opened.</li>
<li>The server MUST enable automatic archiving when each stream is opened.</li> <li>Clients MUST NOT be allowed to disable automatic archiving.</li>
<li>Clients MUST NOT be allowed to disable automatic archiving.</li> <li>If the server has not received a request from a client for its user's archiving preferences (see <link url='#pref-determine'>Determining Preferences</link>) within a few seconds of authenticating the client then the server MUST send a warning message to the client:</li>
<li>Automatic archiving MUST NOT be subject to users' <link url='#pref'>Archiving Preferences</link>.</li> </ul>
<li>If the server has not received a request from a client for its user's archiving preferences (see <link url='#pref-determine'>Determining Preferences</link>) within a few seconds of authenticating the client then the server MUST send a warning message to the client:</li> <example caption='Server warns user of a legacy client about compulsory archiving'><![CDATA[
</ul> <message from='capulet.com' to='juliet@capulet.com/chamber'>
<example caption='Server warns user of a legacy client about compulsory archiving'><![CDATA[
<message to='juliet@capulet.com/chamber'>
<body>WARNING: All messages that you send or <body>WARNING: All messages that you send or
receive will be recorded by the server.</body> receive will be recorded by the server.</body>
</message> </message>
]]></example> ]]></example>
<p>Otherwise:</p> <p>Otherwise:</p>
<ul> <ul>
<li>Automatic archiving MUST default to disabled when each stream is opened.</li> <li>Automatic archiving MUST default to disabled when each stream is opened.</li>
<li>A client MAY enable or disable automatic archiving for messages sent over its stream at any time. Note: If the client switches off all auto-archiving then the server MUST close and archive all active collections.</li> <li>A client MAY enable or disable automatic archiving for messages sent over its stream at any time. Note: If the client switches off all auto-archiving then the server MUST close and archive all active collections.</li>
<li>Once automatic archiving is switched on then the server MUST automatically archive messages only according to the user's <link url='#pref'>Archiving Preferences</link>.</li> <li>Once automatic archiving is switched on then the server MUST automatically archive messages only according to the user's <link url='#pref'>Archiving Preferences</link>.</li>
<li>Note: Both parties to an ESession (see &xep0116;) SHOULD either disable archiving or use an archiving method other than automatic, since ESession decryption keys are short-lived - making it impossible to decrypt automatically archived messages.</li> <li>Note: Both parties to an ESession (see &xep0116;) SHOULD either disable archiving or use an archiving method other than automatic, since ESession decryption keys are short-lived -- making it impossible to decrypt automatically archived messages.</li>
</ul> </ul>
<example caption='Client enables auto archiving'><![CDATA[ <p>The client can enable auto-archiving by setting the 'save' attribute to "true" or "1".</p>
<example caption='Client enables auto archiving'><![CDATA[
<iq type='set' id='auto1'> <iq type='set' id='auto1'>
<auto save='true' xmlns='urn:xmpp:tmp:archive'/> <auto save='true' xmlns='urn:xmpp:tmp:archive'/>
</iq> </iq>
]]></example> ]]></example>
</section2> <p>If the server does not support the saving of full message stanza or stream content and the user has specified the 'message' or 'stream' Save Mode in one of its <link url='#pref'>Archiving Preferences</link>, the server MUST return a &feature; error.</p>
<section2 topic='Not-Implemented Responses' anchor='auto-notimpl'> <example caption='Server Does Not Support Full Message or Stream Content'><![CDATA[
<p>The server MUST return a &lt;feature-not-implemented/&gt; error in the following cases:</p> <iq type='error' id='auto1'>
<ul> <error type='cancel'>
<li><p>If the client is trying to enable automatic archiving, but the server does not allow the saving of full message stanza content, and the user has specified the 'message' Save Mode in one of its <link url='#pref'>Archiving Preferences</link>.</p></li> <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<li><p>If administrator policies require that every message is logged automatically, and the client is trying to disable automatic archiving.</p></li> </error>
<li><p>If the client is trying to enable encryption, but the server does not support encryption or the user did not specify a public key and is not publishing any keys using <cite>XEP-0189</cite>.</p></li> </iq>
</ul> ]]></example>
</section2> <p>The client can enable auto-archiving with server-side encryption by setting the 'save' attribute to "true" or "1" and setting the 'encrypt' attribute to "true" or "1".</p>
<example caption='Client enables auto archiving with encryption'><![CDATA[
<iq type='set' id='auto2'>
<auto encrypt='true' save='true' xmlns='urn:xmpp:tmp:archive'/>
</iq>
]]></example>
<p>If the server does not support encryption but the client attempts to enable encryption, the server MUST return a &feature; error.</p>
<example caption='Server Does Not Support Encrypted Messages'><![CDATA[
<iq type='error' id='auto2'>
<error type='cancel'>
<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>If the server supports encryption but there is no public key available for the user (e.g., as published via &xep0189;, the server MUST return a &notacceptable; error.</p>
<example caption='No Public Key Available'><![CDATA[
<iq type='error' id='auto2'>
<error type='modify'>
<not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
<p>The client can disable auto-archiving by setting the 'save' attribute to "false" or "0".</p>
<example caption='Client disables auto archiving'><![CDATA[
<iq type='set' id='auto3'>
<auto save='false' xmlns='urn:xmpp:tmp:archive'/>
</iq>
]]></example>
<p>If service policies require that every message is logged automatically, the server MUST return a &notallowed; error.</p>
<example caption='Automatic Archiving is Compulsory'><![CDATA[
<iq type='error' id='auto3'>
<error type='cancel'>
<not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
]]></example>
</section1> </section1>
<section1 topic='Archive Management' anchor='manage'> <section1 topic='Archive Management' anchor='manage'>
@ -873,7 +950,7 @@
<p>Refer to <cite>Result Set Management</cite> to learn more about the various ways that the pages of a collection may be accessed.</p> <p>Refer to <cite>Result Set Management</cite> to learn more about the various ways that the pages of a collection may be accessed.</p>
</section2> </section2>
<section2 topic='Removing a Collection' anchor='manage-remove'> <section2 topic='Removing a Collection' anchor='manage-remove'>
<p>To request the removal of a single collection the client sends an empty &lt;remove/&gt; element. The 'with' (full JID) and 'start' attributes MUST be included to uniquely identify the collection.</p> <p>To request the removal of a single collection the client sends an empty &lt;remove/&gt; element. The 'with' and 'start' attributes MUST be included to uniquely identify the collection.</p>
<example caption='Removing a single collection'><![CDATA[ <example caption='Removing a single collection'><![CDATA[
<iq type='set' id='remove1'> <iq type='set' id='remove1'>
<remove xmlns='urn:xmpp:tmp:archive' <remove xmlns='urn:xmpp:tmp:archive'
@ -891,7 +968,7 @@
</iq> </iq>
]]></example> ]]></example>
<p>If the 'with' attribute is omitted then collections with any JID are removed.</p> <p>If the 'with' attribute is omitted then collections with any JID are removed.</p>
<p>If the end date is in the future then then all collections on or after the start date are removed.</p> <p>If the end date is in the future then all collections on or after the start date are removed.</p>
<example caption='Removing all collections after a date'><![CDATA[ <example caption='Removing all collections after a date'><![CDATA[
<iq type='set' id='remove3'> <iq type='set' id='remove3'>
<remove xmlns='urn:xmpp:tmp:archive' <remove xmlns='urn:xmpp:tmp:archive'
@ -912,7 +989,7 @@
<remove xmlns='urn:xmpp:tmp:archive'/> <remove xmlns='urn:xmpp:tmp:archive'/>
</iq> </iq>
]]></example> ]]></example>
<p>If the value of the optional 'open' attribute is set to 'true' then only collections that are currently being recorded automatically by the server (see <link url='#auto'>Automated Archiving</link>) are removed.</p> <p>If the value of the optional 'open' attribute is set to 'true' then only collections that are currently being recorded automatically by the server (see <link url='#auto'>Automatic Archiving</link>) are removed.</p>
<example caption='Removing a collection being recorded by the server'><![CDATA[ <example caption='Removing a collection being recorded by the server'><![CDATA[
<iq type='set' id='remove6'> <iq type='set' id='remove6'>
<remove xmlns='urn:xmpp:tmp:archive' <remove xmlns='urn:xmpp:tmp:archive'
@ -940,6 +1017,57 @@
</section2> </section2>
</section1> </section1>
<section1 topic='Replication' anchor='replication'>
<p>This section describes how a client can replicate an archive locally. <note>Clients that run in constrained environments may not be able to implement replication if they are prevented from accessing (sufficient) local storage.</note> The existence of a local copy of the archive enables clients to search the content of all messages (including collections saved by another client machine). <note>Since collections SHOULD be stored on the server in a form that it cannot decrypt, server-side searching of the content of messages is beyond the scope of this protocol.</note></p>
<p>The client can "synchronize" its local copy of the archive with the "master" archive on the server at any time. The first step is to request the list of collections that the server has modified (created, changed, or removed) in its master archive since the last update to the client's copy of the archive.</p>
<p>Replication uses the &lt;modified/&gt; element. The list of collections that have been modified since a given time is requested by sending a &lt;modified/&gt; element to the server. The server then returns the list of collections that have been created, changed, or removed. A collection that has been created or changed is specified with a &lt;changed/&gt; element (with version zero for created collections), and a collection that has been removed is specified with a &lt;removed/&gt; element.</p>
<p>When requesting the list of modified collections, the client MUST embed appropriate <cite>Result Set Management</cite> data in the &lt;modified/&gt; element. The &lt;modified/&gt; element MUST include a 'start' attribute that specifies a UTC datetime (see <cite>XEP-0082</cite>) that it has previously received from the server or that it has determined locally (e.g., when synchronizing for the first time the client SHOULD choose a suitable time for the first page request, such as 1970-01-01T00:00:00Z).</p>
<example caption='Requesting a page of modifications'><![CDATA[
<iq type='get' id='sync1'>
<modified xmlns='urn:xmpp:tmp:archive'
start='1469-07-21T01:14:47Z'
version='3'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
</set>
</modified>
</iq>
]]></example>
<p>The server MUST return the changed collections in the chronological order that they were changed (most recent last). If a collection has been modified, created, or removed <em>after</em> the time specified by the 'start' attribute, then the server MUST include it in the returned result set page of collections (unless the specified maximum page size would be exceeded). Each &lt;changed/&gt; or &lt;removed/&gt; collection element (for modified/created, or removed collections respectively) in the returned list MUST include only 'with' and 'start' attribues. The XML character data of the &lt;last/&gt; element is a unique, persistent identifier created by the server, which MUST be treated as opaque by the client.</p>
<example caption='Receiving a page of modifications'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
<modified xmlns='urn:xmpp:tmp:archive'>
<changed with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
version='0'/>
[ ... up to 48 more collections ... ]
<removed with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'
version='3'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<last>ja923ljasnvla09woei777</last>
<count>1372</count>
</set>
</modified>
</iq>
]]></example>
<p>Note: The server should remember the 'with' and 'start' attribues and the time of removal of all deleted collections. If this "state" cannot be maintained indefinitely, then unless all the user's clients replicate before the server deletes its memory of a removal it will not be reflected in all the local copies of the archive.</p>
<p>Note: Along with its copy of the archive the client SHOULD save the most recent &lt;last/&gt; identifier that it received from the server. The next time it synchronizes with the server it SHOULD specify that identifier when requesting the first result set page by including it as the XML character data of the &lt;after/&gt; element in Result Set Management.</p>
<example caption='Requesting the next page of modifications'><![CDATA[
<iq type='get' id='sync2'>
<modified xmlns='urn:xmpp:tmp:archive'
start='1469-07-21T01:14:47Z'
version='3'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<after>ja923ljasnvla09woei777</after>
<max>50</max>
</set>
</modified>
</iq>
]]></example>
<p>After receiving each result set page the client SHOULD delete from its local archive any collections that have been removed from the master archive. The client should also retrieve from the server the content of each collection that has been modified (see <link url='#retrieve'>Retrieving a Collection</link>) and add it to its local copy of the archive (deleting any older version of the same collection that it may already have).</p>
</section1>
<section1 topic='Encryption' anchor='crypt'> <section1 topic='Encryption' anchor='crypt'>
<p>The examples above are not encrypted for clarity. However, clients SHOULD encrypt their archived collections. This section describes how to do so.</p> <p>The examples above are not encrypted for clarity. However, clients SHOULD encrypt their archived collections. This section describes how to do so.</p>
<section2 topic='Encryption of Manually-Archived Collections' anchor='crypt-manual'> <section2 topic='Encryption of Manually-Archived Collections' anchor='crypt-manual'>
@ -1268,16 +1396,23 @@
<p>A client discovers whether its server supports this protocol using &xep0030;.</p> <p>A client discovers whether its server supports this protocol using &xep0030;.</p>
<example caption='Client Service Discovery request'> <example caption='Client Service Discovery request'>
<![CDATA[ <![CDATA[
<iq type='get' id='disco1'> <iq from='romeo@montague.net/orchard'
id='disco1'
to='montague.net'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/> <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq> </iq>
]]></example> ]]></example>
<p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'urn:xmpp:tmp:archive:name' &NSNOTE;, where 'name' is 'auto' for the <link url='#auto'>Automated Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automated Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, and 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p> <p>For each feature defined herein, if the server supports that feature it MUST return a &lt;feature/&gt; element with the 'var' attribute set to 'urn:xmpp:tmp:archive:name' &NSNOTE;, where 'name' is 'auto' for the <link url='#auto'>Automatic Archiving</link> feature, 'encrypt' for the <em>server-side</em> encryption feature (see <link url='#auto'>Automatic Archiving</link>), 'manage' for the <link url='#manage'>Archive Management</link> feature, 'manual' for the <link url='#manual'>Manual Archiving</link> feature, and 'pref' for the <link url='#pref'>Archiving Preferences</link> feature.</p>
<example caption='Server Service Discovery response'> <example caption='Server Service Discovery response'>
<![CDATA[ <![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='disco1'> <iq from='montague.net'
id='disco1'
to='romeo@montague.net/orchard'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/> <query xmlns='http://jabber.org/protocol/disco#info'/>
... ...
<feature var='urn:xmpp:tmp:archive'/>
<feature var='urn:xmpp:tmp:archive:auto'/> <feature var='urn:xmpp:tmp:archive:auto'/>
<feature var='urn:xmpp:tmp:archive:encrypt'/> <feature var='urn:xmpp:tmp:archive:encrypt'/>
<feature var='urn:xmpp:tmp:archive:manage'/> <feature var='urn:xmpp:tmp:archive:manage'/>
@ -1298,46 +1433,7 @@
<p>When uploading messages using manual archiving, a client SHOULD NOT upload one message at a time to the server since this increases both bandwidth consumption and the total number of transactions. It is instead RECOMMENDED that clients upload messages only when the conversation thread <em>appears</em> to be terminated, e.g. when the user closes the chat window. If the user reopens the window and the thread continues then the client should append the new messages to the collection when the user closes the window again.</p> <p>When uploading messages using manual archiving, a client SHOULD NOT upload one message at a time to the server since this increases both bandwidth consumption and the total number of transactions. It is instead RECOMMENDED that clients upload messages only when the conversation thread <em>appears</em> to be terminated, e.g. when the user closes the chat window. If the user reopens the window and the thread continues then the client should append the new messages to the collection when the user closes the window again.</p>
</section2> </section2>
<section2 topic='Storage Considerations' anchor='impl-storage'> <section2 topic='Storage Considerations' anchor='impl-storage'>
<p>Server implementations SHOULD give system administrators the option to disable support for both automated and manual archiving, since archived conversations can consume significant storage space.</p> <p>Server implementations SHOULD give system administrators the option to disable support for both automatic and manual archiving, since archived conversations can consume significant storage space.</p>
</section2>
<section2 topic='Replication' anchor='impl-replication'>
<p>This section describes how a client can replicate an archive locally. <note>Clients that run in constrained environments may not be able to implement replication if they are prevented from accessing (sufficient) local storage.</note> The existence of a local copy of the archive enables clients to search the content of all messages (including collections saved by another client machine). <note>Since collections SHOULD be stored on the server in a form that it cannot decrypt, server-side searching of the content of messages is beyond the scope of this protocol.</note></p>
<p>The client can "synchronize" its local copy of the archive with the "master" archive on the server at any time. The first step is to request the list of collections that the server has changed (created, modified or removed) in its master archive since the last update to the client's copy of the archive.</p>
<p>The client MUST request each page of the list using the <cite>Result Set Management</cite> protocol embedded in a &lt;modified/&gt; element. The &lt;modified/&gt; element MUST include a 'start' attribute that specifies a UTC datetime (see <cite>XEP-0082</cite>) that it has previously received from the server. When synchronizing for the first time, the client MAY choose a suitable time for the first page request (e.g. 1970-01-01T00:00:00Z).</p>
<example caption='Requesting a page of modifications'><![CDATA[
<iq type='get' id='sync1'>
<modified xmlns='urn:xmpp:tmp:archive'
start='1469-07-21T01:14:47Z'
version='3'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>50</max>
</set>
</modified>
</iq>
]]></example>
<p>The server MUST return the changed collections in the chronological order that they were changed (most recent last). If a collection has been modified, created or removed <em>after</em> the time specified by the 'start' attribute then the server MUST include it in the returned result set page of collections (unless the specified maximum page size would be exceeded). Each &lt;changed/&gt; or &lt;removed/&gt; collection element (for modified/created, or removed collections respectively) in the returned list MUST include only 'with' and 'start' attribues. The server MUST set the content of the &lt;last/&gt; element to the UTC time (see <cite>XEP-0082</cite>) that the last collection on the page was modified.</p>
<example caption='Receiving a page of modifications'><![CDATA[
<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
<modified xmlns='urn:xmpp:tmp:archive'>
<changed with='juliet@capulet.com/chamber'
start='1469-07-21T02:56:15Z'
version='0'/>
.
[up to 48 more collections]
.
<removed with='balcony@house.capulet.com'
start='1469-07-21T03:16:37Z'
version='3'/>
<set xmlns='http://jabber.org/protocol/rsm'>
<last>1469-07-21T04:22:39Z</last>
<count>1372</count>
</set>
</modified>
</iq>
]]></example>
<p>Note: The server should remember the 'with' and 'start' attribues and the time of removal of all deleted collections. If this "state" cannot be maintained indefinitely, then unless all the user's clients replicate before the server deletes its memory of a removal then it will not be reflected in all the local copies of the archive.</p>
<p>Note: Along with its copy of the archive the client SHOULD save the most recent &lt;last/&gt; time that it received from the server. The next time it synchronizes with the server it SHOULD specify that time when requesting the first result set page (see above).</p>
<p>After receiving each result set page the client SHOULD delete from its local archive any collections that have been removed from the master archive. The client should also retrieve from the server the content of each collection that has been modified (see <link url='#retrieve'>Retrieving a Collection</link>) and add it to its local copy of the archive (deleting any older version of the same collection that it may already have).</p>
</section2> </section2>
</section1> </section1>
@ -1386,31 +1482,6 @@
<li>urn:xmpp:tmp:archive:pref</li> <li>urn:xmpp:tmp:archive:pref</li>
</ul> </ul>
</section2> </section2>
<section2 topic='Field Standardization' anchor='registrar-formtype'>
<p>&xep0068; defines a process for standardizing the fields used within Data Forms qualified by a particular namespace. The following fields shall be registered for use in Message Archiving, where the FORM_TYPE "urn:xmpp:tmp:archive" shall be replaced with the URN issued by the XMPP Registrar:</p>
<code caption='Registry Submission'><![CDATA[
<form_type>
<name>urn:xmpp:tmp:archive</name>
<doc>XEP-0136</doc>
<desc>Attributes of a message collection stored using Message Archiving</desc>
<field
var='task'
type='boolean'
label='Collection contains
information about a task'/>
<field
var='important'
type='boolean'
label='Collection is important'/>
<field
var='action_before'
type='text-single'
label='Datetime (see XEP-0082) before
the action discussed in the
collection must be completed'/>
</form_type>
]]></code>
</section2>
</section1> </section1>
<section1 topic='XML Schema' anchor='schema'> <section1 topic='XML Schema' anchor='schema'>
@ -1483,7 +1554,6 @@
<xs:element name='to' type='messageType'/> <xs:element name='to' type='messageType'/>
<xs:any processContents='lax' namespace='##other'/> <xs:any processContents='lax' namespace='##other'/>
</xs:choice> </xs:choice>
<xs:attribute name='crypt' use='optional' type='xs:boolean'/>
<xs:attribute name='start' type='xs:dateTime' use='required'/> <xs:attribute name='start' type='xs:dateTime' use='required'/>
<xs:attribute name='subject' type='xs:string' use='optional'/> <xs:attribute name='subject' type='xs:string' use='optional'/>
<xs:attribute name='thread' use='optional' type='xs:string'/> <xs:attribute name='thread' use='optional' type='xs:string'/>
@ -1728,4 +1798,7 @@
</xs:schema> </xs:schema>
]]></code> ]]></code>
</section1> </section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>Thanks to Alexey Melnikov and Alexander Tsvyashchenko for their comments and suggestions.</p>
</section1>
</xep> </xep>