diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/chat/components/public | |
parent | Initial commit. (diff) | |
download | thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/chat/components/public')
17 files changed, 1920 insertions, 0 deletions
diff --git a/comm/chat/components/public/imIAccount.idl b/comm/chat/components/public/imIAccount.idl new file mode 100644 index 0000000000..0fcf210d1c --- /dev/null +++ b/comm/chat/components/public/imIAccount.idl @@ -0,0 +1,331 @@ +/* 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 "prplIConversation.idl" +#include "imIUserStatusInfo.idl" + +interface imITag; +interface imIBuddy; +interface prplIAccountBuddy; +interface imIAccount; +interface prplIAccount; +interface prplIProtocol; +interface nsIScriptError; +interface nsITransportSecurityInfo; + +/* + * Used to join chat rooms. + */ + +[scriptable, uuid(7e91accd-f04c-4787-9954-c7db4fb235fb)] +interface prplIChatRoomFieldValues: nsISupports { + AUTF8String getValue(in AUTF8String aIdentifier); + void setValue(in AUTF8String aIdentifier, in AUTF8String aValue); +}; + +[scriptable, uuid(19dff981-b125-4a70-bc1a-efc783d07137)] +interface prplIChatRoomField: nsISupports { + readonly attribute AUTF8String label; + readonly attribute AUTF8String identifier; + readonly attribute boolean required; + + const short TYPE_TEXT = 0; + const short TYPE_PASSWORD = 1; + const short TYPE_INT = 2; + + readonly attribute short type; + readonly attribute long min; + readonly attribute long max; +}; + +/* + * Information about a chat room and the fields required to join it. + */ +[scriptable, uuid(017d5951-fdd0-4f26-b697-fcc138cd2861)] +interface prplIRoomInfo: nsISupports { + readonly attribute AUTF8String name; + readonly attribute AUTF8String topic; + + const long NO_PARTICIPANT_COUNT = -1; + + readonly attribute long participantCount; + readonly attribute prplIChatRoomFieldValues chatRoomFieldValues; +}; + +/* + * Callback passed to an account's requestRoomInfo function. + */ +[scriptable, function, uuid(43102a36-883a-421d-a6ac-126aafee5a28)] +interface prplIRoomInfoCallback: nsISupports { + /* aRooms is an array of chatroom names. This will be called + * multiple times as batches of chat rooms are received. The number of rooms + * in each batch is left for the prplIAccount implementation to decide. + * aCompleted will be true when aRooms is the last batch. + */ + void onRoomInfoAvailable(in Array<AString> aRooms, in boolean aCompleted); +}; + +/** + * Encryption session of the prplIAccount. Usually every logged in device that + * can encrypt will have its own session. + */ +[scriptable, uuid(0254d011-44b3-40a1-8589-d2fd4a18a421)] +interface prplISession: nsISupports { + /** ID of this session as displayed to the user. */ + readonly attribute AUTF8String id; + /** Whether this session is trusted. */ + readonly attribute boolean trusted; + /** Indicates that this is the session we're currently using */ + readonly attribute boolean currentSession; + /** + * Verify the identity of this session. + * + * @returns {Promise<imISessionVerification>} + */ + Promise verify(); +}; + +/* + * This interface should be implemented by the protocol plugin. + */ +[scriptable, uuid(3ce02a3c-f38b-4a1e-9050-a19bea1cb6c1)] +interface prplIAccount: nsISupports { + readonly attribute imIAccount imAccount; + + // observe should only be called by the imIAccount + // implementation to report user status changes that affect this account. + void observe(in nsISupports aObj, in string aEvent, + [optional] in wstring aData); + + // This should only be called by the imIAccountsService + // implementation, never directly. It will call + // imIContactsService.accountBuddyRemoved on each buddy of the + // account and close all prplIConversation instances of the account. + void remove(); + + /* Uninitialize the prplIAccount instance. This is typically done + automatically at shutdown (by the core service) or as part of + the 'remove' method. */ + void unInit(); + + void connect(); + void disconnect(); + + prplIConversation createConversation(in AUTF8String aName); + + // Used when the user wants to add a buddy to the buddy list + void addBuddy(in imITag aTag, in AUTF8String aName); + + // Used while loading the buddy list at startup. + prplIAccountBuddy loadBuddy(in imIBuddy aBuddy, in imITag aTag); + + /* Request more info on a buddy (typically a chat buddy). + * The result (if any) will be provided by user-info-received + * notifications dispatched through the observer service: + * - aSubject will be an nsISimpleEnumerator of prplITooltipInfo. + * - aData will be aBuddyName. + * If multiple user-info-received are sent, subsequent notifications + * will update any previous data. + */ + void requestBuddyInfo(in AUTF8String aBuddyName); + + readonly attribute boolean canJoinChat; + Array<prplIChatRoomField> getChatRoomFields(); + prplIChatRoomFieldValues getChatRoomDefaultFieldValues([optional] in AUTF8String aDefaultChatName); + + /* Request information on available chat rooms, whose names are returned + * via the callback. + */ + void requestRoomInfo(in prplIRoomInfoCallback aCallback); + prplIRoomInfo getRoomInfo(in AUTF8String aRoomName); + readonly attribute boolean isRoomInfoStale; + + /* + * Create a new chat conversation if it doesn't already exist. + */ + void joinChat(in prplIChatRoomFieldValues aComponents); + + // A name that can be used to check for duplicates and is the basis + // for the directory name for log storage. + readonly attribute AUTF8String normalizedName; + // Request that the account normalizes a name. Use this only when an object + // providing a normalizedName doesn't exist yet or isn't accessible. + AUTF8String normalize(in AUTF8String aName); + + // protocol specific options: those functions set the protocol + // specific options for the prplIAccount + void setBool(in string aName, in boolean aVal); + void setInt(in string aName, in long aVal); + void setString(in string aName, in AUTF8String aVal); + + /* When a connection error occurred, this value indicates the type of error */ + readonly attribute short connectionErrorReason; + + /** + * When a certificate error occurs, the host/port that caused a + * SSL/certificate error when connecting to it. This is only valid when + * connectionErrorReason is one of ERROR_CERT_* + */ + readonly attribute AUTF8String connectionTarget; + /** + * When a certificate error occurs, the nsITransportSecurityInfo error of + * the socket. This should only be set when connectionTarget is set. + */ + readonly attribute nsITransportSecurityInfo securityInfo; + + /* Possible connection error reasons: + ERROR_NETWORK_ERROR and ERROR_ENCRYPTION_ERROR are not fatal and + should enable the automatic reconnection feature. */ + const short NO_ERROR = -1; + const short ERROR_NETWORK_ERROR = 0; + const short ERROR_INVALID_USERNAME = 1; + const short ERROR_AUTHENTICATION_FAILED = 2; + const short ERROR_AUTHENTICATION_IMPOSSIBLE = 3; + const short ERROR_NO_SSL_SUPPORT = 4; + const short ERROR_ENCRYPTION_ERROR = 5; + const short ERROR_NAME_IN_USE = 6; + const short ERROR_INVALID_SETTINGS = 7; + const short ERROR_CERT_NOT_PROVIDED = 8; + const short ERROR_CERT_UNTRUSTED = 9; + const short ERROR_CERT_EXPIRED = 10; + const short ERROR_CERT_NOT_ACTIVATED = 11; + const short ERROR_CERT_HOSTNAME_MISMATCH = 12; + const short ERROR_CERT_FINGERPRINT_MISMATCH = 13; + const short ERROR_CERT_SELF_SIGNED = 14; + const short ERROR_CERT_OTHER_ERROR = 15; + const short ERROR_OTHER_ERROR = 16; + + /** + * Get a list of active encryption sessions for the account. + * The protocol sends a "account-sessions-changed" notification when + * the trust state of a session changes, or entries are added or removed. + */ + Array<prplISession> getSessions(); + + /** + * Information as to the state of encryption capabilities of this account. For + * example Matrix surfaces the secret storage, key backup and cross-signing + * status info here. + * The protocol sends a "account-encryption-status-changed" notification when + * this chanes. + */ + readonly attribute Array<AUTF8String> encryptionStatus; +}; + + +[scriptable, uuid(488959b4-992e-4626-ae96-beaf6adc4a77)] +interface imIDebugMessage: nsISupports { + const short LEVEL_DEBUG = 1; + const short LEVEL_LOG = 2; + const short LEVEL_WARNING = 3; + const short LEVEL_ERROR = 4; + readonly attribute short logLevel; // One of the above constants. + readonly attribute nsIScriptError message; +}; + +/* This interface should be implemented by the im core. It inherits +from prplIAccount and in most cases will forward the calls for the +inherited members to a prplIAccount account instance implemented by +the protocol plugin. */ +[scriptable, uuid(20a85b44-e220-4f23-85bf-f8523d1a2b08)] +interface imIAccount: prplIAccount { + /* Check if autologin is enabled for this account, connect it now. */ + void checkAutoLogin(); + + /* Cancel the timer that automatically reconnects the account if it was + disconnected because of a non fatal error. */ + void cancelReconnection(); + + readonly attribute AUTF8String name; + readonly attribute AUTF8String id; + readonly attribute unsigned long numericId; + readonly attribute prplIProtocol protocol; + readonly attribute prplIAccount prplAccount; + + // Save account specific preferences to disk. + void save(); + + attribute boolean autoLogin; + + /* This is the value when the preference firstConnectionState is not set. + It indicates that the account has already been successfully connected at + least once with the current parameters. */ + const short FIRST_CONNECTION_OK = 0; + /* Set when the account has never had a successful connection + with the current parameters */ + const short FIRST_CONNECTION_UNKNOWN = 1; + /* Set when the account is trying to connect for the first time + with the current parameters (removed after a successsful connection) */ + const short FIRST_CONNECTION_PENDING = 2; + /* Set at startup when the previous state was pending */ + const short FIRST_CONNECTION_CRASHED = 4; + + attribute short firstConnectionState; + + /* Passwords are stored in the toolkit Password Manager. + * Warning: Don't attempt to access passwords during startup before + * Services.login.initializationPromise has resolved. + */ + attribute AUTF8String password; + + attribute AUTF8String alias; + + /* While an account is connecting, this attribute contains a message + indicating the current step of the connection */ + readonly attribute AUTF8String connectionStateMsg; + + /* Number of the reconnection attempt + * 0 means that no automatic reconnection currently pending + * n means the nth reconnection attempt is pending + */ + readonly attribute unsigned short reconnectAttempt; + + /* Time stamp of the next reconnection attempt */ + readonly attribute long long timeOfNextReconnect; + + /* Time stamp of the last connection (value not reliable if not connected) */ + readonly attribute long long timeOfLastConnect; + + /* Additional possible connection error reasons: + * (Use a big enough number that it can't conflict with error + * codes used in prplIAccount). + */ + const short ERROR_UNKNOWN_PRPL = 42; + const short ERROR_CRASHED = 43; + const short ERROR_MISSING_PASSWORD = 44; + + /* A message describing the connection error */ + readonly attribute AUTF8String connectionErrorMessage; + + /* Info about the connection state and flags */ + const short STATE_DISCONNECTED = 0; + const short STATE_CONNECTED = 1; + const short STATE_CONNECTING = 2; + const short STATE_DISCONNECTING = 3; + + readonly attribute short connectionState; + + /* The following 4 properties use the above connectionState value. */ + readonly attribute boolean disconnected; + readonly attribute boolean connected; + readonly attribute boolean connecting; + readonly attribute boolean disconnecting; + + void logDebugMessage(in nsIScriptError aMessage, in short aLevel); + + /* Get an array of the 50 most recent debug messages. */ + Array<imIDebugMessage> getDebugMessages(); + + /* The imIUserStatusInfo instance this account should observe for + status changes. When this is null (the default value), the + account will observe the global status. */ + attribute imIUserStatusInfo observedStatusInfo; + // Same as above, but never null (it fallbacks to the global status info). + attribute imIUserStatusInfo statusInfo; + + // imIAccount also implements an observe method but this + // observe should only be called by the prplIAccount + // implementations to report connection status changes. +}; diff --git a/comm/chat/components/public/imIAccountsService.idl b/comm/chat/components/public/imIAccountsService.idl new file mode 100644 index 0000000000..38a2d52a12 --- /dev/null +++ b/comm/chat/components/public/imIAccountsService.idl @@ -0,0 +1,63 @@ +/* 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 "imIAccount.idl" + +[scriptable, uuid(b3b6459a-5c26-47b8-8e9c-ba838b6f632a)] +interface imIAccountsService: nsISupports { + void initAccounts(); + void unInitAccounts(); + + /* This attribute is set to AUTOLOGIN_ENABLED by default. It can be set to + any other value before the initialization of this service to prevent + accounts with autoLogin enabled from being connected when libpurple is + initialized. + Any value other than the ones listed below will disable autoLogin and + display a generic message in the Account Manager. */ + attribute short autoLoginStatus; + + const short AUTOLOGIN_ENABLED = 0; + const short AUTOLOGIN_USER_DISABLED = 1; + const short AUTOLOGIN_SAFE_MODE = 2; + const short AUTOLOGIN_CRASH = 3; + const short AUTOLOGIN_START_OFFLINE = 4; + + /* The method should be used to connect all accounts with autoLogin enabled. + Some use cases: + - if the autologin was disabled at startup + - after a loss of internet connectivity that disconnected all accounts. + */ + void processAutoLogin(); + + imIAccount getAccountById(in AUTF8String aAccountId); + + /* will throw NS_ERROR_FAILURE if not found */ + imIAccount getAccountByNumericId(in unsigned long aAccountId); + + Array<imIAccount> getAccounts(); + + /* will fire the event account-added */ + imIAccount createAccount(in AUTF8String aName, in AUTF8String aPrpl); + + /* will fire the event account-removed */ + void deleteAccount(in AUTF8String aAccountId); +}; + +/* + account related notifications sent to nsIObserverService: + - account-added: a new account has been created + - account-removed: the account has been deleted + - account-connecting: the account is being connected + - account-connected: the account is now connected + - account-connect-error: the account is disconnect with an error. + (before account-disconnecting) + - account-disconnecting: the account is being disconnected + - account-disconnected: the account is now disconnected + - account-updated: when some settings have changed + - account-list-updated: when the list of account is reordered. + These events can be watched using an nsIObserver. + The associated imIAccount will be given as a parameter + (except for account-list-updated). +*/ diff --git a/comm/chat/components/public/imICommandsService.idl b/comm/chat/components/public/imICommandsService.idl new file mode 100644 index 0000000000..9011a673b0 --- /dev/null +++ b/comm/chat/components/public/imICommandsService.idl @@ -0,0 +1,79 @@ +/* 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" +interface prplIConversation; + +[scriptable, uuid(b12b0d89-0e5b-499c-9567-37f2deacc182)] +interface imICommand: nsISupports { + readonly attribute AUTF8String name; + + // Help message displayed when the user types /help <name>. + // Format: <command name> <parameters>: <help message> + // Example: "help <name>: show the help message for the <name> + // command, or the list of possible commands when used without + // parameter." + readonly attribute AUTF8String helpString; + + const short CMD_CONTEXT_IM = 1; + const short CMD_CONTEXT_CHAT = 2; + const short CMD_CONTEXT_ALL = CMD_CONTEXT_IM | CMD_CONTEXT_CHAT; + readonly attribute long usageContext; + + const short CMD_PRIORITY_LOW = -1000; + const short CMD_PRIORITY_DEFAULT = 0; + const short CMD_PRIORITY_PRPL = 1000; + const short CMD_PRIORITY_HIGH = 4000; + // Any integer value is usable as a priority. + // 0 is the default priority. + // < 0 is lower priority. + // > 0 is higher priority. + // Commands registered by protocol plugins will usually use PRIORITY_PRPL. + readonly attribute long priority; + + // Will return true if the command handled the message (it should not be sent). + // The leading slash, the command name and the following space are not included + // in the aMessage parameter. + // If a conversation is returned as a result of executing the command, + // the caller should consider focusing it. + boolean run(in AUTF8String aMessage, + [optional] in prplIConversation aConversation, + [optional] out prplIConversation aReturnedConv); +}; + +[scriptable, uuid(9a1accfd-9bd8-4548-aef7-e8107fc7839f)] +interface imICommandsService: nsISupports { + void initCommands(); + void unInitCommands(); + + // Commands registered without a protocol id will work for all protocols. + // Registering several commands of the same name with the same + // protocol id or no protocol id will replace the former command + // with the latter. + void registerCommand(in imICommand aCommand, + [optional] in AUTF8String aPrplId); + + // aPrplId should be the same as what was used for the command registration. + void unregisterCommand(in AUTF8String aCommandName, + [optional] in AUTF8String aPrplId); + + Array<imICommand> listCommandsForConversation( + [optional] in prplIConversation aConversation); + + Array<imICommand> listCommandsForProtocol(in AUTF8String aPrplId); + + // Will return true if a command handled the message (it should not be sent). + // The aConversation parameters is required to execute protocol specific + // commands. Application global commands will work without it. + // If a conversation is returned as a result of executing the command, + // the caller should consider focusing it. + boolean executeCommand(in AUTF8String aMessage, + [optional] in prplIConversation aConversation, + [optional] out prplIConversation aReturnedConv); +}; + +%{ C++ +#define IM_COMMANDS_SERVICE_CONTRACTID \ + "@mozilla.org/chat/commands-service;1" +%} diff --git a/comm/chat/components/public/imIContactsService.idl b/comm/chat/components/public/imIContactsService.idl new file mode 100644 index 0000000000..d0f42dbac0 --- /dev/null +++ b/comm/chat/components/public/imIContactsService.idl @@ -0,0 +1,290 @@ +/* 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 "imIStatusInfo.idl" +#include "imITagsService.idl" +#include "nsISupports.idl" +#include "nsIObserver.idl" + +interface imIContact; +interface imIBuddy; +interface prplIAccountBuddy; +interface imIAccount; +interface prplIProtocol; + +[scriptable, uuid(45ce33d9-d335-4cce-b904-44821987e048)] +interface imIContactsService: nsISupports { + void initContacts(); + void unInitContacts(); + + imIContact getContactById(in long aId); + // Get an array of all existing contacts. + Array<imIContact> getContacts(); + imIBuddy getBuddyById(in long aId); + imIBuddy getBuddyByNameAndProtocol(in AUTF8String aNormalizedName, + in prplIProtocol aPrpl); + prplIAccountBuddy getAccountBuddyByNameAndAccount(in AUTF8String aNormalizedName, + in imIAccount aAccount); + + // These 3 functions are called by the protocol plugins when + // synchronizing the buddy list with the server stored list, + // or after user operations have been performed. + void accountBuddyAdded(in prplIAccountBuddy aAccountBuddy); + void accountBuddyRemoved(in prplIAccountBuddy aAccountBuddy); + void accountBuddyMoved(in prplIAccountBuddy aAccountBuddy, + in imITag aOldTag, in imITag aNewTag); + + // These methods are called by the imIAccountsService implementation + // to keep the accounts table in sync with accounts stored in the + // preferences. + + // Called when an account is created or loaded to store the new + // account or ensure it doesn't conflict with an existing account + // (to detect database corruption). + // Will throw if a stored account has the id aId but a different + // username or prplId. + void storeAccount(in unsigned long aId, in AUTF8String aUserName, + in AUTF8String aPrplId); + // Check if an account id already exists in the database. + boolean accountIdExists(in unsigned long aId); + // Called when deleting an account to remove it from blist.sqlite. + void forgetAccount(in unsigned long aId); +}; + +/** + * An imIContact represents a person, e.g. our friend Alice. This person might + * have multiple means of contacting them. + * + * Remember that an imIContact can have multiple buddies (imIBuddy instances), + * each imIBuddy can have multiple account-buddies (prplIAccountBuddy instances) + * referencing it. To be explicit, the difference is that an imIBuddy represents + * a contact's account on a network, while a prplIAccountBuddy represents the + * link between your account and your contact's account. + * + * Each of these implement imIStatusInfo: imIContact and imIBuddy should merge + * the status info based on the information available in their instances of + * imIBuddy and prplIAccountBuddy, respectively. + */ +[scriptable, uuid(f585b0df-f6ad-40d5-9de4-c58b14af13e4)] +interface imIContact: imIStatusInfo { + // The id will be positive if the contact is real (stored in the + // SQLite database) and negative if the instance is a dummy contact + // holding only a single buddy without aliases or additional tags. + readonly attribute long id; + attribute AUTF8String alias; + + Array<imITag> getTags(); + + // Will do nothing if the contact already has aTag. + void addTag(in imITag aTag); + // Will throw if the contact doesn't have aTag or doesn't have any other tag. + void removeTag(in imITag aTag); + + readonly attribute imIBuddy preferredBuddy; + Array<imIBuddy> getBuddies(); + + // Move all the buddies of aContact into the current contact, + // and copy all its tags. + void mergeContact(in imIContact aContact); + + // Change the position of aBuddy in the current contact. + // The new position is the current position of aBeforeBuddy if it is + // specified, or at the end otherwise. + void moveBuddyBefore(in imIBuddy aBuddy, [optional] in imIBuddy aBeforeBuddy); + + // Remove aBuddy from its current contact and append it to the list + // of buddies of the current contact. + // aBuddy should not already be attached to the current contact. + void adoptBuddy(in imIBuddy aBuddy); + + // Returns a new contact that contains only aBuddy, and has the same + // list of tags. + // Will throw if aBuddy is not a buddy of the contact. + imIContact detachBuddy(in imIBuddy aBuddy); + + // remove the contact from the buddy list. Will also remove the + // associated buddies. + void remove(); + + void addObserver(in nsIObserver aObserver); + void removeObserver(in nsIObserver aObserver); + /* Observers will be notified of changes related to the contact. + * aSubject will point to the imIContact object + * (with some exceptions for contact-moved-* notifications). + * + * Fired notifications: + * contact-availability-changed + * when either statusType or availabilityDetails has changed. + * contact-signed-on + * contact-signed-off + * contact-status-changed + * when either statusType or statusText has changed. + * contact-display-name-changed + * when the alias (or serverAlias of the most available buddy if + * no alias is set) has changed. + * The old display name is provided in aData. + * contact-preferred-buddy-changed + * The buddy that would be favored to start a conversation has changed. + * contact-moved, contact-moved-in, contact-moved-out + * contact-moved is notified through the observer service + * contact-moved-in is notified to + * - the contact observers (aSubject is the new tag) + * - the new tag (aSubject is the contact instance) + * contact-moved-out is notified to + * - the contact observers (aSubject is the old tag) + * - the old tag (aSubject is the contact instance) + * contact-no-longer-dummy + * When a real contact is created to replace a dummy contact. + * The old (negative) id will be given in aData. + * See also the comment above the 'id' attribute. + * contact-icon-changed + * + * Observers will also receive all the (forwarded) notifications + * from the linked buddies (imIBuddy instances) and their account + * buddies (prplIAccountBuddy instances). + */ + + // Exposed for add-on authors. All internal calls will come from the + // imIContact implementation itself so it wasn't required to expose this. + // This can be used to dispatch custom notifications to the + // observers of the contact and its tags. + // The notification will also be forwarded to the observer service. + void notifyObservers(in nsISupports aObj, in string aEvent, + [optional] in wstring aData); +}; + +/** + * An imIBuddy represents a person's account on a particular network. Note that + * what a network is depends on the implementation of the prpl, e.g. for AIM + * there is only a single network, but both GTalk and XMPP are the same network. + * + * E.g. Our contact Alice has two accounts on the Foo network: @lic4 and + * alice88; and she has a single account on the Bar network: _alice_. This would + * result in an imIBuddy instance for each of these: @lic4, alice88, and _alice_ + * that would all exist as part of the same imIContact. + */ +[scriptable, uuid(c56520ba-d923-4b95-8416-ca6733c4a38e)] +interface imIBuddy: imIStatusInfo { + readonly attribute long id; + readonly attribute prplIProtocol protocol; + readonly attribute AUTF8String userName; // may be formatted + // A name that can be used to check for duplicates and is the basis + // for the directory name for log storage. + readonly attribute AUTF8String normalizedName; + // The optional server alias is in displayName (inherited from imIStatusInfo) + // displayName = serverAlias || userName. + + readonly attribute imIContact contact; + readonly attribute prplIAccountBuddy preferredAccountBuddy; + Array<prplIAccountBuddy> getAccountBuddies(); + + // remove the buddy from the buddy list. If the contact becomes empty, it will be removed too. + void remove(); + + void addObserver(in nsIObserver aObserver); + void removeObserver(in nsIObserver aObserver); + /* Observers will be notified of changes related to the buddy. + * aSubject will point to the imIBuddy object. + * Fired notifications: + * buddy-availability-changed + * when either statusType or availabilityDetails has changed. + * buddy-signed-on + * buddy-signed-off + * buddy-status-changed + * when either statusType or statusText has changed. + * buddy-display-name-changed + * when the serverAlias has changed. + * The old display name is provided in aData. + * buddy-preferred-account-changed + * The account that would be favored to start a conversation has changed. + * buddy-icon-changed + * + * Observers will also receive all the (forwarded) notifications + * from the linked account buddies (prplIAccountBuddy instances). + */ + + // Exposed for add-on authors. All internal calls will come from the + // imIBuddy implementation itself so it wasn't required to expose this. + // This can be used to dispatch custom notifications to the + // observers of the buddy, its contact and its tags. + // The contact will forward the notifications to the observer service. + void notifyObservers(in nsISupports aObj, in string aEvent, + [optional] in wstring aData); + + // observe should only be called by the prplIAccountBuddy + // implementations to report changes. + void observe(in nsISupports aObj, in string aEvent, + [optional] in wstring aData); +}; + +/** + * A prplIAccountBuddy represents the connection on a network between one of the + * current user's accounts and a persons's account. E.g. if we're logged into + * the Foo network as BobbyBoy91 and want to talk to Alice, there may be two + * prplIAccountBuddy instances: @lic4 as seen by BobbyBoy91 or alice88 as seen + * by BobbyBoy91. Additionally, if we also login as 8ob, there could be @lic4 as + * seen by 8ob and alice88 as seen by 8ob; but these (now four) + * prplIAccountBuddy instances would link to only TWO imIBuddy instances (one + * each for @lic4 and alice88). Note that the above uses "may be" and "could" + * because it depends on whether the contacts are on the contact list (and + * therefore have imIContact / imIBuddy instances). + * + * prplIAccountBuddy implementations send notifications to their buddy: + * + * For all of them, aSubject points to the prplIAccountBuddy object. + * + * Supported notifications: + * account-buddy-availability-changed + * when either statusType or availabilityDetails has changed. + * account-buddy-signed-on + * account-buddy-signed-off + * account-buddy-status-changed + * when either statusType or statusText has changed. + * account-buddy-display-name-changed + * when the serverAlias has changed. + * The old display name is provided in aData. + * account-buddy-icon-changed + * + * All notifications (even unsupported ones) will be forwarded to the contact, + * its tags and nsObserverService. + */ +[scriptable, uuid(0c5021ac-7acd-4118-bf4f-c0dd9cb3ddef)] +interface prplIAccountBuddy: imIStatusInfo { + // The setter is for internal use only. buddy will be set by the + // Contacts service when accountBuddyAdded is called on this + // instance of prplIAccountBuddy. + attribute imIBuddy buddy; + readonly attribute imIAccount account; + // Setting the tag will move the buddy to a different group on the + // server-stored buddy list. + attribute imITag tag; + readonly attribute AUTF8String userName; + // A name that can be used to check for duplicates and is the basis + // for the directory name for log storage. + readonly attribute AUTF8String normalizedName; + attribute AUTF8String serverAlias; + + /** Whether we can verify the identity of this buddy. */ + readonly attribute boolean canVerifyIdentity; + + /** + * True if we trust the encryption with this buddy in E2EE conversations. Can + * only be true if |canVerifyIdentity| is true. + */ + readonly attribute boolean identityVerified; + + /** + * Initialize identity verification with this buddy. + * @returns {Promise<imISessionVerification>} + */ + Promise verifyIdentity(); + + // remove the buddy from the buddy list of this account. + void remove(); + + // Called by the contacts service during its uninitialization to + // notify that all references kept to imIBuddy or imIAccount + // instances should be released now. + void unInit(); +}; diff --git a/comm/chat/components/public/imIConversationsService.idl b/comm/chat/components/public/imIConversationsService.idl new file mode 100644 index 0000000000..67affbdfcb --- /dev/null +++ b/comm/chat/components/public/imIConversationsService.idl @@ -0,0 +1,117 @@ +/* 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 "prplIConversation.idl" +#include "prplIMessage.idl" +#include "imIContactsService.idl" + +interface imIMessage; + +[scriptable, uuid(81b8d9a9-4715-4109-b522-84b9d31493a3)] +interface imIConversation: prplIConversation { + // Will be null for MUCs and IMs from people not in the contacts list. + readonly attribute imIContact contact; + + // Write a system message into the conversation. + // Note: this will not be logged. + void systemMessage(in AUTF8String aMessage, + [optional] in boolean aIsError, + [optional] in boolean aNoCollapse); + + // Write a system message into the conversation and trigger the update of the + // notification counter during an off-the-record authentication request. + // Note: this will not be logged. + void notifyVerifyOTR(in AUTF8String aMessage); + + attribute prplIConversation target; + + // Number of unread messages (all messages, including system + // messages are counted). + readonly attribute unsigned long unreadMessageCount; + // Number of unread incoming messages targeted at the user (= IMs or + // message containing the user's nick in MUCs). + readonly attribute unsigned long unreadTargetedMessageCount; + // Number of unread incoming messages (both targeted and untargeted + // messages are counted). + readonly attribute unsigned long unreadIncomingMessageCount; + // Number of unread off-the-record authentication requests. + readonly attribute unsigned long unreadOTRNotificationCount; + // Reset all unread message counts. + void markAsRead(); + + // Can be used instead of the topic when no topic is set. + readonly attribute AUTF8String noTopicString; + + // Call this to give the core an opportunity to close an inactive + // conversation. If the conversation is a left MUC or an IM + // conversation without unread message, the implementation will call + // close(). + // The returned value indicates if the conversation was closed. + boolean checkClose(); + + // Get an array of all messages of the conversation. + Array<imIMessage> getMessages(); +}; + +[scriptable, uuid(984e182c-d395-4fba-ba6e-cc80c71f57bf)] +interface imIConversationsService: nsISupports { + void initConversations(); + void unInitConversations(); + + // Register a conversation. This will create a unique id for the + // conversation and set it. + void addConversation(in prplIConversation aConversation); + void removeConversation(in prplIConversation aConversation); + + Array<imIConversation> getUIConversations(); + imIConversation getUIConversation(in prplIConversation aConversation); + imIConversation getUIConversationByContactId(in long aId); + + Array<prplIConversation> getConversations(); + prplIConversation getConversationById(in unsigned long aId); + prplIConversation getConversationByNameAndAccount(in AUTF8String aName, + in imIAccount aAccount, + in boolean aIsChat); +}; + +// Because of limitations in libpurple (write_conv is called without context), +// there's an implicit contract that whatever message string the conversation +// service passes to a protocol, it'll get back as the originalMessage when +// "new-text" is notified. This is required for the OTR extensions to work. + +// A cancellable outgoing message. Before handing a message off to a protocol, +// the conversation service notifies observers of `preparing-message` and +// `sending-message` (typically add-ons) of an outgoing message, which can be +// transformed or cancelled. +[scriptable, uuid(f88535b1-0b99-433b-a6de-c1a4bf8b43ea)] +interface imIOutgoingMessage: nsISupports { + attribute AUTF8String message; + attribute boolean cancelled; + /** Outgoing message is an action command. */ + readonly attribute boolean action; + /** Outgoing message is a notice */ + readonly attribute boolean notification; + readonly attribute prplIConversation conversation; +}; + +// A cancellable message to be displayed. When the conversation service is +// notified of a `new-text` (ie. an incoming or outgoing message to be +// displayed), it in turn notifies observers of `received-message` +// (again, typically add-ons), which have the opportunity to swap or cancel +// the message. +[scriptable, uuid(3f88cc5c-6940-4eb5-a576-c65770f49ce9)] +interface imIMessage: prplIMessage { + attribute boolean cancelled; + // Holds the sender color for Chats. + // Empty string by default, it is set by the conversation binding. + attribute AUTF8String color; + + // What eventually gets shown to the user. + attribute AUTF8String displayMessage; + + // The related incoming or outgoing message is transmitted + // with encryption through OTR. + attribute boolean otrEncrypted; +}; diff --git a/comm/chat/components/public/imICoreService.idl b/comm/chat/components/public/imICoreService.idl new file mode 100644 index 0000000000..08ae1d2fbe --- /dev/null +++ b/comm/chat/components/public/imICoreService.idl @@ -0,0 +1,28 @@ +/* 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 "imIUserStatusInfo.idl" +#include "prplIProtocol.idl" + +[scriptable, uuid(205d4b2b-1ccf-4879-9ef1-f08942566151)] +interface imICoreService: nsISupports { + readonly attribute boolean initialized; + + // This will emit a prpl-init notification. After this point the 'initialized' + // attribute will be 'true' and it's safe to access the services for accounts, + // contacts, conversations and commands. + void init(); + + // This will emit a prpl-quit notification. This is the last opportunity to + // use the aforementioned services before they are uninitialized. + void quit(); + + // Returns the available protocols. + Array<prplIProtocol> getProtocols(); + + prplIProtocol getProtocolById(in AUTF8String aProtocolId); + + readonly attribute imIUserStatusInfo globalUserStatus; +}; diff --git a/comm/chat/components/public/imILogger.idl b/comm/chat/components/public/imILogger.idl new file mode 100644 index 0000000000..fd8e632d5d --- /dev/null +++ b/comm/chat/components/public/imILogger.idl @@ -0,0 +1,86 @@ +/* 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 "nsIFile.idl" + +interface imIAccount; +interface prplIAccountBuddy; +interface imIBuddy; +interface imIContact; +interface imIMessage; +interface prplIConversation; + +[scriptable, uuid(7771402c-ff55-41f5-86b4-59b93f9b0693)] +interface imILogConversation: nsISupports { + readonly attribute AUTF8String title; + readonly attribute AUTF8String name; + // Value in microseconds. + readonly attribute PRTime startDate; + + // Simplified account implementation: + // - alias will always be empty + // - name (always the normalizedName) + // - statusInfo will return IMServices.core.globalUserStatus + // - protocol will only contain a "name" attribute, with the prpl's normalized name. + // Other methods/attributes aren't implemented. + readonly attribute imIAccount account; + + readonly attribute boolean isChat; // always false (compatibility with prplIConversation). + readonly attribute prplIAccountBuddy buddy; // always null (compatibility with prplIConvIM). + + Array<imIMessage> getMessages(); +}; + +[scriptable, uuid(27712ece-ad2c-4504-87d5-9e2c16d40fef)] +interface imILog: nsISupports { + readonly attribute AUTF8String path; + // Value in seconds. + readonly attribute PRTime time; + readonly attribute AUTF8String format; + // Returns a promise that resolves to an imILogConversation instance, or null + // if the log format isn't JSON. + jsval getConversation(); +}; + +[scriptable, function, uuid(2ab5f8ac-4b89-4954-9a4a-7c167f1e3b0d)] +interface imIProcessLogsCallback: nsISupports { + // The callback can return a promise. If it does, then it will not be called + // on the next log until this promise resolves. If it throws (or rejects), + // iteration will stop. + jsval processLog(in AUTF8String aLogPath); +}; + +[scriptable, uuid(7e2476dc-8199-4454-9661-b78ee73fa49e)] +interface imILogger: nsISupports { + // Returns a promise that resolves to an imILog instance. + jsval getLogFromFile(in AUTF8String aFilePath, [optional] in boolean aGroupByDay); + // Returns a promise that resolves to the log file paths if a log writer + // exists for the conversation, or null otherwise. The promise resolves + // after any pending I/O operations on the files complete. + jsval getLogPathsForConversation(in prplIConversation aConversation); + + // Below methods return promises that resolve to {imILog[]}. + + // Get logs for a contact. + jsval getLogsForContact(in imIContact aContact); + // Get logs for a conversation. + jsval getLogsForConversation(in prplIConversation aConversation); + // Get logs that are from the same conversation. + jsval getSimilarLogs(in imILog aLog); + + // Asynchronously iterates through log folders for all prpls and accounts and + // invokes the callback on every log file. Returns a promise that resolves when + // iteration is complete. If the callback returns a promise, iteration pauses + // until the promise resolves. If the callback throws (or rejects), iteration + // will stop and the returned promise will reject with the same error. + jsval forEach(in imIProcessLogsCallback aCallback); + + // Returns the folder storing all logs for aAccount. + AUTF8String getLogFolderPathForAccount(in imIAccount aAccount); + + // Removes the folder storing all logs for aAccount. + // Be sure the account is disconnected before using this. + jsval deleteLogFolderForAccount(in imIAccount aAccount); +}; diff --git a/comm/chat/components/public/imIStatusInfo.idl b/comm/chat/components/public/imIStatusInfo.idl new file mode 100644 index 0000000000..0338886923 --- /dev/null +++ b/comm/chat/components/public/imIStatusInfo.idl @@ -0,0 +1,55 @@ +/* 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 "prplIConversation.idl" + +interface prplITooltipInfo; + +[scriptable, uuid(f13dc4fc-5334-45cb-aa58-a92851955e55)] +interface imIStatusInfo: nsISupports { + // Name suitable for display in the UI. Can either be the username, + // the server side alias, or the user set local alias of the contact. + readonly attribute AUTF8String displayName; + readonly attribute AUTF8String buddyIconFilename; + + const short STATUS_UNKNOWN = 0; + const short STATUS_OFFLINE = 1; + const short STATUS_INVISIBLE = 2; + const short STATUS_MOBILE = 3; + const short STATUS_IDLE = 4; + const short STATUS_AWAY = 5; + const short STATUS_UNAVAILABLE = 6; + const short STATUS_AVAILABLE = 7; + + // numerical value used to compare the availability of two buddies + // based on their current status. + // Use it only for immediate comparisons, do not store the value, + // it can change between versions for a same status of the buddy. + readonly attribute long statusType; + + readonly attribute boolean online; // (statusType > STATUS_OFFLINE) + readonly attribute boolean available; // (statusType == STATUS_AVAILABLE) + readonly attribute boolean idle; // (statusType == STATUS_IDLE) + readonly attribute boolean mobile; // (statusType == STATUS_MOBILE) + + readonly attribute AUTF8String statusText; + + // Gives more detail to compare the availability of two buddies with the same + // status type. + // Example: 2 buddies may have been idle for various amounts of times. + readonly attribute long availabilityDetails; + + // True if the buddy is online or if the account supports sending + // offline messages to the buddy. + readonly attribute boolean canSendMessage; + + // Array of prplITooltipInfo components. + Array<prplITooltipInfo> getTooltipInfo(); + + // Will select the buddy automatically based on availability, and + // the account (if needed) based on the account order in the account + // manager. + prplIConversation createConversation(); +}; diff --git a/comm/chat/components/public/imITagsService.idl b/comm/chat/components/public/imITagsService.idl new file mode 100644 index 0000000000..e438c971c1 --- /dev/null +++ b/comm/chat/components/public/imITagsService.idl @@ -0,0 +1,81 @@ +/* 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 "nsIObserver.idl" + +interface imIContact; + +[scriptable, uuid(c211e5e2-f0a4-4a86-9e4c-3f6b905628a5)] +interface imITag: nsISupports { + readonly attribute long id; + attribute AUTF8String name; + + /** + * Get an array of all the contacts associated with this tag. + * + * Contacts can either "have the tag" (added by user action) or + * have inherited the tag because it was the server side group for + * one of the AccountBuddy of the contact. + */ + Array<imIContact> getContacts(); + + void addObserver(in nsIObserver aObserver); + void removeObserver(in nsIObserver aObserver); + /* Observers will be notified of changes related to the contacts + * that have the tag: contact-*, buddy-*, account-buddy-* + * notifications forwarded respectively from the imIContact, + * imIBuddy and prplIAccountBuddy instances. + */ + + // Exposed for add-on authors. All internal calls will come from the + // imITag implementation itself so it wasn't required to expose this. + // This can be used to dispatch custom notifications to the + // observers of the tag. + void notifyObservers(in nsISupports aObj, in string aEvent, + [optional] in wstring aData); +}; + +[scriptable, uuid(993aa8c7-8193-4354-8ee1-d2fd9fca692d)] +interface imITagsService: nsISupports { + // Get the default tag (ie. "Contacts" for en-US). + readonly attribute imITag defaultTag; + + /** + * Creates a new tag or gets an existing tag if one already exists. + * + * @param aName the name of the new tag. + * @returns imITag + */ + imITag createTag(in AUTF8String aName); + + /** + * Get an existing tag by ID. + * + * @param aId the numeric tag ID. + * @returns the tag or null if the tag doesn't exist. + */ + imITag getTagById(in long aId); + + /** + * Get an existing tag by name (note that this will do an SQL query). + * + * @param aName the tag name. + * @returns the tag or null if the tag doesn't exist. + */ + imITag getTagByName(in AUTF8String aName); + + /** + * Get an array of all existing tags. + * + * @returns imITag[] + */ + Array<imITag> getTags(); + + boolean isTagHidden(in imITag aTag); + void hideTag(in imITag aTag); + void showTag(in imITag aTag); + + readonly attribute imITag otherContactsTag; +}; diff --git a/comm/chat/components/public/imIUserStatusInfo.idl b/comm/chat/components/public/imIUserStatusInfo.idl new file mode 100644 index 0000000000..dba07c3190 --- /dev/null +++ b/comm/chat/components/public/imIUserStatusInfo.idl @@ -0,0 +1,55 @@ +/* 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 "nsIObserver.idl" + +//forward declarations +interface nsIFile; +interface nsIFileURL; + +[scriptable, uuid(817918fa-1f4b-4254-9cdb-f906da91c45d)] +interface imIUserStatusInfo: nsISupports { + + readonly attribute AUTF8String statusText; + + // See imIStatusInfo for the values. + readonly attribute short statusType; + + /** + * Set the user's current status (e.g. available or away). + * + * When called with the status type STATUS_UNSET, only the status + * message will be changed. + * + * @param aStatus the new status to use. Only works with STATUS_OFFLINE, + * STATUS_UNAVAILABLE, STATUS_AWAY, STATUS_AVAILABLE and STATUS_INVISIBLE. + * @param aMessage the new status message. Ignored when aStatus is STATUS_OFFLINE. + */ + void setStatus(in short aStatus, in AUTF8String aMessage); + + /** + * Sets the user icon, or removes it if null is passed as a parameter. + * + * Calling this will fire a user-icon-changed notification. + */ + void setUserIcon(in nsIFile aIconFile); + + /** + * Returns the location of the current user icon, or null if no icon is set. + */ + nsIFileURL getUserIcon(); + + /* The setter will fire a user-display-name-changed notification. */ + attribute AUTF8String displayName; + + void addObserver(in nsIObserver aObserver); + void removeObserver(in nsIObserver aObserver); + /* Observers will receive the following notifications: + * status-changed (when either the status type or text has changed) + * user-icon-changed + * user-display-name-changed + * idle-time-changed + */ +}; diff --git a/comm/chat/components/public/moz.build b/comm/chat/components/public/moz.build new file mode 100644 index 0000000000..71758d842d --- /dev/null +++ b/comm/chat/components/public/moz.build @@ -0,0 +1,25 @@ +# vim: set filetype=python: +# 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/. + +XPIDL_SOURCES += [ + "imIAccount.idl", + "imIAccountsService.idl", + "imICommandsService.idl", + "imIContactsService.idl", + "imIConversationsService.idl", + "imICoreService.idl", + "imILogger.idl", + "imIStatusInfo.idl", + "imITagsService.idl", + "imIUserStatusInfo.idl", + "prplIConversation.idl", + "prplIMessage.idl", + "prplIPref.idl", + "prplIProtocol.idl", + "prplIRequest.idl", + "prplITooltipInfo.idl", +] + +XPIDL_MODULE = "chat" diff --git a/comm/chat/components/public/prplIConversation.idl b/comm/chat/components/public/prplIConversation.idl new file mode 100644 index 0000000000..dd947337bb --- /dev/null +++ b/comm/chat/components/public/prplIConversation.idl @@ -0,0 +1,274 @@ +/* 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 "nsIObserver.idl" + +interface prplIAccountBuddy; +interface imIAccount; +interface imIOutgoingMessage; +interface imIMessage; +interface nsIURI; +interface prplIChatRoomFieldValues; + +/** + * This interface represents a conversation as implemented by a protocol. It + * contains the properties and methods shared between direct (IM) and multi + * user (chat) conversations. + */ +[scriptable, uuid(f71c58d6-2c47-4468-934b-b1c61462c01a)] +interface prplIConversation: nsISupports { + + /** + * Indicate if this conversation implements prplIConvIM or prplIConvChat. If + * this ever changes at runtime, the conversation should emit a + * "chat-update-type" notification. */ + readonly attribute boolean isChat; + + /* The account used for this conversation */ + readonly attribute imIAccount account; + + /* The name of the conversation, typically in English */ + readonly attribute AUTF8String name; + + /* A name that can be used to check for duplicates and is the basis + for the directory name for log storage. */ + readonly attribute AUTF8String normalizedName; + + /* The title of the conversation, typically localized */ + readonly attribute AUTF8String title; + + /* The time and date of the conversation's creation, in microseconds */ + readonly attribute PRTime startDate; + /* Unique identifier of the conversation */ + /* Setable only once by purpleCoreService while calling addConversation. */ + attribute unsigned long id; + + /** URI of the icon for the conversation */ + readonly attribute AUTF8String convIconFilename; + + /** + * The user can not enable encryption for this room (another participant may + * be able to enable encryption however) + */ + const short ENCRYPTION_NOT_SUPPORTED = 0; + /** + * Encryption can be initialized in this conversation. + */ + const short ENCRYPTION_AVAILABLE = 1; + /** + * New messages in this conversation are end-to-end encrypted. + */ + const short ENCRYPTION_ENABLED = 2; + /** + * Indicates that the encryption with the other side should be trusted, for + * example because the user has verified their public keys. Implies + * ENCRYPTION_ENABLED. + */ + const short ENCRYPTION_TRUSTED = 3; + + /** + * State of encryption for this conversation, as available via the protocol. + * update-conv-encryption is observed when this changes. + */ + readonly attribute short encryptionState; + + /** + * When encryptionState is ENCRYPTION_AVAILABLE this tries to initialize + * encryption for all new messages in the conversation. + */ + void initializeEncryption(); + + /** + * Send a message in the conversation. Protocols should consider resetting + * the typing state with this call, similar to |sendTyping("")|. + */ + void sendMsg(in AUTF8String aMsg, in boolean aAction, in boolean aNotice); + + /** + * Preprocess messages before they are sent (eg. split long messages). + * + * @returns the potentially modified message(s). + */ + Array<AString> prepareForSending(in imIOutgoingMessage aMsg); + + /** + * Postprocess messages before they are displayed (eg. escaping). The + * implementation can set aMsg.displayMessage, otherwise the originalMessage + * is used. + */ + void prepareForDisplaying(in imIMessage aMsg); + + /** + * Send information about the current typing state to the server. + * + * @param aString should contain the content currently in the text field. + * @returns the number of characters that can still be typed. + */ + long sendTyping(in AUTF8String aString); + const long NO_TYPING_LIMIT = 2147483647; // max int = 2 ^ 31 - 1 + + /** + * Un-initialize the conversation. + * + * This will be called by purpleCoreService::RemoveConversation + * when the conversation is closed or by purpleCoreService::Quit + * while exiting. + */ + void unInit(); + + /** + * Called when the conversation is closed from the UI. + */ + void close(); + + /** + * Method to add or remove an observer. + */ + void addObserver(in nsIObserver aObserver); + void removeObserver(in nsIObserver aObserver); + + /** + * Observers will all receive new-text and update-text notifications. + * aSubject will contain the message (prplIMessage). For update-text the + * update applies to any message with the same |remoteId| in the same + * conversation. + * The remove-text notification has no subject, but a remote ID as data. + * It indicates that the message should be removed from the conversation. + * Neither update-text nor remove-text affect unread counts. + */ +}; + +[scriptable, uuid(c0b5b647-b0ec-4dc6-9e53-31a762a30a6e)] +interface prplIConvIM: prplIConversation { + + /* The buddy at the remote end of the conversation */ + readonly attribute prplIAccountBuddy buddy; + + /* The remote buddy is not currently typing */ + const short NOT_TYPING = 0; + + /* The remote buddy is currently typing */ + const short TYPING = 1; + + /* The remote buddy started typing, but has stopped typing */ + const short TYPED = 2; + + /* The typing state of the remote buddy. + The value is NOT_TYPING, TYPING or TYPED. */ + readonly attribute short typingState; +}; + +/** This represents a participant in a chat room */ +[scriptable, uuid(b0e9177b-40f6-420b-9918-04bbbb9ce44f)] +interface prplIConvChatBuddy: nsISupports { + + /* The name of the buddy */ + readonly attribute AUTF8String name; + + /* The alias (FIXME: can this be non-null if buddy is null?) */ + readonly attribute AUTF8String alias; + + /* Indicates if this chat buddy corresponds to a buddy in our buddy list */ + readonly attribute boolean buddy; + + /** URI of the user icon for the buddy */ + readonly attribute AUTF8String buddyIconFilename; + + /* The role of the participant in the room. */ + + /* Voiced users can send messages to the room. */ + readonly attribute boolean voiced; + /* Moderators can manage other participants. */ + readonly attribute boolean moderator; + /* Admins have additional powers. */ + readonly attribute boolean admin; + /* Founders have complete control of a room. */ + readonly attribute boolean founder; + + /* Whether the participant is currently typing. */ + readonly attribute boolean typing; + + /** Whether we can verify the identity of this participant. */ + readonly attribute boolean canVerifyIdentity; + + /** + * True if we trust the encryption with this participant in E2EE chats. Can + * only be true if |canVerifyIdentity| is true. + */ + readonly attribute boolean identityVerified; + + /** + * Initialize identity verification with this participant. + * @returns {Promise<imISessionVerification>} + */ + Promise verifyIdentity(); +}; + +[scriptable, uuid(72c17398-639f-4141-a19c-78cbdeb39fba)] +interface prplIConvChat: prplIConversation { + + /** + * Get the prplIConvChatBuddy of a participant. + * + * @param aName the participant's nick in the conversation exists + * @returns prplIConvChatBuddy if the participant exists, otherwise null + */ + prplIConvChatBuddy getParticipant(in AUTF8String aName); + + /** + * Get the list of people participating in this chat. + * + * @returns an array of prplIConvChatBuddy objects. + */ + Array<prplIConvChatBuddy> getParticipants(); + + /** + * Normalize the name of a chat buddy. This will be suitable for calling + * createConversation to start a private conversation or calling + * requestBuddyInfo. + * + * @returns the normalized chat buddy name. + */ + AUTF8String getNormalizedChatBuddyName(in AUTF8String aChatBuddyName); + + /* The topic of this chat room */ + attribute AUTF8String topic; + + /* The name/nick of the person who set the topic */ + readonly attribute AUTF8String topicSetter; + + /* Whether the protocol plugin can set a topic. Doesn't check that + the user has the necessary rights in the current conversation. */ + readonly attribute boolean topicSettable; + + /* The nick seen by other people in the room */ + readonly attribute AUTF8String nick; + + /* This is true when we left the chat but kept the conversation open */ + readonly attribute boolean left; + + /* This is true if we are in the process of joining the channel */ + readonly attribute boolean joining; + + /* This stores the data required to join the chat with joinChat(). + If null, the chat will not be rejoined automatically when the + account reconnects after a disconnect. + Should be set to null by the prpl if the user parts the chat. */ + readonly attribute prplIChatRoomFieldValues chatRoomFields; + + /* Observers will receive chat-buddy-add, chat-buddy-update, + chat-buddy-remove and chat-update-topic notifications. + + aSubject will be of type: + nsISimpleEnumerator of prplIConvChatBuddy for chat-buddy-add, + nsISimpleEnumerator of nsISupportsString for chat-buddy-remove, + prplIConvChatBuddy for chat-buddy-update, + null for chat-update-topic. + + aData will contain the old nick for chat-buddy-update if the name + has changed. + */ +}; diff --git a/comm/chat/components/public/prplIMessage.idl b/comm/chat/components/public/prplIMessage.idl new file mode 100644 index 0000000000..610c6a477d --- /dev/null +++ b/comm/chat/components/public/prplIMessage.idl @@ -0,0 +1,106 @@ +/* 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 "nsIRunnable.idl" +#include "prplIConversation.idl" + +/** + * An action that the user may perform in relation to a particular message. + */ +[scriptable, uuid(7e470f0e-d948-4d9a-b8dc-4beecf6554b9)] +interface prplIMessageAction: nsIRunnable +{ + /** + * The protocol plugins need to provide a localized label suitable + * for being shown in the user interface (for example as a context + * menu item). + */ + readonly attribute AUTF8String label; +}; + +[scriptable, uuid(d6accb66-cdd2-4a91-8854-1156e65d5a43)] +interface prplIMessage: nsISupports { + /** + * The uniqueness of the message id is only guaranteed across + * messages of a conversation, not across all messages created + * during the execution of the application. + */ + readonly attribute unsigned long id; + /** + * An ID for this message provided by the protocol. Used for finding the + * message in the conversation for actions like editing. This is expected to + * be absolute per conversation, meaning if two prplIMessages in the same + * conversation have identical |remoteId|s they refer to the same message in + * the conversation as far as the protocol is concerned. + */ + readonly attribute AUTF8String remoteId; + /** The name of the message sender. */ + readonly attribute AUTF8String who; + /** The alias of the message sender (frequently the same as who). */ + readonly attribute AUTF8String alias; + /** The original message, if it was modified, e.g. via OTR. */ + readonly attribute AUTF8String originalMessage; + /** The message that will be sent over the wire. */ + attribute AUTF8String message; + /** An icon to associate with the message sender. */ + readonly attribute AUTF8String iconURL; + /** The time the message was sent, in seconds. */ + readonly attribute PRTime time; + /** The conversation the message was sent to. */ + readonly attribute prplIConversation conversation; + + /** Outgoing message. */ + readonly attribute boolean outgoing; + /** Incoming message. */ + readonly attribute boolean incoming; + /** System message, i.e. a message from the server or client (not from another user). */ + readonly attribute boolean system; + /** Auto response. */ + readonly attribute boolean autoResponse; + /** Contains your nick, e.g. if you were pinged. */ + readonly attribute boolean containsNick; + /** This message should not be logged. */ + readonly attribute boolean noLog; + /** Error message. */ + readonly attribute boolean error; + /** Delayed message, e.g. it was received from a queue of historical messages on the server. */ + readonly attribute boolean delayed; + /** "Raw" message - don't apply formatting. */ + readonly attribute boolean noFormat; + /** Message contains images. */ + readonly attribute boolean containsImages; + /** Message is a notification. */ + readonly attribute boolean notification; + /** Message should not be auto-linkified. */ + readonly attribute boolean noLinkification; + /** Do not collapse the message. */ + readonly attribute boolean noCollapse; + /** Message is encrypted. */ + readonly attribute boolean isEncrypted; + /** The message should be displayed as an action/emote. */ + readonly attribute boolean action; + /** Message was deleted, this is a placeholder for it */ + readonly attribute boolean deleted; + + /** + * Get an array of actions the user may perform on this message. + * + * @returns prplIMessageAction[] + */ + Array<prplIMessageAction> getActions(); + + /** + * Called when the message is first displayed to the user. Only invoked for + * the latest message in a conversation. + */ + void whenDisplayed(); + + /** + * Called when the message has been read by the user, as defined by it being + * above the unread marker in the conversation. Only called for the message + * immediately above the marker. + */ + void whenRead(); +}; diff --git a/comm/chat/components/public/prplIPref.idl b/comm/chat/components/public/prplIPref.idl new file mode 100644 index 0000000000..7f3f827952 --- /dev/null +++ b/comm/chat/components/public/prplIPref.idl @@ -0,0 +1,38 @@ +/* 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 "nsISimpleEnumerator.idl" + +[scriptable, uuid(8fc16882-ba8e-432a-999f-0d4dc104234b)] +interface prplIKeyValuePair: nsISupports { + readonly attribute AUTF8String name; + readonly attribute AUTF8String value; +}; + +/* + * This is a proxy for libpurple PurpleAccountOption + */ + +[scriptable, uuid(e781563f-9088-4a96-93e3-4fb6f5ce6a77)] +interface prplIPref: nsISupports { + const short typeBool = 1; + const short typeInt = 2; + const short typeString = 3; + const short typeList = 4; + + readonly attribute AUTF8String name; + readonly attribute AUTF8String label; + readonly attribute short type; + readonly attribute boolean masked; + + boolean getBool(); + long getInt(); + AUTF8String getString(); + /** + * @returns array of prplIKeyValuePair + */ + Array<prplIKeyValuePair> getList(); + AUTF8String getListDefault(); +}; diff --git a/comm/chat/components/public/prplIProtocol.idl b/comm/chat/components/public/prplIProtocol.idl new file mode 100644 index 0000000000..f6d30826f4 --- /dev/null +++ b/comm/chat/components/public/prplIProtocol.idl @@ -0,0 +1,148 @@ +/* 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 "imIAccount.idl" + +interface prplIPref; +interface prplIUsernameSplit; + +/** + * This must be implemented for every protocol. + * + * See jsProtoHelper.jsm for a base class. + */ +[scriptable, uuid(7d302db0-3813-4c51-8372-c7eb5fc9f3d3)] +interface prplIProtocol: nsISupports { + /** + * This method is used so that classes implementing several protocol + * plugins can know which protocol is desired for this instance. + * + * @param aId The prpl id. + */ + void init(in AUTF8String aId); + + /** + * A human readable (potentially localized) name for the protocol. + */ + readonly attribute AUTF8String name; + /** + * A unique ID for the protocol, should start with the prefix 'prpl-'. + */ + readonly attribute AUTF8String id; + /** + * A unique name for this protocol, it must consist of only lowercase letters + * & numbers. + * + * It can be used to check for duplicates and is the basis for the directory + * name for log storage. + */ + readonly attribute AUTF8String normalizedName; + + /** + * A chrome URI pointing to a folder that contains the icon files: + * icon.png icon32.png and icon48.png + */ + readonly attribute AUTF8String iconBaseURI; + + /** + * @returns an array of prplIPref + */ + Array<prplIPref> getOptions(); + + /** + * String to put in front of the full account username identifier. Usually + * an empty string. + */ + readonly attribute AUTF8String usernamePrefix; + + /** + * @returns an array of prplIUsernameSplit + */ + Array<prplIUsernameSplit> getUsernameSplit(); + + /** + * Split a username into its parts without separators (or prefix). + * Returns an empty array if the username can not be split. + */ + Array<AUTF8String> splitUsername(in AUTF8String aName); + + /** + * Descriptive text used in the account wizard to describe the username. + */ + readonly attribute AUTF8String usernameEmptyText; + + /** + * Use this function to avoid attempting to create duplicate accounts. + */ + boolean accountExists(in AUTF8String aName); + + // The following should all be flags that describe whether a protocol has a + // particular feature. + + /** + * Whether chat rooms have topics. + */ + readonly attribute boolean chatHasTopic; + + /** + * True if passwords are unused for this protocol. + * + * Passwords are unused for some protocols, e.g. Bonjour. + */ + readonly attribute boolean noPassword; + + /** + * True if a password is not required for sign-in. + * + * Passwords in IRC are optional, and are needed for certain functionality. + */ + readonly attribute boolean passwordOptional; + + /** + * Indicates that slash commands are native to this protocol. + * Used as a hint that unknown commands should not be sent as messages. + */ + readonly attribute boolean slashCommandsNative; + + /** + * True if the protocol can provide end-to-end message encryption in + * conversations. + */ + readonly attribute boolean canEncrypt; + + /** + * Get the protocol specific part of an already initialized + * imIAccount instance. + */ + prplIAccount getAccount(in imIAccount aImAccount); +}; + +/** + * The chat account wizards requests the sign-in information as a series of + * fields generated by a list of prplIUsernameSplit. + * + * The result of these is composed into a string and stored as the account name. + * It is the responsibity of the prplIAccount to re-parse this back to usable + * connection data. + * + * TODO Replace this with storing account data as separate fields. + */ +[scriptable, uuid(20c4971a-f7c2-4781-8e85-69fee7b83a3d)] +interface prplIUsernameSplit: nsISupports { + /** + * The field name presented in the account wizard, e.g. server. + */ + readonly attribute AUTF8String label; + /** + * The default value that is presented in the account wizard. + */ + readonly attribute AUTF8String defaultValue; + /** + * The string used to compose the account name. + * + * E.g. an "@" would cause "@" to be appended before this field. + */ + readonly attribute char separator; +}; diff --git a/comm/chat/components/public/prplIRequest.idl b/comm/chat/components/public/prplIRequest.idl new file mode 100644 index 0000000000..2e9b58584f --- /dev/null +++ b/comm/chat/components/public/prplIRequest.idl @@ -0,0 +1,115 @@ +/* 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" + +interface imIAccount; +interface nsIDOMWindow; +interface nsIWebProgress; + +/** + * This interface is for use in the browser-request notification, to + * let protocol plugins open a browser window. This is an unfortunate + * necessity for protocols that require an OAuth authentication. + */ +[scriptable, uuid(b89dbb38-0de4-11e0-b3d0-0002e304243c)] +interface prplIRequestBrowser: nsISupports { + readonly attribute AUTF8String promptText; + readonly attribute AUTF8String url; + void cancelled(); + void loaded(in nsIDOMWindow aWindow, + in nsIWebProgress aWebProgress); +}; + +/** + * This interface is used for buddy authorization requests, when the + * user needs to confirm if a remote contact should be allowed to see + * his presence information. It is implemented by the aSubject + * parameter of the buddy-authorization-request and + * buddy-authorization-request-canceled notifications. + */ +[scriptable, uuid(a55c1e24-17cc-4ddc-8c64-3bc315a3c3b1)] +interface prplIBuddyRequest: nsISupports { + readonly attribute imIAccount account; + readonly attribute AUTF8String userName; + void grant(); + void deny(); +}; + +/** + * This is used with chat room invitation requests, so the user can accept or + * reject an invitation. It is implemented by the aSubject parameter of the + * conv-authorization-request notification. + */ +[scriptable, uuid(44ac9606-711b-40f6-9031-94a9c60c938d)] +interface prplIChatRequest: nsISupports { + readonly attribute imIAccount account; + readonly attribute AUTF8String conversationName; + /** + * Resolves when the request is completed, with a boolean indicating if it + * was granted. Rejected if the request is cancelled. + * + * @type {Promise<boolean>} + */ + readonly attribute Promise completePromise; + readonly attribute boolean canDeny; + void grant(); + void deny(); +}; + +/** + * Verification information for an encryption session (for example prplISession). + * Used to present a verification flow to the user. + */ +[scriptable, uuid(48c1748d-ba51-44c0-aa3c-e979d4d4bdf3)] +interface imISessionVerification: nsISupports { + /** + * Challenge mode where a text string is presented to the user and they have + * to confirm it matches with the other user/device's. + */ + const short CHALLENGE_TEXT = 1; + /** Verification mode */ + readonly attribute short challengeType; + /** Challenge string to present to the user for CHALLENGE_TEXT */ + readonly attribute AUTF8String challenge; + /** + * Optional description of the challenge contents. For example text + * representation of emoji. + */ + readonly attribute AUTF8String challengeDescription; + /** + * User readable name for the entity the verification is about (so the + * user/device on the other side of the flow). + */ + readonly attribute AUTF8String subject; + /** + * resolves with the result from the challenge, rejects if the action was + * cancelled. + * + * @type {Promise<boolean>} + */ + readonly attribute Promise completePromise; + /** + * Submit result of the challenge, completing the verification on this side. + */ + void submitResponse(in boolean challengeMatches); + /** + * Cancel the verification. + */ + void cancel(); +}; + +/** + * Incoming verification request, sent to the UI via buddy-verification-request + * notification. Can be canelled with buddy-verification-request-cancelled. + */ +[scriptable, uuid(c46d426f-6e99-4713-b0aa-0b404db5a40d)] +interface imIIncomingSessionVerification: imISessionVerification { + readonly attribute imIAccount account; + /** + * Method to accept the verification. Resolves once |challenge| is + * populated. + */ + Promise verify(); +}; diff --git a/comm/chat/components/public/prplITooltipInfo.idl b/comm/chat/components/public/prplITooltipInfo.idl new file mode 100644 index 0000000000..baa62b89a7 --- /dev/null +++ b/comm/chat/components/public/prplITooltipInfo.idl @@ -0,0 +1,29 @@ +/* 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" + +/* + * This interface provides access to the content of a + * PurpleNotifyUserInfoEntry structure. + */ + +[scriptable, uuid(e4c1def4-d1fe-4449-b195-51f137d1f215)] +interface prplITooltipInfo: nsISupports { + const short pair = 0; + const short sectionBreak = 1; + const short sectionHeader = 2; + const short status = 3; + const short icon = 4; + + readonly attribute short type; + + /* + * When type == status, the label holds the statusType (a short + * converted to a string), while the value holds the statusText. + * When type == icon, the value holds the user icon URI. + */ + readonly attribute AUTF8String label; + readonly attribute AUTF8String value; +}; |