@rapidmx/autodiscover-plugin 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,205 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ ///////////////////////////////////////////////////////////////////////////////
14
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
15
+ // SPDX-License-Identifier: MPL-2.0
16
+ ///////////////////////////////////////////////////////////////////////////////
17
+ import { ObjectDecorators } from "@rapidrest/core";
18
+ import { RepoUtils, RouteDecorators } from "@rapidrest/service-core";
19
+ import { buildOutlookSuccessXml, buildPoxSuccessXml, extractAcceptableResponseSchema, extractEmailAddress, OUTLOOK_RESPONSE_SCHEMA, } from "./AutodiscoverXml.js";
20
+ import { PluginRegistry } from "@rapidmx/restapi";
21
+ const { Config, Init, Logger } = ObjectDecorators;
22
+ /** The plugin packages whose endpoints Autodiscover advertises. */
23
+ export const ACTIVESYNC_PLUGIN = "@rapidmx/activesync";
24
+ export const MAPI_PLUGIN = "@rapidmx/mapi";
25
+ const { Get, Param, Post, Query, Request, Response } = RouteDecorators;
26
+ /**
27
+ * Abstract base for the two Autodiscover endpoints a real mail client uses to find this deployment's EAS
28
+ * server URL from just an email address - classic POX (`POST /autodiscover/autodiscover.xml`, per
29
+ * `[MS-ASCMD]`'s "MobileSync" response schema) and the modern JSON variant Microsoft calls "Autodiscover v2"
30
+ * (`GET /autodiscover/autodiscover.json/v1.0/<email>?Protocol=ActiveSync`). Like `BaseMailIngestRoute`/
31
+ * `BaseEasRoute`, this class is undecorated; its Mongo/SQL concrete classes are mounted at `/autodiscover`, which
32
+ * composes with this class's own relative method paths to land exactly on the real spec's conventional paths (`/autodiscover/autodiscover.xml`, `/autodiscover/autodiscover.json/v1.0/:email`).
33
+ *
34
+ * **Auth: deliberately none.** Real classic Autodiscover conventionally expects the client to send HTTP Basic
35
+ * credentials (email+password), with the server free to answer `401` and force re-entry - a model this
36
+ * library's JWT-only, no-credential-verification-of-our-own boundary (see `BaseEasRoute`'s own doc comment on
37
+ * why per-request Basic Auth was rejected there) can't and shouldn't absorb; no credential-verification
38
+ * function exists in this codebase or its dependencies. Instead, both endpoints here follow Microsoft's own
39
+ * Autodiscover v2 design intent exactly: answer anonymously, and reveal nothing but a deployment-wide,
40
+ * config-supplied EAS server URL - not a per-mailbox secret - once the request email is confirmed to belong to
41
+ * a real `Mailbox` in this deployment. The actual security boundary is unchanged from Phase 2: real mailbox
42
+ * access still requires a JWT at `BaseEasRoute`, exactly as today.
43
+ *
44
+ * **Known gap, deliberately out of scope**: `Action.Redirect` (for multi-tenant hosted providers whose mailbox
45
+ * moved to a different domain) is not implemented - this library serves exactly one EAS URL for its whole
46
+ * deployment, so there's never a different domain to redirect to. The client-side well-known-URL discovery
47
+ * sequence (`MS-OXDISCO`: root domain -> `autodiscover.` subdomain -> unauthenticated HTTP redirect probe ->
48
+ * DNS SRV record -> cache) and the DNS `CNAME`/`SRV` record setup it depends on are also out of scope here -
49
+ * both are client/deployment concerns, not application code; this class only needs to answer correctly once a
50
+ * request actually arrives at one of its two paths.
51
+ *
52
+ * `mailboxClass` is supplied by the Mongo/SQL concrete subclasses following the exact one-line-per-backend
53
+ * pattern used throughout this library. The advertised URLs are built from the `mail:autodiscover:public_url`
54
+ * setting, and each protocol is only advertised while its plugin (`@rapidmx/activesync`, `@rapidmx/mapi`) is
55
+ * loaded, so a client is never pointed at an endpoint this deployment doesn't serve.
56
+ *
57
+ * @author Jean-Philippe Steinmetz
58
+ */
59
+ export class BaseAutodiscoverRoute {
60
+ constructor() {
61
+ /** The public base URL clients reach this deployment at, e.g. `https://mail.example.com`. */
62
+ this.publicUrl = "";
63
+ }
64
+ /** The EAS endpoint URL to report, or `undefined` when ActiveSync isn't available here. */
65
+ get easUrl() {
66
+ return this.endpointUrl(ACTIVESYNC_PLUGIN, "/Microsoft-Server-ActiveSync");
67
+ }
68
+ /** The MAPI/HTTP `emsmdb` endpoint URL to report to a real Outlook desktop client, or `undefined` when MAPI
69
+ * isn't available here. Only used by `pox()`'s Outlook/EXCH response branch. */
70
+ get mapiUrl() {
71
+ return this.endpointUrl(MAPI_PLUGIN, "/mapi/emsmdb");
72
+ }
73
+ /**
74
+ * Builds the query value used to match `Mailbox.aliasAddresses` against the given address. See
75
+ * `BaseMailIngestRoute.aliasQueryValue()`'s identical doc comment - same Mongo-array vs.
76
+ * SQL-`simple-json`-column backend split, same override point (`AutodiscoverRouteSQL` overrides this
77
+ * identically to `MailIngestRouteSQL`).
78
+ */
79
+ aliasQueryValue(address) {
80
+ return address;
81
+ }
82
+ endpointUrl(plugin, path) {
83
+ if (!this.publicUrl || !PluginRegistry.isActive(plugin)) {
84
+ return undefined;
85
+ }
86
+ return `${this.publicUrl.replace(/\/+$/, "")}${path}`;
87
+ }
88
+ async init() {
89
+ if (!this.publicUrl) {
90
+ this.logger?.warn("Autodiscover has no mail:autodiscover:public_url set, so it can't point clients at any protocol.");
91
+ }
92
+ this.mailboxRepo = await this._objectFactory.newInstance(RepoUtils, {
93
+ name: this.mailboxClass.name,
94
+ args: [this.mailboxClass],
95
+ });
96
+ }
97
+ async resolveMailbox(email) {
98
+ const address = email.trim().toLowerCase();
99
+ const [byPrimary, byAlias] = await Promise.all([
100
+ this.mailboxRepo.find({ primarySmtpAddress: address }, { ignoreACL: true, limit: 1 }),
101
+ this.mailboxRepo.find({ aliasAddresses: this.aliasQueryValue(address) }, { ignoreACL: true, limit: 1 }),
102
+ ]);
103
+ return byPrimary[0] ?? byAlias[0];
104
+ }
105
+ /**
106
+ * Classic POX Autodiscover. Per Microsoft's own client-behavior documentation, a permanent failure is just
107
+ * as validly conveyed via a plain HTTP status as via an inner `Error` element, so this uses the HTTP-status
108
+ * form for both error cases rather than inventing values for `[MS-ASCMD]`'s provider-specific numeric
109
+ * error-code table.
110
+ *
111
+ * Branches on the request's `AcceptableResponseSchema` to decide which response shape to build: a real
112
+ * Outlook desktop client sends `[MS-OXDSCLI]`'s Outlook/EXCH schema (`OUTLOOK_RESPONSE_SCHEMA`) to locate
113
+ * this deployment's MAPI/HTTP endpoint (`buildOutlookSuccessXml`); any other value (or a mobile/EAS-only
114
+ * client that omits the field entirely) gets the original MobileSync/EAS response (`buildPoxSuccessXml`).
115
+ */
116
+ async pox(req, res) {
117
+ if (!this.mailboxRepo) {
118
+ res.status(500).send();
119
+ return;
120
+ }
121
+ const body = req.rawBody ? req.rawBody.toString("utf-8") : "";
122
+ const email = extractEmailAddress(body);
123
+ if (!email) {
124
+ res.status(400).send();
125
+ return;
126
+ }
127
+ const mailbox = await this.resolveMailbox(email);
128
+ if (!mailbox) {
129
+ res.status(404).send();
130
+ return;
131
+ }
132
+ const outlook = extractAcceptableResponseSchema(body) === OUTLOOK_RESPONSE_SCHEMA;
133
+ const url = outlook ? this.mapiUrl : this.easUrl;
134
+ if (!url) {
135
+ // The protocol this client asked about isn't served here - a 404 lets it move on to its next discovery step.
136
+ res.status(404).send();
137
+ return;
138
+ }
139
+ const xml = outlook
140
+ ? buildOutlookSuccessXml({ emailAddress: email, displayName: mailbox.displayName, mapiUrl: url })
141
+ : buildPoxSuccessXml({ emailAddress: email, displayName: mailbox.displayName, easUrl: url });
142
+ res.setHeader("Content-Type", "application/xml; charset=utf-8").status(200).send(xml);
143
+ }
144
+ /**
145
+ * Autodiscover v2 (JSON). Only the `ActiveSync` protocol is served - this library has no EWS/other
146
+ * protocol surface to advertise - so any other `Protocol` value is rejected outright rather than silently
147
+ * answered with an EAS URL under the wrong protocol name.
148
+ */
149
+ async v2(email, protocol, res) {
150
+ if (!this.mailboxRepo) {
151
+ res.status(500).send();
152
+ return;
153
+ }
154
+ // An unsupported protocol and ActiveSync not being available here get the same answer.
155
+ const easUrl = this.easUrl;
156
+ if (protocol !== "ActiveSync" || !easUrl) {
157
+ res.status(400).json({
158
+ ErrorCode: "ProtocolNotSupported",
159
+ ErrorMessage: `Unsupported protocol: ${protocol ?? ""}`,
160
+ });
161
+ return;
162
+ }
163
+ const mailbox = await this.resolveMailbox(decodeURIComponent(email));
164
+ if (!mailbox) {
165
+ res.status(404).json({
166
+ ErrorCode: "UserNotFound",
167
+ ErrorMessage: "No mailbox exists for the given address.",
168
+ });
169
+ return;
170
+ }
171
+ res.status(200).json({ Protocol: "ActiveSync", Url: easUrl });
172
+ }
173
+ }
174
+ __decorate([
175
+ Config("mail:autodiscover:public_url", ""),
176
+ __metadata("design:type", String)
177
+ ], BaseAutodiscoverRoute.prototype, "publicUrl", void 0);
178
+ __decorate([
179
+ Logger,
180
+ __metadata("design:type", Object)
181
+ ], BaseAutodiscoverRoute.prototype, "logger", void 0);
182
+ __decorate([
183
+ Init,
184
+ __metadata("design:type", Function),
185
+ __metadata("design:paramtypes", []),
186
+ __metadata("design:returntype", Promise)
187
+ ], BaseAutodiscoverRoute.prototype, "init", null);
188
+ __decorate([
189
+ Post("/autodiscover.xml"),
190
+ __param(0, Request),
191
+ __param(1, Response),
192
+ __metadata("design:type", Function),
193
+ __metadata("design:paramtypes", [Object, Object]),
194
+ __metadata("design:returntype", Promise)
195
+ ], BaseAutodiscoverRoute.prototype, "pox", null);
196
+ __decorate([
197
+ Get("/autodiscover.json/v1.0/:email"),
198
+ __param(0, Param("email")),
199
+ __param(1, Query("Protocol")),
200
+ __param(2, Response),
201
+ __metadata("design:type", Function),
202
+ __metadata("design:paramtypes", [String, Object, Object]),
203
+ __metadata("design:returntype", Promise)
204
+ ], BaseAutodiscoverRoute.prototype, "v2", null);
205
+ //# sourceMappingURL=BaseAutodiscoverRoute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAutodiscoverRoute.js","sourceRoot":"","sources":["../../src/BaseAutodiscoverRoute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ /**
6
+ * Autodiscover protocol compatibility: the mechanism a real mail client uses to find this deployment's EAS
7
+ * server URL from just an email address, before it has any credentials or JWT of its own. Exports the
8
+ * backend-agnostic surface - the request/response XML helpers and the abstract route base class. The concrete
9
+ * Mongo/SQL classes a deployment actually instantiates (`AutodiscoverRouteMongo`/`AutodiscoverRouteSQL`) are
10
+ * exported from this package's `./mongo`/`./sql` subpaths instead, alongside every other entity/route/job this
11
+ * library defines - see `src/eas/index.ts`'s identical doc comment for the same convention.
12
+ *
13
+ * A deployment mounts Autodiscover with a trivial subclass supplying its own EAS URL:
14
+ * ```ts
15
+ * import { AutodiscoverRouteMongo } from "@rapidrest/mail/mongo";
16
+ * import { RouteDecorators } from "@rapidrest/service-core";
17
+ * const { Route } = RouteDecorators;
18
+ *
19
+ * @Route("/autodiscover")
20
+ * export class MyAutodiscoverRoute extends AutodiscoverRouteMongo {
21
+ * protected readonly easUrl = "https://mail.example.com/Microsoft-Server-ActiveSync";
22
+ * protected readonly mapiUrl = "https://mail.example.com/mapi/emsmdb";
23
+ * }
24
+ * ```
25
+ */
26
+ export * from "./AutodiscoverXml.js";
27
+ export * from "./BaseAutodiscoverRoute.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAc,sBAAsB,CAAC;AACrC,cAAc,4BAA4B,CAAC"}
@@ -0,0 +1,31 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ ///////////////////////////////////////////////////////////////////////////////
8
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
9
+ // SPDX-License-Identifier: MPL-2.0
10
+ ///////////////////////////////////////////////////////////////////////////////
11
+ import { MailboxMongo } from "@rapidmx/restapi/mongo";
12
+ import { RouteDecorators } from "@rapidrest/service-core";
13
+ import { BaseAutodiscoverRoute } from "../BaseAutodiscoverRoute.js";
14
+ const { Route } = RouteDecorators;
15
+ /**
16
+ * Mongo-backed concrete `BaseAutodiscoverRoute`, mounted at `/autodiscover`. Exported from this plugin's `./mongo`
17
+ * entry point, so the server host mounts it without a wrapper class of its own.
18
+ *
19
+ * @author Jean-Philippe Steinmetz
20
+ */
21
+ let AutodiscoverRouteMongo = class AutodiscoverRouteMongo extends BaseAutodiscoverRoute {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.mailboxClass = MailboxMongo;
25
+ }
26
+ };
27
+ AutodiscoverRouteMongo = __decorate([
28
+ Route("/autodiscover")
29
+ ], AutodiscoverRouteMongo);
30
+ export { AutodiscoverRouteMongo };
31
+ //# sourceMappingURL=AutodiscoverRouteMongo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutodiscoverRouteMongo.js","sourceRoot":"","sources":["../../../src/mongo/AutodiscoverRouteMongo.ts"],"names":[],"mappings":";;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC;AAElC;;;;;GAKG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,qBAAmC;IAAxE;;QACO,iBAAY,GAAQ,YAAY,CAAC;IAC/C,CAAC;CAAA,CAAA;AAFY,sBAAsB;IADlC,KAAK,CAAC,eAAe,CAAC;GACV,sBAAsB,CAElC"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./AutodiscoverRouteMongo.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mongo/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./mongo/index.js";
6
+ //# sourceMappingURL=mongo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.js","sourceRoot":"","sources":["../../src/mongo.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,39 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ ///////////////////////////////////////////////////////////////////////////////
8
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
9
+ // SPDX-License-Identifier: MPL-2.0
10
+ ///////////////////////////////////////////////////////////////////////////////
11
+ import { Raw } from "typeorm";
12
+ import { MailboxSQL } from "@rapidmx/restapi/sql";
13
+ import { RouteDecorators } from "@rapidrest/service-core";
14
+ import { BaseAutodiscoverRoute } from "../BaseAutodiscoverRoute.js";
15
+ const { Route } = RouteDecorators;
16
+ /**
17
+ * SQL-backed concrete `BaseAutodiscoverRoute`, mounted at `/autodiscover` and exported from this plugin's `./sql`
18
+ * entry point. `aliasQueryValue()` is overridden identically to `MailIngestRouteSQL` - see
19
+ * that class's doc comment for the full vulnerability rationale (unescaped `%`/`_` enabling alias-enumeration
20
+ * and cross-mailbox matches) this same escaping closes here too, since `resolveMailbox()` is reached by
21
+ * unauthenticated callers exactly like `MailIngestRoute.resolve()` is.
22
+ *
23
+ * @author Jean-Philippe Steinmetz
24
+ */
25
+ let AutodiscoverRouteSQL = class AutodiscoverRouteSQL extends BaseAutodiscoverRoute {
26
+ constructor() {
27
+ super(...arguments);
28
+ this.mailboxClass = MailboxSQL;
29
+ }
30
+ aliasQueryValue(address) {
31
+ const escaped = address.replace(/[\\%_]/g, (ch) => `\\${ch}`);
32
+ return Raw((alias) => `${alias} LIKE :pattern ESCAPE '\\'`, { pattern: `%"${escaped}"%` });
33
+ }
34
+ };
35
+ AutodiscoverRouteSQL = __decorate([
36
+ Route("/autodiscover")
37
+ ], AutodiscoverRouteSQL);
38
+ export { AutodiscoverRouteSQL };
39
+ //# sourceMappingURL=AutodiscoverRouteSQL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutodiscoverRouteSQL.js","sourceRoot":"","sources":["../../../src/sql/AutodiscoverRouteSQL.ts"],"names":[],"mappings":";;;;;;AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC;AAElC;;;;;;;;GAQG;AAEI,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,qBAAiC;IAApE;;QACO,iBAAY,GAAQ,UAAU,CAAC;IAM7C,CAAC;IAJa,eAAe,CAAC,OAAe;QACrC,MAAM,OAAO,GAAW,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,4BAA4B,EAAE,EAAE,OAAO,EAAE,KAAK,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/F,CAAC;CACJ,CAAA;AAPY,oBAAoB;IADhC,KAAK,CAAC,eAAe,CAAC;GACV,oBAAoB,CAOhC"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./AutodiscoverRouteSQL.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sql/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,6 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2026 Jean-Philippe Steinmetz. All rights reserved.
3
+ // SPDX-License-Identifier: MPL-2.0
4
+ ///////////////////////////////////////////////////////////////////////////////
5
+ export * from "./sql/index.js";
6
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/sql.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mEAAmE;AACnE,mCAAmC;AACnC,+EAA+E;AAC/E,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Extracts the request's `<EMailAddress>` text content via a small, tightly-scoped regex rather than a DOM
3
+ * parse. Never resolves entities/DTDs - only the literal text between the open/close tags is ever inspected.
4
+ */
5
+ export declare function extractEmailAddress(xml: string): string | undefined;
6
+ /** Escapes the 5 XML-predefined-entity characters for safe inclusion as element text content. */
7
+ export declare function escapeXml(value: string): string;
8
+ export interface AutodiscoverPoxSuccess {
9
+ emailAddress: string;
10
+ displayName?: string;
11
+ easUrl: string;
12
+ }
13
+ /** The `AcceptableResponseSchema` value a real Outlook desktop client sends to request the Outlook/EXCH
14
+ * response shape (`buildOutlookSuccessXml`) instead of the EAS-only MobileSync one - confirmed against
15
+ * `[MS-OXDSCLI]`'s own Autodiscover Response XSD, whose target namespace is exactly this value. */
16
+ export declare const OUTLOOK_RESPONSE_SCHEMA = "http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a";
17
+ /**
18
+ * Extracts the request's `<AcceptableResponseSchema>` text content via the same small, tightly-scoped regex
19
+ * approach as `extractEmailAddress` - never a DOM parse, same rationale (unauthenticated, internet-facing
20
+ * endpoint).
21
+ */
22
+ export declare function extractAcceptableResponseSchema(xml: string): string | undefined;
23
+ /**
24
+ * Builds a real `mobilesync:Response` success document per `[MS-ASCMD]`'s `AutodiscoverMobileSync.xsd` -
25
+ * `Culture`/`User`/`Action.Settings.Server{Type=MobileSync,Url,Name}`, matching the shape confirmed against
26
+ * Microsoft's own "Autodiscover for Exchange ActiveSync developers" example response. A real response can also
27
+ * carry a `CertEnroll` server block for client-certificate enrollment - deliberately omitted, same "pragmatic
28
+ * subset" scoping as Phase 2's own documented gaps, since this library has no certificate-enrollment support.
29
+ */
30
+ export declare function buildPoxSuccessXml({ emailAddress, displayName, easUrl }: AutodiscoverPoxSuccess): string;
31
+ export interface AutodiscoverOutlookSuccess {
32
+ emailAddress: string;
33
+ displayName?: string;
34
+ mapiUrl: string;
35
+ }
36
+ /**
37
+ * Builds a real Outlook/EXCH `2006a` response per `[MS-OXDSCLI]`'s confirmed Autodiscover Response XSD -
38
+ * an `Autodiscover`(namespace `.../responseschema/2006`) element wrapping a `Response`
39
+ * (namespace `.../outlook/responseschema/2006a`) with `User`/`Account` children.
40
+ *
41
+ * Since this library only speaks MAPI/HTTP (no classic RPC/TCP MAPI transport), the response always
42
+ * advertises exactly one `Protocol`, using `Type`/`Version` as XML ATTRIBUTES rather than the classic
43
+ * `<Type>EXCH</Type>` child element - `[MS-OXDSCLI]`'s "Processing the X-MapiHttpCapability Header" section
44
+ * confirms a mapiHttp-capable client's response "MUST include a Protocol element that contains a Type
45
+ * attribute set to 'mapiHttp' and a Version attribute" and "MUST NOT include a Protocol element that contains
46
+ * a Type element set to 'EXCH' or 'EXPR'" - the two forms are mutually exclusive by design, not merely
47
+ * alternatives. This deployment has no classic RPC/TCP MAPI endpoint to fall back to, so every Outlook-schema
48
+ * request always gets the mapiHttp form - the real `X-MapiHttpCapability` request-header negotiation a full
49
+ * implementation would consult to choose between EXCH/mapiHttp is not implemented, a documented gap.
50
+ * `MailStore.InternalUrl`/`ExternalUrl` are both set to the same `mapiUrl`, since this library serves one URL
51
+ * per deployment with no separate internal/external network split.
52
+ *
53
+ * `LegacyDN`/`DeploymentId` are schema-required fields this library has no real backing value for (no X.500
54
+ * DN resolution, no multi-tenant deployment identity) - both are synthesized placeholders. Real Outlook does
55
+ * not validate their exact content for MAPI/HTTP connectivity; they matter for classic RPC/TCP MAPI
56
+ * free-busy/permissions lookups this library doesn't implement anyway.
57
+ */
58
+ export declare function buildOutlookSuccessXml({ emailAddress, displayName, mapiUrl }: AutodiscoverOutlookSuccess): string;
@@ -0,0 +1,79 @@
1
+ import { HttpRequest, HttpResponse } from "@rapidrest/service-core";
2
+ import { Mailbox } from "@rapidmx/restapi";
3
+ /** The plugin packages whose endpoints Autodiscover advertises. */
4
+ export declare const ACTIVESYNC_PLUGIN = "@rapidmx/activesync";
5
+ export declare const MAPI_PLUGIN = "@rapidmx/mapi";
6
+ /**
7
+ * Abstract base for the two Autodiscover endpoints a real mail client uses to find this deployment's EAS
8
+ * server URL from just an email address - classic POX (`POST /autodiscover/autodiscover.xml`, per
9
+ * `[MS-ASCMD]`'s "MobileSync" response schema) and the modern JSON variant Microsoft calls "Autodiscover v2"
10
+ * (`GET /autodiscover/autodiscover.json/v1.0/<email>?Protocol=ActiveSync`). Like `BaseMailIngestRoute`/
11
+ * `BaseEasRoute`, this class is undecorated; its Mongo/SQL concrete classes are mounted at `/autodiscover`, which
12
+ * composes with this class's own relative method paths to land exactly on the real spec's conventional paths (`/autodiscover/autodiscover.xml`, `/autodiscover/autodiscover.json/v1.0/:email`).
13
+ *
14
+ * **Auth: deliberately none.** Real classic Autodiscover conventionally expects the client to send HTTP Basic
15
+ * credentials (email+password), with the server free to answer `401` and force re-entry - a model this
16
+ * library's JWT-only, no-credential-verification-of-our-own boundary (see `BaseEasRoute`'s own doc comment on
17
+ * why per-request Basic Auth was rejected there) can't and shouldn't absorb; no credential-verification
18
+ * function exists in this codebase or its dependencies. Instead, both endpoints here follow Microsoft's own
19
+ * Autodiscover v2 design intent exactly: answer anonymously, and reveal nothing but a deployment-wide,
20
+ * config-supplied EAS server URL - not a per-mailbox secret - once the request email is confirmed to belong to
21
+ * a real `Mailbox` in this deployment. The actual security boundary is unchanged from Phase 2: real mailbox
22
+ * access still requires a JWT at `BaseEasRoute`, exactly as today.
23
+ *
24
+ * **Known gap, deliberately out of scope**: `Action.Redirect` (for multi-tenant hosted providers whose mailbox
25
+ * moved to a different domain) is not implemented - this library serves exactly one EAS URL for its whole
26
+ * deployment, so there's never a different domain to redirect to. The client-side well-known-URL discovery
27
+ * sequence (`MS-OXDISCO`: root domain -> `autodiscover.` subdomain -> unauthenticated HTTP redirect probe ->
28
+ * DNS SRV record -> cache) and the DNS `CNAME`/`SRV` record setup it depends on are also out of scope here -
29
+ * both are client/deployment concerns, not application code; this class only needs to answer correctly once a
30
+ * request actually arrives at one of its two paths.
31
+ *
32
+ * `mailboxClass` is supplied by the Mongo/SQL concrete subclasses following the exact one-line-per-backend
33
+ * pattern used throughout this library. The advertised URLs are built from the `mail:autodiscover:public_url`
34
+ * setting, and each protocol is only advertised while its plugin (`@rapidmx/activesync`, `@rapidmx/mapi`) is
35
+ * loaded, so a client is never pointed at an endpoint this deployment doesn't serve.
36
+ *
37
+ * @author Jean-Philippe Steinmetz
38
+ */
39
+ export declare abstract class BaseAutodiscoverRoute<M extends Mailbox> {
40
+ protected abstract mailboxClass: any;
41
+ /** The public base URL clients reach this deployment at, e.g. `https://mail.example.com`. */
42
+ protected publicUrl: string;
43
+ /** The EAS endpoint URL to report, or `undefined` when ActiveSync isn't available here. */
44
+ protected get easUrl(): string | undefined;
45
+ /** The MAPI/HTTP `emsmdb` endpoint URL to report to a real Outlook desktop client, or `undefined` when MAPI
46
+ * isn't available here. Only used by `pox()`'s Outlook/EXCH response branch. */
47
+ protected get mapiUrl(): string | undefined;
48
+ private _objectFactory?;
49
+ private mailboxRepo?;
50
+ private logger;
51
+ /**
52
+ * Builds the query value used to match `Mailbox.aliasAddresses` against the given address. See
53
+ * `BaseMailIngestRoute.aliasQueryValue()`'s identical doc comment - same Mongo-array vs.
54
+ * SQL-`simple-json`-column backend split, same override point (`AutodiscoverRouteSQL` overrides this
55
+ * identically to `MailIngestRouteSQL`).
56
+ */
57
+ protected aliasQueryValue(address: string): any;
58
+ private endpointUrl;
59
+ init(): Promise<void>;
60
+ private resolveMailbox;
61
+ /**
62
+ * Classic POX Autodiscover. Per Microsoft's own client-behavior documentation, a permanent failure is just
63
+ * as validly conveyed via a plain HTTP status as via an inner `Error` element, so this uses the HTTP-status
64
+ * form for both error cases rather than inventing values for `[MS-ASCMD]`'s provider-specific numeric
65
+ * error-code table.
66
+ *
67
+ * Branches on the request's `AcceptableResponseSchema` to decide which response shape to build: a real
68
+ * Outlook desktop client sends `[MS-OXDSCLI]`'s Outlook/EXCH schema (`OUTLOOK_RESPONSE_SCHEMA`) to locate
69
+ * this deployment's MAPI/HTTP endpoint (`buildOutlookSuccessXml`); any other value (or a mobile/EAS-only
70
+ * client that omits the field entirely) gets the original MobileSync/EAS response (`buildPoxSuccessXml`).
71
+ */
72
+ pox(req: HttpRequest, res: HttpResponse): Promise<void>;
73
+ /**
74
+ * Autodiscover v2 (JSON). Only the `ActiveSync` protocol is served - this library has no EWS/other
75
+ * protocol surface to advertise - so any other `Protocol` value is rejected outright rather than silently
76
+ * answered with an EAS URL under the wrong protocol name.
77
+ */
78
+ v2(email: string, protocol: string | undefined, res: HttpResponse): Promise<void>;
79
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Autodiscover protocol compatibility: the mechanism a real mail client uses to find this deployment's EAS
3
+ * server URL from just an email address, before it has any credentials or JWT of its own. Exports the
4
+ * backend-agnostic surface - the request/response XML helpers and the abstract route base class. The concrete
5
+ * Mongo/SQL classes a deployment actually instantiates (`AutodiscoverRouteMongo`/`AutodiscoverRouteSQL`) are
6
+ * exported from this package's `./mongo`/`./sql` subpaths instead, alongside every other entity/route/job this
7
+ * library defines - see `src/eas/index.ts`'s identical doc comment for the same convention.
8
+ *
9
+ * A deployment mounts Autodiscover with a trivial subclass supplying its own EAS URL:
10
+ * ```ts
11
+ * import { AutodiscoverRouteMongo } from "@rapidrest/mail/mongo";
12
+ * import { RouteDecorators } from "@rapidrest/service-core";
13
+ * const { Route } = RouteDecorators;
14
+ *
15
+ * @Route("/autodiscover")
16
+ * export class MyAutodiscoverRoute extends AutodiscoverRouteMongo {
17
+ * protected readonly easUrl = "https://mail.example.com/Microsoft-Server-ActiveSync";
18
+ * protected readonly mapiUrl = "https://mail.example.com/mapi/emsmdb";
19
+ * }
20
+ * ```
21
+ */
22
+ export * from "./AutodiscoverXml.js";
23
+ export * from "./BaseAutodiscoverRoute.js";
@@ -0,0 +1,11 @@
1
+ import { MailboxMongo } from "@rapidmx/restapi/mongo";
2
+ import { BaseAutodiscoverRoute } from "../BaseAutodiscoverRoute.js";
3
+ /**
4
+ * Mongo-backed concrete `BaseAutodiscoverRoute`, mounted at `/autodiscover`. Exported from this plugin's `./mongo`
5
+ * entry point, so the server host mounts it without a wrapper class of its own.
6
+ *
7
+ * @author Jean-Philippe Steinmetz
8
+ */
9
+ export declare class AutodiscoverRouteMongo extends BaseAutodiscoverRoute<MailboxMongo> {
10
+ protected mailboxClass: any;
11
+ }
@@ -0,0 +1 @@
1
+ export * from "./AutodiscoverRouteMongo.js";
@@ -0,0 +1 @@
1
+ export * from "./mongo/index.js";
@@ -0,0 +1,15 @@
1
+ import { MailboxSQL } from "@rapidmx/restapi/sql";
2
+ import { BaseAutodiscoverRoute } from "../BaseAutodiscoverRoute.js";
3
+ /**
4
+ * SQL-backed concrete `BaseAutodiscoverRoute`, mounted at `/autodiscover` and exported from this plugin's `./sql`
5
+ * entry point. `aliasQueryValue()` is overridden identically to `MailIngestRouteSQL` - see
6
+ * that class's doc comment for the full vulnerability rationale (unescaped `%`/`_` enabling alias-enumeration
7
+ * and cross-mailbox matches) this same escaping closes here too, since `resolveMailbox()` is reached by
8
+ * unauthenticated callers exactly like `MailIngestRoute.resolve()` is.
9
+ *
10
+ * @author Jean-Philippe Steinmetz
11
+ */
12
+ export declare class AutodiscoverRouteSQL extends BaseAutodiscoverRoute<MailboxSQL> {
13
+ protected mailboxClass: any;
14
+ protected aliasQueryValue(address: string): any;
15
+ }
@@ -0,0 +1 @@
1
+ export * from "./AutodiscoverRouteSQL.js";
@@ -0,0 +1 @@
1
+ export * from "./sql/index.js";