@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.
@@ -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
- export type TMailSubmissionErrorCode = 'INVALID_REPLY_TO' | 'REPLY_TO_FIELD_HEADER_CONFLICT';
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
- /** Platformclient apps use typedEndpoint; third-party apps with their own SMTP server use smtpForward. */
179
- targetType?: 'typedEndpoint' | 'smtpForward';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serve.zone/interfaces",
3
- "version": "30.11.0",
3
+ "version": "30.13.0",
4
4
  "private": false,
5
5
  "description": "Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.",
6
6
  "exports": {
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
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/interfaces',
6
- version: '30.11.0',
6
+ version: '30.13.0',
7
7
  description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
8
8
  }