@serve.zone/interfaces 30.11.0 → 30.13.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 +18 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/coremail.d.ts +67 -0
- package/dist_ts/data/coremail.js +1 -1
- package/dist_ts/data/coremail.runtime.d.ts +19 -1
- package/dist_ts/data/coremail.runtime.js +191 -4
- package/dist_ts/data/index.d.ts +1 -0
- package/dist_ts/data/index.js +2 -1
- package/dist_ts/data/mail.d.ts +17 -4
- package/dist_ts/data/networkcredential.d.ts +32 -0
- package/dist_ts/data/networkcredential.js +66 -0
- package/dist_ts/requests/coremail.d.ts +44 -1
- package/dist_ts/requests/mail.d.ts +50 -0
- package/dist_ts/requests/runtimesession.d.ts +7 -0
- package/package.json +1 -1
- package/readme.md +60 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/coremail.runtime.ts +278 -2
- package/ts/data/coremail.ts +72 -0
- package/ts/data/index.ts +1 -0
- package/ts/data/mail.ts +36 -4
- package/ts/data/networkcredential.ts +88 -0
- package/ts/requests/coremail.ts +48 -0
- package/ts/requests/mail.ts +62 -0
- package/ts/requests/runtimesession.ts +10 -0
package/dist_ts/data/mail.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type TMailGatewayClientType = 'onebox' | 'cloudly' | 'custom' | (string & {});
|
|
2
2
|
export type TMailAddressPatternType = 'exactAddress' | 'domainWildcard' | 'localPartPattern';
|
|
3
|
-
export type TMailInboundTargetType = 'webhook' | 'smtpForward' | 'typedEndpoint' | 'discard' | 'reject';
|
|
3
|
+
export type TMailInboundTargetType = 'webhook' | 'smtpForward' | 'typedEndpoint' | 'coreMail' | 'discard' | 'reject';
|
|
4
4
|
export type TMailRecipientPolicyMode = 'acceptAll' | 'staticList' | 'cachedResolver' | 'appResolver';
|
|
5
5
|
export type TMailCredentialType = 'smtp' | 'api';
|
|
6
6
|
export type TMailCredentialStatus = 'active' | 'disabled' | 'rotated' | 'revoked';
|
|
@@ -12,7 +12,12 @@ export type TMailBounceType = 'hard' | 'soft' | 'complaint' | 'unknown';
|
|
|
12
12
|
export type TMailInboundProtocol = 'smtp' | 'submission' | 'api';
|
|
13
13
|
export type TMailRecipientResolutionAction = 'accept' | 'reject' | 'defer';
|
|
14
14
|
export type TMailDeliveryJournalEventType = 'accepted' | 'queued' | 'deliveryStarted' | 'deliverySucceeded' | 'deliveryDeferred' | 'deliveryFailed' | 'deadLettered' | 'rejected' | 'bounced' | 'complaint';
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Error codes a mail submission may return. The CoreMail-fronted path maps the
|
|
17
|
+
* matching `TCoreMailErrorCode` values through unchanged so applications can
|
|
18
|
+
* branch on them regardless of which transport carried the submission.
|
|
19
|
+
*/
|
|
20
|
+
export type TMailSubmissionErrorCode = 'INVALID_REPLY_TO' | 'REPLY_TO_FIELD_HEADER_CONFLICT' | 'AUTHENTICATION_FAILED' | 'CAPABILITY_DENIED' | 'INVALID_REQUEST' | 'INVALID_MAILBOX' | 'INVALID_SENDER' | 'INVALID_RECIPIENT' | 'INVALID_HEADER' | 'PAYLOAD_LIMIT_EXCEEDED' | 'QUOTA_EXCEEDED' | 'IDEMPOTENCY_CONFLICT' | 'STATE_CONFLICT' | 'NOT_FOUND';
|
|
16
21
|
/**
|
|
17
22
|
* Runtime owner of a mail resource. `appInstanceId` is the deployed WorkApp or service
|
|
18
23
|
* instance, not an App Store template id.
|
|
@@ -48,11 +53,16 @@ export interface IMailTypedEndpointTarget {
|
|
|
48
53
|
queueName?: string;
|
|
49
54
|
timeoutMs?: number;
|
|
50
55
|
}
|
|
56
|
+
export interface IMailCoreMailTarget {
|
|
57
|
+
/** CoreMail service identity that owns the inbound mailbox. */
|
|
58
|
+
coreMailServiceId: string;
|
|
59
|
+
}
|
|
51
60
|
export interface IMailInboundTarget {
|
|
52
61
|
type: TMailInboundTargetType;
|
|
53
62
|
webhook?: IMailWebhookTarget;
|
|
54
63
|
smtpForward?: IMailSmtpForwardTarget;
|
|
55
64
|
typedEndpoint?: IMailTypedEndpointTarget;
|
|
65
|
+
coreMail?: IMailCoreMailTarget;
|
|
56
66
|
reject?: {
|
|
57
67
|
smtpCode: number;
|
|
58
68
|
message: string;
|
|
@@ -175,8 +185,11 @@ export interface IWorkAppMailBinding {
|
|
|
175
185
|
export type TServiceMailSubmissionTlsMode = 'plain' | 'starttls' | 'implicitTls';
|
|
176
186
|
export interface IServiceMailInboundConfig {
|
|
177
187
|
enabled?: boolean;
|
|
178
|
-
/**
|
|
179
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Platformclient apps use typedEndpoint; third-party apps with their own SMTP
|
|
190
|
+
* server use smtpForward; services bound to a CoreMail workload use coreMail.
|
|
191
|
+
*/
|
|
192
|
+
targetType?: 'typedEndpoint' | 'smtpForward' | 'coreMail';
|
|
180
193
|
/** TypedRequest method exposed by platformclient over TypedSocket for inbound delivery. */
|
|
181
194
|
typedMethod?: string;
|
|
182
195
|
/** Published Docker/Swarm port that dcrouter may SMTP-forward inbound mail to. */
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IRuntimeAuthorityReferenceV1 } from './runtimeassignment.js';
|
|
2
|
+
import { type IRuntimeSessionBindingV1 } from './runtimesession.js';
|
|
3
|
+
export interface IGetRuntimeManagedVpnCredentialRequestV1 {
|
|
4
|
+
session: IRuntimeSessionBindingV1;
|
|
5
|
+
projection: IRuntimeAuthorityReferenceV1;
|
|
6
|
+
}
|
|
7
|
+
/** Secret response over the current authenticated physical peer only. Never
|
|
8
|
+
* persist, hash, log, or include it in a signed network projection. The native
|
|
9
|
+
* Noise owner validates and uses the keys; these shapes confer no TUN readiness. */
|
|
10
|
+
export interface IGetRuntimeManagedVpnCredentialResponseV1 extends IGetRuntimeManagedVpnCredentialRequestV1 {
|
|
11
|
+
transport: 'quic';
|
|
12
|
+
relay: {
|
|
13
|
+
id: string;
|
|
14
|
+
address: string;
|
|
15
|
+
port: number;
|
|
16
|
+
};
|
|
17
|
+
authorityId: string;
|
|
18
|
+
serverPublicKey: string;
|
|
19
|
+
clientPublicKey: string;
|
|
20
|
+
clientPrivateKey: string;
|
|
21
|
+
/** Unix milliseconds; cannot outlive the referenced projection's DNS lease. */
|
|
22
|
+
expiresAt: number;
|
|
23
|
+
}
|
|
24
|
+
export declare const snapshotGetRuntimeManagedVpnCredentialRequestV1: (value: unknown) => IGetRuntimeManagedVpnCredentialRequestV1;
|
|
25
|
+
export declare const snapshotGetRuntimeManagedVpnCredentialResponseV1: (value: unknown) => IGetRuntimeManagedVpnCredentialResponseV1;
|
|
26
|
+
/** Content binding only. The caller must resolve the exact current projection
|
|
27
|
+
* and authenticate/fence the current physical peer before and after native work. */
|
|
28
|
+
export declare const bindGetRuntimeManagedVpnCredentialRequestV1: (value: unknown, projectionValue: unknown, trustedSessionValue: unknown) => Promise<IGetRuntimeManagedVpnCredentialRequestV1>;
|
|
29
|
+
/** Bind the secret response to the original request and exact selected router
|
|
30
|
+
* UDP endpoint. Time is caller-qualified; this helper does not sample a clock,
|
|
31
|
+
* authenticate a transport, admit policy or prove a running managed connection. */
|
|
32
|
+
export declare const bindGetRuntimeManagedVpnCredentialResponseV1: (value: unknown, requestValue: unknown, projectionValue: unknown, trustedSessionValue: unknown, nowValue: unknown) => Promise<IGetRuntimeManagedVpnCredentialResponseV1>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { snapshotRuntimeSessionBindingV1 } from './runtimesession.js';
|
|
2
|
+
import { validateRuntimeNetworkProjectionV1 } from './networkprojection.js';
|
|
3
|
+
import { captureNetwork, failNetwork, networkCounter, networkEqual, networkId, networkIpv4, networkRecord, networkReference, networkReferenceOf, networkSafe, requireNetwork } from '../private/networkcontract.js';
|
|
4
|
+
/** Canonical 32-byte key encoding only. Cryptographic key agreement and pair
|
|
5
|
+
* validation belong to the native Noise implementation, not this JSON parser. */
|
|
6
|
+
const key = (value) => {
|
|
7
|
+
requireNetwork(typeof value === 'string' && /^[A-Za-z0-9+/]{43}=$/.test(value));
|
|
8
|
+
const decoded = atob(value);
|
|
9
|
+
requireNetwork(decoded.length === 32 && btoa(decoded) === value && [...decoded].some(byte => byte.charCodeAt(0) !== 0));
|
|
10
|
+
return value;
|
|
11
|
+
};
|
|
12
|
+
export const snapshotGetRuntimeManagedVpnCredentialRequestV1 = (value) => networkSafe(() => {
|
|
13
|
+
const item = networkRecord(captureNetwork(value), ['session', 'projection']);
|
|
14
|
+
return { session: snapshotRuntimeSessionBindingV1(item.session), projection: networkReference(item.projection) };
|
|
15
|
+
});
|
|
16
|
+
export const snapshotGetRuntimeManagedVpnCredentialResponseV1 = (value) => networkSafe(() => {
|
|
17
|
+
const item = networkRecord(captureNetwork(value), ['session', 'projection', 'transport', 'relay', 'authorityId',
|
|
18
|
+
'serverPublicKey', 'clientPublicKey', 'clientPrivateKey', 'expiresAt']);
|
|
19
|
+
const relay = networkRecord(item.relay, ['id', 'address', 'port']);
|
|
20
|
+
requireNetwork(item.transport === 'quic');
|
|
21
|
+
return { session: snapshotRuntimeSessionBindingV1(item.session), projection: networkReference(item.projection), transport: 'quic',
|
|
22
|
+
relay: { id: networkId(relay.id), address: networkIpv4(relay.address), port: networkCounter(relay.port, 65535) },
|
|
23
|
+
authorityId: networkId(item.authorityId), serverPublicKey: key(item.serverPublicKey), clientPublicKey: key(item.clientPublicKey),
|
|
24
|
+
clientPrivateKey: key(item.clientPrivateKey), expiresAt: networkCounter(item.expiresAt) };
|
|
25
|
+
});
|
|
26
|
+
const bindRequest = (request, projection, trusted) => {
|
|
27
|
+
requireNetwork(networkEqual(request.session, trusted) && networkEqual(request.projection, networkReferenceOf(projection))
|
|
28
|
+
&& networkEqual(projection.controller, trusted.controller) && projection.nodeId === trusted.nodeId
|
|
29
|
+
&& projection.runtimeNamespace === trusted.runtimeNamespace && projection.handoff);
|
|
30
|
+
};
|
|
31
|
+
/** Content binding only. The caller must resolve the exact current projection
|
|
32
|
+
* and authenticate/fence the current physical peer before and after native work. */
|
|
33
|
+
export const bindGetRuntimeManagedVpnCredentialRequestV1 = async (value, projectionValue, trustedSessionValue) => {
|
|
34
|
+
try {
|
|
35
|
+
const request = snapshotGetRuntimeManagedVpnCredentialRequestV1(value);
|
|
36
|
+
const trusted = snapshotRuntimeSessionBindingV1(trustedSessionValue);
|
|
37
|
+
const projection = await validateRuntimeNetworkProjectionV1(projectionValue);
|
|
38
|
+
bindRequest(request, projection, trusted);
|
|
39
|
+
return request;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return failNetwork();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
/** Bind the secret response to the original request and exact selected router
|
|
46
|
+
* UDP endpoint. Time is caller-qualified; this helper does not sample a clock,
|
|
47
|
+
* authenticate a transport, admit policy or prove a running managed connection. */
|
|
48
|
+
export const bindGetRuntimeManagedVpnCredentialResponseV1 = async (value, requestValue, projectionValue, trustedSessionValue, nowValue) => {
|
|
49
|
+
try {
|
|
50
|
+
const response = snapshotGetRuntimeManagedVpnCredentialResponseV1(value);
|
|
51
|
+
const request = snapshotGetRuntimeManagedVpnCredentialRequestV1(requestValue);
|
|
52
|
+
const trusted = snapshotRuntimeSessionBindingV1(trustedSessionValue), now = networkCounter(nowValue);
|
|
53
|
+
const projection = await validateRuntimeNetworkProjectionV1(projectionValue);
|
|
54
|
+
bindRequest(request, projection, trusted);
|
|
55
|
+
requireNetwork(networkEqual(response.session, request.session) && networkEqual(response.projection, request.projection));
|
|
56
|
+
requireNetwork(projection.router?.platformEndpointIds.includes(response.relay.id));
|
|
57
|
+
const endpoint = projection.protectedAuthority.platformEndpoints.find(item => item.id === response.relay.id);
|
|
58
|
+
requireNetwork(endpoint && endpoint.protocol === 'udp' && endpoint.address === response.relay.address && endpoint.port === response.relay.port);
|
|
59
|
+
requireNetwork(projection.dns.notBefore <= now && now < response.expiresAt && response.expiresAt <= projection.dns.expiresAt);
|
|
60
|
+
return response;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return failNetwork();
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV0d29ya2NyZWRlbnRpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL25ldHdvcmtjcmVkZW50aWFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSwrQkFBK0IsRUFBaUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRyxPQUFPLEVBQUUsa0NBQWtDLEVBQW9DLE1BQU0sd0JBQXdCLENBQUM7QUFDOUcsT0FBTyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUN4RixhQUFhLEVBQUUsZ0JBQWdCLEVBQUUsa0JBQWtCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBcUIxSDtpRkFDaUY7QUFDakYsTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFjLEVBQVUsRUFBRTtJQUNyQyxjQUFjLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLHNCQUFzQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ2hGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QixjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hILE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sK0NBQStDLEdBQUcsQ0FBQyxLQUFjLEVBQTRDLEVBQUUsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFO0lBQzVJLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxjQUFjLENBQUMs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
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as plugins from '../plugins.js';
|
|
2
|
-
import type { ICoreMailEnvelope, ICoreMailInboundDeliveryPage, ICoreMailDownloadGrant, ICoreMailGatewayMessageDescriptor, ICoreMailGatewayOutboundStatus, ICoreMailInboundDelivery, ICoreMailOutboundMessageDescriptor, ICoreMailRecipientResolution, ICoreMailReconciliationStatus, ICoreMailReplicaIdentity, ICoreMailSubmission, ICoreMailUploadGrant, TCoreMailInboundAckOutcome, TCoreMailSha256, TCoreMailWorkloadOperation } from '../data/coremail.js';
|
|
2
|
+
import type { ICoreMailEnvelope, ICoreMailInboundDeliveryPage, ICoreMailDownloadGrant, ICoreMailGatewayMessageDescriptor, ICoreMailGatewayOutboundStatus, ICoreMailInboundDelivery, ICoreMailOutboundMessageDescriptor, ICoreMailRecipientResolution, ICoreMailReconciliationStatus, ICoreMailReplicaIdentity, ICoreMailServiceMailStatistics, ICoreMailSubmission, ICoreMailUploadGrant, TCoreMailInboundAckOutcome, TCoreMailSha256, TCoreMailWorkloadOperation } from '../data/coremail.js';
|
|
3
3
|
import type { IMailConnectionInfo } from '../data/mail.js';
|
|
4
4
|
export interface IReq_CoreMailAuthenticateWorkload extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailAuthenticateWorkload> {
|
|
5
5
|
method: 'coreMailAuthenticateWorkload';
|
|
@@ -164,6 +164,29 @@ export interface IReq_CoreMailGetReconciliationStatus extends plugins.typedreque
|
|
|
164
164
|
status: ICoreMailReconciliationStatus;
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Control-session read of per-service mail counters. Authority comes from the
|
|
169
|
+
* authenticated control session; the request carries no tenant or binding
|
|
170
|
+
* authority of its own.
|
|
171
|
+
*/
|
|
172
|
+
export interface IReq_CoreMailGetServiceMailStatistics extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGetServiceMailStatistics> {
|
|
173
|
+
method: 'coreMailGetServiceMailStatistics';
|
|
174
|
+
request: {
|
|
175
|
+
/** Inclusive first UTC calendar day, `YYYY-MM-DD`. */
|
|
176
|
+
fromDayUtc: string;
|
|
177
|
+
/** Inclusive last UTC calendar day, `YYYY-MM-DD`. */
|
|
178
|
+
toDayUtc: string;
|
|
179
|
+
/** Optional service filter. Omitted means every service known to this CoreMail. */
|
|
180
|
+
serviceIds?: string[];
|
|
181
|
+
/** Opaque CoreMail-owned composite cursor. */
|
|
182
|
+
cursor?: string;
|
|
183
|
+
limit: number;
|
|
184
|
+
};
|
|
185
|
+
response: {
|
|
186
|
+
statistics: ICoreMailServiceMailStatistics[];
|
|
187
|
+
nextCursor?: string;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
167
190
|
export interface IReq_CoreMailGatewayAuthenticate extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGatewayAuthenticate> {
|
|
168
191
|
method: 'coreMailGatewayAuthenticate';
|
|
169
192
|
request: {
|
|
@@ -179,6 +202,13 @@ export interface IReq_CoreMailGatewayAuthenticate extends plugins.typedrequestIn
|
|
|
179
202
|
coreMailTransferOrigin: string;
|
|
180
203
|
};
|
|
181
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* CoreMail binds every issued routing handle to a digest of the exact
|
|
207
|
+
* normalized `envelope` and `source` sent here. The following
|
|
208
|
+
* `coreMailGatewayPrepareInboundHandoff` call must therefore resend
|
|
209
|
+
* byte-identical values: the full `rcptTo` set in the same order, the same
|
|
210
|
+
* `mailFrom`, and the same connection source fields.
|
|
211
|
+
*/
|
|
182
212
|
export interface IReq_CoreMailGatewayResolveRecipients extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGatewayResolveRecipients> {
|
|
183
213
|
method: 'coreMailGatewayResolveRecipients';
|
|
184
214
|
request: {
|
|
@@ -190,6 +220,13 @@ export interface IReq_CoreMailGatewayResolveRecipients extends plugins.typedrequ
|
|
|
190
220
|
resolutions: ICoreMailRecipientResolution[];
|
|
191
221
|
};
|
|
192
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* The handoff is validated against the routing handles issued by
|
|
225
|
+
* `coreMailGatewayResolveRecipients`. `message.envelope` and `source` must be
|
|
226
|
+
* byte-identical to the resolve-time values, including the full `rcptTo` set in
|
|
227
|
+
* the same order, because CoreMail recomputes the envelope digest the handles
|
|
228
|
+
* are bound to.
|
|
229
|
+
*/
|
|
193
230
|
export interface IReq_CoreMailGatewayPrepareInboundHandoff extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGatewayPrepareInboundHandoff> {
|
|
194
231
|
method: 'coreMailGatewayPrepareInboundHandoff';
|
|
195
232
|
request: {
|
|
@@ -246,6 +283,12 @@ export interface IReq_CoreMailGatewayCompleteOutboundHandoff extends plugins.typ
|
|
|
246
283
|
replayed: boolean;
|
|
247
284
|
};
|
|
248
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Status polling for one accepted transport message. `status.updatedAt` must be
|
|
288
|
+
* monotonic per `transportMessageId`. A `transportMessageId` that is
|
|
289
|
+
* permanently unknown to the gateway must be answered with a terminal `failed`
|
|
290
|
+
* status rather than an error, because CoreMail retries errors indefinitely.
|
|
291
|
+
*/
|
|
249
292
|
export interface IReq_CoreMailGatewayGetOutboundStatus extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CoreMailGatewayGetOutboundStatus> {
|
|
250
293
|
method: 'coreMailGatewayGetOutboundStatus';
|
|
251
294
|
request: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
|
+
import type { ICoreMailGatewayPeerDesiredState } from '../data/coremail.js';
|
|
2
3
|
import type { IIdentity } from '../data/user.js';
|
|
3
4
|
import type { IMailAddressBinding, IMailCredentialOneTimeSecret, IMailConnectionInfo, IMailDeliveryJournalEvent, IMailDeliveryStatus, IMailDomainAuthority, IMailEnvelope, IMailInboundMessagePayload, IMailOutboundIdentity, IMailOutboundMessagePayload, IMailRecipientResolution, IMailResourceOwner, IMailSpoolItem, IWorkAppMailBinding, TMailSubmissionErrorCode } from '../data/mail.js';
|
|
4
5
|
export interface IMailControlRequestAuth {
|
|
@@ -89,6 +90,55 @@ export interface IReq_DeleteMailAddressBinding extends plugins.typedrequestInter
|
|
|
89
90
|
message?: string;
|
|
90
91
|
};
|
|
91
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* dcrouter-owned CoreMail gateway peer state.
|
|
95
|
+
*
|
|
96
|
+
* `peer.transferOrigin` must equal the `gateway.coreMailTransferOrigin` carried
|
|
97
|
+
* in that CoreMail service's own desired state. The producer (Cloudly or
|
|
98
|
+
* Onebox) is the single owner of that string: dcrouter never infers it from a
|
|
99
|
+
* socket, Host header, TypedSocket tag, or peer input.
|
|
100
|
+
*/
|
|
101
|
+
export interface IReq_ListCoreMailGatewayPeers extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ListCoreMailGatewayPeers> {
|
|
102
|
+
method: 'listCoreMailGatewayPeers';
|
|
103
|
+
request: {
|
|
104
|
+
auth: IMailControlRequestAuth;
|
|
105
|
+
owner: IMailResourceOwner;
|
|
106
|
+
};
|
|
107
|
+
response: {
|
|
108
|
+
peers: ICoreMailGatewayPeerDesiredState[];
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Creates or replaces one CoreMail gateway peer. On success the accepted peer is
|
|
113
|
+
* returned in its stored form so the producer can compare the exact applied
|
|
114
|
+
* state. `owner` is required (not partial) because a peer is producer-owned
|
|
115
|
+
* provisioning state, never a filtered listing.
|
|
116
|
+
*/
|
|
117
|
+
export interface IReq_SyncCoreMailGatewayPeer extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_SyncCoreMailGatewayPeer> {
|
|
118
|
+
method: 'syncCoreMailGatewayPeer';
|
|
119
|
+
request: {
|
|
120
|
+
auth: IMailControlRequestAuth;
|
|
121
|
+
owner: IMailResourceOwner;
|
|
122
|
+
peer: ICoreMailGatewayPeerDesiredState;
|
|
123
|
+
};
|
|
124
|
+
response: {
|
|
125
|
+
success: boolean;
|
|
126
|
+
peer?: ICoreMailGatewayPeerDesiredState;
|
|
127
|
+
message?: string;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export interface IReq_DeleteCoreMailGatewayPeer extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_DeleteCoreMailGatewayPeer> {
|
|
131
|
+
method: 'deleteCoreMailGatewayPeer';
|
|
132
|
+
request: {
|
|
133
|
+
auth: IMailControlRequestAuth;
|
|
134
|
+
owner: IMailResourceOwner;
|
|
135
|
+
coreMailServiceId: string;
|
|
136
|
+
};
|
|
137
|
+
response: {
|
|
138
|
+
success: boolean;
|
|
139
|
+
message?: string;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
92
142
|
export interface IReq_ListWorkAppMailBindings extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ListWorkAppMailBindings> {
|
|
93
143
|
method: 'listWorkAppMailBindings';
|
|
94
144
|
request: {
|
|
@@ -3,6 +3,13 @@ import type * as data from '../data/runtimesession.js';
|
|
|
3
3
|
import type * as terminal from '../data/runtimeterminalreceipt.js';
|
|
4
4
|
import type * as network from '../data/networkdelivery.js';
|
|
5
5
|
import type * as protection from '../data/networkprotection.js';
|
|
6
|
+
import type * as credential from '../data/networkcredential.js';
|
|
7
|
+
/** Current-peer, exact-projection authorization; response contains secret keys. */
|
|
8
|
+
export interface IReq_Pallet_Controller_GetRuntimeManagedVpnCredentialV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Controller_GetRuntimeManagedVpnCredentialV1> {
|
|
9
|
+
method: 'getRuntimeManagedVpnCredentialV1';
|
|
10
|
+
request: credential.IGetRuntimeManagedVpnCredentialRequestV1;
|
|
11
|
+
response: credential.IGetRuntimeManagedVpnCredentialResponseV1;
|
|
12
|
+
}
|
|
6
13
|
/** Current authenticated peer reports its durable complete native protection journal. */
|
|
7
14
|
export interface IReq_Pallet_Controller_ReportRuntimeNetworkProtectionV1 extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Pallet_Controller_ReportRuntimeNetworkProtectionV1> {
|
|
8
15
|
method: 'reportRuntimeNetworkProtectionV1';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -415,6 +415,31 @@ exported material only through its encrypted internal secret store. The dedicate
|
|
|
415
415
|
peer. Their response acknowledges durable admission only, never application,
|
|
416
416
|
readiness, independent fencing or pool activation.
|
|
417
417
|
|
|
418
|
+
The `getRuntimeManagedVpnCredentialV1` method contract in `requests.runtimesession`
|
|
419
|
+
uses `IGetRuntimeManagedVpnCredentialRequestV1` and
|
|
420
|
+
`IGetRuntimeManagedVpnCredentialResponseV1`. Its request carries the exact current
|
|
421
|
+
session and signed projection reference. The secret response repeats those
|
|
422
|
+
bindings and supplies a QUIC relay tuple, managed authority ID, Noise server
|
|
423
|
+
public key, client keypair and expiry in Unix milliseconds. Keep the response
|
|
424
|
+
process-local; never persist, hash, log or embed it in a signed projection.
|
|
425
|
+
|
|
426
|
+
`snapshotGetRuntimeManagedVpnCredentialRequestV1` and its response counterpart
|
|
427
|
+
capture closed detached JSON shapes and canonical 32-byte key encodings.
|
|
428
|
+
`bindGetRuntimeManagedVpnCredentialRequestV1(request, projection, trustedSession)`
|
|
429
|
+
validates the complete projection digest and binds node, controller, namespace,
|
|
430
|
+
physical-session identity and projection reference. The response binder takes
|
|
431
|
+
`(response, request, projection, trustedSession, now)` and additionally requires
|
|
432
|
+
the relay's exact UDP tuple to be selected in `router.platformEndpointIds`.
|
|
433
|
+
Expiry must be after the caller-qualified time and no later than the referenced
|
|
434
|
+
projection's DNS lease; acceptance before that lease starts rejects.
|
|
435
|
+
|
|
436
|
+
These helpers perform content validation. Callers authenticate and fence the
|
|
437
|
+
current physical peer and projection before and after native work, qualify time
|
|
438
|
+
independently, and retain ownership through revocation and shutdown. The native
|
|
439
|
+
Noise implementation owns cryptographic validation and authentication. Credential
|
|
440
|
+
delivery does not prove a connected VPN, TUN ownership, packet enforcement or
|
|
441
|
+
workload readiness, and does not replace explicit packet withdrawals.
|
|
442
|
+
|
|
418
443
|
### Node-Bound Runtime Assignments
|
|
419
444
|
|
|
420
445
|
The `data` namespace exports `IRuntimeAssignmentV1`, canonical digest helpers,
|
|
@@ -1192,6 +1217,17 @@ may continue its next configured resolver. Consumers must apply
|
|
|
1192
1217
|
`data.normalizeCoreMailRecipientResolutions()` against the exact requested
|
|
1193
1218
|
recipient set before acting on a peer response.
|
|
1194
1219
|
|
|
1220
|
+
CoreMail binds every issued routing handle to a digest of the exact normalized
|
|
1221
|
+
`envelope` and `source` sent at resolve time. A following
|
|
1222
|
+
`coreMailGatewayPrepareInboundHandoff` must resend byte-identical values,
|
|
1223
|
+
including the complete `rcptTo` set in the same order. Both peers use
|
|
1224
|
+
`data.normalizeCoreMailGatewayMessage` and
|
|
1225
|
+
`data.normalizeCoreMailConnectionInfo` so the digested bytes come from one
|
|
1226
|
+
shared implementation. Outbound status is monotonic per `transportMessageId`,
|
|
1227
|
+
and a permanently unknown `transportMessageId` is answered with a terminal
|
|
1228
|
+
`failed` status rather than an error, because CoreMail retries errors
|
|
1229
|
+
indefinitely.
|
|
1230
|
+
|
|
1195
1231
|
Large content never travels inside TypedRequest JSON. Outbound body parts and
|
|
1196
1232
|
attachments use prepare/upload/complete operations with short-lived one-time
|
|
1197
1233
|
HTTP transfer grants. Inbound delivery uses bounded delivery listing followed
|
|
@@ -1220,6 +1256,23 @@ credential-lifecycle inconsistencies. CoreMail credential verifiers use the
|
|
|
1220
1256
|
versioned `argon2id-v1` format and the exact policy exported as
|
|
1221
1257
|
`data.coreMailCredentialVerifierPolicy`.
|
|
1222
1258
|
|
|
1259
|
+
`data.ICoreMailDesiredState.smtp` is the optional CoreMail SMTP submission
|
|
1260
|
+
listener (MSA). It carries the listener port, the advertised EHLO hostname, and
|
|
1261
|
+
the runtime secret keys holding certificate and private-key PEM text; plaintext
|
|
1262
|
+
PEM material never appears in desired state. SMTP AUTH uses the binding
|
|
1263
|
+
identity directly: the username is the `bindingId` and the password is any
|
|
1264
|
+
current or retiring credential secret of that binding. The listener stays
|
|
1265
|
+
unavailable until the referenced PEM material resolves. Omitting `smtp` keeps
|
|
1266
|
+
the exact canonical bytes and digest of an API-only CoreMail. Accepted
|
|
1267
|
+
submissions report their entry point through the optional
|
|
1268
|
+
`ICoreMailSubmission.source`, either `api` or `smtp`.
|
|
1269
|
+
|
|
1270
|
+
`data.ICoreMailServiceMailStatistics` reports per-service outbound and inbound
|
|
1271
|
+
counters for one UTC calendar day. Control sessions read them through
|
|
1272
|
+
`coreMailGetServiceMailStatistics` using an inclusive day range, an optional
|
|
1273
|
+
service filter, and an opaque cursor. Apply
|
|
1274
|
+
`data.normalizeCoreMailServiceMailStatistics` before using reported counters.
|
|
1275
|
+
|
|
1223
1276
|
`data.ICoreMailControlBootstrap` is installed before ordinary reconciliation.
|
|
1224
1277
|
It contains the CoreMail service identity and verifier metadata only. The
|
|
1225
1278
|
matching plaintext control credential is delivered exclusively to Coreflow
|
|
@@ -1244,7 +1297,13 @@ CoreMail transfer origin associated with an authenticated CoreMail service.
|
|
|
1244
1297
|
The same origin is carried in CoreMail desired state and returned by workload
|
|
1245
1298
|
and gateway authentication. It must never be inferred from a socket, Host
|
|
1246
1299
|
header, TypedSocket tag, or unrestricted peer input. CoreMail compares both
|
|
1247
|
-
authoritative views before handing over a path-only transfer grant.
|
|
1300
|
+
authoritative views before handing over a path-only transfer grant. Cloudly and
|
|
1301
|
+
Onebox provision that peer state through `listCoreMailGatewayPeers`,
|
|
1302
|
+
`syncCoreMailGatewayPeer`, and `deleteCoreMailGatewayPeer` on the gateway-client
|
|
1303
|
+
mail surface, and the producer is the single owner of `peer.transferOrigin`. A
|
|
1304
|
+
mail inbound target may point at a CoreMail service using `type: 'coreMail'`
|
|
1305
|
+
with `coreMail.coreMailServiceId`, mirrored by the `coreMail` member of
|
|
1306
|
+
`IServiceMailInboundConfig.targetType`.
|
|
1248
1307
|
|
|
1249
1308
|
Inbound delivery pagination uses an opaque CoreMail-owned `cursor`, is bounded
|
|
1250
1309
|
by `data.coreMailLimits.inboundPageSize`, and returns `nextCursor` only when
|