wespeak-exchange-ews

Exchange Server mail, folders and shared calendars over HTTPS EWS with NTLMv2 and TLS channel binding

Package Information

Released: this month
Downloads: 0 weekly / 0 monthly
Latest Version: 0.2.0
Author: mirrose

Documentation

n8n-nodes-wespeak-exchange-ews

n8n community node for on-premises Microsoft Exchange Server mail, folders and calendars through EWS over HTTPS with NTLMv2. Supports shared/delegated calendars with existing Exchange permissions.

Install

In self-hosted n8n, open Settings → Community Nodes → Install and enter:

n8n-nodes-wespeak-exchange-ews

Requires Node.js 20 or newer and an n8n version supporting community nodes. This is an unverified community package, not an n8n-certified integration.

Credentials

Create an Exchange EWS (NTLMv2) credential. You can name it ExchangeMail or any name you prefer.

  • EWS URL: https://mail.example.com/EWS/Exchange.asmx, or the HTTPS server root. Do not use /owa/.
  • Username: DOMAIN\user, or enter user and fill in Domain separately.
  • Password: stored in n8n's credential system, never in node parameters or exports.
  • Additional Trusted CA (PEM): optional internal CA chain. The hostname and certificate chain are still verified. This extends trust without disabling TLS validation.

Existing Header Auth credentials cannot be reused; they are a different credential type. The credential test authenticates and checks access to the Inbox without retrieving messages.

Operations

Select Resource: Mail, Calendar or Folder. Existing mail workflows keep their resource and operation defaults.

Mail

  • Get Many Emails: exact subject search in Inbox, paginated automatically, optional unread-only filter, optional suppression of previously returned EWS IDs, and optional file attachment downloads.
  • Get Email: retrieve one message by its EWS item ID.
  • Download Attachment: retrieve one file attachment as n8n binary data.
  • Move Email: move one email per input item to an existing mail folder by EWS folder ID, or to a well-known mail folder. The source must be an email and the destination must have a mail folder class. An optional Change Key rejects stale source data. The operation returns the new item ID; Exchange IDs change on moves. For a cross-mailbox move Exchange may omit the new ID, in which case id is null rather than the old ID.

For polling, connect Schedule Trigger (for example every 5 minutes) to Exchange EWS Mail → Get Many Emails. Set Exact Subject. Search comparisons are rechecked case-sensitively after retrieval, so prefixes, suffixes, different case, and extra spaces are excluded.

Emails return id, messageId, subject, body, from, to, cc, timestamps, and attachment metadata. Downloaded attachments use binary properties attachment_0, attachment_1, etc. The standalone download operation uses data. Embedded Outlook item attachments are reported separately but not downloaded.

Mail reads do not delete, move, send, or mark messages as read. Move Email writes only when explicitly selected, including during a manual execution. Placing this operation after successful downstream processing lets you move completed messages to a processed folder. Obtain the destination ID using Folder → List Folders, filter/select the intended folder, then configure Move Email. Display names alone are not EWS folder IDs.

Folder

List Folders returns the selected root and its descendants with IDs, display names and folder classes. Choose Mailbox Root, Inbox, Calendar or an explicit root folder ID. You can specify an owner mailbox email when you already have access. The configured Maximum Folders is an explicit output limit.

For a shared calendar where you have only folder-level permissions, choose Root Folder = Calendar with Mailbox Owner set to its owner. Access to another mailbox's full root is not assumed or granted. An access-denied response is reported without fallback or impersonation.

Calendar

  • Get Many Events: read a date range from your own or a shared calendar. CalendarView expands recurring occurrences. Full details are fetched for each event. If Exchange truncates the view, the node fails visibly; narrow the date range or raise Maximum Events (maximum 1,000). Query ranges are limited to 366 days.
  • Get Event: read a calendar item by EWS ID, returning its Change Key, dates, organizer, attendees, folder and event type.
  • Create Appointment: create a timed appointment with subject, Start, End, optional location and text body. No attendees are added and no invitations are sent.
  • Update Appointment: update subject, location, body, or Start/End for a single appointment or specific recurring occurrence. Supply the Event ID and Change Key from a read. Start and End must be supplied together when changing times. Concurrent changes are rejected using NeverOverwrite; no forced overwrite is used.

Shared calendars: for a default shared calendar, enter its owner's primary mailbox email in Calendar Mailbox Owner. For a secondary calendar or a directly shared folder, use its Calendar Folder ID; this overrides the default-calendar/owner selection. Exchange enforces the account's existing permissions. Read permission is sufficient for reads; create/edit operations require suitable Author/Editor/delegate rights. The node never creates permissions, requests administrator rights or uses Exchange impersonation.

Use ISO date/time values with an explicit UTC offset or Z, e.g. 2026-10-07T09:00:00+02:00. Values are normalized to UTC. New timed appointments have UTC Start/End time zones; Outlook displays them in the user's configured time zone. Impossible dates and timezone-free timestamps are rejected.

This release does not send invitations or meeting updates, delete events, create all-day appointments or edit whole recurring series. Existing meetings can be read but cannot be updated; all-day appointment text/location can be updated, while their times cannot be changed. These restrictions avoid silently changing attendee calendars or an entire series.

Write operations and retries: Move Email, Create Appointment and Update Appointment modify Exchange when executed, including in manual tests. They perform one operation per input item. A network failure after submission can leave the write result unknown. Do not enable blind automatic retries for calendar creation; first check the calendar to avoid duplicates. Moves may invalidate the old ID. Multi-item workflow executions are not atomic and are not rolled back after later failures. Test writes against a test mailbox/calendar first.

Security and compatibility

  • TLS certificate and hostname verification are always enabled; there is no "ignore certificate errors" option.
  • TLS 1.2 or newer; HTTPS only.
  • NTLMv2 only. No NTLMv1 or Basic Auth fallback.
  • NTLMv2 client challenges use the operating system's cryptographically secure random generator.
  • TLS channel binding (tls-server-end-point) and an NTLM message integrity code are included for Extended Protection.
  • No OpenSSL legacy provider, Node.js downgrade, or Code-node module allowlist changes are needed. MD4 required by NTLMv2 is computed inside the package using js-md4.
  • Redirects are never followed with credentials. The NTLM handshake must remain on one connection.
  • Network/NTLM error messages do not include passwords, authentication tokens, or raw server error bodies.
  • Unknown certificate signature algorithms fail closed. RSA, RSA-PSS, ECDSA and supported DSA signature hash combinations are supported; Ed25519/Ed448 certificate signatures are currently unsupported for channel binding.

Exchange 2019 with an NTLM-enabled EWS virtual directory is the target. Compatibility with a particular Exchange build, proxy, and Extended Protection deployment needs an actual connection test. Behind a TLS-terminating proxy, the channel binding must agree with Exchange's supported proxy configuration. A failure is reported; do not disable Extended Protection to work around it.

Processing state

Skip Previously Processed Emails uses n8n workflow static data. n8n saves it after successful production executions; manual tests do not save it. Existing matching Inbox messages are included on the first production run. No data is marked processed until the node's message and attachment reads finish successfully.

This is at-least-once processing, not exactly-once delivery. Avoid concurrent executions of the same workflow. Downstream systems should use messageId as an idempotency key. EWS IDs can change when a message is moved or copied. The ID ledger is capped at 100,000 entries; larger workloads need a durable processing database. Search scan limits fail visibly rather than silently skipping older matching messages.

Per-request responses are capped at 64 MiB. XML must be well formed, is limited to 64 nesting levels and 50,000 tags, and cannot contain DTDs, entity declarations, or JavaScript prototype keys. Empty search pages cannot bypass the page budget. Numeric limits are checked at runtime, including expression overrides.

The default attachment limit is 20 MiB. Total decoded attachments and total email result data are separately capped at 64 MiB per execution. Invalid base64 is rejected before decoding. File names are reduced to safe base names and MIME types are validated; downstream workflows must still treat message and file content as untrusted. Large or unsupported attachments fail the batch instead of silently being dropped. Prefer failing the workflow to using "Continue On Fail" when downstream delivery must be retried.

Development

npm ci --ignore-scripts
npm test
npm audit --omit=dev
npm pack

Build and tests cover protocol vectors, NTLMv2-only enforcement, channel binding, certificate rejection, exact subject filtering, paging, binary attachments, credentials and package discovery. Live Exchange testing remains necessary before production use. The code has not undergone an independent security audit.

Releases

  • 0.2.0: includes the 0.1.1 resource/XML/input hardening, adds folder discovery, explicit mail moves, calendar reads, timed appointment creation/update and shared-calendar targeting. The mail read defaults and credential type remain compatible.
  • 0.1.1: locally tested security corrections; superseded by 0.2.0 before publication.
  • 0.1.0: initial read-only pilot release.

Protocol references: MS-NLMP, RFC 5929.

Discussion