rfc9661.original.xml   rfc9661.xml 
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- draft submitted in xml v3 -->
<!DOCTYPE rfc [ <!DOCTYPE rfc [
<!ENTITY nbsp "&#160;"> <!ENTITY nbsp "&#160;">
<!ENTITY zwsp "&#8203;"> <!ENTITY zwsp "&#8203;">
<!ENTITY nbhy "&#8209;"> <!ENTITY nbhy "&#8209;">
<!ENTITY wj "&#8288;"> <!ENTITY wj "&#8288;">
]> ]>
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" category="std"
ipr="trust200902" docName="draft-ietf-jmap-sieve-22" number="9661" obsoletes="" updates="" submis
category="std" sionType="IETF" consensus="true" xml:lang="en" tocInclude="true" symRefs="true"
docName="draft-ietf-jmap-sieve-22" sortRefs="true" version="3">
obsoletes=""
updates=""
submissionType="IETF"
consensus="true"
xml:lang="en"
tocInclude="true"
symRefs="true"
sortRefs="true"
version="3">
<!-- xml2rfc v2v3 conversion 3.10.0 -->
<front> <front>
<title abbrev="JMAP Sieve">JMAP for Sieve Scripts</title> <title abbrev="JMAP Sieve">The JSON Meta Application Protocol (JMAP) for Sie
<seriesInfo name="Internet-Draft" value="draft-ietf-jmap-sieve-22"/> ve Scripts</title>
<seriesInfo name="RFC" value="9661"/>
<author initials="K." surname="Murchison" fullname="Kenneth Murchison"> <author initials="K." surname="Murchison" fullname="Kenneth Murchison">
<organization abbrev="Fastmail">Fastmail US LLC</organization> <organization abbrev="Fastmail">Fastmail US LLC</organization>
<address> <address>
<postal> <postal>
<street>1429 Walnut Street - Suite 1201</street> <street>1429 Walnut Street, Suite 1201</street>
<city>Philadelphia</city> <city>Philadelphia</city>
<region>PA</region> <region>PA</region>
<code>19102</code> <code>19102</code>
<country>USA</country> <country>United States of America</country>
</postal> </postal>
<email>murch@fastmailteam.com</email> <email>murch@fastmailteam.com</email>
</address> </address>
</author> </author>
<date/> <date month="September" year="2024"/>
<area>ART</area> <area>ART</area>
<!-- <workgroup>Independent Submission</workgroup>--> <workgroup>jmap</workgroup>
<workgroup>JMAP</workgroup>
<keyword>JMAP</keyword> <keyword>JMAP</keyword>
<keyword>JSON</keyword> <keyword>JSON</keyword>
<keyword>Sieve</keyword> <keyword>Sieve</keyword>
<abstract> <abstract>
<t>This document specifies a data model for managing Sieve <t>This document specifies a data model for managing Sieve
scripts on a server using the JSON Meta Application Protocol scripts on a server using the JSON Meta Application Protocol
(JMAP). (JMAP).
Clients can use this protocol to efficiently search, access, Clients can use this protocol to efficiently search, access,
organize, and validate Sieve scripts. organize, and validate Sieve scripts.
</t> </t>
</abstract> </abstract>
<!--
<note title="Open Issues">
<ul spacing="normal">
<li>
</li>
</ul>
</note>
</front> </front>
<middle> <middle>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>Introduction</name> <name>Introduction</name>
<t><xref target="RFC8620">JMAP</xref> <t><xref target="RFC8620">The JSON Meta Application Protocol (JMAP)</xref>
(JSON Meta Application Protocol) is a generic protocol for is a generic protocol for
synchronizing data, such as mail, calendars or contacts, between synchronizing data, such as mail, calendars, or contacts, between
a client and a server. a client and a server.
It is optimized for mobile and web environments, and aims to It is optimized for mobile and web environments, and it aims to
provide a consistent interface to different data types. provide a consistent interface to different data types.
</t> </t>
<t>This specification defines a data model for managing <t>This specification defines a data model for managing
<xref target="RFC5228">Sieve</xref> scripts on <xref target="RFC5228">Sieve scripts</xref> on
a server using JMAP. a server using JMAP.
The data model is designed to allow a server to provide The data model is designed to allow a server to provide
consistent access to the same scripts via consistent access to the same scripts via
<xref target="RFC5804">ManageSieve</xref> as well as JMAP. <xref target="RFC5804">ManageSieve</xref> as well as JMAP.
</t> </t>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>Notational Conventions</name> <name>Notational Conventions</name>
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>",
RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>",
interpreted as described in BCP 14 "<bcp14>SHOULD NOT</bcp14>",
<xref target="RFC2119"/> "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
<xref target="RFC8174"/> when, and only when, "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document
they appear in all capitals, as shown here. are to be interpreted as described in BCP&nbsp;14
</t> <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only
when, they appear in all capitals, as shown here.</t>
<t>Type signatures, examples, and property descriptions in <t>Type signatures, examples, and property descriptions in
this document follow the conventions established in this document follow the conventions established in
<xref target="RFC8620" section="1.1"/>. <xref target="RFC8620" section="1.1"/>.
This document also uses data types and terminology established This document also uses data types and terminology established
in Sections in Sections&nbsp;<xref target="RFC8620" section="1.2"
<xref target="RFC8620" section="1.2" sectionFormat="bare"/> through <xref target="RFC8620"
sectionFormat="bare"/>-<xref target="RFC8620"
section="1.6" sectionFormat="bare"/> of section="1.6" sectionFormat="bare"/> of
<xref target="RFC8620"/>.</t> <xref target="RFC8620"/>.</t>
<t>The term SieveScript (with this specific capitalization) is <t>The term "SieveScript" (with this specific capitalization) is
used to refer to the data type defined in this document and used to refer to the data type defined in <xref target="object"/>
instances of those data types. and instances of this data type used throughout this document.
Servers MUST support all properties specified for the Servers <bcp14>MUST</bcp14> support all properties specified for the
data type defined in this document.</t> data type defined in this document.</t>
<t>For brevity, JMAP API <t>For brevity, JMAP API examples
(see <xref target="RFC8620" section="3"/>) (see <xref target="RFC8620" section="3"/>)
examples only show the "methodCalls" property of the Request only show the "methodCalls" property of the "Request"
object, and the "methodResponses" property of the Response object and the "methodResponses" property of the "Response"
object. object.
All other examples are shown using the All other examples are shown using the
<xref target="RFC9112">HTTP 1.1</xref> protocol.</t> <xref target="RFC9112">HTTP/1.1 protocol</xref>.</t>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>Addition to the Capabilities Object</name> <name>Addition to the Capabilities Object</name>
<t>The capabilities object is returned as part of the JMAP <t>The "capabilities" object is returned as part of the JMAP
Session object; Session object;
see <xref target="RFC8620" section="2" sectionFormat="comma"/>. see <xref target="RFC8620" section="2" sectionFormat="comma"/>.
This document defines one additional capability URI. This document defines one additional capability URI.
</t> </t>
<section anchor="capa" numbered="true" toc="default"> <section anchor="capa" numbered="true" toc="default">
<name>urn:ietf:params:jmap:sieve</name> <name>urn:ietf:params:jmap:sieve</name>
<t>The urn:ietf:params:jmap:sieve URI represents support for <t>The urn:ietf:params:jmap:sieve URI represents support for
the SieveScript data type and associated API methods. the SieveScript data type and associated API methods.
The value of this property in the JMAP Session The value of this property in the JMAP Session
capabilities property is an object that MUST contain "capabilities" property is an object that <bcp14>MUST</bcp14> contain
the following information on server capabilities: the following information on server capabilities:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>implementation</strong>:</dt><dd><t>
<t><strong>implementation</strong>:
<tt>String</tt> <tt>String</tt>
</t> </t>
<t> <t>
The name and version of the Sieve implementation. The name and version of the Sieve implementation.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
<t>The value of this property in an account's <t>The value of this property in an account's
accountCapabilities property is an object that MUST contain "accountCapabilities" property is an object that <bcp14>MUST</bcp14> c ontain
the following information on per-account server capabilities: the following information on per-account server capabilities:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>maxSizeScriptName</strong>:</dt>
<t><strong>maxSizeScriptName</strong>: <dd><t><tt>UnsignedInt</tt>
<tt>UnsignedInt</tt>
</t> </t>
<t> <t>
The maximum length, in octets, allowed for the The maximum length, in octets, allowed for the
name of a SieveScript. name of a SieveScript.
For compatibility with ManageSieve, this MUST be at For compatibility with ManageSieve, this <bcp14>MUST</bcp14> be at
least 512 (up to 128 Unicode characters). least 512 (up to 128 Unicode characters).
</t> </t></dd>
<t/>
</li> <dt><strong>maxSizeScript</strong>:</dt><dd>
<li> <t><tt>UnsignedInt|null</tt>
<t><strong>maxSizeScript</strong>:
<tt>UnsignedInt|null</tt>
</t> </t>
<t> <t>
The maximum size (in octets) of a Sieve script the The maximum size (in octets) of a Sieve script the
server is willing to store for the user, server is willing to store for the user,
or <tt>null</tt> for no limit. or <tt>null</tt> for no limit.
</t> </t>
<t/> </dd>
</li> <dt><strong>maxNumberScripts</strong>:</dt>
<li> <dd><t><tt>UnsignedInt|null</tt>
<t><strong>maxNumberScripts</strong>:
<tt>UnsignedInt|null</tt>
</t> </t>
<t> <t>
The maximum number of Sieve scripts the server is The maximum number of Sieve scripts the server is
willing to store for the user, willing to store for the user,
or <tt>null</tt> for no limit. or <tt>null</tt> for no limit.
</t> </t>
<t/> </dd>
</li> <dt><strong>maxNumberRedirects</strong>:</dt>
<li> <dd><t><tt>UnsignedInt|null</tt>
<t><strong>maxNumberRedirects</strong>:
<tt>UnsignedInt|null</tt>
</t> </t>
<t> <t>
The maximum number of Sieve "redirect" actions a The maximum number of Sieve "redirect" actions a
script can perform during a single evaluation script can perform during a single evaluation,
or <tt>null</tt> for no limit. or <tt>null</tt> for no limit.
Note that this is different from the total number of Note that this is different from the total number of
"redirect" actions a script can contain. "redirect" actions a script can contain.
</t> </t>
<t/> </dd>
</li>
<li> <dt><strong>sieveExtensions</strong>:</dt>
<t><strong>sieveExtensions</strong>: <dd><t><tt>String[]</tt>
<tt>String[]</tt>
</t> </t>
<t> <t>
A list of case-sensitive Sieve capability strings (as A list of case-sensitive Sieve capability strings (as
listed in Sieve "require" action; see listed in the Sieve "require" action; see
<xref target="RFC5228" section="3.2" sectionFormat="comma"/>) <xref target="RFC5228" section="3.2" sectionFormat="comma"/>)
indicating the extensions supported by the Sieve engine. indicating the extensions supported by the Sieve engine.
</t> </t></dd>
<t/> <dt><strong>notificationMethods</strong>:</dt>
</li> <dd><t><tt>String[]|null</tt>
<li>
<t><strong>notificationMethods</strong>:
<tt>String[]|null</tt>
</t> </t>
<t> <t>
A list of A list of
<xref target="RFC3986">URI schema parts</xref> <xref target="RFC3986">URI scheme parts</xref>
for notification methods supported by the Sieve for notification methods supported by the Sieve
<xref target="RFC5435">"enotify"</xref> <xref target="RFC5435">"enotify" extension</xref>,
extension, or <tt>null</tt> if the extension or <tt>null</tt> if the extension
is not supported by the Sieve engine. is not supported by the Sieve engine.
</t> </t>
<t/> </dd>
</li> <dt><strong>externalLists</strong>:</dt>
<li> <dd><t><tt>String[]|null</tt>
<t><strong>externalLists</strong>:
<tt>String[]|null</tt>
</t> </t>
<t> <t>
A list of A list of
<xref target="RFC3986">URI schema parts</xref> <xref target="RFC3986">URI scheme parts</xref>
for externally stored list types supported by the for externally stored list types supported by the
Sieve <xref target="RFC6134">"extlists"</xref> Sieve <xref target="RFC6134">"extlists" extension</xref>,
extension, or <tt>null</tt> if the extension or <tt>null</tt> if the extension
is not supported by the Sieve engine. is not supported by the Sieve engine.
</t> </t>
</li> </dd>
</ul> </dl>
</section> </section>
<section anchor="session" numbered="true" toc="default"> <section anchor="session" numbered="true" toc="default">
<name>Example</name> <name>Example</name>
<t keepWithNext="true"> <t keepWithNext="true">
A JMAP Session object showing a user that has access to their This example JMAP Session object shows a user that has access to the ir
own Sieve scripts with support for a few Sieve extensions: own Sieve scripts with support for a few Sieve extensions:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
{ {
"capabilities": { "capabilities": {
"urn:ietf:params:jmap:core": { "urn:ietf:params:jmap:core": {
... ...
}, },
"urn:ietf:params:jmap:mail": {}, "urn:ietf:params:jmap:mail": {},
"urn:ietf:params:jmap:quota": {}, "urn:ietf:params:jmap:quota": {},
"urn:ietf:params:jmap:blob": {}, "urn:ietf:params:jmap:blob": {},
"urn:ietf:params:jmap:sieve": { "urn:ietf:params:jmap:sieve": {
"implementation": "ACME Email Filtering" "implementation": "ACME Email Filtering"
skipping to change at line 320 skipping to change at line 287
"urn:ietf:params:jmap:vacationresponse": "ken", "urn:ietf:params:jmap:vacationresponse": "ken",
... ...
}, },
"username": "ken@example.com", "username": "ken@example.com",
"apiUrl": "/jmap/", "apiUrl": "/jmap/",
"downloadUrl": "downloadUrl":
"/jmap/download/{accountId}/{blobId}/{name}?accept={type}", "/jmap/download/{accountId}/{blobId}/{name}?accept={type}",
"uploadUrl": "/jmap/upload/{accountId}/", "uploadUrl": "/jmap/upload/{accountId}/",
... ...
} }
]]></artwork> ]]></sourcecode>
</section> </section>
</section> </section>
</section> </section>
<section anchor="object" numbered="true" toc="default"> <section anchor="object" numbered="true" toc="default">
<name>Sieve Scripts</name> <name>Sieve Scripts</name>
<t>A <strong>SieveScript</strong> object represents <t>A "SieveScript" object represents
a single <xref target="RFC5228">Sieve</xref> script for a single <xref target="RFC5228">Sieve script</xref> for
filtering email messages at time of final delivery. filtering email messages at the time of final delivery.
</t> </t>
<section anchor="props" numbered="true" toc="default"> <section anchor="props" numbered="true" toc="default">
<name>Sieve Script Properties</name> <name>Sieve Script Properties</name>
<t>A <strong>SieveScript</strong> object has the <t>A "SieveScript" object has the
following properties: following properties:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>id</strong>:</dt>
<t><strong>id</strong>: <dd><t><tt>Id</tt>
<tt>Id</tt>
(immutable; server-set) (immutable; server-set)
</t> </t>
<t> <t>
The id of the script. The id of the script.
</t> </t>
<t/> </dd>
</li> <dt><strong>name</strong>:</dt>
<li> <dd><t><tt>String|null</tt>
<t><strong>name</strong>: (optional; default is server dependent)
<tt>String|null</tt>
(optional; default is server-dependent)
</t> </t>
<t> <t>
User-visible name for the SieveScript. User-visible name for the SieveScript.
If non-null, this MUST be a If non-null, this <bcp14>MUST</bcp14> be a
<xref target="RFC5198">Net-Unicode</xref> <xref target="RFC5198">Net-Unicode string</xref>
string of at least 1 character in length, subject to the of at least 1 character in length, subject to the
maximum size given in the capability object. maximum size given in the "capability" object.
</t> </t>
<t> <t>
For compatibility with ManageSieve, servers MUST reject For compatibility with ManageSieve, servers <bcp14>MUST</bcp14> re ject
names that contain any of the following Unicode characters: names that contain any of the following Unicode characters:
U+0000 - U+001F, U+007F - U+009F, U+2028, U+2029. U+0000-U+001F, U+007F-U+009F, U+2028, or U+2029.
</t> </t>
<t> <t>
Servers MAY reject names that violate server policy Servers <bcp14>MAY</bcp14> reject names that violate server policy
(e.g., names containing slash (/)). (e.g., names containing a slash (/)).
</t> </t>
<t> <t>
The name MUST be unique among all SieveScripts within an The name <bcp14>MUST</bcp14> be unique among all SieveScripts with in an
account. account.
</t> </t>
<t/> </dd>
</li> <dt><strong>blobId</strong>:</dt>
<li> <dd><t><tt>Id</tt>
<t><strong>blobId</strong>:
<tt>Id</tt>
</t> </t>
<t> <t>
The id of the blob containing the raw octets of the script. The id of the blob containing the raw octets of the script.
</t> </t>
<t/> </dd>
</li> <dt><strong>isActive</strong>:</dt>
<li> <dd><t><tt>Boolean</tt>
<t><strong>isActive</strong>:
<tt>Boolean</tt>
(server-set; default: false) (server-set; default: false)
</t> </t>
<t> <t>
Indicator that the SieveScript is actively filtering Indicator that the SieveScript is actively filtering
incoming messages. incoming messages.
</t> </t>
<t> <t>
A user may have at most one active script. A user may have at most one active script.
The <xref target="set">SieveScript/set</xref> method is The <xref target="set">SieveScript/set method</xref> is
used for changing the active script or disabling Sieve used for changing the active script or disabling Sieve
processing. processing.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
</section> </section>
<section anchor="content" numbered="true" toc="default"> <section anchor="content" numbered="true" toc="default">
<name>Sieve Script Content</name> <name>Sieve Script Content</name>
<t>A script MUST be <xref target="RFC3629">UTF-8</xref> <t>A script <bcp14>MUST</bcp14> be <xref target="RFC3629">UTF-8 content<
content of at least 1 character in length, subject to the /xref>
of at least 1 character in length, subject to the
syntax of <xref target="RFC5228">Sieve</xref>. syntax of <xref target="RFC5228">Sieve</xref>.
A script MUST NOT contain any "require" statement(s) A script <bcp14>MUST NOT</bcp14> contain any "require" statement(s)
mentioning Sieve capability strings not present in the mentioning Sieve capability strings not present in the
<xref target="capa">capability</xref> object. <xref target="capa">"capability" object</xref>.
Note that if the Sieve <xref target="RFC5463">"ihave"</xref> Note that if the Sieve <xref target="RFC5463">"ihave" capability strin
capability string is present in the capability object, g </xref>
the script MAY mention unrecognized/unsupported extensions is present in the "capability" object,
the script <bcp14>MAY</bcp14> mention unrecognized/unsupported extensi
ons
in the "ihave" test. in the "ihave" test.
</t> </t>
<t>Script content is treated as a binary blob and <t>Script content is treated as a binary blob and
uploaded/downloaded via the mechanisms in uploaded/downloaded via the mechanisms provided in
<xref target="RFC8620"/> Sections Sections&nbsp;<xref target="RFC8620" section="6.1"
<xref target="RFC8620" section="6.1" sectionFormat="bare"/> and <xref target="RFC8620"
sectionFormat="bare"/>/<xref target="RFC8620" section="6.2" sectionFormat="bare"/> of <xref target="RFC8620"/>
section="6.2" sectionFormat="bare"/> ,
respectively and/or via the JMAP Blob management methods in respectively, and/or via the JMAP Blob management methods provided in
<xref target="RFC9404"/> Sections Sections&nbsp;<xref target="RFC9404" section="4.1"
<xref target="RFC9404" section="4.1" sectionFormat="bare"/> and <xref target="RFC9404"
sectionFormat="bare"/>/<xref target="RFC9404" section="4.2" sectionFormat="bare"/> of <xref target="RFC9404"/>
section="4.2" sectionFormat="bare"/> ,
respectively. respectively.
</t> </t>
<t>Downloading script content via the JMAP downloadUrl or the <t>Downloading script content via the JMAP downloadUrl or the
Blob/get method provides equivalent functionality to the Blob/get method provides functionality equivalent to that of the
GETSCRIPT command in <xref target="RFC5804"/>. GETSCRIPT command defined in <xref target="RFC5804"/>.
</t> </t>
</section> </section>
<section anchor="get" numbered="true" toc="default"> <section anchor="get" numbered="true" toc="default">
<name>SieveScript/get</name> <name>SieveScript/get</name>
<t>This is a standard "/get" method as described in <t>This is a standard "/get" method as described in
<xref target="RFC8620" section="5.1" sectionFormat="comma"/>. <xref target="RFC8620" section="5.1" sectionFormat="comma"/>.
The <em>ids</em> argument may be The "ids" argument may be
<tt>null</tt> to fetch all scripts at once. <tt>null</tt> to fetch all scripts at once.
</t> </t>
<t>This method provides equivalent functionality to the <t>This method provides functionality equivalent to that of the
LISTSCRIPTS command in <xref target="RFC5804"/>. LISTSCRIPTS command defined in <xref target="RFC5804"/>.
</t> </t>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>Examples</name> <name>Examples</name>
<t keepWithNext="true"> <t keepWithNext="true">
List all scripts: List all scripts:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/get", { ["SieveScript/get", {
"accountId": "ken" "accountId": "ken"
}, "0"] }, "0"]
] ]
[ [
[ [
"SieveScript/get", "SieveScript/get",
{ {
skipping to change at line 481 skipping to change at line 438
"isActive": true, "isActive": true,
"blobId": "S7" "blobId": "S7"
} }
], ],
"notFound": [], "notFound": [],
"accountId": "ken" "accountId": "ken"
}, },
"0" "0"
] ]
] ]
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Download the script content via Download the script content via
the JMAP downloadUrl as advertised in <xref target="session"/>: the JMAP downloadUrl as advertised in the example in <xref target="s ession"/>:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="http-message"><![CDATA[
GET /jmap/download/ken/S7/test1.siv?accept=application/sieve HTTP/1.1 GET /jmap/download/ken/S7/test1.siv?accept=application/sieve HTTP/1.1
Host: jmap.example.com Host: jmap.example.com
Authorization: Basic a2VuOnBhc3N3b3Jk Authorization: Basic a2VuOnBhc3N3b3Jk
HTTP/1.1 200 OK HTTP/1.1 200 OK
Date: Fri, 22 Oct 2021 15:27:38 GMT Date: Fri, 22 Oct 2021 15:27:38 GMT
Content-Type: application/sieve; charset=utf-8 Content-Type: application/sieve; charset=utf-8
Content-Disposition: attachment; filename="test1.siv" Content-Disposition: attachment; filename="test1.siv"
Content-Length: 49 Content-Length: 49
require ["fileinto"]; require ["fileinto"];
fileinto "INBOX.target"; fileinto "INBOX.target";
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Fetch script properties Fetch script properties
and content in a single JMAP API request using the and content in a single JMAP API request using the
<xref target="RFC9404"> JMAP Blob management extension</xref>: <xref target="RFC9404"> JMAP Blob management extension</xref>:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[
<sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/get", { ["SieveScript/get", {
"accountId": "ken", "accountId": "ken",
"ids": [ "2d647053-dded-418d-917a-63eda3ac8f7b" ] "ids": [ "2d647053-dded-418d-917a-63eda3ac8f7b" ]
}, "0"], }, "0"],
["Blob/get", { ["Blob/get", {
"accountId": "ken", "accountId": "ken",
"#ids": { "#ids": {
"resultOf": "0", "resultOf": "0",
"name": "SieveScript/get", "name": "SieveScript/get",
skipping to change at line 558 skipping to change at line 516
"require [\"fileinto\"];\\r\\nfileinto \"INBOX.target\";\\r\\n", "require [\"fileinto\"];\\r\\nfileinto \"INBOX.target\";\\r\\n",
"size": 49 "size": 49
} }
], ],
"notFound": [], "notFound": [],
"accountId": "ken" "accountId": "ken"
}, },
"1" "1"
] ]
] ]
]]></artwork> ]]></sourcecode>
</section> </section>
</section> </section>
<!-- /get -->
<section anchor="set" numbered="true" toc="default"> <section anchor="set" numbered="true" toc="default">
<name>SieveScript/set</name> <name>SieveScript/set</name>
<t>This is a standard "/set" method as described in <t>This is a standard "/set" method as described in
<xref target="RFC8620" section="5.3" sectionFormat="comma"/> <xref target="RFC8620" section="5.3" sectionFormat="comma"/>,
but with the following additional optional request arguments: but with the following additional optional request arguments:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>onSuccessActivateScript</strong>:</dt>
<t><strong>onSuccessActivateScript</strong>: <dd><t><tt>Id</tt>
<tt>Id</tt>
</t> </t>
<t> <t>
The id of the SieveScript to activate if and The id of the SieveScript to activate if and
only if all of the creations, modifications, and only if all of the creations, modifications, and
destructions (if any) succeed. destructions (if any) succeed.
(For references to SieveScript creations, this is (For references to SieveScript creations, this is
equivalent to a creation-reference, so the id will be the equivalent to a creation-reference, so the id will be the
creation id prefixed with a "#".) creation id prefixed with a "#".)
The currently active SieveScript (if any) will be deactivated The currently active SieveScript (if any) will be deactivated
before activating the specified SieveScript. before activating the specified SieveScript.
</t> </t>
<t> <t>
If omitted, or if the id is either invalid or nonexistent, it MUST b If omitted, or if the id is either invalid or nonexistent, it <bcp14
e >MUST</bcp14> be
ignored and the currently active SieveScript (if any) will ignored, and the currently active SieveScript (if any) will
remain as such. remain as such.
</t> </t>
<t> <t>
The id of any activated SieveScript MUST be reported in The id of any activated SieveScript <bcp14>MUST</bcp14> be reported in
either the "created" or "updated" argument in the response either the "created" or "updated" argument in the response
as appropriate, including a value of "true" for the "isActive" as appropriate, including a value of "true" for the "isActive"
property. property.
The id of any deactivated SieveScript MUST be reported in The id of any deactivated SieveScript <bcp14>MUST</bcp14> be reporte d in
the "updated" argument in the response, including a value of the "updated" argument in the response, including a value of
"false" for the "isActive" property. "false" for the "isActive" property.
</t> </t>
<t/> </dd>
</li>
<li> <dt><strong>onSuccessDeactivateScript</strong>:</dt>
<t><strong>onSuccessDeactivateScript</strong>: <dd><t><tt>Boolean</tt>
<tt>Boolean</tt>
</t> </t>
<t> <t>
If <tt>true</tt>, the currently active If "true", the currently active
SieveScript (if any) will be deactivated if and only if SieveScript (if any) will be deactivated if and only if
all of the creations, modifications, and destructions (if all of the creations, modifications, and destructions (if
any) succeed. any) succeed.
If <tt>false</tt> or omitted, the currently active SieveScript (if If "false" or omitted, the currently active SieveScript (if
any) will remain as such. any) will remain as such.
</t> </t>
<t> <t>
The id of any deactivated SieveScript MUST be reported in The id of any deactivated SieveScript <bcp14>MUST</bcp14> be reporte d in
the "updated" argument in the response, including a value of the "updated" argument in the response, including a value of
"false" for the "isActive" property. "false" for the "isActive" property.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
<t>If both the <strong>onSuccessActivateScript</strong> and <t>If both the "onSuccessActivateScript" and
<strong>onSuccessDeactivateScript</strong> arguments are "onSuccessDeactivateScript" arguments are
present in the request, then present in the request, then
<strong>onSuccessDeactivateScript</strong> MUST be processed first. "onSuccessDeactivateScript" <bcp14>MUST</bcp14> be processed first.
If neither argument is present in the request, the currently If neither argument is present in the request, the currently
active SieveScript (if any) will remain as such. active SieveScript (if any) will remain as such.
</t> </t>
<t>This method provides equivalent functionality to the <t>This method provides functionality equivalent to that of the
PUTSCRIPT, DELETESCRIPT, RENAMESCRIPT, and SETACTIVE commands PUTSCRIPT, DELETESCRIPT, RENAMESCRIPT, and SETACTIVE commands defined
in <xref target="RFC5804"/>. in <xref target="RFC5804"/>.
</t> </t>
<t>Script content must first be uploaded as per <t>Script content must first be uploaded as per
<xref target="content"/> prior to referencing it in a <xref target="content"/> prior to referencing it in a
SieveScript/set call.</t> SieveScript/set call.</t>
<t>If the SieveScript can not be created or updated because it <t>If the SieveScript cannot be created or updated because it
would result in two SieveScripts with the same name, the would result in two SieveScripts with the same name, the
server MUST reject the request with an "alreadyExists" server <bcp14>MUST</bcp14> reject the request with an "alreadyExists"
SetError. SetError.
An "existingId" property of type "Id" MUST be included on the An "existingId" property of type "Id" <bcp14>MUST</bcp14> be included on the
SetError object with the id of the existing SieveScript.</t> SetError object with the id of the existing SieveScript.</t>
<t>If the SieveScript can not be created or updated because <t>If the SieveScript cannot be created or updated because
its size exceeds the "maxSizeScript" limit, the server MUST its size exceeds the "maxSizeScript" limit, the server <bcp14>MUST</bcp1
4>
reject the request with a "tooLarge" SetError.</t> reject the request with a "tooLarge" SetError.</t>
<t>If the SieveScript can not be created because it would <t>If the SieveScript cannot be created because it would
exceed the "maxNumberScripts" limit or would exceed a exceed the "maxNumberScripts" limit or would exceed a
server-imposed storage limit, the server MUST server-imposed storage limit, the server <bcp14>MUST</bcp14>
reject the request with an "overQuota" SetError.</t> reject the request with an "overQuota" SetError.</t>
<t>The active SieveScript MUST NOT be destroyed <t>The active SieveScript <bcp14>MUST NOT</bcp14> be destroyed
unless it is first deactivated in a separate SieveScript/set unless it is first deactivated in a separate SieveScript/set
method call.</t> method call.</t>
<t>The following extra SetError types are defined: <t>The following extra SetError types are defined:
</t> </t>
<t>For "create" and "update": <t>For "create" and "update":
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li>
<t><strong>invalidSieve</strong>: <dt><strong>invalidSieve</strong>:</dt>
</t> <dd><t>
<t>
The SieveScript content violates the The SieveScript content violates the
<xref target="RFC5228">Sieve</xref> <xref target="RFC5228">Sieve grammar</xref>,
grammar and/or one and/or one
or more extensions mentioned in the script's "require" or more extensions mentioned in the script's "require"
statement(s) are not supported by the Sieve interpreter. statement(s) are not supported by the Sieve interpreter.
The <em>description</em> property on The "description" property on
the SetError object SHOULD contain a specific error the SetError object <bcp14>SHOULD</bcp14> contain a specific error
message giving at least the line number of the first error. message giving at least the line number of the first error.</t>
</t> </dd>
<t/> </dl>
</li>
</ul>
<t>For "destroy": <t>For "destroy":
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>sieveIsActive</strong>:</dt>
<t><strong>sieveIsActive</strong>: <dd><t>
</t>
<t>
The SieveScript is active. The SieveScript is active.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>Examples</name> <name>Examples</name>
<t keepWithNext="true"> <t keepWithNext="true">
Upload a script Upload a script
requiring the Imap4Flags requiring the Imap4Flags Extension
<xref target="RFC5232"/> <xref target="RFC5232"/>
Extension using the JMAP uploadUrl as advertised in using the JMAP uploadUrl as advertised in the example in
<xref target="session"/>: <xref target="session"/>:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="http-message"><![CDATA[
POST /jmap/upload/ken/ HTTP/1.1 POST /jmap/upload/ken/ HTTP/1.1
Host: jmap.example.com Host: jmap.example.com
Authorization: Basic a2VuOnBhc3N3b3Jk Authorization: Basic a2VuOnBhc3N3b3Jk
Content-Type: application/sieve Content-Type: application/sieve
Content-Length: 98 Content-Length: 98
require "imapflags"; require "imapflags";
if address :is ["To", "Cc"] "jmap@ietf.org" { if address :is ["To", "Cc"] "jmap@ietf.org" {
setflag "\\Flagged"; setflag "\\Flagged";
skipping to change at line 729 skipping to change at line 676
Date: Thu, 10 Dec 2020 17:14:31 GMT Date: Thu, 10 Dec 2020 17:14:31 GMT
Content-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8
Content-Length: 171 Content-Length: 171
{ {
"accountId": "ken", "accountId": "ken",
"blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123", "blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123",
"type": "application/sieve" "type": "application/sieve"
"size": 98 "size": 98
} }
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Create and activate Create and activate
a script using the uploaded blob. a script using the uploaded blob.
Note that the response shows that an existing active Note that the response shows that an existing active
script has been deactivated in lieu of the newly script has been deactivated in lieu of the newly
created script being activated. created script being activated.
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/set", { ["SieveScript/set", {
"accountId": "ken", "accountId": "ken",
"create": { "create": {
"A": { "A": {
"name": null, "name": null,
"blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123" "blobId": "Gabcc83e44a6e19991c4568d0b94e1767c83dd123"
} }
}, },
"onSuccessActivateScript": "#A" "onSuccessActivateScript": "#A"
skipping to change at line 779 skipping to change at line 726
}, },
"destroyed": null, "destroyed": null,
"notCreated": null, "notCreated": null,
"notUpdated": null, "notUpdated": null,
"notDestroyed": null, "notDestroyed": null,
"accountId": "ken" "accountId": "ken"
}, },
"0" "0"
] ]
] ]
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Update the script content using Update the script content using
the <xref target="RFC9404"> JMAP Blob management extension</xref>: the <xref target="RFC9404"> JMAP Blob management extension</xref>:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
{ {
[ [
["Blob/upload", { ["Blob/upload", {
"accountId": "ken", "accountId": "ken",
"create": { "create": {
"B": { "B": {
"data": [ { "data": [ {
"data:asText": "data:asText":
"redirect \"ken@example.com\"\r\n;" "redirect \"ken@example.com\"\r\n;"
} ], } ],
skipping to change at line 845 skipping to change at line 792
}, },
"destroyed": null, "destroyed": null,
"notCreated": null, "notCreated": null,
"notUpdated": null, "notUpdated": null,
"notDestroyed": null, "notDestroyed": null,
"accountId": "ken" "accountId": "ken"
}, },
"2" "2"
] ]
] ]
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Update the script name and deactivate it: Update the script name, and deactivate it:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/set", { ["SieveScript/set", {
"accountId": "ken", "accountId": "ken",
"update": { "dd1b164f-8cdc-448c-9f54": { "update": { "dd1b164f-8cdc-448c-9f54": {
"name": "myscript" "name": "myscript"
} }
}, },
"onSuccessDeactivateScript": true "onSuccessDeactivateScript": true
}, "3"] }, "3"]
] ]
skipping to change at line 882 skipping to change at line 829
}, },
"destroyed": null, "destroyed": null,
"notCreated": null, "notCreated": null,
"notUpdated": null, "notUpdated": null,
"notDestroyed": null, "notDestroyed": null,
"accountId": "ken" "accountId": "ken"
}, },
"3" "3"
] ]
] ]
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Reactivate the script: Reactivate the script:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/set", { ["SieveScript/set", {
"accountId": "ken", "accountId": "ken",
"onSuccessActivateScript": "dd1b164f-8cdc-448c-9f54" "onSuccessActivateScript": "dd1b164f-8cdc-448c-9f54"
}, "4"] }, "4"]
] ]
[ [
[ [
"SieveScript/set", "SieveScript/set",
skipping to change at line 915 skipping to change at line 862
}, },
"destroyed": null, "destroyed": null,
"notCreated": null, "notCreated": null,
"notUpdated": null, "notUpdated": null,
"notDestroyed": null, "notDestroyed": null,
"accountId": "ken" "accountId": "ken"
}, },
"4" "4"
] ]
] ]
]]></artwork> ]]></sourcecode>
<t keepWithNext="true"> <t keepWithNext="true">
Deactivate and destroy the active script: Deactivate and destroy the active script:
</t> </t>
<artwork name="" type="" align="left" alt=""><![CDATA[ <sourcecode name="" type="json"><![CDATA[
[ [
["SieveScript/set", { ["SieveScript/set", {
"accountId": "ken", "accountId": "ken",
"onSuccessDeactivateScript": true "onSuccessDeactivateScript": true
}, "5"], }, "5"],
["SieveScript/set", { ["SieveScript/set", {
"accountId": "ken", "accountId": "ken",
"destroy": [ "dd1b164f-8cdc-448c-9f54" ] "destroy": [ "dd1b164f-8cdc-448c-9f54" ]
}, "6"] }, "6"]
] ]
skipping to change at line 969 skipping to change at line 916
"dd1b164f-8cdc-448c-9f54" "dd1b164f-8cdc-448c-9f54"
], ],
"notCreated": null, "notCreated": null,
"notUpdated": null, "notUpdated": null,
"notDestroyed": null, "notDestroyed": null,
"accountId": "ken" "accountId": "ken"
}, },
"6" "6"
] ]
] ]
]]></artwork> ]]></sourcecode>
</section> </section>
</section> </section>
<!-- /set -->
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>SieveScript/query</name> <name>SieveScript/query</name>
<t>This is a standard "/query" method as described in <t>This is a standard "/query" method as described in
<xref target="RFC8620" section="5.5" sectionFormat="comma"/>. <xref target="RFC8620" section="5.5" sectionFormat="comma"/>.
A <em>FilterCondition</em> object has the A "FilterCondition" object has the
following properties, either of which may be omitted: following properties, either of which may be omitted:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li>
<t><strong>name</strong>: <dt><strong>name</strong>:</dt>
<tt>String</tt> <dd><t><tt>String</tt>
</t> </t>
<t> <t>
The SieveScript "name" property contains the given string. The SieveScript "name" property contains the given string.
</t> </t>
<t/> </dd>
</li>
<li> <dt><strong>isActive</strong>:</dt>
<t><strong>isActive</strong>: <dd><t><tt>Boolean</tt>
<tt>Boolean</tt>
</t> </t>
<t> <t>
The "isActive" property of the SieveScript must be The "isActive" property of the SieveScript must be
identical to the value given to match the condition. identical to the value given to match the condition.
</t> </t>
<t/> </dd>
</li> </dl>
<!-- <t>The following SieveScript properties <bcp14>MUST</bcp14> be supported
<t> for
<spanx style="strong">isIncluded</spanx>:
<spanx style="verb">Boolean</spanx>
<vspace blankLines="1"/>
If true, the SieveScript must be included
(see <xref target="RFC6609" />) by the content of another
SieveScript to match the condition.
Otherwise, the SieveScript must not be included by the
content of another SieveScript to match the condition.
<vspace blankLines="1"/>
</t>
</ul>
<t>The following SieveScript properties MUST be supported for
sorting: sorting:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li> <li>
<t><strong>name</strong> <t><strong>name</strong>
</t> </t>
<t/>
</li> </li>
<li> <li>
<strong>isActive</strong> <strong>isActive</strong>
</li> </li>
</ul> </ul>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>SieveScript/validate</name> <name>SieveScript/validate</name>
<t>This method is used by the client to verify Sieve script <t>This method is used by the client to verify Sieve script
validity without storing the script on the server. validity without storing the script on the server.
</t> </t>
<t>The method takes the following arguments: <t>The method takes the following arguments:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>accountId</strong>:</dt>
<t><strong>accountId</strong>: <dd><t><tt>Id</tt>
<tt>Id</tt>
</t> </t>
<t> <t>
The id of the account to use. The id of the account to use.
</t> </t>
<t/> </dd>
</li> <dt><strong>blobId</strong>:</dt>
<li> <dd><t><tt>Id</tt>
<t><strong>blobId</strong>:
<tt>Id</tt>
</t> </t>
<t> <t>
The id of the blob containing the raw octets of the The id of the blob containing the raw octets of the
script to validate, script to validate,
subject to the same requirements in subject to the same requirements in
<xref target="object"/>. <xref target="content"/>.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
<t>The response has the following arguments: <t>The response has the following arguments:
</t> </t>
<ul spacing="normal"> <dl spacing="normal">
<li> <dt><strong>accountId</strong>:</dt>
<t><strong>accountId</strong>: <dd><t><tt>Id</tt>
<tt>Id</tt>
</t> </t>
<t> <t>
The id of the account used for this call. The id of the account used for this call.
</t> </t>
<t/> </dd>
</li>
<li> <dt><strong>error</strong>:</dt>
<t><strong>error</strong>: <dd><t><tt>SetError|null</tt>
<tt>SetError|null</tt>
</t> </t>
<t> <t>
An "invalidSieve" SetError object if the script content An "invalidSieve" SetError object if the script content
is invalid (see <xref target="set"/>), is invalid (see <xref target="set"/>),
or <tt>null</tt> if the or <tt>null</tt> if the
script content is valid. script content is valid.
</t> </t>
<t/> </dd>
</li> </dl>
</ul>
<t>This method provides equivalent functionality to the <t>This method provides functionality equivalent to that of the
CHECKSCRIPT command in <xref target="RFC5804"/>.</t> CHECKSCRIPT command defined in <xref target="RFC5804"/>.</t>
<t>Script content must first be uploaded as per <t>Script content must first be uploaded as per
<xref target="content"/> prior to referencing it in a <xref target="content"/> prior to referencing it in a
SieveScript/validate call.</t> SieveScript/validate call.</t>
</section> </section>
<!-- /validate -->
</section> </section>
<section anchor="quotas" numbered="true" toc="default"> <section anchor="quotas" numbered="true" toc="default">
<name>Quotas</name> <name>Quotas</name>
<t>Servers SHOULD impose quotas on Sieve scripts to prevent <t>Servers <bcp14>SHOULD</bcp14> impose quotas on Sieve scripts to prevent
malicious users from exceeding available storage. malicious users from exceeding available storage.
Administration of such quotas is outside of the scope of this Administration of such quotas is outside of the scope of this
specification, however <xref target="RFC9425"/> defines a data specification; however, <xref target="RFC9425"/> defines a data
model for users to obtain quota details over JMAP.</t> model for users to obtain quota details over JMAP.</t>
<t>The mechanism for handling SieveScript requests that would place <t>The mechanism for handling SieveScript requests that would place
a user over a quota setting is discussed in <xref target="set"/>. a user over a quota setting is discussed in <xref target="set"/>.
</t> </t>
</section> </section>
<section anchor="vacation" numbered="true" toc="default"> <section anchor="vacation" numbered="true" toc="default">
<name>Compatibility with JMAP Vacation Response</name> <name>Compatibility with JMAP Vacation Response</name>
<t><xref target="RFC8621" section="8"/> defines a <t><xref target="RFC8621" section="8"/> defines a
VacationResponse object to represent an autoresponder to "VacationResponse" object to represent an autoresponder to
incoming email messages. incoming email messages.
Servers that implement the VacationResponse as a Sieve script Servers that implement the VacationResponse as a Sieve script
that resides amongst other user scripts are subject to the that resides among other user scripts are subject to the
following requirements: following requirements:
</t> </t>
<ul spacing="normal"> <ul spacing="normal">
<li>MUST allow the VacationResponse Sieve script to be fetched <li><bcp14>MUST</bcp14> allow the VacationResponse Sieve script to be fe
by the <xref target="get">SieveScript/get</xref> tched
method. by the <xref target="get">SieveScript/get method</xref>.
</li> </li>
<li>MUST allow the VacationResponse Sieve script to be <li><bcp14>MUST</bcp14> allow the VacationResponse Sieve script to be
[de]activated via the "onSuccessActivateScript" argument to activated or deactivated via the "onSuccessActivateScript" argument to
the <xref target="set">SieveScript/set</xref> method. the <xref target="set">SieveScript/set method</xref>.
</li> </li>
<li>MUST NOT allow the VacationResponse Sieve script to be <li><bcp14>MUST NOT</bcp14> allow the VacationResponse Sieve script to b e
destroyed or have its content updated by the destroyed or have its content updated by the
<xref target="set">SieveScript/set</xref> method. <xref target="set">SieveScript/set method</xref>.
Any such request MUST be rejected with a "forbidden" SetError. Any such request <bcp14>MUST</bcp14> be rejected with a "forbidden" SetE
A "description" property MAY be present with an explanation rror.
A "description" property <bcp14>MAY</bcp14> be present with an explanati
on
that the script can only be modified by a VacationResponse/set that the script can only be modified by a VacationResponse/set
method. method.
</li> </li>
</ul> </ul>
</section> </section>
<section anchor="security" numbered="true" toc="default"> <section anchor="security" numbered="true" toc="default">
<name>Security Considerations</name> <name>Security Considerations</name>
<t>All security considerations of <t>All security considerations discussed in
<xref target="RFC8620">JMAP</xref> <xref target="RFC8620">JMAP</xref>
and <xref target="RFC5228">Sieve</xref> and <xref target="RFC5228">Sieve</xref>
apply to this specification.</t> apply to this specification.</t>
<t>Additionally, implementations MUST treat Sieve script content <t>Additionally, implementations <bcp14>MUST</bcp14> treat Sieve script co
as untrusted data. As such, script parsers MUST fail gracefully ntent
as untrusted data. As such, script parsers <bcp14>MUST</bcp14> fail grace
fully
in the face of syntactically invalid or malicious content and in the face of syntactically invalid or malicious content and
MUST be prepared to deal with resource exhaustion (E.g., <bcp14>MUST</bcp14> be prepared to deal with resource exhaustion (e.g.,
allocation of enormous strings, lists, or command blocks). allocation of enormous strings, lists, or command blocks).
</t> </t>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>IANA Considerations</name> <name>IANA Considerations</name>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>JMAP Capability Registration for "sieve"</name> <name>JMAP Capability Registration for "sieve"</name>
<t>IANA will register the "sieve" JMAP Capability as follows: <t>IANA has registered "sieve" in the "JMAP Capabilities" registry as fo
</t> llows:
<t>Capability Name:
<tt>urn:ietf:params:jmap:sieve</tt>
</t>
<t>Specification document: this document
</t>
<t>Intended use: common
</t>
<t>Change Controller: IETF
</t>
<t>Security and privacy considerations: this document,
<xref target="security"/>
</t> </t>
<dl spacing="normal">
<dt>Capability Name:</dt><dd><tt>urn:ietf:params:jmap:sieve</tt></dd>
<dt>Reference:</dt><dd>RFC 9661</dd>
<dt>Intended Use:</dt><dd>common</dd>
<dt>Change Controller:</dt><dd>IETF</dd>
<dt>Security and Privacy Considerations:</dt><dd>RFC 9661,
<xref target="security"/></dd>
</dl>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>JMAP Data Type Registration for "SieveScript"</name> <name>JMAP Data Type Registration for "SieveScript"</name>
<t>IANA will register the "SieveScript" JMAP Data Type as follows: <t>IANA has registered "SieveScript" in the "JMAP Data Types" registry a
</t> s follows:
<t>Type Name: <tt>SieveScript</tt>
</t>
<t>Can Reference Blobs: yes
</t>
<t>Can Use for State Change: yes
</t>
<t>Capability:
<tt>urn:ietf:params:jmap:sieve</tt>
</t>
<t>Specification document: this document
</t> </t>
<dl spacing="normal">
<dt>Type Name:</dt><dd><tt>SieveScript</tt></dd>
<dt>Can Reference Blobs:</dt><dd>Yes</dd>
<dt>Can Use for State Change:</dt><dd>Yes</dd>
<dt>Capability:</dt><dd><tt>urn:ietf:params:jmap:sieve</tt></dd>
<dt>Reference:</dt><dd>RFC 9661</dd>
</dl>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>JMAP Error Codes Registry</name> <name>JMAP Error Codes Registry</name>
<t> <t>
The following sub-sections register two new error codes in the IANA has registered the following two new error codes in the
JMAP Error Codes registry, as defined in "JMAP Error Codes" registry, as defined in
<xref target="RFC8620"/>. <xref target="RFC8620"/>.
</t> </t>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>invalidSieve</name> <name>invalidSieve</name>
<t>JMAP Error Code: invalidSieve </t> <dl spacing="normal">
<t>Intended use: common </t> <dt>JMAP Error Code:</dt><dd>invalidSieve</dd>
<t>Change controller: IETF </t> <dt>Intended Use:</dt><dd>common</dd>
<t>Reference: This document, <xref target="set"/> </t> <dt>Change Controller:</dt><dd>IETF</dd>
<t>Description: The SieveScript violates the <dt>Reference:</dt><dd>RFC 9661, <xref target="set"/></dd>
<xref target="RFC5228">Sieve grammar</xref> and/or one <dt>Description:</dt><dd>The SieveScript violates the
<xref target="RFC5228">Sieve grammar</xref>, and/or one
or more extensions mentioned in the script's "require" or more extensions mentioned in the script's "require"
statement(s) are not supported by the Sieve interpreter.</t> statement(s) are not supported by the Sieve interpreter.</dd>
</dl>
</section> </section>
<section numbered="true" toc="default"> <section numbered="true" toc="default">
<name>sieveIsActive</name> <name>sieveIsActive</name>
<t>JMAP Error Code: sieveIsActive </t> <dl spacing="normal">
<t>Intended use: common </t> <dt>JMAP Error Code:</dt><dd>sieveIsActive</dd>
<t>Change controller: IETF </t> <dt>Intended Use:</dt><dd>common</dd>
<t>Reference: This document, <xref target="set"/> </t> <dt>Change Controller:</dt><dd>IETF</dd>
<t>Description: The client tried to destroy the active <dt>Reference:</dt><dd>RFC 9661, <xref target="set"/></dd>
SieveScript.</t> <dt>Description:</dt><dd>The client tried to destroy the active
SieveScript.</dd>
</dl>
</section> </section>
</section> </section>
</section> </section>
<section numbered="true" toc="default">
<name>Acknowledgments</name>
<t>The concepts in this document are based largely on those in
<xref target="RFC5804"/>.
The author would like to thank the authors of that document for
providing both inspiration and some borrowed text for this
document.</t>
<t>The author would also like to thank the following
individuals for contributing their ideas and support for
writing this specification: Joris Baum, Mauro De Gennaro,
Bron Gondwana, Neil Jenkins, Alexey Melnikov, and Ricardo Signes.</t>
</section>
</middle> </middle>
<back> <back>
<references> <references>
<name>References</name> <name>References</name>
<references> <references>
<name>Normative References</name> <name>Normative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2
FC.2119.xml"/> 119.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8
FC.8174.xml"/> 174.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8
FC.8620.xml"/> 620.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8
FC.8621.xml"/> 621.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5228.xml"/> 228.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3
FC.3986.xml"/> 986.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5435.xml"/> 435.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6
FC.6134.xml"/> 134.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3
FC.3629.xml"/> 629.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5198.xml"/> 198.xml"/>
</references> </references>
<references> <references>
<name>Informative References</name> <name>Informative References</name>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5232.xml"/> 232.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5463.xml"/> 463.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5
FC.5804.xml"/> 804.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9
FC.9112.xml"/> 112.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9
FC.9404.xml"/> 404.xml"/>
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.R <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9
FC.9425.xml"/> 425.xml"/>
</references> </references>
</references> </references>
<section numbered="true" toc="default"> <section numbered="false" toc="default">
<name>Change History <name>Acknowledgments</name>
(To be removed by RFC Editor before publication)</name> <t>The concepts in this document are based largely on those in
<t>Changes since ietf-21: <xref target="RFC5804"/>.
</t> The author would like to thank the authors of that document for
<ul spacing="normal"> providing both inspiration and some borrowed text for this
<li>Rearranged and tweaked some /validate text.</li> document.</t>
</ul> <t>The author would also like to thank the following
<t>Changes since ietf-20: individuals for contributing their ideas and support for
</t> writing this specification: <contact fullname="Joris Baum"/>, <contact ful
<ul spacing="normal"> lname="Mauro De Gennaro"/>,
<li>Listed Unicode characters prohibited in script names.</li> <contact fullname="Bron Gondwana"/>, <contact fullname="Neil Jenkins"/>, <
<li>Cleaned up the language of the optional /set arguments.</li> contact fullname="Alexey Melnikov"/>, and <contact fullname="Ricardo Signes"/>.<
<li>Added security considerations about parsing Sieve script /t>
content.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-19:
</t>
<ul spacing="normal">
<li>Tweaked the example captions.</li>
</ul>
<t>Changes since ietf-18:
</t>
<ul spacing="normal">
<li>Edited JMAP API examples for brevity to match other JMAP
specs, and added explanatory text to 1.1.</li>
<li>Updated &lt;xref&gt; elements to to use "section" and
"sectionFormat" attributes.</li>
</ul>
<t>Changes since ietf-17:
</t>
<ul spacing="normal">
<li>Several editorial changes resulting from IESG review
comments.</li>
<li>Added a section discussuing quotas.</li>
</ul>
<t>Changes since ietf-16:
</t>
<ul spacing="normal">
<li>Renamed the "invalidScript" and "scriptIsActive" SetErrors
to "invalidSieve" and "sieveIsActive" respectively.</li>
</ul>
<t>Changes since ietf-15:
</t>
<ul spacing="normal">
<li>Added registration for SieveScript JMAP Data Type.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-14:
</t>
<ul spacing="normal">
<li>Updated reference for JMAP Blobs.</li>
</ul>
<t>Changes since ietf-13:
</t>
<ul spacing="normal">
<li>Added implementation argument to capabilities.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-12:
</t>
<ul spacing="normal">
<li>Added onSuccessDeactivateScipt argument to /set
method.</li>
<li>Clarified that the "isActive" property must be included in the
created/uodated/destroyed arguments in a response of the
active script is changed and/or deactivated.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-11:
</t>
<ul spacing="normal">
<li>Fixed examples to be proper JSON and JMAP.</li>
</ul>
<t>Changes since ietf-10:
</t>
<ul spacing="normal">
<li>Fixed SieveScript/set response deactivating script example.</li>
<li>Fixed line line nit in Blob/get request.</li>
<li>Removed unused references.</li>
</ul>
<t>Changes since ietf-09:
</t>
<ul spacing="normal">
<li>Fixed Blob/upload request in example.</li>
</ul>
<t>Changes since ietf-08:
</t>
<ul spacing="normal">
<li>Fixed Blob/upload response in example.</li>
<li>Removed SieveScript/test method (to be written as an
extension document).</li>
</ul>
<t>Changes since ietf-07:
</t>
<ul spacing="normal">
<li>Updated example to use Blob/upload rather than Blob/set.</li>
</ul>
<t>Changes since ietf-06:
</t>
<ul spacing="normal">
<li>None (refreshed to avoid expiration).</li>
</ul>
<t>Changes since ietf-05:
</t>
<ul spacing="normal">
<li>Converted source from xml2rfc v2 to v3.</li>
<li>Added examples for SieveScript/get.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-04:
</t>
<ul spacing="normal">
<li>SieveScript/test: Switched from using a JSON array for each
completed action and its args to a JSON object.</li>
<li>Switched to referencing draft-ietf-jmap-blob.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-03:
</t>
<ul spacing="normal">
<li>SieveScript/test: Moved positional arguments into their own
array (because the specfications don't use a consistent method for
defining the action syntax or naming of positional arguments).</li>
</ul>
<t>Changes since ietf-02:
</t>
<ul spacing="normal">
<li>Removed open issues.</li>
<li>Reverted back to using only blob ids for script content.</li>
<li>Added "rateLimit" and "requestTooLarge" to the list of
possible error codes for /set method.</li>
<li>Added Compatibility with JMAP Vacation Response
section.</li>
<li>Added RFC5228 to Security Considerations.</li>
<li>Miscellaneous editorial changes.</li>
</ul>
<t>Changes since ietf-01:
</t>
<ul spacing="normal">
<li>Removed normative references to ManageSieve (RFC 5804).</li>
<li>Added the 'maxSizeScriptName' capability.</li>
<li>Made the 'name' property in the SieveScript object
optional.</li>
<li>Added requirements for the 'name' property in the
SieveScript object.</li>
<li>Removed the 'blobId' property from the SieveScript
object.</li>
<li>Removed the 'replaceOnCreate' argument from the /set
method.</li>
<li>Removed the 'blobId' argument from the /validate method.</li>
<li>Removed the 'scriptBlobId' argument from, and added the
'scriptContent' argument to, the /test method.</li>
<li>Editorial fixes from Neil Jenkins and Ricardo Signes.</li>
<li>Other miscellaneous text reorganization and editorial fixes.</li>
</ul>
<t>Changes since ietf-00:
</t>
<ul spacing="normal">
<li>Specified that changes made by onSuccessActivateScript MUST
be reported in the /set response as created and/or updated as
appropriate.</li>
<li>Reworked and specified more of the /test response based on
implementation experience.</li>
</ul>
<t>Changes since murchison-01:
</t>
<ul spacing="normal">
<li>Explicitly stated that Sieve capability strings are
case-sensitive.</li>
<li>errorDescription is now String|null.</li>
<li>Added /query method.</li>
<li>Added /test method.</li>
</ul>
<t>Changes since murchison-00:
</t>
<ul spacing="normal">
<li>Added IANA registration for "scriptIsActive" JMAP error code.</li>
<li>Added open issue about /set{create} with an existing script name.</l
i>
</ul>
</section> </section>
</back> </back>
</rfc> </rfc>
 End of changes. 148 change blocks. 
592 lines changed or deleted 348 lines changed or added

This html diff was produced by rfcdiff 1.48.