Revision control

Copy as Markdown

Other Tools

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
#include "nsIArray.idl"
#include "nsISupportsPrimitives.idl"
#include "MailNewsTypes2.idl"
interface nsIMsgDBHdr;
interface nsIRequest;
interface nsIStreamListener;
interface nsIMsgIncomingServer;
interface nsIInputStream;
interface nsIMsgCopyServiceListener;
interface nsIURI;
interface nsIUrlListener;
// Forward declarations of callback classes defined later in this file.
interface IEwsFolderListener;
interface IEwsMessageSyncListener;
interface IEwsMessageCreateListener;
interface IEwsMessageFetchListener;
interface IEwsSimpleOperationListener;
interface IEwsFallibleOperationListener;
/**
* A client for communicating with a Microsoft Exchange server via Exchange Web
* Services.
*
* This interface is intended to provide an abstraction of EWS operations to
* bridge the foreign function interface between the components of a Thunderbird
* mail protocol implementation and a single implementation of those EWS ops.
*
* With the exception of initialization, all client operations are intended to
* be asynchronous, with implementations of the callback interfaces used to
* handle the results of the operations or handle errors.
*/
[scriptable, uuid(4a117361-653b-48a5-9ddb-588482ef9dbb)]
interface IEwsClient : nsISupports
{
/**
* Initializes a new client with the necessary host address and authentication
* details to communicate with an Exchange server.
*
* @param endpoint - The HTTP(S) address of an Exchange server's EWS endpoint.
* @param server - An incoming server entity corresponding to an EWS-capable
* account.
* @param overrideOAuthDetails - Whether or not to override OAuth default issuer details.
* @param applicationId - The override value for the application (client) ID.
* @param tenantId - The override value for the tenant ID.
* @param redirectUri - The override value for the redirect URI.
* @param endpointHost - The override value for the endpoint host, which also
* identifies the issuer domain.
* @param scopes - The override value for the OAuth scopes.
*/
void initialize(
in AUTF8String endpoint,
in nsIMsgIncomingServer server,
in boolean overrideOAuthDetails,
in AUTF8String applicationId,
in AUTF8String tenantId,
in AUTF8String redirectUri,
in AUTF8String endpointHost,
in AUTF8String scopes);
/**
* Checks that the current client configuration is able to connect and
* authenticate against an EWS server.
*
* EWS does not have a dedicated endpoint that can be queried for this, so
* instead we test this by attempting to look up the account's root mail
* folder, since it results in a fairly small request and represents the first
* operation performed when adding the account to Thunderbird.
*
* @param listener - Listener to communicate the success or failure of the
* check.
* @returns The client's EWS endpoint's URL.
*/
nsIURI checkConnectivity(in nsIUrlListener listener);
/**
* Synchronizes the local folder listing with changes made on the remote
* Exchange server.
*
* @param listener - Listener for communicating changes to the folder list and
* to the recorded synchronization state.
* @param syncStateToken - A synchronization state token provided by a prior
* sync request, or an empty string to indicate that this is the initial
* sync.
*/
void syncFolderHierarchy(in IEwsFolderListener listener, in AUTF8String syncStateToken);
/**
* Creates a new folder on the Exchange server as a child of the specified
* parent.
*
* @param listener - Listener that propagates the success or failure of the
* folder creation operation to the consumer.
* @param parentId - The EWS ID of the folder under which to create the new
* folder.
* @param name - The name to use for the new folder.
*/
void createFolder(in IEwsSimpleOperationListener listener, in AUTF8String parentId, in AUTF8String name);
/**
* Synchronizes the local message listing for the given folder with changes
* made on the remote Exchange server.
*
* @param listener - Listener for communicating changes to the message list
* and to the recorded synchronization state.
* @param folderId - The EWS ID of the folder which message list to
* synchronize.
* @param syncStateToken - A synchronization state token provided by a prior
* sync request, or an empty string to indicate that this is the initial
* sync.
*/
void syncMessagesForFolder(in IEwsMessageSyncListener listener, in AUTF8String folderId, in AUTF8String syncStateToken);
/**
* Retrieves the content of a message on the Exchange server.
*
* @param listener - Listener to communicate the operation's state and status,
* as well as the message's content, to the consumer.
* @param id - The EWS ID of the message to fetch.
*/
void getMessage(in IEwsMessageFetchListener listener, in AUTF8String id);
/**
* Changes the read/unread status of one or more messages on the Exchange
* server.
*
* @param messageIds - The EWS IDs of the messages which read/unread status to
* change.
* @param isRead - The new read/unread state for the message, indicating
* whether the message should be marked as read.
*/
void changeReadStatus(in Array<AUTF8String> messageIds, in boolean isRead);
/**
* Creates a new message on the server using the data read from the stream.
*
* @param listener - Listener to indicate operation state and status.
* @param folderId - The EWS ID of the folder.
* @param isDraft - Whether the message being created is an unsent draft.
* @param isRead - Whether the message has already been read.
* @param messageStream - The input stream to read the message from.
*/
void createMessage(in IEwsMessageCreateListener listener,
in AUTF8String folderId,
in boolean isDraft,
in boolean isRead,
in nsIInputStream messageStream);
/**
* Deletes the messages with the given EWS IDs from the server.
*
* @param listener - Listener to indicate the success or failure of the
* message deletion operation.
* @param messageEwsIds - The EWS IDs of the messages to delete.
*/
void deleteMessages(in IEwsSimpleOperationListener listener, in Array<AUTF8String> messageEwsIds);
/**
* Deletes a folder on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the
* folder deletion operation.
* @param folderId - The EWS ID of the folder to delete.
*/
void deleteFolder(in IEwsSimpleOperationListener listener, in AUTF8String folderId);
/**
* Renames a folder on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the
* folder update operation to rename the folder.
* @param folderId - The EWS ID of the folder to rename.
*/
void updateFolder(in IEwsSimpleOperationListener listener, in AUTF8String folderId, in AUTF8String folderName);
/**
* Moves items on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the move
* operation.
* @param destinationFolderId - The EWS ID of the destination folder.
* @param itemIds - A list of the EWS IDs of the items to be moved.
*/
void moveItems(in IEwsSimpleOperationListener listener, in AUTF8String destinationFolderId, in Array<AUTF8String> itemIds);
/**
* Copies items on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the copy
* operation.
* @param destinationFolderId - The EWS ID of the destination folder.
* @param itemIds - A list of the EWS IDs of the items to be copied.
*/
void copyItems(in IEwsSimpleOperationListener listener, in AUTF8String destinationFolderId, in Array<AUTF8String> itemIds);
/**
* Moves folders on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the move
* operation.
* @param destinationFolderId - The EWS ID of the destination folder.
* @param itemIds - A list of the EWS IDs of the folders to be moved.
*/
void moveFolders(in IEwsSimpleOperationListener listener, in AUTF8String destinationFolderId, in Array<AUTF8String> folderIds);
/**
* Copies folders on the Exchange server.
*
* @param listener - Listener to indicate the success or failure of the copy
* operation.
* @param destinationFolderId - The EWS ID of the destination folder.
* @param itemIds - A list of the EWS IDs of the folders to be copied.
*/
void copyFolders(in IEwsSimpleOperationListener listener, in AUTF8String destinationFolderId, in Array<AUTF8String> folderIds);
/**
* Mark an item as Junk or not junk.
*
* @param listener - Callbacks to indicate the success or failure of the operation.
* @param itemIds - The EWS IDs for the items to mark as junk or not junk.
* @param isJunk - Whether to mark as junk or not junk.
* @param legacyDestinationFolderId - The EWS ID as the folder to use as the junk folder for
* older versions of Exchange that do not support the `MarkAsJunk` operation.
*/
void markItemsAsJunk(
in IEwsSimpleOperationListener listener,
in Array<AUTF8String> itemIds,
in boolean isJunk,
in AUTF8String legacyDestinationFolderId);
};
[scriptable, uuid(5dacc994-30e0-42f7-94c8-52756638add5)]
interface IEwsFolderListener : nsISupports
{
/**
* Called on the first sync when we have requested and received the EWS ID for
* the account's root folder.
*
* The EWS client is responsible for ensuring this is only called in the first
* sync.
*
* @param id - The root folder's EWS ID.
*/
void onNewRootFolder(in AUTF8String id);
/**
* Called if a folder has been created on the server.
*
* This may be called multiple times in a single sync if multiple folders
* have been created since the last sync.
*
* @param id - The new folder's EWS ID.
* @param parentId - The EWS ID for the new folder's parent folder.
* @param name - The new folder's name.
* @param flags - The `nsMsgFolderFlags` for the new folder.
*/
void onFolderCreated(in AUTF8String id, in AUTF8String parentId, in AUTF8String name, in unsigned long flags);
/**
* Called if an existing folder has been updated on the server.
*
* An update can mean the folder has been either renamed or moved to a new
* parent.
*
* This may be called multiple times in a single sync if multiple folders
* have been created since the last sync.
*
* @param id - The folder's EWS ID.
* @param parentId - The EWS ID for the folder's parent folder.
* @param name - The folder's name.
*/
void onFolderUpdated(in AUTF8String id, in AUTF8String parentId, in AUTF8String name);
/**
* Called if an existing folder has been deleted on the server.
*
* This may be called multiple times in a single sync if multiple folders
* have been created since the last sync.
*
* @param id - The folder's EWS ID.
*/
void onFolderDeleted(in AUTF8String id);
/**
* Called after a sync has completed.
*
* In this context, a sync having completed does not necessarily mean the
* client has stopped syncing, because the server might have told it there is
* more data to sync than what could be included in one sync. In this case,
* the client will sync again (and call this method again).
*
* @param syncStateToken - The new sync state token to use in future syncs.
*/
void onSyncStateTokenChanged(in AUTF8String syncStateToken);
/**
* Called after processing everything there was to sync from the server.
*
* Unlike `onSyncStateTokenChanged`, this will only be called after all the
* necessary sync operations have completed (rather than at the end of each
* one).
*/
void onSuccess();
};
/**
* Callbacks used when interacting with an EWS server via an `IEwsClient` in the
* context of synchronizing changes to the message list.
*
* These callbacks allow the `IEwsClient` instance to perform local operation on
* the folder that is being synchronized.
*/
[scriptable, uuid(dec2ddd5-b5a2-4724-bfc7-e5de31840f76)]
interface IEwsMessageSyncListener : nsISupports
{
/**
* Called when a new message has been created on the server.
*
* Implementations are expected to check if a database entry already exists
* for the given EWS ID, and return `NS_ERROR_ILLEGAL_VALUE` if so.
*
* @param ewsId - The EWS ID for the new message.
* @returns A detached database entry for the new message.
*/
nsIMsgDBHdr onMessageCreated(in AUTF8String ewsId);
/**
* Called when an existing message has been updated on the server.
*
* Implementations are expected to return `NS_ERROR_NOT_AVAILABLE` if no
* database entry exists for the given EWS ID.
*
* @param ewsId - The EWS ID for the updated message.
* @returns An existing (non-detached) database entry for the message.
*/
nsIMsgDBHdr onMessageUpdated(in AUTF8String ewsId);
/**
* Called when the read/unread flag was changed for a specific message.
*
* When a message is marked as read/unread on the EWS server, the EWS server
* will represent this either as an `Update` element or `ReadFlagChange`
* element (presumably for older versions of Exchange Server) when syncing the
* message list.
*
* If the server represents changes to read/unread flags as `ReadFlagChange`,
* then this method will be called, otherwise only `onMessageUpdated` will be
* called.
*
* @param ewsId - The EWS ID for the updated message.
* @param IsRead - The new read/unread status for the message.
*/
void onReadStatusChanged(in AUTF8String ewsId, in boolean isRead);
/**
* Called when an existing message has been deleted on the server.
*
* @param ewsId - The EWS ID for the deleted message.
*/
void onMessageDeleted(in AUTF8String ewsId);
/**
* Called when a detached database entry has been populated for a new message
* and is ready to be persisted.
*
* @param hdr - The database entry that was populated.
*/
void onDetachedHdrPopulated(in nsIMsgDBHdr hdr);
/**
* Called when an existing (non-detached) database entry has been changed, and
* the changes are ready to be persisted (i.e. committed).
*
* Since the database entry is already attached to the relevant message
* database, no argument is necessary here.
*/
void onExistingHdrChanged();
/**
* Called after a sync has completed.
*
* In this context, a sync having completed does not necessarily mean the
* client has stopped syncing, because the server might have told it there is
* more data to sync than what could be included in one sync. In this case,
* the client will sync again (and call this method again).
*
* @param syncStateToken - The new sync state token to use in future syncs.
*/
void onSyncStateTokenChanged(in AUTF8String syncStateToken);
/**
* Called after processing everything there was to sync from the server.
*
* Unlike `onSyncStateTokenChanged`, this will only be called after all the
* necessary sync operations have completed (rather than at the end of each
* one).
*/
void onSyncComplete();
};
/**
* A set of callbacks called during the creation of a new message on an Exchange
* server.
*/
[scriptable, uuid(ff45569f-d618-4bb0-9686-6cb24b92b02b)]
interface IEwsMessageCreateListener : nsISupports
{
/**
* Inform consumers that the message creation has finished, both on the server
* and the relevant local database and message store, with the provided
* status.
*
* This will still be called if `onRemoteCreateSuccessful` is.
*
* @param status - The status describing the operation's outcome.
*/
void onStopCreate(in nsresult status);
/**
* Inform consumers of the key for the newly-created message in the local
* message database.
*
* @param msgKey - The key for the new message.
*/
void onNewMessageKey(in nsMsgKey msgKey);
/**
* Signal that the message was correctly created on the server.
*
* This does not signal the end of the message creation operation (as the
* client still has some processing to work through at this point), just the
* remote part.
*
* `nsIMsgDBHdr` is a type quite strongly associated with the message database
* and storage, and, going forwards, we'll want to decouple these interfaces
* from local storage management. We use currently use it because we don't
* have a better way to represent structured headers over the XPCOM boundary,
* and parsing RFC822 messages is easier in Rust than using the C++ message
* parser. We should revisit our use of `nsIMsgDBHdr` in client code when the
* situation improves.
*
* @param ewsId - The EWS ID of the new message.
* @returns A new `nsIMsgDBHdr` object to update with the message's metadata
* and to commit to the message database
*/
nsIMsgDBHdr onRemoteCreateSuccessful(in AUTF8String ewsId);
/**
* Inform consumers that the provided `nsIMsgDBHdr` has been fully populated
* and is ready to be persisted.
*
* @param hdr - The `nsIMsgDBHdr` that has been populated.
*/
void onHdrPopulated(in nsIMsgDBHdr hdr);
};
/**
* A listener used when downloading message content.
*
* Its shape is loosely based on `nsIStreamListener`, which cannot be used in
* this instance because we don't always have a request/channel that can be used
* in method calls when fetching a message's content (and using `nullptr`
* everywhere is quite ugly and potentially unsafe).
*/
[scriptable, uuid(027150b1-d127-41a9-8945-18f9374755b3)]
interface IEwsMessageFetchListener : nsISupports
{
void onFetchStart();
void onFetchedDataAvailable(in nsIInputStream inputStream, in unsigned long count);
void onFetchStop(in nsresult status);
};
/**
* A listener for "simple" operations, which only report a success to the
* consumer.
*/
[scriptable, uuid(0217030b-dcad-4289-914f-48bad6693f2e)]
interface IEwsSimpleOperationListener : nsISupports {
/**
* Signals a successful completion of the EWS operation.
*
* @param newIds - If the operation involves generating new EWS identifiers
* for one or several entities, they are included in this array. Otherwise,
* this is an empty array.
* @param useLegacyFallback - Whether the client has decided the Exchange
* server is too old to perform the operation the "normal" way and we need
* to fall back to a "legacy" behaviour. What the normal and legacy
* behaviours are, and whether there's even a difference in behaviour
* depending on the server version, depends on the specific operation.
*/
void onOperationSuccess(in Array<AUTF8String> newIds, in boolean useLegacyFallback);
};
/**
* A listener for operations which failures we want to report to the consumer.
*
* This interface will likely not be implemented on its own but be QI'd from an
* object of a different type (e.g. `IEwsSimpleOperationListener`).
*/
[scriptable, uuid(50b04351-609c-4650-b915-81e2b8e209c0)]
interface IEwsFallibleOperationListener : nsISupports {
/**
* Signals an error causing the operation to be aborted.
*
* @param status - The status describing the error.
*/
void onOperationFailure(in nsresult status);
};