@serve.zone/interfaces 20.2.0 → 21.0.0
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.
- package/changelog.md +10 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/coremail.d.ts +37 -0
- package/dist_ts/data/coremail.js +15 -1
- package/dist_ts/data/coremail.runtime.d.ts +31 -0
- package/dist_ts/data/coremail.runtime.js +419 -0
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/requests/coremail.d.ts +2 -0
- package/package.json +1 -1
- package/readme.md +34 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/coremail.runtime.ts +675 -0
- package/ts/data/coremail.ts +41 -0
- package/ts/data/index.ts +1 -0
- package/ts/requests/coremail.ts +2 -0
package/changelog.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-07-29 - 21.0.0
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
- harden runtime contracts with canonical digests and transfer-origin binding (coremail)
|
|
8
|
+
- Add strict CoreMail runtime normalization, canonicalization, desired-state digest creation, and digest verification helpers.
|
|
9
|
+
- Require versioned argon2id-v1 verifier format on CoreMail credential DTOs and expose the verifier policy/runtime keys.
|
|
10
|
+
- Add control bootstrap and gateway peer desired-state contracts for verifier metadata and authoritative transfer origins.
|
|
11
|
+
- Return dcrouter-bound CoreMail transfer origin from gateway authentication responses.
|
|
12
|
+
|
|
3
13
|
## 2026-07-29 - 20.2.0
|
|
4
14
|
|
|
5
15
|
### Features
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '
|
|
6
|
+
version: '21.0.0',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
|
@@ -10,6 +10,7 @@ export type TCoreMailSha256 = `sha256:${string}`;
|
|
|
10
10
|
export type TCoreMailCapability = 'outbound' | 'inbound';
|
|
11
11
|
export type TCoreMailBindingState = 'active' | 'disabled';
|
|
12
12
|
export type TCoreMailCredentialState = 'current' | 'retiring';
|
|
13
|
+
export type TCoreMailCredentialVerifierFormat = 'argon2id-v1';
|
|
13
14
|
export type TCoreMailPartKind = 'text' | 'html' | 'attachment';
|
|
14
15
|
export type TCoreMailTransferMethod = 'PUT' | 'GET';
|
|
15
16
|
export type TCoreMailSubmissionState = 'preparing' | 'uploading' | 'ready' | 'accepted' | 'queued' | 'delivering' | 'delivered' | 'deferred' | 'failed' | 'deadLettered';
|
|
@@ -115,6 +116,8 @@ export interface ICoreMailBindingCredentialVerifier {
|
|
|
115
116
|
credentialId: string;
|
|
116
117
|
version: number;
|
|
117
118
|
state: TCoreMailCredentialState;
|
|
119
|
+
/** Versioned verifier contract. CoreMail currently accepts only argon2id-v1. */
|
|
120
|
+
format: TCoreMailCredentialVerifierFormat;
|
|
118
121
|
/** Password-verifier string only. Plaintext credential material is never part of desired state. */
|
|
119
122
|
verificationHash: string;
|
|
120
123
|
acceptUntil?: number;
|
|
@@ -144,6 +147,26 @@ export interface ICoreMailGatewayDesiredState {
|
|
|
144
147
|
/** Key in CoreMail's resolved runtime secret material, never a plaintext value. */
|
|
145
148
|
credentialSecretKey: string;
|
|
146
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Bootstrap authority installed in CoreMail before Coreflow can reconcile
|
|
152
|
+
* ordinary desired state. The verifier payload is safe to deliver as runtime
|
|
153
|
+
* configuration; the matching plaintext is delivered only to Coreflow.
|
|
154
|
+
*/
|
|
155
|
+
export interface ICoreMailControlBootstrap {
|
|
156
|
+
schemaVersion: 1;
|
|
157
|
+
coreMailServiceId: string;
|
|
158
|
+
credentials: ICoreMailBindingCredentialVerifier[];
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* dcrouter-owned desired state for one authenticated CoreMail gateway peer.
|
|
162
|
+
* transferOrigin is authoritative control-plane data, never peer supplied.
|
|
163
|
+
*/
|
|
164
|
+
export interface ICoreMailGatewayPeerDesiredState {
|
|
165
|
+
schemaVersion: 1;
|
|
166
|
+
coreMailServiceId: string;
|
|
167
|
+
transferOrigin: string;
|
|
168
|
+
credentials: ICoreMailBindingCredentialVerifier[];
|
|
169
|
+
}
|
|
147
170
|
export interface ICoreMailDesiredState {
|
|
148
171
|
schemaVersion: 1;
|
|
149
172
|
configEpoch: number;
|
|
@@ -214,3 +237,17 @@ export declare const coreMailLimits: Readonly<{
|
|
|
214
237
|
readonly transferIdleTimeoutMs: number;
|
|
215
238
|
readonly transferOverallTimeoutMs: number;
|
|
216
239
|
}>;
|
|
240
|
+
export declare const coreMailCredentialVerifierPolicy: Readonly<{
|
|
241
|
+
readonly format: "argon2id-v1";
|
|
242
|
+
readonly version: 19;
|
|
243
|
+
readonly memoryCost: 65536;
|
|
244
|
+
readonly timeCost: 3;
|
|
245
|
+
readonly parallelism: 1;
|
|
246
|
+
readonly saltLengthBytes: 16;
|
|
247
|
+
readonly hashLengthBytes: 32;
|
|
248
|
+
}>;
|
|
249
|
+
export declare const coreMailRuntimeKeys: Readonly<{
|
|
250
|
+
readonly controlBootstrap: "COREMAIL_CONTROL_BOOTSTRAP";
|
|
251
|
+
readonly controlCredentialSecret: "COREMAIL_CONTROL_CREDENTIAL_SECRET";
|
|
252
|
+
readonly gatewayCredentialSecret: "COREMAIL_GATEWAY_CREDENTIAL";
|
|
253
|
+
}>;
|
package/dist_ts/data/coremail.js
CHANGED
|
@@ -21,4 +21,18 @@ export const coreMailLimits = Object.freeze({
|
|
|
21
21
|
transferIdleTimeoutMs: 15 * 1000,
|
|
22
22
|
transferOverallTimeoutMs: 2 * 60 * 1000,
|
|
23
23
|
});
|
|
24
|
-
|
|
24
|
+
export const coreMailCredentialVerifierPolicy = Object.freeze({
|
|
25
|
+
format: 'argon2id-v1',
|
|
26
|
+
version: 19,
|
|
27
|
+
memoryCost: 65_536,
|
|
28
|
+
timeCost: 3,
|
|
29
|
+
parallelism: 1,
|
|
30
|
+
saltLengthBytes: 16,
|
|
31
|
+
hashLengthBytes: 32,
|
|
32
|
+
});
|
|
33
|
+
export const coreMailRuntimeKeys = Object.freeze({
|
|
34
|
+
controlBootstrap: 'COREMAIL_CONTROL_BOOTSTRAP',
|
|
35
|
+
controlCredentialSecret: 'COREMAIL_CONTROL_CREDENTIAL_SECRET',
|
|
36
|
+
gatewayCredentialSecret: 'COREMAIL_GATEWAY_CREDENTIAL',
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZW1haWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL2NvcmVtYWlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O0dBT0c7QUF3UkgsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUMsbUJBQW1CLEVBQUUsRUFBRSxHQUFHLElBQUk7SUFDOUIsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJO0lBQ2xDLGFBQWEsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUk7SUFDOUIsYUFBYSxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSTtJQUM5QixlQUFlLEVBQUUsRUFBRTtJQUNuQixlQUFlLEVBQUUsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJO0lBQ2pDLHdCQUF3QixFQUFFLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSTtJQUMxQyxnQkFBZ0IsRUFBRSxHQUFHLEdBQUcsSUFBSTtJQUM1QixtQkFBbUIsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUk7SUFDckMsa0JBQWtCLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJO0lBQ2pDLHVCQUF1QixFQUFFLEVBQUUsR0FBRyxJQUFJO0lBQ2xDLHFCQUFxQixFQUFFLEVBQUUsR0FBRyxJQUFJO0lBQ2hDLHdCQUF3QixFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSTtDQUMvQixDQUFDLENBQUM7QUFFWixNQUFNLENBQUMsTUFBTSxnQ0FBZ0MsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzVELE1BQU0sRUFBRSxhQUFzQjtJQUM5QixPQUFPLEVBQUUsRUFBRTtJQUNYLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLFFBQVEsRUFBRSxDQUFDO0lBQ1gsV0FBVyxFQUFFLENBQUM7SUFDZCxlQUFlLEVBQUUsRUFBRTtJQUNuQixlQUFlLEVBQUUsRUFBRTtDQUNYLENBQUMsQ0FBQztBQUVaLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDL0MsZ0JBQWdCLEVBQUUsNEJBQTRCO0lBQzlDLHVCQUF1QixFQUFFLG9DQUFvQztJQUM3RCx1QkFBdUIsRUFBRSw2QkFBNkI7Q0FDOUMsQ0FBQyxDQUFDIn0=
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ICoreMailBindingCredentialVerifier, type ICoreMailControlBootstrap, type ICoreMailDesiredState, type ICoreMailGatewayPeerDesiredState, type TCoreMailSha256 } from './coremail.js';
|
|
2
|
+
export declare const coreMailCanonicalJsonRules: Readonly<{
|
|
3
|
+
version: 1;
|
|
4
|
+
encoding: "utf-8";
|
|
5
|
+
objectKeyOrdering: "utf-16-code-unit-ascending";
|
|
6
|
+
arrayOrdering: "preserved-dense";
|
|
7
|
+
unicodeNormalization: "preserved";
|
|
8
|
+
numberEncoding: "safe-integer-json-no-negative-zero";
|
|
9
|
+
digest: "sha256-lowercase-hex";
|
|
10
|
+
}>;
|
|
11
|
+
export declare const coreMailContractLimits: Readonly<{
|
|
12
|
+
readonly maximumIdentifierBytes: 128;
|
|
13
|
+
readonly maximumEnvironmentKeyBytes: 128;
|
|
14
|
+
readonly maximumEndpointBytes: 2048;
|
|
15
|
+
readonly maximumMailboxBytes: 254;
|
|
16
|
+
readonly maximumBindings: 10000;
|
|
17
|
+
readonly maximumCredentialsPerAuthority: 16;
|
|
18
|
+
readonly maximumAllowedSendersPerBinding: 1000;
|
|
19
|
+
readonly maximumInboundRecipientsPerBinding: 10000;
|
|
20
|
+
}>;
|
|
21
|
+
export declare class CoreMailContractError extends Error {
|
|
22
|
+
constructor(reasonArg: string);
|
|
23
|
+
}
|
|
24
|
+
export declare const normalizeCoreMailSha256: (valueArg: unknown, pathArg?: string) => TCoreMailSha256;
|
|
25
|
+
export declare const normalizeCoreMailCredentialVerifier: (valueArg: unknown, pathArg?: string) => ICoreMailBindingCredentialVerifier;
|
|
26
|
+
export declare const normalizeCoreMailDesiredState: (valueArg: unknown) => ICoreMailDesiredState;
|
|
27
|
+
export declare const canonicalizeCoreMailDesiredState: (valueArg: unknown) => string;
|
|
28
|
+
export declare const createCoreMailDesiredStateDigest: (valueArg: unknown) => Promise<TCoreMailSha256>;
|
|
29
|
+
export declare const verifyCoreMailDesiredStateDigest: (valueArg: unknown, digestArg: unknown) => Promise<boolean>;
|
|
30
|
+
export declare const normalizeCoreMailControlBootstrap: (valueArg: unknown) => ICoreMailControlBootstrap;
|
|
31
|
+
export declare const normalizeCoreMailGatewayPeerDesiredState: (valueArg: unknown) => ICoreMailGatewayPeerDesiredState;
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import { canonicalizeStrictJson, createCanonicalJsonSha256Hex, deepFreezeValue, strictCanonicalJsonRules, } from '../private/canonicaljson.js';
|
|
2
|
+
import { coreMailCredentialVerifierPolicy, } from './coremail.js';
|
|
3
|
+
export const coreMailCanonicalJsonRules = strictCanonicalJsonRules;
|
|
4
|
+
export const coreMailContractLimits = Object.freeze({
|
|
5
|
+
maximumIdentifierBytes: 128,
|
|
6
|
+
maximumEnvironmentKeyBytes: 128,
|
|
7
|
+
maximumEndpointBytes: 2_048,
|
|
8
|
+
maximumMailboxBytes: 254,
|
|
9
|
+
maximumBindings: 10_000,
|
|
10
|
+
maximumCredentialsPerAuthority: 16,
|
|
11
|
+
maximumAllowedSendersPerBinding: 1_000,
|
|
12
|
+
maximumInboundRecipientsPerBinding: 10_000,
|
|
13
|
+
});
|
|
14
|
+
export class CoreMailContractError extends Error {
|
|
15
|
+
constructor(reasonArg) {
|
|
16
|
+
super(`CoreMail contract error: ${reasonArg}`);
|
|
17
|
+
this.name = 'CoreMailContractError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const fail = (reasonArg) => {
|
|
21
|
+
throw new CoreMailContractError(reasonArg);
|
|
22
|
+
};
|
|
23
|
+
const compareStrings = (leftArg, rightArg) => leftArg < rightArg ? -1 : leftArg > rightArg ? 1 : 0;
|
|
24
|
+
const readRecord = (valueArg, pathArg) => {
|
|
25
|
+
if (!valueArg
|
|
26
|
+
|| typeof valueArg !== 'object'
|
|
27
|
+
|| Array.isArray(valueArg)
|
|
28
|
+
|| (Object.getPrototypeOf(valueArg) !== Object.prototype
|
|
29
|
+
&& Object.getPrototypeOf(valueArg) !== null)) {
|
|
30
|
+
return fail(`${pathArg} must be a plain object`);
|
|
31
|
+
}
|
|
32
|
+
return valueArg;
|
|
33
|
+
};
|
|
34
|
+
const assertKeys = (recordArg, pathArg, requiredKeysArg, optionalKeysArg = []) => {
|
|
35
|
+
const allowedKeys = new Set([...requiredKeysArg, ...optionalKeysArg]);
|
|
36
|
+
const keys = Reflect.ownKeys(recordArg);
|
|
37
|
+
if (keys.some((keyArg) => typeof keyArg !== 'string')) {
|
|
38
|
+
fail(`${pathArg} must not contain symbol keys`);
|
|
39
|
+
}
|
|
40
|
+
for (const requiredKey of requiredKeysArg) {
|
|
41
|
+
if (!Object.hasOwn(recordArg, requiredKey)) {
|
|
42
|
+
fail(`${pathArg}.${requiredKey} is required`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const key of keys) {
|
|
46
|
+
const descriptor = Object.getOwnPropertyDescriptor(recordArg, key);
|
|
47
|
+
if (!descriptor
|
|
48
|
+
|| !descriptor.enumerable
|
|
49
|
+
|| !Object.hasOwn(descriptor, 'value')) {
|
|
50
|
+
fail(`${pathArg}.${key} must be an enumerable data property`);
|
|
51
|
+
}
|
|
52
|
+
if (!allowedKeys.has(key)) {
|
|
53
|
+
fail(`${pathArg}.${key} is not allowed`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const readArray = (valueArg, pathArg, maximumLengthArg) => {
|
|
58
|
+
if (!Array.isArray(valueArg) || Object.getPrototypeOf(valueArg) !== Array.prototype) {
|
|
59
|
+
return fail(`${pathArg} must be a plain array`);
|
|
60
|
+
}
|
|
61
|
+
if (valueArg.length > maximumLengthArg) {
|
|
62
|
+
fail(`${pathArg} exceeds its maximum length of ${maximumLengthArg}`);
|
|
63
|
+
}
|
|
64
|
+
for (let index = 0; index < valueArg.length; index++) {
|
|
65
|
+
if (!Object.hasOwn(valueArg, index)) {
|
|
66
|
+
fail(`${pathArg} must not contain sparse entries`);
|
|
67
|
+
}
|
|
68
|
+
const descriptor = Object.getOwnPropertyDescriptor(valueArg, String(index));
|
|
69
|
+
if (!descriptor
|
|
70
|
+
|| !descriptor.enumerable
|
|
71
|
+
|| !Object.hasOwn(descriptor, 'value')) {
|
|
72
|
+
fail(`${pathArg}[${index}] must be an enumerable data property`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const key of Reflect.ownKeys(valueArg)) {
|
|
76
|
+
if (key === 'length') {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (typeof key !== 'string'
|
|
80
|
+
|| !/^(?:0|[1-9][0-9]*)$/.test(key)
|
|
81
|
+
|| Number(key) >= valueArg.length) {
|
|
82
|
+
fail(`${pathArg} must not contain extra properties`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return valueArg;
|
|
86
|
+
};
|
|
87
|
+
const requireString = (valueArg, pathArg, maximumBytesArg) => {
|
|
88
|
+
if (typeof valueArg !== 'string' || valueArg.length === 0) {
|
|
89
|
+
return fail(`${pathArg} must be a non-empty string`);
|
|
90
|
+
}
|
|
91
|
+
if (new TextEncoder().encode(valueArg).byteLength > maximumBytesArg) {
|
|
92
|
+
fail(`${pathArg} exceeds ${maximumBytesArg} UTF-8 bytes`);
|
|
93
|
+
}
|
|
94
|
+
return valueArg;
|
|
95
|
+
};
|
|
96
|
+
const identifierRegex = /^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,126}[A-Za-z0-9])?$/;
|
|
97
|
+
const requireIdentifier = (valueArg, pathArg) => {
|
|
98
|
+
const value = requireString(valueArg, pathArg, coreMailContractLimits.maximumIdentifierBytes);
|
|
99
|
+
if (!identifierRegex.test(value)) {
|
|
100
|
+
fail(`${pathArg} must be a canonical identifier`);
|
|
101
|
+
}
|
|
102
|
+
return value;
|
|
103
|
+
};
|
|
104
|
+
const requireSafeInteger = (valueArg, pathArg, minimumArg) => {
|
|
105
|
+
if (!Number.isSafeInteger(valueArg) || valueArg < minimumArg) {
|
|
106
|
+
return fail(`${pathArg} must be a safe integer greater than or equal to ${minimumArg}`);
|
|
107
|
+
}
|
|
108
|
+
return valueArg;
|
|
109
|
+
};
|
|
110
|
+
const decodeCanonicalBase64 = (valueArg, expectedBytesArg, pathArg) => {
|
|
111
|
+
if (!/^[A-Za-z0-9+/]+$/.test(valueArg)) {
|
|
112
|
+
fail(`${pathArg} must use unpadded standard base64`);
|
|
113
|
+
}
|
|
114
|
+
const paddedValue = `${valueArg}${'='.repeat((4 - (valueArg.length % 4)) % 4)}`;
|
|
115
|
+
let decoded;
|
|
116
|
+
try {
|
|
117
|
+
decoded = globalThis.atob(paddedValue);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return fail(`${pathArg} must be valid base64`);
|
|
121
|
+
}
|
|
122
|
+
if (decoded.length !== expectedBytesArg) {
|
|
123
|
+
fail(`${pathArg} must encode exactly ${expectedBytesArg} bytes`);
|
|
124
|
+
}
|
|
125
|
+
const canonical = globalThis.btoa(decoded).replace(/=+$/u, '');
|
|
126
|
+
if (canonical !== valueArg) {
|
|
127
|
+
fail(`${pathArg} must be canonical unpadded base64`);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
export const normalizeCoreMailSha256 = (valueArg, pathArg = 'sha256') => {
|
|
131
|
+
if (typeof valueArg !== 'string'
|
|
132
|
+
|| !/^sha256:[0-9a-f]{64}$/.test(valueArg)) {
|
|
133
|
+
return fail(`${pathArg} must be a canonical sha256:<64 lowercase hex> digest`);
|
|
134
|
+
}
|
|
135
|
+
return valueArg;
|
|
136
|
+
};
|
|
137
|
+
export const normalizeCoreMailCredentialVerifier = (valueArg, pathArg = 'credential') => {
|
|
138
|
+
const record = readRecord(valueArg, pathArg);
|
|
139
|
+
assertKeys(record, pathArg, ['credentialId', 'version', 'state', 'format', 'verificationHash'], ['acceptUntil']);
|
|
140
|
+
const credentialId = requireIdentifier(record.credentialId, `${pathArg}.credentialId`);
|
|
141
|
+
const version = requireSafeInteger(record.version, `${pathArg}.version`, 1);
|
|
142
|
+
const state = record.state === 'current' || record.state === 'retiring'
|
|
143
|
+
? record.state
|
|
144
|
+
: fail(`${pathArg}.state must be current or retiring`);
|
|
145
|
+
const format = record.format === coreMailCredentialVerifierPolicy.format
|
|
146
|
+
? record.format
|
|
147
|
+
: fail(`${pathArg}.format must be ${coreMailCredentialVerifierPolicy.format}`);
|
|
148
|
+
const verificationHash = requireString(record.verificationHash, `${pathArg}.verificationHash`, 512);
|
|
149
|
+
const match = verificationHash.match(/^\$argon2id\$v=19\$m=65536,t=3,p=1\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/);
|
|
150
|
+
if (!match) {
|
|
151
|
+
return fail(`${pathArg}.verificationHash must use the canonical argon2id-v1 PHC form`);
|
|
152
|
+
}
|
|
153
|
+
const [, saltBase64, digestBase64] = match;
|
|
154
|
+
decodeCanonicalBase64(saltBase64, coreMailCredentialVerifierPolicy.saltLengthBytes, `${pathArg}.verificationHash salt`);
|
|
155
|
+
decodeCanonicalBase64(digestBase64, coreMailCredentialVerifierPolicy.hashLengthBytes, `${pathArg}.verificationHash digest`);
|
|
156
|
+
if (state === 'current' && Object.hasOwn(record, 'acceptUntil')) {
|
|
157
|
+
fail(`${pathArg}.acceptUntil is forbidden for a current credential`);
|
|
158
|
+
}
|
|
159
|
+
if (state === 'retiring' && !Object.hasOwn(record, 'acceptUntil')) {
|
|
160
|
+
fail(`${pathArg}.acceptUntil is required for a retiring credential`);
|
|
161
|
+
}
|
|
162
|
+
const normalized = {
|
|
163
|
+
credentialId,
|
|
164
|
+
version,
|
|
165
|
+
state,
|
|
166
|
+
format,
|
|
167
|
+
verificationHash,
|
|
168
|
+
};
|
|
169
|
+
if (state === 'retiring') {
|
|
170
|
+
normalized.acceptUntil = requireSafeInteger(record.acceptUntil, `${pathArg}.acceptUntil`, 1);
|
|
171
|
+
}
|
|
172
|
+
return deepFreezeValue(normalized);
|
|
173
|
+
};
|
|
174
|
+
const normalizeCredentialSet = (valueArg, pathArg) => {
|
|
175
|
+
const credentials = readArray(valueArg, pathArg, coreMailContractLimits.maximumCredentialsPerAuthority).map((entryArg, indexArg) => normalizeCoreMailCredentialVerifier(entryArg, `${pathArg}[${indexArg}]`));
|
|
176
|
+
if (credentials.length === 0) {
|
|
177
|
+
fail(`${pathArg} must contain at least one credential`);
|
|
178
|
+
}
|
|
179
|
+
if (credentials.filter((entryArg) => entryArg.state === 'current').length !== 1) {
|
|
180
|
+
fail(`${pathArg} must contain exactly one current credential`);
|
|
181
|
+
}
|
|
182
|
+
const identities = new Set();
|
|
183
|
+
const versions = new Set();
|
|
184
|
+
for (const credential of credentials) {
|
|
185
|
+
const identity = `${credential.credentialId}:${credential.version}`;
|
|
186
|
+
if (identities.has(identity) || versions.has(credential.version)) {
|
|
187
|
+
fail(`${pathArg} contains a duplicate credential identity or version`);
|
|
188
|
+
}
|
|
189
|
+
identities.add(identity);
|
|
190
|
+
versions.add(credential.version);
|
|
191
|
+
}
|
|
192
|
+
const current = credentials.find((entryArg) => entryArg.state === 'current');
|
|
193
|
+
if (credentials.some((entryArg) => entryArg.state === 'retiring' && entryArg.version >= current.version)) {
|
|
194
|
+
fail(`${pathArg} current credential must have the greatest version`);
|
|
195
|
+
}
|
|
196
|
+
return credentials.sort((leftArg, rightArg) => leftArg.version - rightArg.version
|
|
197
|
+
|| compareStrings(leftArg.credentialId, rightArg.credentialId));
|
|
198
|
+
};
|
|
199
|
+
const mailboxLocalPartRegex = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+$/;
|
|
200
|
+
const mailboxDomainLabelRegex = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
201
|
+
const requireCanonicalMailbox = (valueArg, pathArg) => {
|
|
202
|
+
const value = requireString(valueArg, pathArg, coreMailContractLimits.maximumMailboxBytes);
|
|
203
|
+
const atIndex = value.lastIndexOf('@');
|
|
204
|
+
const localPart = atIndex > 0 ? value.slice(0, atIndex) : '';
|
|
205
|
+
const domain = atIndex > 0 ? value.slice(atIndex + 1) : '';
|
|
206
|
+
const domainLabels = domain.split('.');
|
|
207
|
+
if (value !== value.toLowerCase()
|
|
208
|
+
|| localPart.length === 0
|
|
209
|
+
|| localPart.length > 64
|
|
210
|
+
|| !mailboxLocalPartRegex.test(localPart)
|
|
211
|
+
|| localPart.startsWith('.')
|
|
212
|
+
|| localPart.endsWith('.')
|
|
213
|
+
|| localPart.includes('..')
|
|
214
|
+
|| domain.length === 0
|
|
215
|
+
|| domain.length > 253
|
|
216
|
+
|| domainLabels.length < 2
|
|
217
|
+
|| domainLabels.some((labelArg) => !mailboxDomainLabelRegex.test(labelArg))) {
|
|
218
|
+
fail(`${pathArg} must be a canonical lowercase mailbox`);
|
|
219
|
+
}
|
|
220
|
+
return value;
|
|
221
|
+
};
|
|
222
|
+
const normalizeUniqueSortedStrings = (valueArg, pathArg, maximumLengthArg, normalizeEntryArg) => {
|
|
223
|
+
const values = readArray(valueArg, pathArg, maximumLengthArg).map((entryArg, indexArg) => normalizeEntryArg(entryArg, `${pathArg}[${indexArg}]`));
|
|
224
|
+
if (new Set(values).size !== values.length) {
|
|
225
|
+
fail(`${pathArg} must contain unique values`);
|
|
226
|
+
}
|
|
227
|
+
return values.sort();
|
|
228
|
+
};
|
|
229
|
+
const normalizeCapabilities = (valueArg, pathArg) => {
|
|
230
|
+
const capabilities = readArray(valueArg, pathArg, 2).map((entryArg, indexArg) => {
|
|
231
|
+
if (entryArg !== 'outbound' && entryArg !== 'inbound') {
|
|
232
|
+
return fail(`${pathArg}[${indexArg}] must be outbound or inbound`);
|
|
233
|
+
}
|
|
234
|
+
return entryArg;
|
|
235
|
+
});
|
|
236
|
+
if (capabilities.length === 0 || new Set(capabilities).size !== capabilities.length) {
|
|
237
|
+
fail(`${pathArg} must contain unique capabilities`);
|
|
238
|
+
}
|
|
239
|
+
return capabilities.sort();
|
|
240
|
+
};
|
|
241
|
+
const normalizeLimits = (valueArg, pathArg) => {
|
|
242
|
+
const record = readRecord(valueArg, pathArg);
|
|
243
|
+
assertKeys(record, pathArg, [], ['messagesPerMinute', 'messagesPerDay', 'maxPendingInbound']);
|
|
244
|
+
if (Object.keys(record).length === 0) {
|
|
245
|
+
fail(`${pathArg} must not be empty`);
|
|
246
|
+
}
|
|
247
|
+
const normalized = {};
|
|
248
|
+
for (const key of [
|
|
249
|
+
'messagesPerMinute',
|
|
250
|
+
'messagesPerDay',
|
|
251
|
+
'maxPendingInbound',
|
|
252
|
+
]) {
|
|
253
|
+
if (Object.hasOwn(record, key)) {
|
|
254
|
+
normalized[key] = requireSafeInteger(record[key], `${pathArg}.${key}`, 1);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return normalized;
|
|
258
|
+
};
|
|
259
|
+
const normalizeBinding = (valueArg, pathArg) => {
|
|
260
|
+
const record = readRecord(valueArg, pathArg);
|
|
261
|
+
assertKeys(record, pathArg, [
|
|
262
|
+
'schemaVersion',
|
|
263
|
+
'bindingId',
|
|
264
|
+
'serviceId',
|
|
265
|
+
'tenantId',
|
|
266
|
+
'revision',
|
|
267
|
+
'state',
|
|
268
|
+
'capabilities',
|
|
269
|
+
'credentials',
|
|
270
|
+
'allowedSenders',
|
|
271
|
+
'inboundRecipients',
|
|
272
|
+
], ['defaultSender', 'limits']);
|
|
273
|
+
if (record.schemaVersion !== 1) {
|
|
274
|
+
fail(`${pathArg}.schemaVersion must be 1`);
|
|
275
|
+
}
|
|
276
|
+
const state = record.state === 'active' || record.state === 'disabled'
|
|
277
|
+
? record.state
|
|
278
|
+
: fail(`${pathArg}.state must be active or disabled`);
|
|
279
|
+
const capabilities = normalizeCapabilities(record.capabilities, `${pathArg}.capabilities`);
|
|
280
|
+
const allowedSenders = normalizeUniqueSortedStrings(record.allowedSenders, `${pathArg}.allowedSenders`, coreMailContractLimits.maximumAllowedSendersPerBinding, requireCanonicalMailbox);
|
|
281
|
+
const inboundRecipients = normalizeUniqueSortedStrings(record.inboundRecipients, `${pathArg}.inboundRecipients`, coreMailContractLimits.maximumInboundRecipientsPerBinding, requireCanonicalMailbox);
|
|
282
|
+
if (!capabilities.includes('outbound') && allowedSenders.length > 0) {
|
|
283
|
+
fail(`${pathArg}.allowedSenders requires the outbound capability`);
|
|
284
|
+
}
|
|
285
|
+
if (!capabilities.includes('inbound') && inboundRecipients.length > 0) {
|
|
286
|
+
fail(`${pathArg}.inboundRecipients requires the inbound capability`);
|
|
287
|
+
}
|
|
288
|
+
const normalized = {
|
|
289
|
+
schemaVersion: 1,
|
|
290
|
+
bindingId: requireIdentifier(record.bindingId, `${pathArg}.bindingId`),
|
|
291
|
+
serviceId: requireIdentifier(record.serviceId, `${pathArg}.serviceId`),
|
|
292
|
+
tenantId: requireIdentifier(record.tenantId, `${pathArg}.tenantId`),
|
|
293
|
+
revision: requireSafeInteger(record.revision, `${pathArg}.revision`, 1),
|
|
294
|
+
state,
|
|
295
|
+
capabilities,
|
|
296
|
+
credentials: normalizeCredentialSet(record.credentials, `${pathArg}.credentials`),
|
|
297
|
+
allowedSenders,
|
|
298
|
+
inboundRecipients,
|
|
299
|
+
};
|
|
300
|
+
if (Object.hasOwn(record, 'defaultSender')) {
|
|
301
|
+
normalized.defaultSender = requireCanonicalMailbox(record.defaultSender, `${pathArg}.defaultSender`);
|
|
302
|
+
if (!allowedSenders.includes(normalized.defaultSender)) {
|
|
303
|
+
fail(`${pathArg}.defaultSender must be present in allowedSenders`);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
if (Object.hasOwn(record, 'limits')) {
|
|
307
|
+
normalized.limits = normalizeLimits(record.limits, `${pathArg}.limits`);
|
|
308
|
+
}
|
|
309
|
+
return normalized;
|
|
310
|
+
};
|
|
311
|
+
const requireCanonicalUrl = (valueArg, pathArg, protocolArg, originOnlyArg) => {
|
|
312
|
+
const value = requireString(valueArg, pathArg, coreMailContractLimits.maximumEndpointBytes);
|
|
313
|
+
let url;
|
|
314
|
+
try {
|
|
315
|
+
url = new URL(value);
|
|
316
|
+
}
|
|
317
|
+
catch {
|
|
318
|
+
return fail(`${pathArg} must be an absolute URL`);
|
|
319
|
+
}
|
|
320
|
+
if (url.protocol !== protocolArg
|
|
321
|
+
|| url.username
|
|
322
|
+
|| url.password
|
|
323
|
+
|| url.search
|
|
324
|
+
|| url.hash) {
|
|
325
|
+
fail(`${pathArg} must be a credential-free canonical ${protocolArg} URL`);
|
|
326
|
+
}
|
|
327
|
+
if (originOnlyArg && url.pathname !== '/') {
|
|
328
|
+
fail(`${pathArg} must be an origin without a path`);
|
|
329
|
+
}
|
|
330
|
+
const canonical = originOnlyArg
|
|
331
|
+
? url.origin
|
|
332
|
+
: url.toString();
|
|
333
|
+
if (canonical !== value) {
|
|
334
|
+
fail(`${pathArg} must already be in canonical URL form`);
|
|
335
|
+
}
|
|
336
|
+
return canonical;
|
|
337
|
+
};
|
|
338
|
+
const normalizeGateway = (valueArg, pathArg) => {
|
|
339
|
+
const record = readRecord(valueArg, pathArg);
|
|
340
|
+
assertKeys(record, pathArg, ['endpointUrl', 'credentialId', 'credentialVersion', 'credentialSecretKey']);
|
|
341
|
+
const credentialSecretKey = requireString(record.credentialSecretKey, `${pathArg}.credentialSecretKey`, coreMailContractLimits.maximumEnvironmentKeyBytes);
|
|
342
|
+
if (!/^[A-Z][A-Z0-9_]{0,127}$/.test(credentialSecretKey)) {
|
|
343
|
+
fail(`${pathArg}.credentialSecretKey must be a canonical environment key`);
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
endpointUrl: requireCanonicalUrl(record.endpointUrl, `${pathArg}.endpointUrl`, 'wss:', false),
|
|
347
|
+
credentialId: requireIdentifier(record.credentialId, `${pathArg}.credentialId`),
|
|
348
|
+
credentialVersion: requireSafeInteger(record.credentialVersion, `${pathArg}.credentialVersion`, 1),
|
|
349
|
+
credentialSecretKey,
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
export const normalizeCoreMailDesiredState = (valueArg) => {
|
|
353
|
+
const record = readRecord(valueArg, 'desiredState');
|
|
354
|
+
assertKeys(record, 'desiredState', ['schemaVersion', 'configEpoch', 'bindings', 'gateway']);
|
|
355
|
+
if (record.schemaVersion !== 1) {
|
|
356
|
+
fail('desiredState.schemaVersion must be 1');
|
|
357
|
+
}
|
|
358
|
+
const bindings = readArray(record.bindings, 'desiredState.bindings', coreMailContractLimits.maximumBindings).map((entryArg, indexArg) => normalizeBinding(entryArg, `desiredState.bindings[${indexArg}]`));
|
|
359
|
+
const bindingIds = new Set();
|
|
360
|
+
const activeInboundRecipients = new Set();
|
|
361
|
+
for (const binding of bindings) {
|
|
362
|
+
if (bindingIds.has(binding.bindingId)) {
|
|
363
|
+
fail('desiredState.bindings contains a duplicate bindingId');
|
|
364
|
+
}
|
|
365
|
+
bindingIds.add(binding.bindingId);
|
|
366
|
+
if (binding.state === 'active') {
|
|
367
|
+
for (const recipient of binding.inboundRecipients) {
|
|
368
|
+
if (activeInboundRecipients.has(recipient)) {
|
|
369
|
+
fail('active inbound recipient ownership must be unique');
|
|
370
|
+
}
|
|
371
|
+
activeInboundRecipients.add(recipient);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
bindings.sort((leftArg, rightArg) => compareStrings(leftArg.bindingId, rightArg.bindingId));
|
|
376
|
+
return deepFreezeValue({
|
|
377
|
+
schemaVersion: 1,
|
|
378
|
+
configEpoch: requireSafeInteger(record.configEpoch, 'desiredState.configEpoch', 1),
|
|
379
|
+
bindings,
|
|
380
|
+
gateway: normalizeGateway(record.gateway, 'desiredState.gateway'),
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
export const canonicalizeCoreMailDesiredState = (valueArg) => {
|
|
384
|
+
return canonicalizeStrictJson(normalizeCoreMailDesiredState(valueArg), fail, 'CoreMail desired state');
|
|
385
|
+
};
|
|
386
|
+
export const createCoreMailDesiredStateDigest = async (valueArg) => {
|
|
387
|
+
const digestHex = await createCanonicalJsonSha256Hex(canonicalizeCoreMailDesiredState(valueArg), fail);
|
|
388
|
+
return `sha256:${digestHex}`;
|
|
389
|
+
};
|
|
390
|
+
export const verifyCoreMailDesiredStateDigest = async (valueArg, digestArg) => {
|
|
391
|
+
return normalizeCoreMailSha256(digestArg, 'desiredStateDigest')
|
|
392
|
+
=== await createCoreMailDesiredStateDigest(valueArg);
|
|
393
|
+
};
|
|
394
|
+
export const normalizeCoreMailControlBootstrap = (valueArg) => {
|
|
395
|
+
const record = readRecord(valueArg, 'controlBootstrap');
|
|
396
|
+
assertKeys(record, 'controlBootstrap', ['schemaVersion', 'coreMailServiceId', 'credentials']);
|
|
397
|
+
if (record.schemaVersion !== 1) {
|
|
398
|
+
fail('controlBootstrap.schemaVersion must be 1');
|
|
399
|
+
}
|
|
400
|
+
return deepFreezeValue({
|
|
401
|
+
schemaVersion: 1,
|
|
402
|
+
coreMailServiceId: requireIdentifier(record.coreMailServiceId, 'controlBootstrap.coreMailServiceId'),
|
|
403
|
+
credentials: normalizeCredentialSet(record.credentials, 'controlBootstrap.credentials'),
|
|
404
|
+
});
|
|
405
|
+
};
|
|
406
|
+
export const normalizeCoreMailGatewayPeerDesiredState = (valueArg) => {
|
|
407
|
+
const record = readRecord(valueArg, 'gatewayPeer');
|
|
408
|
+
assertKeys(record, 'gatewayPeer', ['schemaVersion', 'coreMailServiceId', 'transferOrigin', 'credentials']);
|
|
409
|
+
if (record.schemaVersion !== 1) {
|
|
410
|
+
fail('gatewayPeer.schemaVersion must be 1');
|
|
411
|
+
}
|
|
412
|
+
return deepFreezeValue({
|
|
413
|
+
schemaVersion: 1,
|
|
414
|
+
coreMailServiceId: requireIdentifier(record.coreMailServiceId, 'gatewayPeer.coreMailServiceId'),
|
|
415
|
+
transferOrigin: requireCanonicalUrl(record.transferOrigin, 'gatewayPeer.transferOrigin', 'https:', true),
|
|
416
|
+
credentials: normalizeCredentialSet(record.credentials, 'gatewayPeer.credentials'),
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZW1haWwucnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvY29yZW1haWwucnVudGltZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLDRCQUE0QixFQUM1QixlQUFlLEVBQ2Ysd0JBQXdCLEdBQ3pCLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUNMLGdDQUFnQyxHQVNqQyxNQUFNLGVBQWUsQ0FBQztBQUV2QixNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyx3QkFBd0IsQ0FBQztBQUVuRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ2xELHNCQUFzQixFQUFFLEdBQUc7SUFDM0IsMEJBQTBCLEVBQUUsR0FBRztJQUMvQixvQkFBb0IsRUFBRSxLQUFLO0lBQzNCLG1CQUFtQixFQUFFLEdBQUc7SUFDeEIsZUFBZSxFQUFFLE1BQU07SUFDdkIsOEJBQThCLEVBQUUsRUFBRTtJQUNsQywrQkFBK0IsRUFBRSxLQUFLO0lBQ3RDLGtDQUFrQyxFQUFFLE1BQU07Q0FDbEMsQ0FBQyxDQUFDO0FBRVosTUFBTSxPQUFPLHFCQUFzQixTQUFRLEtBQUs7SUFDOUMsWUFBbUIsU0FBaUI7UUFDbEMsS0FBSyxDQUFDLDRCQUE0QixTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxJQUFJLEdBQUcsdUJBQXVCLENBQUM7SUFDdEMsQ0FBQztDQUNGO0FBSUQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxTQUFpQixFQUFTLEVBQUU7SUFDeEMsTUFBTSxJQUFJLHFCQUFxQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzdDLENBQUMsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHLENBQUMsT0FBZSxFQUFFLFFBQWdCLEVBQVUsRUFBRSxDQUNuRSxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxD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
|
package/dist_ts/data/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './cloudlyconfig.js';
|
|
|
2
2
|
export * from './cluster.js';
|
|
3
3
|
export * from './config.js';
|
|
4
4
|
export * from './coremail.js';
|
|
5
|
+
export * from './coremail.runtime.js';
|
|
5
6
|
export * from './deployment.js';
|
|
6
7
|
export * from './deploymentadoption.js';
|
|
7
8
|
export * from './deploymentoperation.js';
|
package/dist_ts/data/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export * from './cloudlyconfig.js';
|
|
|
2
2
|
export * from './cluster.js';
|
|
3
3
|
export * from './config.js';
|
|
4
4
|
export * from './coremail.js';
|
|
5
|
+
export * from './coremail.runtime.js';
|
|
5
6
|
export * from './deployment.js';
|
|
6
7
|
export * from './deploymentadoption.js';
|
|
7
8
|
export * from './deploymentoperation.js';
|
|
@@ -36,4 +37,4 @@ export * from './traffic.js';
|
|
|
36
37
|
export * from './user.js';
|
|
37
38
|
export * from './version.js';
|
|
38
39
|
export * from './webpush.js';
|
|
39
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsY0FBYyxVQUFVLENBQUM7QUFDekIsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLDZCQUE2QixDQUFDO0FBQzVDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxrQkFBa0IsQ0FBQztBQUNqQyxjQUFjLGdCQUFnQixDQUFDO0FBQy9CLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxlQUFlLENBQUM7QUFDOUIsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsY0FBYyxDQUFDO0FBQzdCLGNBQWMsY0FBYyxDQUFDIn0=
|
|
@@ -168,6 +168,8 @@ export interface IReq_CoreMailGatewayAuthenticate extends plugins.typedrequestIn
|
|
|
168
168
|
response: {
|
|
169
169
|
authenticated: true;
|
|
170
170
|
credentialVersion: number;
|
|
171
|
+
/** dcrouter's authoritative, control-plane-bound origin for CoreMail transfer paths. */
|
|
172
|
+
coreMailTransferOrigin: string;
|
|
171
173
|
};
|
|
172
174
|
}
|
|
173
175
|
export interface IReq_CoreMailGatewayResolveRecipients extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGatewayResolveRecipients> {
|