Skip to content

Commit

Permalink
Mail: Remove duplicative text
Browse files Browse the repository at this point in the history
The JMAP Mail spec should just be:

1. The data type definitions
2. Which standard method types can be used with each data type (e.g. Threads
   are immutable so there is no setThreads method).
3. Any changes to the standard method for that particular type (extra arguments
   etc.)

This makes the spec *much* shorter, more understandable and easier to implement.

This commit does the get/getUpdates/set methods. The getList/getListUpdates
methods will receive similar treatment in a future commit.

This commit causes the following minor semantic (rather than editorial) changes:

* A new "singleton" SetError is defined for setVacationResponse, as technically
  you can pass it created/destroy arguments as per a standard setFoos.
* Following standard getFoos pattern, getThreads now takes an optional
  "properties" argument.
  • Loading branch information
neilj committed Oct 23, 2017
1 parent fe39389 commit 1a112f6
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 785 deletions.
144 changes: 13 additions & 131 deletions spec/mail/identity.mdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A **Identity** object stores information about an email address (or domain) the user may send from. It has the following properties:

- **id**: `String`
The id of the identity. This property is immutable.
The id of the identity. This property is immutable and may only be set by the server.
- **name**: `String`
The "From" *name* the client SHOULD use when creating a new message from this identity.
- **email**: `String`
Expand All @@ -21,145 +21,27 @@ A **Identity** object stores information about an email address (or domain) the

Multiple identities with the same email address MAY exist, to allow for different settings the user wants to pick between (for example with different names/signatures).

## getIdentities

Identities can either be fetched explicitly by id, or all of them at once. To fetch identities, make a call to `getIdentities`. It takes the following arguments:

- **accountId**: `String|null`
The Account to fetch the identities for. If `null`, the primary account is used.
- **ids**: `String[]|null`
The ids of the identities to fetch. If `null`, all identities in the account are be fetched.

The response to *getIdentities* is called *identities*. It has the following arguments:

- **accountId**: `String`
The id of the account used for the call.
- **state**: `String`
A string encoding the current state on the server. This string will change
if any identities change (that is, a new identity is created, a change is made to an existing identity, or an identity is deleted). It can be passed to *getIdentityUpdates* to efficiently get the list of changes from the previous state.
- **list**: `Identity[]`
An array of the Identity objects requested. This will be the **empty array** if the *ids* argument was the empty array, or contained only ids for identities that could not be found.
- **notFound**: `String[]|null`
This array contains the ids passed to the method for identities that do not exist, or `null` if all requested ids were found. It MUST be `null` if the *ids* argument in the call was `null`.
The following JMAP methods are supported:

The following errors may be returned instead of the *identities* response:

`accountNotFound`: Returned if an *accountId* was explicitly included with the request, but it does not correspond to a valid account.

`accountNotSupportedByMethod`: Returned if the *accountId* given corresponds to a valid account, but the account does not support this data type.
## getIdentities

`invalidArguments`: Returned if one of the arguments is of the wrong type, or otherwise invalid. A `description` property MAY be present on the response object to help debug with an explanation of what the problem was.
Standard *getFoos* method. The *ids* argument may be `null` to fetch all at once.

## getIdentityUpdates

The *getIdentityUpdates* call allows a client to efficiently update the state of its cached identities to match the new state on the server. It takes the following arguments:

- **accountId**: `String|null`
The id of the account to use for this call. If `null`, the primary account will be used.
- **sinceState**: `String`
The current state of the client. This is the string that was returned as the *state* argument in the *identities* response. The server will return the changes made since this state.
- **maxChanges**: `Number|null`
The maximum number of Identity ids to return in the response. The server MAY choose to clamp this value to a particular maximum or set a maximum if none is given by the client. If supplied by the client, the value MUST be a positive integer greater than 0. If a value outside of this range is given, the server MUST reject the call with an `invalidArguments` error.
- **fetchRecords**: `Boolean|null`
If `true`, immediately after outputting an *identityUpdates* response, an implicit call will be made to *getidentities* with the *changed* property of the response as the *ids* argument, and the *fetchRecordProperties* argument as the *properties* argument. If `false` or `null`, no implicit call is made.

The response to *getIdentityUpdates* is called *identityUpdates*. It has the following arguments:

- **accountId**: `String`
The id of the account used for the call.
- **oldState**: `String`
This is the *sinceState* argument echoed back; the state from which the server is returning changes.
- **newState**: `String`
This is the state the client will be in after applying the set of changes to the old state.
- **hasMoreUpdates**: `Boolean`
If `true`, the client may call *getIdentityUpdates* again with the *newState* returned to get further updates. If `false`, *newState* is the current server state.
- **changed**: `String[]`
An array of Identity ids where a property of the identity has changed between the old state and the new state, or the identity has been created, and the identity has not been destroyed.
- **removed**: `String[]`
An array of Identity ids for identities which have been destroyed since the old state.

If a *maxChanges* is supplied, or set automatically by the server, the server must try to limit the number of ids across *changed* and *removed* to the number given. If there are more changes than this between the client's state and the current server state, the update returned MUST take the client to an intermediate state, from which the client can continue to call *getIdentityUpdates* until it is fully up to date. The server MAY return more ids than the *maxChanges* total if this is required for it to be able to produce an update to an intermediate state, but it SHOULD try to keep it close to the maximum requested.

If an identity has been modified AND deleted since the oldState, the server should just return the id in the *removed* array, but MAY return it in the *changed* array as well. If an identity has been created AND deleted since the oldState, the server SHOULD remove the identity id from the response entirely, but MAY include it in the *removed* array.

The following errors may be returned instead of the `identityUpdates` response:

`accountNotFound`: Returned if an *accountId* was explicitly included with the request, but it does not correspond to a valid account.

`accountNotSupportedByMethod`: Returned if the *accountId* given corresponds to a valid account, but the account does not support this data type.

`invalidArguments`: Returned if the request does not include one of the required arguments, or one of the arguments is of the wrong type, or otherwise invalid. A `description` property MAY be present on the response object to help debug with an explanation of what the problem was.

`cannotCalculateChanges`: Returned if the server cannot calculate the changes from the state string given by the client. Usually due to the client's state being too old, or the server being unable to produce an update to an intermediate state when there are too many updates. The client MUST invalidate its Identity cache.
Standard *getFooUpdates* method.

## setIdentities

Modifying the state of Identity objects on the server is done via the *setIdentities* method. This encompasses creating, updating and destroying Identity records.

The *setIdentities* method takes the following arguments:

- **accountId**: `String|null`
The id of the account to use for this call. If `null`, the primary account will be used.
- **ifInState**: `String|null`
This is a state string as returned by the *getIdentities* method. If supplied, the string must match the current state, otherwise the method MUST be aborted and a `stateMismatch` error returned. If `null`, any changes will be applied to the current state.
- **create**: `String[Identity]|null`
A map of *creation id* (an arbitrary string set by the client) to Identity objects (containing all properties except the id).
- **update**: `String[Identity]|null`
A map of id to Identity objects. The object may omit any property; only properties that have changed need be included.
- **destroy**: `String[]|null`
A list of ids for Identity objects to permanently delete.

Each creation, modification or destruction of an object is considered an atomic unit. It is permissible for the server to commit changes to some objects but not others, however it is not permissible to only commit part of an update to a single identity.

If a create, update or destroy is rejected, the appropriate error MUST be added to the notCreated/notUpdated/notDestroyed property of the response and the server MUST continue to the next create/update/destroy. It does not terminate the method.

A **create** MAY be rejected with one of the following errors:

- `maxQuotaReached`: Returned if the user has reached a server-defined limit on the number of identities.
- `emailNotPermitted`: Returned if the user tries to create an identity with an email address the user does not allow them to send from.

If the identity has `mayDeleteIdentity == false`, any attempt to destroy it MUST be rejected with a `forbidden` error.

If an id given cannot be found, the update or destroy MUST be rejected with a `notFound` set error.

The response to *setIdentities* is called *identitiesSet*. It has the following arguments:

- **accountId**: `String`
The id of the account used for the call.
- **oldState**: `String|null`
The state string that would have been returned by *getIdentities* before making the requested changes, or `null` if the server doesn't know what the previous state string was.
- **newState**: `String`
The state string that will now be returned by *getIdentities*.
- **created**: `String[Identity]`
A map of the creation id to an object containing the **id** property for all successfully created identities.
- **updated**: `String[Identity|null]`
The *keys* in this map are the ids of all identities that were successfully updated. If the server made any other changes to the record beyond those explicitly requested by the client, the *value* for the corresponding id in the map is an object containing the updated value of each property the **server changed**. Otherwise (if no properties changed on the server other than those explicitly updated by the client), the value is `null`.
- **destroyed**: `String[]`
A list of ids for identities that were successfully destroyed.
- **notCreated**: `String[SetError]`
A map of creation id to a SetError object for each identity that failed to be created. The possible errors are defined in the description of the method for specific data types.
- **notUpdated**: `String[SetError]`
A map of Identity id to a SetError object for each identity that failed to be updated. The possible errors are defined in the description of the method for specific data types.
- **notDestroyed**: `String[SetError]`
A map of Identity id to a SetError object for each identity that failed to be destroyed. The possible errors are defined in the description of the method for specific data types.

A **SetError** object has the following properties:

- **type**: `String`
The type of error.
- **description**: `String|null`
A description of the error to display to the user.

The following errors may be returned instead of the *identitiesSet* response:

`accountNotFound`: Returned if an *accountId* was explicitly included with the request, but it does not correspond to a valid account.

`accountNotSupportedByMethod`: Returned if the *accountId* given corresponds to a valid account, but the account does not support this data type.
Standard *setFoos* method. The following extra *SetError* types are defined:

`accountReadOnly`: Returned if the account has MailCapabilities with `isReadOnly == true`.
For **create**:

`requestTooLarge`: Returned if the total number of objects to create, update or destroy exceeds the maximum number the server is willing to process in a single method call.
- `maxQuotaReached`: The user has reached a server-defined limit on the number
of identities.
- `emailNotPermitted`: The user is not alloed to send from the address given as
the *email* property of the identity.

`invalidArguments`: Returned if one of the arguments is of the wrong type, or otherwise invalid. A *description* property MAY be present on the response object to help debug with an explanation of what the problem was.
For **destroy**:

`stateMismatch`: Returned if an *ifInState* argument was supplied and it does not match the current state.
- `forbidden`: Returned if the identity's *mayDelete* value is `false`.

0 comments on commit 1a112f6

Please sign in to comment.