Exchange Web Services (EWS)
This page is imported automatically from an external repository.
Source project: Open repository
This module provides the base functionality to communicate with a Microsoft Exchange server via EWS (Exchange Web Services). It wraps the ADITO ewsclient Java plugin and exposes a small JavaScript/JDito API to build request XMLs, dispatch them to the plugin, and receive the XML response.
The module is a base module — it does not implement business logic (contact sync, mail sync, calendar sync, ...) on its own. Instead, it is consumed by higher-level modules (e.g. ews-sync) that build task-specific XMLs and pass them to this module.
Get Started
Plugin Requirement
Under the hood every EWS call is executed by the ADITO plugin de.adito.plugin.ewsclient.EwsClientPlugin. This plugin must be available in the project. It is declared by the EwsClientPlugin alias:
| Property | Value |
|---|---|
pluginGroupId | plugins |
pluginArtifactId | ewsclient |
pluginVersion | 1.12.0 |
Server-side Requirements
Depending on the chosen authentication method, the target Exchange server must be reachable and configured accordingly:
- Basic Auth (
DEFAULT): an on-premises Exchange server with a valid EWS endpoint (/ews/Exchange.asmx) and a user/password (optionally with a Windows domain). - OAuth2: an app registration in the customer’s Azure portal with
full_access_as_apppermission on Exchange Online, providingclientId,clientSecretandtenantId.
If impersonation is used, the connection user must have the ApplicationImpersonation role on the target mailboxes.
Configuration
Alias Configuration
Consuming modules typically configure a project alias of type “Exchange (web service)”. The EwsClientXMLUtils.getRequestXMLforAlias helper reads the following properties from the alias model:
| Alias Property | Purpose |
|---|---|
host | Exchange host name |
port | Exchange port |
security | 2 → HTTPS, otherwise HTTP |
authMethod | DEFAULT (basic auth) or OAUTH2 |
user | User for basic auth or default mailbox for OAuth2 |
password | Password (basic auth only) |
domain | Windows domain (basic auth only) |
clientId | Azure app client id (OAuth2 only) |
clientSecret | Azure app client secret (OAuth2 only) |
tenantId | Azure tenant id (OAuth2 only) |
The alias itself is defined by the consuming module (see for example EwsSync_Data_alias in the ews-sync module – it was moved out of this base module in v3.0.0).
Dependencies
package.json declares a peer dependency on @aditosoftware/contact. Add this module to your project via:
@aditosoftware/ews
Usage
All public API is exported from the Ews_lib process:
import { EwsClientUtils, EwsClientXMLUtils, $EwsClientTaskDescriptions, $EwsClientImpersonationModes }
from "@aditosoftware/ews/process/Ews_lib/process";
Impersonation Modes
$EwsClientImpersonationModes defines how the connection user relates to the mailbox that is accessed:
| Constant | When to use |
|---|---|
NONE | No impersonation – every user authenticates with their own credentials. |
SINGLE | An impersonation user impersonates exactly one other user (e.g. syncing a single contact folder). |
LIST | An impersonation user impersonates several users (e.g. loading calendar permissions for a list of mailboxes). |
Task Descriptions
$EwsClientTaskDescriptions defines the supported task types. The plugin dispatches on this value to decide which EWS operation to perform. Each task expects a matching pTaskXML payload (built by the consumer).
| Group | Constants |
|---|---|
GET_EMAIL_IDS, GET_EMAIL_BY_ID, GET_EMAILS, DELETE_EMAIL_BY_ID, INSERT_EMAIL | |
| Contacts | GET_CONTACTS, GET_CONTACT_BY_ID, GET_CONTACTS_BY_CATEGORIE, GET_CONTACTS_BY_FOLDERS, INSERT_CONTACT, INSERT_CONTACT_TO_FOLDER, INSERT_CONTACT_LIST, INSERT_CONTACT_LIST_TO_FOLDER, UPDATE_CONTACT, UPDATE_CONTACT_LIST, DELETE_CONTACT, DELETE_CONTACT_BY_ID, DELETE_CONTACT_LIST_BY_IDS |
| Folders | GET_CONTACTSDEFAULTFOLDER, GET_CONTACTFOLDERS |
| Calendar | GET_CALENDAR_TASKS_PERMISSIONS |
Building Request XMLs
EwsClientXMLUtils offers three factories for the top-level request XML. All of them expect a task-specific inner XML (pTaskXML) which is appended under <task>.
From an alias (recommended)
let taskXml = new XML("<...task specific payload...>");
let request = EwsClientXMLUtils.getRequestXMLforAlias(
$EwsClientTaskDescriptions.GET_CONTACTS(),
taskXml,
$EwsClientImpersonationModes.SINGLE(),
"MyExchangeAlias",
"user@customer.com" // optional, overrides the alias mailbox for OAuth2
);
Depending on the authMethod of the alias, this internally delegates to getRequestXMLbasicAuth or getRequestXMLOAuth2.
Basic Auth (explicit)
let request = EwsClientXMLUtils.getRequestXMLbasicAuth(
"https://exchange.mycustomer.com:443/ews/Exchange.asmx",
"MYDOMAIN",
$EwsClientImpersonationModes.NONE(),
$EwsClientTaskDescriptions.GET_EMAILS(),
taskXml,
"serviceUser",
"s3cret"
);
OAuth2 (explicit)
let request = EwsClientXMLUtils.getRequestXMLOAuth2(
clientId, clientSecret, tenantId,
$EwsClientTaskDescriptions.GET_CONTACTS(),
taskXml,
$EwsClientImpersonationModes.SINGLE(),
"user@customer.com"
);
The XML values are automatically escaped, so complex passwords or client secrets do not need to be pre-escaped by the caller.
Executing the Request
EwsClientUtils.callPlugin sends the request XML through the EwsClientPlugin alias and returns the plugin’s XML response:
let responseXml = EwsClientUtils.callPlugin(request);
Notes on the response:
- The returned value is an
XMLobject. Use.toString()to log it. - The plugin does not always throw when permissions on a folder are missing – in some of those cases the returned XML simply contains no data. Callers should be defensive about empty results.
Extension Points
ewsCallPlugin_service
The ewsCallPlugin_service service is invoked for every call of EwsClientUtils.callPlugin. Each implementation receives the original pPluginInput (XML string) and may return a replacement response XML string. Returning a falsy value keeps the original plugin response.
This is the intended hook for:
- mocking / stubbing EWS in test environments
- transparently rewriting requests or responses
- injecting additional logging / auditing
// implementation of ewsCallPlugin_service
export function ewsCallPlugin_service(pPluginInput)
{
// return a custom response XML string, or null to keep the plugin's response
return null;
}
Library Overrides
Both EwsClientUtils and EwsClientXMLUtils are registered with the Overrides mechanism from the @aditosoftware/utility module (LibraryOverrideManager_lib). Consumers can therefore override individual static functions on a per-project basis without patching this module.
Module Structure
| Path | Content |
|---|---|
| aliasDefinition/EwsClientPlugin/ | Plugin alias that binds the ewsclient Java plugin. |
| process/Ews_lib/ | Public library: EwsClientUtils, EwsClientXMLUtils, task and impersonation constants. |
| serviceDefinition/ewsCallPlugin_service/ | Extension point invoked after each plugin call. |
| others/Ews_lib_Upgrader.json | Upgrader metadata for consumers of older releases. |
Related Modules
ews-sync– contains the actual data alias (EwsSync_Data_alias) and higher-level sync logic. Since v3.0.0 the alias and its liquibase files live there, not in this module.contact– peer dependency, provides contact data structures used by the contact-related tasks.