Skip to main content

Exchange Web Services (EWS)

Auto-generated

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:

PropertyValue
pluginGroupIdplugins
pluginArtifactIdewsclient
pluginVersion1.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_app permission on Exchange Online, providing clientId, clientSecret and tenantId.

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 PropertyPurpose
hostExchange host name
portExchange port
security2 → HTTPS, otherwise HTTP
authMethodDEFAULT (basic auth) or OAUTH2
userUser for basic auth or default mailbox for OAuth2
passwordPassword (basic auth only)
domainWindows domain (basic auth only)
clientIdAzure app client id (OAuth2 only)
clientSecretAzure app client secret (OAuth2 only)
tenantIdAzure 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:

ConstantWhen to use
NONENo impersonation – every user authenticates with their own credentials.
SINGLEAn impersonation user impersonates exactly one other user (e.g. syncing a single contact folder).
LISTAn 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).

GroupConstants
MailGET_EMAIL_IDS, GET_EMAIL_BY_ID, GET_EMAILS, DELETE_EMAIL_BY_ID, INSERT_EMAIL
ContactsGET_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
FoldersGET_CONTACTSDEFAULTFOLDER, GET_CONTACTFOLDERS
CalendarGET_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>.

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 XML object. 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

PathContent
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.jsonUpgrader metadata for consumers of older releases.
  • 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.