@automagik/omni 2.260727.2 → 2.260728.2
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/dist/commands/keys.d.ts.map +1 -1
- package/dist/index.js +1244 -183
- package/dist/sdk/types.generated.d.ts +1767 -46
- package/dist/sdk/types.generated.d.ts.map +1 -1
- package/dist/server/index.js +5501 -2135
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -8187,6 +8187,74 @@ var init_types2 = __esm(() => {
|
|
|
8187
8187
|
"voice.user_left_channel"
|
|
8188
8188
|
];
|
|
8189
8189
|
});
|
|
8190
|
+
// ../core/src/events/envelope.ts
|
|
8191
|
+
function classifyEnvelope(metadata) {
|
|
8192
|
+
if (metadata === null || metadata === undefined)
|
|
8193
|
+
return { world: "legacy" };
|
|
8194
|
+
const { envelopeVersion, tenantId } = metadata;
|
|
8195
|
+
if (envelopeVersion === undefined || envelopeVersion === null) {
|
|
8196
|
+
if (tenantId !== undefined && tenantId !== null) {
|
|
8197
|
+
return { world: "quarantine", reason: "malformed_envelope" };
|
|
8198
|
+
}
|
|
8199
|
+
return { world: "legacy" };
|
|
8200
|
+
}
|
|
8201
|
+
if (typeof envelopeVersion !== "number" || !KNOWN_ENVELOPE_VERSIONS.has(envelopeVersion)) {
|
|
8202
|
+
return { world: "quarantine", reason: "unknown_version" };
|
|
8203
|
+
}
|
|
8204
|
+
if (tenantId === undefined || tenantId === null || tenantId === "") {
|
|
8205
|
+
return { world: "quarantine", reason: "missing_tenant" };
|
|
8206
|
+
}
|
|
8207
|
+
if (typeof tenantId !== "string" || !UUID.test(tenantId)) {
|
|
8208
|
+
return { world: "quarantine", reason: "invalid_tenant" };
|
|
8209
|
+
}
|
|
8210
|
+
return { world: "tenant", tenantId, envelopeVersion };
|
|
8211
|
+
}
|
|
8212
|
+
function stampTenantEnvelope(metadata, tenantId) {
|
|
8213
|
+
if (typeof tenantId !== "string" || !UUID.test(tenantId)) {
|
|
8214
|
+
throw new Error(`stampTenantEnvelope: refusing to stamp a non-UUID tenant (${String(tenantId)})`);
|
|
8215
|
+
}
|
|
8216
|
+
return { ...metadata, envelopeVersion: CURRENT_ENVELOPE_VERSION, tenantId };
|
|
8217
|
+
}
|
|
8218
|
+
function isStampableTenantId(tenantId) {
|
|
8219
|
+
return typeof tenantId === "string" && UUID.test(tenantId);
|
|
8220
|
+
}
|
|
8221
|
+
function setEnvelopeTenantResolver(resolver) {
|
|
8222
|
+
ambientTenantResolver = resolver;
|
|
8223
|
+
}
|
|
8224
|
+
function resolveAmbientTenantId() {
|
|
8225
|
+
if (!ambientTenantResolver)
|
|
8226
|
+
return null;
|
|
8227
|
+
try {
|
|
8228
|
+
const tenantId = ambientTenantResolver();
|
|
8229
|
+
return isStampableTenantId(tenantId) ? tenantId : null;
|
|
8230
|
+
} catch {
|
|
8231
|
+
return null;
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
function setEnvelopeInstanceTenantResolver(resolver) {
|
|
8235
|
+
instanceOwnerTenantResolver = resolver;
|
|
8236
|
+
}
|
|
8237
|
+
function resolveInstanceOwnerTenantId(instanceId) {
|
|
8238
|
+
if (!instanceOwnerTenantResolver || !instanceId)
|
|
8239
|
+
return null;
|
|
8240
|
+
try {
|
|
8241
|
+
const tenantId = instanceOwnerTenantResolver(instanceId);
|
|
8242
|
+
return isStampableTenantId(tenantId) ? tenantId : null;
|
|
8243
|
+
} catch {
|
|
8244
|
+
return null;
|
|
8245
|
+
}
|
|
8246
|
+
}
|
|
8247
|
+
function resolvePublishTenantId(explicitTenantId, instanceId) {
|
|
8248
|
+
if (isStampableTenantId(explicitTenantId))
|
|
8249
|
+
return explicitTenantId;
|
|
8250
|
+
return resolveAmbientTenantId() ?? resolveInstanceOwnerTenantId(instanceId);
|
|
8251
|
+
}
|
|
8252
|
+
var CURRENT_ENVELOPE_VERSION = 1, KNOWN_ENVELOPE_VERSIONS, UUID, ambientTenantResolver = null, instanceOwnerTenantResolver = null;
|
|
8253
|
+
var init_envelope = __esm(() => {
|
|
8254
|
+
KNOWN_ENVELOPE_VERSIONS = new Set([CURRENT_ENVELOPE_VERSION]);
|
|
8255
|
+
UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
8256
|
+
});
|
|
8257
|
+
|
|
8190
8258
|
// ../../node_modules/.bun/@opentelemetry+api@1.9.1/node_modules/@opentelemetry/api/build/src/version.js
|
|
8191
8259
|
var require_version = __commonJS((exports) => {
|
|
8192
8260
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -30595,7 +30663,8 @@ function createSubscription(options) {
|
|
|
30595
30663
|
maxRetries = DEFAULT_CONSUMER_CONFIG.maxRetries,
|
|
30596
30664
|
retryDelayMs = DEFAULT_CONSUMER_CONFIG.retryDelayMs,
|
|
30597
30665
|
concurrency = 1,
|
|
30598
|
-
onDeadLetter
|
|
30666
|
+
onDeadLetter,
|
|
30667
|
+
onQuarantine
|
|
30599
30668
|
} = options;
|
|
30600
30669
|
const subscriptionId = crypto.randomUUID();
|
|
30601
30670
|
const abortController = new AbortController;
|
|
@@ -30647,6 +30716,25 @@ function createSubscription(options) {
|
|
|
30647
30716
|
msg.term();
|
|
30648
30717
|
return;
|
|
30649
30718
|
}
|
|
30719
|
+
const classification = classifyEnvelope(event.metadata);
|
|
30720
|
+
if (classification.world === "quarantine") {
|
|
30721
|
+
log3.error("Envelope quarantined by consumer validation", {
|
|
30722
|
+
subscriptionId,
|
|
30723
|
+
eventType: event.type,
|
|
30724
|
+
eventId: event.id,
|
|
30725
|
+
reason: classification.reason,
|
|
30726
|
+
tenantId: event.metadata.tenantId ?? null
|
|
30727
|
+
});
|
|
30728
|
+
if (onQuarantine) {
|
|
30729
|
+
try {
|
|
30730
|
+
await onQuarantine(event, classification);
|
|
30731
|
+
} catch (qError) {
|
|
30732
|
+
log3.error("Quarantine handler failed", { subscriptionId, error: String(qError) });
|
|
30733
|
+
}
|
|
30734
|
+
}
|
|
30735
|
+
msg.term();
|
|
30736
|
+
return;
|
|
30737
|
+
}
|
|
30650
30738
|
try {
|
|
30651
30739
|
const validation = eventRegistry.validate(event.type, event.payload);
|
|
30652
30740
|
if (!validation.success) {
|
|
@@ -30761,6 +30849,7 @@ class SubscriptionManager {
|
|
|
30761
30849
|
var import_api, log3, ValidationError;
|
|
30762
30850
|
var init_subscription = __esm(() => {
|
|
30763
30851
|
init_logger();
|
|
30852
|
+
init_envelope();
|
|
30764
30853
|
init_consumer();
|
|
30765
30854
|
init_registry();
|
|
30766
30855
|
import_api = __toESM(require_src(), 1);
|
|
@@ -30867,6 +30956,7 @@ class NatsEventBus {
|
|
|
30867
30956
|
await this.ensureConnected();
|
|
30868
30957
|
const eventId = crypto.randomUUID();
|
|
30869
30958
|
const timestamp = Date.now();
|
|
30959
|
+
const tenantId = resolvePublishTenantId(metadata?.tenantId, metadata?.instanceId);
|
|
30870
30960
|
const event = {
|
|
30871
30961
|
id: eventId,
|
|
30872
30962
|
type,
|
|
@@ -30881,7 +30971,8 @@ class NatsEventBus {
|
|
|
30881
30971
|
traceId: metadata?.traceId ?? eventId,
|
|
30882
30972
|
source: metadata?.source ?? this.config.serviceName,
|
|
30883
30973
|
ingestMode: metadata?.ingestMode,
|
|
30884
|
-
timings: metadata?.timings
|
|
30974
|
+
timings: metadata?.timings,
|
|
30975
|
+
...tenantId ? { envelopeVersion: CURRENT_ENVELOPE_VERSION, tenantId } : {}
|
|
30885
30976
|
}
|
|
30886
30977
|
};
|
|
30887
30978
|
let subject;
|
|
@@ -31018,6 +31109,17 @@ class NatsEventBus {
|
|
|
31018
31109
|
retryCount,
|
|
31019
31110
|
timestamp: Date.now()
|
|
31020
31111
|
}, { source: this.config.serviceName });
|
|
31112
|
+
},
|
|
31113
|
+
onQuarantine: async (event, classification) => {
|
|
31114
|
+
await this.publishGeneric("system.dead_letter", {
|
|
31115
|
+
originalEventId: event.id,
|
|
31116
|
+
originalEventType: event.type,
|
|
31117
|
+
error: `envelope_quarantined:${classification.reason}`,
|
|
31118
|
+
retryCount: 0,
|
|
31119
|
+
timestamp: Date.now(),
|
|
31120
|
+
quarantineReason: classification.reason,
|
|
31121
|
+
tenantId: event.metadata.tenantId
|
|
31122
|
+
}, { source: this.config.serviceName });
|
|
31021
31123
|
}
|
|
31022
31124
|
});
|
|
31023
31125
|
this.subscriptionManager.add(subscription);
|
|
@@ -31148,6 +31250,7 @@ async function connectEventBus(config2) {
|
|
|
31148
31250
|
var import_api2, import_nats, log4, DEFAULTS, ENSURE_CONNECTED_WAIT_MS = 5000;
|
|
31149
31251
|
var init_client = __esm(() => {
|
|
31150
31252
|
init_logger();
|
|
31253
|
+
init_envelope();
|
|
31151
31254
|
init_consumer();
|
|
31152
31255
|
init_registry();
|
|
31153
31256
|
init_streams();
|
|
@@ -31360,6 +31463,7 @@ function estimateCompletion(progress) {
|
|
|
31360
31463
|
// ../core/src/events/index.ts
|
|
31361
31464
|
var init_events = __esm(() => {
|
|
31362
31465
|
init_types2();
|
|
31466
|
+
init_envelope();
|
|
31363
31467
|
init_nats();
|
|
31364
31468
|
init_dead_letter();
|
|
31365
31469
|
init_payload_store();
|
|
@@ -35900,6 +36004,32 @@ var require_prom_client = __commonJS((exports) => {
|
|
|
35900
36004
|
exports.AggregatorRegistry = require_cluster();
|
|
35901
36005
|
});
|
|
35902
36006
|
|
|
36007
|
+
// ../core/src/metrics/tenant-labels.ts
|
|
36008
|
+
import { createHash as createHash3 } from "crypto";
|
|
36009
|
+
function configureTenantLabelBuckets(count) {
|
|
36010
|
+
if (!Number.isInteger(count) || count < 1) {
|
|
36011
|
+
throw new Error(`tenant-labels: bucket count must be a positive integer, got ${count}`);
|
|
36012
|
+
}
|
|
36013
|
+
bucketCount = count;
|
|
36014
|
+
}
|
|
36015
|
+
function tenantLabelBucketCount() {
|
|
36016
|
+
return bucketCount;
|
|
36017
|
+
}
|
|
36018
|
+
function boundedTenantLabel(tenantId) {
|
|
36019
|
+
if (!tenantId)
|
|
36020
|
+
return TENANTLESS_LABEL;
|
|
36021
|
+
const digest = createHash3("sha256").update(tenantId).digest();
|
|
36022
|
+
const bucket = digest.readUInt32BE(0) % bucketCount;
|
|
36023
|
+
return `t${bucket}`;
|
|
36024
|
+
}
|
|
36025
|
+
function resetTenantLabelConfig() {
|
|
36026
|
+
bucketCount = DEFAULT_TENANT_LABEL_BUCKETS;
|
|
36027
|
+
}
|
|
36028
|
+
var DEFAULT_TENANT_LABEL_BUCKETS = 128, TENANTLESS_LABEL = "none", bucketCount;
|
|
36029
|
+
var init_tenant_labels = __esm(() => {
|
|
36030
|
+
bucketCount = DEFAULT_TENANT_LABEL_BUCKETS;
|
|
36031
|
+
});
|
|
36032
|
+
|
|
35903
36033
|
// ../core/src/metrics/index.ts
|
|
35904
36034
|
function getRegistry() {
|
|
35905
36035
|
return registry;
|
|
@@ -35913,9 +36043,14 @@ async function getMetricsText() {
|
|
|
35913
36043
|
async function getMetricsJson() {
|
|
35914
36044
|
return registry.getMetricsAsJSON();
|
|
35915
36045
|
}
|
|
35916
|
-
function recordEventProcessed(eventType, status, durationSeconds) {
|
|
36046
|
+
function recordEventProcessed(eventType, status, durationSeconds, tenantId) {
|
|
35917
36047
|
eventsProcessed.inc({ event_type: eventType, status });
|
|
35918
36048
|
eventProcessingDuration.observe({ event_type: eventType }, durationSeconds);
|
|
36049
|
+
if (tenantId)
|
|
36050
|
+
recordTenantEventProcessed(tenantId, eventType, status);
|
|
36051
|
+
}
|
|
36052
|
+
function recordTenantEventProcessed(tenantId, eventType, status) {
|
|
36053
|
+
tenantEventsProcessed.inc({ tenant_bucket: boundedTenantLabel(tenantId), event_type: eventType, status });
|
|
35919
36054
|
}
|
|
35920
36055
|
function recordDeadLetterOp(operation, result) {
|
|
35921
36056
|
deadLetterOperations.inc({ operation, result });
|
|
@@ -35964,9 +36099,11 @@ function recordOpenClawReconnect(providerId) {
|
|
|
35964
36099
|
async function resetMetrics() {
|
|
35965
36100
|
registry.resetMetrics();
|
|
35966
36101
|
}
|
|
35967
|
-
var import_prom_client, registry, eventsProcessed, eventProcessingDuration, deadLettersPending, deadLetterOperations, payloadStorageSize, payloadOperations, natsConnectionStatus, natsMessagesPublished, natsMessagesReceived, natsPublishLatency, natsPendingMessages, dbPoolSize, dbQueries, dbQueryDuration, dbErrors, appUptime, httpActiveConnections, httpRequests, httpRequestDuration, scheduledJobRuns, scheduledJobDuration, scheduledJobNextRun, openclawWsState, openclawTriggerDuration, openclawTriggerErrors, openclawReconnects, openclawTimeToFirstDelta, openclawCircuitBreakerState;
|
|
36102
|
+
var import_prom_client, registry, eventsProcessed, tenantEventsProcessed, eventProcessingDuration, deadLettersPending, deadLetterOperations, payloadStorageSize, payloadOperations, natsConnectionStatus, natsMessagesPublished, natsMessagesReceived, natsPublishLatency, natsPendingMessages, dbPoolSize, dbQueries, dbQueryDuration, dbErrors, appUptime, httpActiveConnections, httpRequests, httpRequestDuration, scheduledJobRuns, scheduledJobDuration, scheduledJobNextRun, openclawWsState, openclawTriggerDuration, openclawTriggerErrors, openclawReconnects, openclawTimeToFirstDelta, openclawCircuitBreakerState;
|
|
35968
36103
|
var init_metrics = __esm(() => {
|
|
36104
|
+
init_tenant_labels();
|
|
35969
36105
|
import_prom_client = __toESM(require_prom_client(), 1);
|
|
36106
|
+
init_tenant_labels();
|
|
35970
36107
|
registry = new import_prom_client.Registry;
|
|
35971
36108
|
eventsProcessed = new import_prom_client.Counter({
|
|
35972
36109
|
name: "omni_events_processed_total",
|
|
@@ -35974,6 +36111,12 @@ var init_metrics = __esm(() => {
|
|
|
35974
36111
|
labelNames: ["event_type", "status"],
|
|
35975
36112
|
registers: [registry]
|
|
35976
36113
|
});
|
|
36114
|
+
tenantEventsProcessed = new import_prom_client.Counter({
|
|
36115
|
+
name: "omni_tenant_events_processed_total",
|
|
36116
|
+
help: "Events processed, labelled by bounded/redacted tenant bucket (never a raw tenant id)",
|
|
36117
|
+
labelNames: ["tenant_bucket", "event_type", "status"],
|
|
36118
|
+
registers: [registry]
|
|
36119
|
+
});
|
|
35977
36120
|
eventProcessingDuration = new import_prom_client.Histogram({
|
|
35978
36121
|
name: "omni_event_processing_duration_seconds",
|
|
35979
36122
|
help: "Event processing duration in seconds",
|
|
@@ -36140,6 +36283,226 @@ var init_metrics = __esm(() => {
|
|
|
36140
36283
|
});
|
|
36141
36284
|
});
|
|
36142
36285
|
|
|
36286
|
+
// ../core/src/observability/tenant-observability.ts
|
|
36287
|
+
function keyIsSecret(key) {
|
|
36288
|
+
const lower = key.toLowerCase();
|
|
36289
|
+
return SECRET_KEY_SUBSTRINGS.some((needle) => lower.includes(needle));
|
|
36290
|
+
}
|
|
36291
|
+
function looksLikeHighEntropyToken(value) {
|
|
36292
|
+
if (value.length < 24)
|
|
36293
|
+
return false;
|
|
36294
|
+
if (!/^[A-Za-z0-9._~+/=-]+$/.test(value))
|
|
36295
|
+
return false;
|
|
36296
|
+
return /[A-Za-z]/.test(value) && /[0-9]/.test(value);
|
|
36297
|
+
}
|
|
36298
|
+
function valueLooksSecret(value) {
|
|
36299
|
+
if (typeof value !== "string")
|
|
36300
|
+
return false;
|
|
36301
|
+
if (UUID2.test(value))
|
|
36302
|
+
return false;
|
|
36303
|
+
if (SECRET_VALUE_PATTERNS.some((re) => re.test(value)))
|
|
36304
|
+
return true;
|
|
36305
|
+
if (JWT_VALUE.test(value))
|
|
36306
|
+
return true;
|
|
36307
|
+
return looksLikeHighEntropyToken(value);
|
|
36308
|
+
}
|
|
36309
|
+
function redactSecrets(metadata) {
|
|
36310
|
+
const out = {};
|
|
36311
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
36312
|
+
if (PRESERVE_KEYS.has(key)) {
|
|
36313
|
+
out[key] = value;
|
|
36314
|
+
continue;
|
|
36315
|
+
}
|
|
36316
|
+
if (keyIsSecret(key))
|
|
36317
|
+
continue;
|
|
36318
|
+
if (valueLooksSecret(value))
|
|
36319
|
+
continue;
|
|
36320
|
+
out[key] = value;
|
|
36321
|
+
}
|
|
36322
|
+
return out;
|
|
36323
|
+
}
|
|
36324
|
+
function buildTenantAuditFields(input) {
|
|
36325
|
+
if (typeof input.tenantId !== "string" || !UUID2.test(input.tenantId)) {
|
|
36326
|
+
throw new Error("tenant-observability: tenantId must be a well-formed UUID");
|
|
36327
|
+
}
|
|
36328
|
+
if (typeof input.actorCredentialId !== "string" || input.actorCredentialId.length === 0) {
|
|
36329
|
+
throw new Error("tenant-observability: actorCredentialId must be a non-empty string");
|
|
36330
|
+
}
|
|
36331
|
+
const fields = {
|
|
36332
|
+
tenantId: input.tenantId,
|
|
36333
|
+
actorCredentialId: input.actorCredentialId,
|
|
36334
|
+
...input.requestId ? { requestId: input.requestId } : {}
|
|
36335
|
+
};
|
|
36336
|
+
return fields;
|
|
36337
|
+
}
|
|
36338
|
+
function buildTenantAuditRecord(input, extraMetadata = {}) {
|
|
36339
|
+
const identity = buildTenantAuditFields(input);
|
|
36340
|
+
const scrubbed = redactSecrets(extraMetadata);
|
|
36341
|
+
for (const dotted of DOTTED_IDENTITY_KEYS)
|
|
36342
|
+
delete scrubbed[dotted];
|
|
36343
|
+
return { ...scrubbed, ...identity };
|
|
36344
|
+
}
|
|
36345
|
+
function tenantTraceAttributes(fields) {
|
|
36346
|
+
return {
|
|
36347
|
+
"tenant.id": fields.tenantId,
|
|
36348
|
+
"actor.credential_id": fields.actorCredentialId,
|
|
36349
|
+
...fields.requestId ? { "request.id": fields.requestId } : {}
|
|
36350
|
+
};
|
|
36351
|
+
}
|
|
36352
|
+
var UUID2, PRESERVE_KEYS, SECRET_KEY_SUBSTRINGS, SECRET_VALUE_PATTERNS, JWT_VALUE, DOTTED_IDENTITY_KEYS;
|
|
36353
|
+
var init_tenant_observability = __esm(() => {
|
|
36354
|
+
UUID2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
36355
|
+
PRESERVE_KEYS = new Set(["tenantId", "actorCredentialId", "requestId", "instanceId"]);
|
|
36356
|
+
SECRET_KEY_SUBSTRINGS = [
|
|
36357
|
+
"secret",
|
|
36358
|
+
"password",
|
|
36359
|
+
"passwd",
|
|
36360
|
+
"apikey",
|
|
36361
|
+
"api_key",
|
|
36362
|
+
"api-key",
|
|
36363
|
+
"privatekey",
|
|
36364
|
+
"private_key",
|
|
36365
|
+
"private-key",
|
|
36366
|
+
"plaintext",
|
|
36367
|
+
"plain_text",
|
|
36368
|
+
"plain-text",
|
|
36369
|
+
"bearer",
|
|
36370
|
+
"authorization",
|
|
36371
|
+
"auth_token",
|
|
36372
|
+
"authtoken",
|
|
36373
|
+
"access_key",
|
|
36374
|
+
"accesskey",
|
|
36375
|
+
"signing_key",
|
|
36376
|
+
"session_secret",
|
|
36377
|
+
"session_key",
|
|
36378
|
+
"webhook_secret",
|
|
36379
|
+
"keyhash",
|
|
36380
|
+
"key_hash",
|
|
36381
|
+
"cookie",
|
|
36382
|
+
"signature",
|
|
36383
|
+
"token",
|
|
36384
|
+
"refresh_token",
|
|
36385
|
+
"key",
|
|
36386
|
+
"credentials",
|
|
36387
|
+
"jwt"
|
|
36388
|
+
];
|
|
36389
|
+
SECRET_VALUE_PATTERNS = [/omni_sk_/i, /-----BEGIN [A-Z ]*PRIVATE KEY-----/];
|
|
36390
|
+
JWT_VALUE = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
36391
|
+
DOTTED_IDENTITY_KEYS = ["tenant.id", "actor.credential_id", "request.id"];
|
|
36392
|
+
});
|
|
36393
|
+
|
|
36394
|
+
// ../core/src/observability/index.ts
|
|
36395
|
+
var init_observability = __esm(() => {
|
|
36396
|
+
init_tenant_observability();
|
|
36397
|
+
});
|
|
36398
|
+
|
|
36399
|
+
// ../core/src/secrets/tenant-secret-box.ts
|
|
36400
|
+
import { createCipheriv, createDecipheriv, hkdfSync, randomBytes as randomBytes2 } from "crypto";
|
|
36401
|
+
function setTenantSecretMasterKey(key) {
|
|
36402
|
+
if (key === null) {
|
|
36403
|
+
masterKey = null;
|
|
36404
|
+
return;
|
|
36405
|
+
}
|
|
36406
|
+
if (key.length < DEK_BYTES) {
|
|
36407
|
+
throw new TenantSecretError(`master key must be at least ${DEK_BYTES} bytes`);
|
|
36408
|
+
}
|
|
36409
|
+
masterKey = Buffer.from(key);
|
|
36410
|
+
}
|
|
36411
|
+
function isTenantSecretSealingEnabled() {
|
|
36412
|
+
return masterKey !== null;
|
|
36413
|
+
}
|
|
36414
|
+
function requireKey() {
|
|
36415
|
+
if (masterKey === null)
|
|
36416
|
+
throw new TenantSecretUnconfiguredError;
|
|
36417
|
+
return masterKey;
|
|
36418
|
+
}
|
|
36419
|
+
function requireTenant(tenantId) {
|
|
36420
|
+
if (typeof tenantId !== "string" || !UUID3.test(tenantId)) {
|
|
36421
|
+
throw new TenantSecretError(`refusing a non-UUID tenant (${String(tenantId)})`);
|
|
36422
|
+
}
|
|
36423
|
+
}
|
|
36424
|
+
function deriveDek(key, tenantId) {
|
|
36425
|
+
const derived = hkdfSync("sha256", key, Buffer.from(tenantId, "utf8"), Buffer.from(DEK_INFO, "utf8"), DEK_BYTES);
|
|
36426
|
+
return Buffer.from(derived);
|
|
36427
|
+
}
|
|
36428
|
+
function sealTenantSecret(tenantId, plaintext) {
|
|
36429
|
+
const key = requireKey();
|
|
36430
|
+
requireTenant(tenantId);
|
|
36431
|
+
const dek = deriveDek(key, tenantId);
|
|
36432
|
+
const iv = randomBytes2(IV_BYTES);
|
|
36433
|
+
const cipher = createCipheriv(CIPHER, dek, iv);
|
|
36434
|
+
cipher.setAAD(Buffer.from(tenantId, "utf8"));
|
|
36435
|
+
const ct = Buffer.concat([cipher.update(Buffer.from(plaintext, "utf8")), cipher.final()]);
|
|
36436
|
+
const tag = cipher.getAuthTag();
|
|
36437
|
+
return {
|
|
36438
|
+
v: SECRET_BOX_VERSION,
|
|
36439
|
+
alg: "A256GCM",
|
|
36440
|
+
kdf: "HKDF-SHA256",
|
|
36441
|
+
t: tenantId,
|
|
36442
|
+
iv: iv.toString("base64"),
|
|
36443
|
+
ct: ct.toString("base64"),
|
|
36444
|
+
tag: tag.toString("base64")
|
|
36445
|
+
};
|
|
36446
|
+
}
|
|
36447
|
+
function openTenantSecret(tenantId, sealed) {
|
|
36448
|
+
const key = requireKey();
|
|
36449
|
+
requireTenant(tenantId);
|
|
36450
|
+
if (!isSealedSecret(sealed)) {
|
|
36451
|
+
throw new TenantSecretError("value is not a sealed secret");
|
|
36452
|
+
}
|
|
36453
|
+
if (sealed.v !== SECRET_BOX_VERSION) {
|
|
36454
|
+
throw new TenantSecretError(`unknown sealed-secret version (${String(sealed.v)})`);
|
|
36455
|
+
}
|
|
36456
|
+
if (sealed.t !== tenantId) {
|
|
36457
|
+
throw new TenantSecretError("tenant mismatch");
|
|
36458
|
+
}
|
|
36459
|
+
const dek = deriveDek(key, tenantId);
|
|
36460
|
+
try {
|
|
36461
|
+
const decipher = createDecipheriv(CIPHER, dek, Buffer.from(sealed.iv, "base64"));
|
|
36462
|
+
decipher.setAAD(Buffer.from(tenantId, "utf8"));
|
|
36463
|
+
decipher.setAuthTag(Buffer.from(sealed.tag, "base64"));
|
|
36464
|
+
const pt = Buffer.concat([decipher.update(Buffer.from(sealed.ct, "base64")), decipher.final()]);
|
|
36465
|
+
return pt.toString("utf8");
|
|
36466
|
+
} catch {
|
|
36467
|
+
throw new TenantSecretError("authentication failed (wrong tenant or tampered secret)");
|
|
36468
|
+
}
|
|
36469
|
+
}
|
|
36470
|
+
function sealTenantSecretJson(tenantId, value) {
|
|
36471
|
+
return sealTenantSecret(tenantId, JSON.stringify(value));
|
|
36472
|
+
}
|
|
36473
|
+
function openTenantSecretJson(tenantId, sealed) {
|
|
36474
|
+
return JSON.parse(openTenantSecret(tenantId, sealed));
|
|
36475
|
+
}
|
|
36476
|
+
function isSealedSecret(value) {
|
|
36477
|
+
if (typeof value !== "object" || value === null)
|
|
36478
|
+
return false;
|
|
36479
|
+
const s = value;
|
|
36480
|
+
return typeof s.v === "number" && s.alg === "A256GCM" && s.kdf === "HKDF-SHA256" && typeof s.t === "string" && typeof s.iv === "string" && typeof s.ct === "string" && typeof s.tag === "string";
|
|
36481
|
+
}
|
|
36482
|
+
var SECRET_BOX_VERSION = 1, CIPHER = "aes-256-gcm", IV_BYTES = 12, DEK_BYTES = 32, DEK_INFO = "omni-tenant-secret-box:v1:dek", UUID3, TenantSecretError, TenantSecretUnconfiguredError, masterKey = null;
|
|
36483
|
+
var init_tenant_secret_box = __esm(() => {
|
|
36484
|
+
UUID3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
36485
|
+
TenantSecretError = class TenantSecretError extends Error {
|
|
36486
|
+
code = "tenant_secret_denied";
|
|
36487
|
+
constructor(reason) {
|
|
36488
|
+
super(`tenant-secret-box: ${reason}`);
|
|
36489
|
+
this.name = "TenantSecretError";
|
|
36490
|
+
}
|
|
36491
|
+
};
|
|
36492
|
+
TenantSecretUnconfiguredError = class TenantSecretUnconfiguredError extends Error {
|
|
36493
|
+
code = "tenant_secret_unconfigured";
|
|
36494
|
+
constructor() {
|
|
36495
|
+
super("tenant-secret-box: no master key configured (sealing disabled)");
|
|
36496
|
+
this.name = "TenantSecretUnconfiguredError";
|
|
36497
|
+
}
|
|
36498
|
+
};
|
|
36499
|
+
});
|
|
36500
|
+
|
|
36501
|
+
// ../core/src/secrets/index.ts
|
|
36502
|
+
var init_secrets = __esm(() => {
|
|
36503
|
+
init_tenant_secret_box();
|
|
36504
|
+
});
|
|
36505
|
+
|
|
36143
36506
|
// ../core/src/automations/types.ts
|
|
36144
36507
|
var CONDITION_OPERATORS, ACTION_TYPES, AUTOMATION_DEBOUNCE_MODES, AUTOMATION_LOG_STATUSES;
|
|
36145
36508
|
var init_types6 = __esm(() => {
|
|
@@ -36424,6 +36787,568 @@ var init_templates = __esm(() => {
|
|
|
36424
36787
|
TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
|
|
36425
36788
|
});
|
|
36426
36789
|
|
|
36790
|
+
// ../core/src/egress/policy.ts
|
|
36791
|
+
import { isIP } from "net";
|
|
36792
|
+
function isAllowedClass(destinationClass) {
|
|
36793
|
+
return destinationClass === "approved-public";
|
|
36794
|
+
}
|
|
36795
|
+
function schemesFor(policy) {
|
|
36796
|
+
return policy.approvedSchemes && policy.approvedSchemes.length > 0 ? policy.approvedSchemes : DEFAULT_SCHEMES;
|
|
36797
|
+
}
|
|
36798
|
+
function portFor(url) {
|
|
36799
|
+
if (url.port) {
|
|
36800
|
+
const parsed = Number.parseInt(url.port, 10);
|
|
36801
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
36802
|
+
}
|
|
36803
|
+
if (url.protocol === "https:")
|
|
36804
|
+
return 443;
|
|
36805
|
+
if (url.protocol === "http:")
|
|
36806
|
+
return 80;
|
|
36807
|
+
return null;
|
|
36808
|
+
}
|
|
36809
|
+
function portsFor(policy) {
|
|
36810
|
+
return policy.approvedPorts && policy.approvedPorts.length > 0 ? policy.approvedPorts : DEFAULT_PORTS;
|
|
36811
|
+
}
|
|
36812
|
+
function hostMatchesSuffix(host, suffix) {
|
|
36813
|
+
const s = suffix.toLowerCase().replace(/^\.+/, "").replace(/\.+$/, "");
|
|
36814
|
+
if (s.length === 0)
|
|
36815
|
+
return false;
|
|
36816
|
+
return host === s || host.endsWith(`.${s}`);
|
|
36817
|
+
}
|
|
36818
|
+
function isApprovedHost(host, policy) {
|
|
36819
|
+
return policy.approvedHostSuffixes.some((suffix) => hostMatchesSuffix(host, suffix));
|
|
36820
|
+
}
|
|
36821
|
+
function parseIpv4Part(part) {
|
|
36822
|
+
if (part.length === 0)
|
|
36823
|
+
return null;
|
|
36824
|
+
let value;
|
|
36825
|
+
if (/^0x[0-9a-f]+$/i.test(part))
|
|
36826
|
+
value = Number.parseInt(part.slice(2), 16);
|
|
36827
|
+
else if (/^0[0-7]+$/.test(part))
|
|
36828
|
+
value = Number.parseInt(part, 8);
|
|
36829
|
+
else if (/^[0-9]+$/.test(part))
|
|
36830
|
+
value = Number.parseInt(part, 10);
|
|
36831
|
+
else
|
|
36832
|
+
return null;
|
|
36833
|
+
return Number.isNaN(value) ? null : value;
|
|
36834
|
+
}
|
|
36835
|
+
function canonicalizeIpv4(host) {
|
|
36836
|
+
const parts = host.split(".");
|
|
36837
|
+
const looksNumeric = parts.every((p2) => /^(0x[0-9a-f]+|[0-9]+)$/i.test(p2));
|
|
36838
|
+
if (!looksNumeric)
|
|
36839
|
+
return null;
|
|
36840
|
+
if (parts.length > 4)
|
|
36841
|
+
return { invalid: true };
|
|
36842
|
+
const values2 = parts.map(parseIpv4Part);
|
|
36843
|
+
if (values2.some((v2) => v2 === null))
|
|
36844
|
+
return { invalid: true };
|
|
36845
|
+
const nums = values2;
|
|
36846
|
+
let ip32;
|
|
36847
|
+
if (nums.length === 1) {
|
|
36848
|
+
ip32 = nums[0];
|
|
36849
|
+
if (ip32 > 4294967295)
|
|
36850
|
+
return { invalid: true };
|
|
36851
|
+
} else {
|
|
36852
|
+
const leading = nums.slice(0, -1);
|
|
36853
|
+
const last = nums[nums.length - 1];
|
|
36854
|
+
if (leading.some((n2) => n2 > 255))
|
|
36855
|
+
return { invalid: true };
|
|
36856
|
+
const maxLast = 2 ** (8 * (4 - leading.length));
|
|
36857
|
+
if (last >= maxLast)
|
|
36858
|
+
return { invalid: true };
|
|
36859
|
+
ip32 = last;
|
|
36860
|
+
for (let i = 0;i < leading.length; i++) {
|
|
36861
|
+
ip32 += leading[i] * 2 ** (8 * (3 - i));
|
|
36862
|
+
}
|
|
36863
|
+
}
|
|
36864
|
+
if (ip32 < 0 || ip32 > 4294967295)
|
|
36865
|
+
return { invalid: true };
|
|
36866
|
+
const a = ip32 >>> 24 & 255;
|
|
36867
|
+
const b3 = ip32 >>> 16 & 255;
|
|
36868
|
+
const c2 = ip32 >>> 8 & 255;
|
|
36869
|
+
const d2 = ip32 & 255;
|
|
36870
|
+
return { ipv4: `${a}.${b3}.${c2}.${d2}` };
|
|
36871
|
+
}
|
|
36872
|
+
function ipv4ToInt(address) {
|
|
36873
|
+
const octets = address.split(".");
|
|
36874
|
+
if (octets.length !== 4)
|
|
36875
|
+
return null;
|
|
36876
|
+
let value = 0;
|
|
36877
|
+
for (const octet of octets) {
|
|
36878
|
+
if (!/^[0-9]{1,3}$/.test(octet))
|
|
36879
|
+
return null;
|
|
36880
|
+
const n2 = Number.parseInt(octet, 10);
|
|
36881
|
+
if (n2 > 255)
|
|
36882
|
+
return null;
|
|
36883
|
+
value = value * 256 + n2;
|
|
36884
|
+
}
|
|
36885
|
+
return value >>> 0;
|
|
36886
|
+
}
|
|
36887
|
+
function cidr(base, bits) {
|
|
36888
|
+
const lo = ipv4ToInt(base);
|
|
36889
|
+
const size2 = 2 ** (32 - bits);
|
|
36890
|
+
return [lo, lo + size2 - 1];
|
|
36891
|
+
}
|
|
36892
|
+
function classifyIpv4(address) {
|
|
36893
|
+
const value = ipv4ToInt(address);
|
|
36894
|
+
if (value === null)
|
|
36895
|
+
return "invalid-ip-encoding";
|
|
36896
|
+
for (const [lo, hi, cls] of RESERVED_IPV4) {
|
|
36897
|
+
if (value >= lo && value <= hi)
|
|
36898
|
+
return cls;
|
|
36899
|
+
}
|
|
36900
|
+
return null;
|
|
36901
|
+
}
|
|
36902
|
+
function mappedSuffixToIpv4(suffix) {
|
|
36903
|
+
if (suffix.includes("."))
|
|
36904
|
+
return isIP(suffix) === 4 ? suffix : null;
|
|
36905
|
+
const hextets = suffix.split(":");
|
|
36906
|
+
if (hextets.length !== 2)
|
|
36907
|
+
return null;
|
|
36908
|
+
const hi = Number.parseInt(hextets[0], 16);
|
|
36909
|
+
const lo = Number.parseInt(hextets[1], 16);
|
|
36910
|
+
if (Number.isNaN(hi) || Number.isNaN(lo) || hi > 65535 || lo > 65535)
|
|
36911
|
+
return null;
|
|
36912
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
36913
|
+
}
|
|
36914
|
+
function hextetsToIpv4(hi, lo) {
|
|
36915
|
+
return `${hi >> 8 & 255}.${hi & 255}.${lo >> 8 & 255}.${lo & 255}`;
|
|
36916
|
+
}
|
|
36917
|
+
function ipv6ToHextets(normalized) {
|
|
36918
|
+
const parseGroups = (groups) => {
|
|
36919
|
+
const out = [];
|
|
36920
|
+
for (let i = 0;i < groups.length; i++) {
|
|
36921
|
+
const g3 = groups[i];
|
|
36922
|
+
if (g3.includes(".")) {
|
|
36923
|
+
if (i !== groups.length - 1)
|
|
36924
|
+
return null;
|
|
36925
|
+
const octets = g3.split(".").map((o) => Number.parseInt(o, 10));
|
|
36926
|
+
if (octets.length !== 4 || octets.some((n2) => Number.isNaN(n2) || n2 < 0 || n2 > 255))
|
|
36927
|
+
return null;
|
|
36928
|
+
out.push(octets[0] << 8 | octets[1]);
|
|
36929
|
+
out.push(octets[2] << 8 | octets[3]);
|
|
36930
|
+
} else {
|
|
36931
|
+
const n2 = Number.parseInt(g3, 16);
|
|
36932
|
+
if (Number.isNaN(n2) || n2 < 0 || n2 > 65535)
|
|
36933
|
+
return null;
|
|
36934
|
+
out.push(n2);
|
|
36935
|
+
}
|
|
36936
|
+
}
|
|
36937
|
+
return out;
|
|
36938
|
+
};
|
|
36939
|
+
const dc = normalized.indexOf("::");
|
|
36940
|
+
if (dc >= 0) {
|
|
36941
|
+
const before = normalized.slice(0, dc);
|
|
36942
|
+
const after = normalized.slice(dc + 2);
|
|
36943
|
+
const head = before === "" ? [] : before.split(":");
|
|
36944
|
+
const tail = after === "" ? [] : after.split(":");
|
|
36945
|
+
const h2 = parseGroups(head);
|
|
36946
|
+
const t = parseGroups(tail);
|
|
36947
|
+
if (h2 === null || t === null)
|
|
36948
|
+
return null;
|
|
36949
|
+
const fill = 8 - h2.length - t.length;
|
|
36950
|
+
if (fill < 0)
|
|
36951
|
+
return null;
|
|
36952
|
+
return [...h2, ...new Array(fill).fill(0), ...t];
|
|
36953
|
+
}
|
|
36954
|
+
const g2 = parseGroups(normalized.split(":"));
|
|
36955
|
+
if (g2 === null || g2.length !== 8)
|
|
36956
|
+
return null;
|
|
36957
|
+
return g2;
|
|
36958
|
+
}
|
|
36959
|
+
function classifyIpv6Transition(normalized) {
|
|
36960
|
+
const hextets = ipv6ToHextets(normalized);
|
|
36961
|
+
if (hextets === null)
|
|
36962
|
+
return;
|
|
36963
|
+
const [h0, h1, h2, h3, h4, h5, h6, h7] = hextets;
|
|
36964
|
+
if (h0 === 8194) {
|
|
36965
|
+
return classifyIpv4(hextetsToIpv4(h1, h2));
|
|
36966
|
+
}
|
|
36967
|
+
if (h0 === 100 && h1 === 65435 && h2 === 0 && h3 === 0 && h4 === 0 && h5 === 0) {
|
|
36968
|
+
return classifyIpv4(hextetsToIpv4(h6, h7));
|
|
36969
|
+
}
|
|
36970
|
+
if (h0 === 8193 && h1 === 0) {
|
|
36971
|
+
const server = classifyIpv4(hextetsToIpv4(h2, h3));
|
|
36972
|
+
if (server !== null)
|
|
36973
|
+
return server;
|
|
36974
|
+
const client = classifyIpv4(hextetsToIpv4(h6 ^ 65535, h7 ^ 65535));
|
|
36975
|
+
if (client !== null)
|
|
36976
|
+
return client;
|
|
36977
|
+
return null;
|
|
36978
|
+
}
|
|
36979
|
+
return;
|
|
36980
|
+
}
|
|
36981
|
+
function classifyIpv6(address) {
|
|
36982
|
+
const normalized = address.toLowerCase().replace(/^\[|\]$/g, "");
|
|
36983
|
+
if (normalized === "::" || normalized === "::0" || normalized === "0:0:0:0:0:0:0:0")
|
|
36984
|
+
return "unspecified";
|
|
36985
|
+
if (normalized === "::1")
|
|
36986
|
+
return "loopback";
|
|
36987
|
+
const mappedFfff = /^::ffff:([0-9a-f:.]+)$/.exec(normalized);
|
|
36988
|
+
const compat = /^::([0-9a-f]{1,4}:[0-9a-f]{1,4}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/.exec(normalized);
|
|
36989
|
+
const suffix = mappedFfff?.[1] ?? compat?.[1];
|
|
36990
|
+
if (suffix) {
|
|
36991
|
+
const v4 = mappedSuffixToIpv4(suffix);
|
|
36992
|
+
if (v4) {
|
|
36993
|
+
const inner = classifyIpv4(v4);
|
|
36994
|
+
return inner ?? "ipv4-mapped-ipv6";
|
|
36995
|
+
}
|
|
36996
|
+
}
|
|
36997
|
+
const transition = classifyIpv6Transition(normalized);
|
|
36998
|
+
if (transition !== undefined)
|
|
36999
|
+
return transition;
|
|
37000
|
+
const firstHextet = normalized.split(":", 1)[0] ?? "";
|
|
37001
|
+
if (firstHextet.startsWith("fc") || firstHextet.startsWith("fd"))
|
|
37002
|
+
return "ipv6-ula";
|
|
37003
|
+
if (/^fe[89ab]/.test(firstHextet))
|
|
37004
|
+
return "link-local";
|
|
37005
|
+
if (firstHextet.startsWith("ff"))
|
|
37006
|
+
return "multicast";
|
|
37007
|
+
return null;
|
|
37008
|
+
}
|
|
37009
|
+
function classifyResolvedAddress(address) {
|
|
37010
|
+
const family = isIP(address);
|
|
37011
|
+
if (family === 4)
|
|
37012
|
+
return classifyIpv4(address);
|
|
37013
|
+
if (family === 6)
|
|
37014
|
+
return classifyIpv6(address);
|
|
37015
|
+
return "invalid-ip-encoding";
|
|
37016
|
+
}
|
|
37017
|
+
function decide(allowed, destinationClass, reason, policy, host) {
|
|
37018
|
+
return { allowed, destinationClass, reason, policyVersion: policy.policyVersion, host };
|
|
37019
|
+
}
|
|
37020
|
+
function classifyUrl(url, policy) {
|
|
37021
|
+
if (!schemesFor(policy).includes(url.protocol)) {
|
|
37022
|
+
return decide(false, "unapproved-scheme", `scheme ${url.protocol} is not approved`, policy, url.hostname);
|
|
37023
|
+
}
|
|
37024
|
+
if (url.username !== "" || url.password !== "") {
|
|
37025
|
+
return decide(false, "credentialed-url", "URL carries userinfo credentials", policy, url.hostname);
|
|
37026
|
+
}
|
|
37027
|
+
const port = portFor(url);
|
|
37028
|
+
if (port === null || !portsFor(policy).includes(port)) {
|
|
37029
|
+
return decide(false, "unapproved-port", `port ${url.port || "(default)"} is not approved`, policy, url.hostname);
|
|
37030
|
+
}
|
|
37031
|
+
const host = url.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
37032
|
+
if (host.length === 0) {
|
|
37033
|
+
return decide(false, "malformed-url", "URL has no host", policy, host);
|
|
37034
|
+
}
|
|
37035
|
+
return classifyHost(host, policy);
|
|
37036
|
+
}
|
|
37037
|
+
function classifyHost(host, policy) {
|
|
37038
|
+
if (isIP(host) !== 0) {
|
|
37039
|
+
const literalClass = classifyResolvedAddress(host);
|
|
37040
|
+
if (literalClass !== null) {
|
|
37041
|
+
return decide(false, literalClass, `literal IP ${host} is in a ${literalClass} range`, policy, host);
|
|
37042
|
+
}
|
|
37043
|
+
return approvedOrDenied(isApprovedHost(host, policy), "literal IP", host, policy);
|
|
37044
|
+
}
|
|
37045
|
+
const canon = canonicalizeIpv4(host);
|
|
37046
|
+
if (canon !== null) {
|
|
37047
|
+
if ("invalid" in canon) {
|
|
37048
|
+
return decide(false, "invalid-ip-encoding", `host ${host} is a malformed numeric address`, policy, host);
|
|
37049
|
+
}
|
|
37050
|
+
const literalClass = classifyResolvedAddress(canon.ipv4);
|
|
37051
|
+
if (literalClass !== null) {
|
|
37052
|
+
return decide(false, literalClass, `host ${host} canonicalises to ${canon.ipv4} (${literalClass})`, policy, host);
|
|
37053
|
+
}
|
|
37054
|
+
const approved = isApprovedHost(canon.ipv4, policy) || isApprovedHost(host, policy);
|
|
37055
|
+
return approvedOrDenied(approved, "numeric IP", host, policy);
|
|
37056
|
+
}
|
|
37057
|
+
return approvedOrDenied(isApprovedHost(host, policy), "host", host, policy);
|
|
37058
|
+
}
|
|
37059
|
+
function approvedOrDenied(approved, kind, host, policy) {
|
|
37060
|
+
return approved ? decide(true, "approved-public", `approved ${kind} (allowlist match; DNS pending for names)`, policy, host) : decide(false, "not-approved", `${kind} ${host} is not on the tenant allowlist`, policy, host);
|
|
37061
|
+
}
|
|
37062
|
+
var DEFAULT_SCHEMES, DEFAULT_PORTS, RESERVED_IPV4;
|
|
37063
|
+
var init_policy = __esm(() => {
|
|
37064
|
+
DEFAULT_SCHEMES = ["https:"];
|
|
37065
|
+
DEFAULT_PORTS = [443];
|
|
37066
|
+
RESERVED_IPV4 = [
|
|
37067
|
+
[...cidr("0.0.0.0", 8), "unspecified"],
|
|
37068
|
+
[...cidr("10.0.0.0", 8), "private-rfc1918"],
|
|
37069
|
+
[...cidr("127.0.0.0", 8), "loopback"],
|
|
37070
|
+
[...cidr("100.64.0.0", 10), "cgnat"],
|
|
37071
|
+
[...cidr("169.254.0.0", 16), "link-local"],
|
|
37072
|
+
[...cidr("172.16.0.0", 12), "private-rfc1918"],
|
|
37073
|
+
[...cidr("192.168.0.0", 16), "private-rfc1918"],
|
|
37074
|
+
[...cidr("192.88.99.0", 24), "reserved"],
|
|
37075
|
+
[...cidr("192.0.0.0", 24), "reserved"],
|
|
37076
|
+
[...cidr("192.0.2.0", 24), "reserved"],
|
|
37077
|
+
[...cidr("198.18.0.0", 15), "reserved"],
|
|
37078
|
+
[...cidr("198.51.100.0", 24), "reserved"],
|
|
37079
|
+
[...cidr("203.0.113.0", 24), "reserved"],
|
|
37080
|
+
[...cidr("224.0.0.0", 4), "multicast"],
|
|
37081
|
+
[...cidr("240.0.0.0", 4), "reserved"]
|
|
37082
|
+
];
|
|
37083
|
+
});
|
|
37084
|
+
|
|
37085
|
+
// ../core/src/egress/broker.ts
|
|
37086
|
+
import { lookup } from "dns/promises";
|
|
37087
|
+
import { isIP as isIP2 } from "net";
|
|
37088
|
+
function hostMatchesSuffix2(hostname, suffix) {
|
|
37089
|
+
const h2 = hostname.toLowerCase();
|
|
37090
|
+
const s = suffix.toLowerCase().replace(/^\.+/, "");
|
|
37091
|
+
return h2 === s || h2.endsWith(`.${s}`);
|
|
37092
|
+
}
|
|
37093
|
+
function nextHopHeaders(request, currentUrl, nextUrl) {
|
|
37094
|
+
const headers = new Headers(request.headers ?? {});
|
|
37095
|
+
const sameOrigin = nextUrl.origin === currentUrl.origin;
|
|
37096
|
+
const preserved = Boolean(request.preserveAuthRedirectHostSuffixes?.some((suffix) => hostMatchesSuffix2(currentUrl.hostname, suffix) && hostMatchesSuffix2(nextUrl.hostname, suffix)));
|
|
37097
|
+
if (!sameOrigin && !preserved) {
|
|
37098
|
+
for (const header2 of CROSS_ORIGIN_CREDENTIAL_HEADERS)
|
|
37099
|
+
headers.delete(header2);
|
|
37100
|
+
}
|
|
37101
|
+
return headers;
|
|
37102
|
+
}
|
|
37103
|
+
|
|
37104
|
+
class Semaphore {
|
|
37105
|
+
max;
|
|
37106
|
+
active = 0;
|
|
37107
|
+
waiters = [];
|
|
37108
|
+
constructor(max) {
|
|
37109
|
+
this.max = max;
|
|
37110
|
+
}
|
|
37111
|
+
async acquire() {
|
|
37112
|
+
if (this.active < this.max) {
|
|
37113
|
+
this.active += 1;
|
|
37114
|
+
return;
|
|
37115
|
+
}
|
|
37116
|
+
await new Promise((resolve2) => this.waiters.push(resolve2));
|
|
37117
|
+
this.active += 1;
|
|
37118
|
+
}
|
|
37119
|
+
release() {
|
|
37120
|
+
this.active -= 1;
|
|
37121
|
+
const next = this.waiters.shift();
|
|
37122
|
+
if (next)
|
|
37123
|
+
next();
|
|
37124
|
+
}
|
|
37125
|
+
}
|
|
37126
|
+
|
|
37127
|
+
class TenantEgressBroker {
|
|
37128
|
+
resolveAddresses;
|
|
37129
|
+
transport;
|
|
37130
|
+
audit;
|
|
37131
|
+
limits;
|
|
37132
|
+
semaphore;
|
|
37133
|
+
constructor(options = {}) {
|
|
37134
|
+
this.resolveAddresses = options.resolveAddresses ?? defaultLookup;
|
|
37135
|
+
this.transport = options.transport ?? defaultTransport;
|
|
37136
|
+
this.audit = options.audit ?? (() => {});
|
|
37137
|
+
this.limits = { ...DEFAULT_EGRESS_LIMITS, ...options.limits };
|
|
37138
|
+
this.semaphore = new Semaphore(this.limits.maxConcurrency);
|
|
37139
|
+
}
|
|
37140
|
+
record(context, decision, outcome, hops) {
|
|
37141
|
+
this.audit({
|
|
37142
|
+
tenantId: context.tenantId,
|
|
37143
|
+
actorCredentialId: context.actorCredentialId,
|
|
37144
|
+
integration: context.integration,
|
|
37145
|
+
destinationClass: decision.destinationClass,
|
|
37146
|
+
policyVersion: decision.policyVersion,
|
|
37147
|
+
outcome,
|
|
37148
|
+
host: decision.host,
|
|
37149
|
+
redirectHops: hops,
|
|
37150
|
+
reason: decision.reason
|
|
37151
|
+
});
|
|
37152
|
+
}
|
|
37153
|
+
async validateDestination(url, policy, context, hops) {
|
|
37154
|
+
const decision = classifyUrl(url, policy);
|
|
37155
|
+
if (!decision.allowed) {
|
|
37156
|
+
this.record(context, decision, "blocked", hops);
|
|
37157
|
+
throw new EgressBlockedError(decision.destinationClass, decision.reason);
|
|
37158
|
+
}
|
|
37159
|
+
const host = decision.host;
|
|
37160
|
+
const canon = canonicalizeIpv4(host);
|
|
37161
|
+
const isLiteralIp = isIP2(host) !== 0 || canon !== null && "ipv4" in canon;
|
|
37162
|
+
if (!isLiteralIp) {
|
|
37163
|
+
let addresses;
|
|
37164
|
+
try {
|
|
37165
|
+
addresses = await this.resolveAddresses(host);
|
|
37166
|
+
} catch (error2) {
|
|
37167
|
+
throw new EgressLimitError(`DNS resolution failed for host: ${error2 instanceof Error ? error2.message : "unknown"}`);
|
|
37168
|
+
}
|
|
37169
|
+
if (addresses.length === 0) {
|
|
37170
|
+
throw new EgressLimitError("DNS resolution returned no addresses");
|
|
37171
|
+
}
|
|
37172
|
+
for (const { address } of addresses) {
|
|
37173
|
+
const addrClass = classifyResolvedAddress(address);
|
|
37174
|
+
if (addrClass !== null) {
|
|
37175
|
+
const blocked = {
|
|
37176
|
+
allowed: false,
|
|
37177
|
+
destinationClass: addrClass,
|
|
37178
|
+
reason: `host ${host} resolves to a ${addrClass} address`,
|
|
37179
|
+
policyVersion: policy.policyVersion,
|
|
37180
|
+
host
|
|
37181
|
+
};
|
|
37182
|
+
this.record(context, blocked, "blocked", hops);
|
|
37183
|
+
throw new EgressBlockedError(addrClass, blocked.reason);
|
|
37184
|
+
}
|
|
37185
|
+
}
|
|
37186
|
+
}
|
|
37187
|
+
return decision;
|
|
37188
|
+
}
|
|
37189
|
+
async send(request, policy, context) {
|
|
37190
|
+
await this.semaphore.acquire();
|
|
37191
|
+
try {
|
|
37192
|
+
let currentUrl = new URL(request.url);
|
|
37193
|
+
let lastDecision = await this.validateDestination(currentUrl, policy, context, 0);
|
|
37194
|
+
let headers = new Headers(request.headers ?? {});
|
|
37195
|
+
for (let hop = 0;hop <= this.limits.maxRedirects; hop++) {
|
|
37196
|
+
const response = await this.transport(currentUrl.toString(), {
|
|
37197
|
+
method: request.method ?? "GET",
|
|
37198
|
+
headers,
|
|
37199
|
+
body: request.body ?? undefined,
|
|
37200
|
+
redirect: "manual",
|
|
37201
|
+
signal: AbortSignal.timeout(this.limits.timeoutMs)
|
|
37202
|
+
});
|
|
37203
|
+
if (response.status < 300 || response.status >= 400) {
|
|
37204
|
+
this.enforceBodyLimit(response);
|
|
37205
|
+
this.record(context, lastDecision, "allowed", hop);
|
|
37206
|
+
return response;
|
|
37207
|
+
}
|
|
37208
|
+
const location = response.headers.get("location");
|
|
37209
|
+
if (!location) {
|
|
37210
|
+
this.enforceBodyLimit(response);
|
|
37211
|
+
this.record(context, lastDecision, "allowed", hop);
|
|
37212
|
+
return response;
|
|
37213
|
+
}
|
|
37214
|
+
const nextUrl = new URL(location, currentUrl);
|
|
37215
|
+
lastDecision = await this.validateDestination(nextUrl, policy, context, hop + 1);
|
|
37216
|
+
headers = nextHopHeaders(request, currentUrl, nextUrl);
|
|
37217
|
+
currentUrl = nextUrl;
|
|
37218
|
+
}
|
|
37219
|
+
const exhausted = {
|
|
37220
|
+
allowed: false,
|
|
37221
|
+
destinationClass: lastDecision.destinationClass,
|
|
37222
|
+
reason: "too many redirects",
|
|
37223
|
+
policyVersion: policy.policyVersion,
|
|
37224
|
+
host: lastDecision.host
|
|
37225
|
+
};
|
|
37226
|
+
this.record(context, exhausted, "error", this.limits.maxRedirects);
|
|
37227
|
+
throw new EgressLimitError("too many redirects");
|
|
37228
|
+
} catch (error2) {
|
|
37229
|
+
if (!(error2 instanceof EgressBlockedError) && !(error2 instanceof EgressLimitError)) {
|
|
37230
|
+
this.audit({
|
|
37231
|
+
tenantId: context.tenantId,
|
|
37232
|
+
actorCredentialId: context.actorCredentialId,
|
|
37233
|
+
integration: context.integration,
|
|
37234
|
+
destinationClass: "approved-public",
|
|
37235
|
+
policyVersion: policy.policyVersion,
|
|
37236
|
+
outcome: "error",
|
|
37237
|
+
host: safeHost(request.url),
|
|
37238
|
+
redirectHops: 0,
|
|
37239
|
+
reason: error2 instanceof Error ? error2.name : "transport error"
|
|
37240
|
+
});
|
|
37241
|
+
}
|
|
37242
|
+
throw error2;
|
|
37243
|
+
} finally {
|
|
37244
|
+
this.semaphore.release();
|
|
37245
|
+
}
|
|
37246
|
+
}
|
|
37247
|
+
enforceBodyLimit(response) {
|
|
37248
|
+
const declared = response.headers.get("content-length");
|
|
37249
|
+
if (declared) {
|
|
37250
|
+
const length = Number.parseInt(declared, 10);
|
|
37251
|
+
if (!Number.isNaN(length) && length > this.limits.maxResponseBytes) {
|
|
37252
|
+
throw new EgressLimitError(`response body ${length} exceeds ${this.limits.maxResponseBytes} bytes`);
|
|
37253
|
+
}
|
|
37254
|
+
}
|
|
37255
|
+
}
|
|
37256
|
+
async readBounded(response) {
|
|
37257
|
+
const cap = this.limits.maxResponseBytes;
|
|
37258
|
+
const reader = response.body?.getReader();
|
|
37259
|
+
if (!reader)
|
|
37260
|
+
return new Uint8Array(0);
|
|
37261
|
+
const chunks = [];
|
|
37262
|
+
let total = 0;
|
|
37263
|
+
while (true) {
|
|
37264
|
+
const { done, value } = await reader.read();
|
|
37265
|
+
if (done)
|
|
37266
|
+
break;
|
|
37267
|
+
if (value) {
|
|
37268
|
+
total += value.byteLength;
|
|
37269
|
+
if (total > cap) {
|
|
37270
|
+
await reader.cancel();
|
|
37271
|
+
throw new EgressLimitError(`response body exceeds ${cap} bytes`);
|
|
37272
|
+
}
|
|
37273
|
+
chunks.push(value);
|
|
37274
|
+
}
|
|
37275
|
+
}
|
|
37276
|
+
const out = new Uint8Array(total);
|
|
37277
|
+
let offset = 0;
|
|
37278
|
+
for (const chunk of chunks) {
|
|
37279
|
+
out.set(chunk, offset);
|
|
37280
|
+
offset += chunk.byteLength;
|
|
37281
|
+
}
|
|
37282
|
+
return out;
|
|
37283
|
+
}
|
|
37284
|
+
}
|
|
37285
|
+
function safeHost(url) {
|
|
37286
|
+
try {
|
|
37287
|
+
return new URL(url).hostname.toLowerCase();
|
|
37288
|
+
} catch {
|
|
37289
|
+
return "(unparseable)";
|
|
37290
|
+
}
|
|
37291
|
+
}
|
|
37292
|
+
function setEgressPolicyResolver(resolver) {
|
|
37293
|
+
egressPolicyResolver = resolver;
|
|
37294
|
+
}
|
|
37295
|
+
function resolveEgressPolicy(context) {
|
|
37296
|
+
if (!egressPolicyResolver)
|
|
37297
|
+
return null;
|
|
37298
|
+
try {
|
|
37299
|
+
return egressPolicyResolver(context) ?? null;
|
|
37300
|
+
} catch {
|
|
37301
|
+
return { policyVersion: -1, approvedHostSuffixes: [] };
|
|
37302
|
+
}
|
|
37303
|
+
}
|
|
37304
|
+
async function brokeredFetch(input, init, broker = sharedBroker) {
|
|
37305
|
+
const { egress, ...rest } = init;
|
|
37306
|
+
const policy = resolveEgressPolicy(egress);
|
|
37307
|
+
if (!policy) {
|
|
37308
|
+
return fetch(input, rest);
|
|
37309
|
+
}
|
|
37310
|
+
return broker.send({
|
|
37311
|
+
url: input,
|
|
37312
|
+
method: typeof rest.method === "string" ? rest.method : undefined,
|
|
37313
|
+
headers: rest.headers,
|
|
37314
|
+
body: rest.body ?? null
|
|
37315
|
+
}, policy, egress);
|
|
37316
|
+
}
|
|
37317
|
+
var defaultLookup = async (hostname) => lookup(hostname, { all: true }), defaultTransport = (url, init) => fetch(url, init), DEFAULT_EGRESS_LIMITS, EgressBlockedError, EgressLimitError, CROSS_ORIGIN_CREDENTIAL_HEADERS, egressPolicyResolver = null, sharedBroker;
|
|
37318
|
+
var init_broker = __esm(() => {
|
|
37319
|
+
init_policy();
|
|
37320
|
+
DEFAULT_EGRESS_LIMITS = {
|
|
37321
|
+
timeoutMs: 1e4,
|
|
37322
|
+
maxRedirects: 3,
|
|
37323
|
+
maxResponseBytes: 8 * 1024 * 1024,
|
|
37324
|
+
maxConcurrency: 16
|
|
37325
|
+
};
|
|
37326
|
+
EgressBlockedError = class EgressBlockedError extends Error {
|
|
37327
|
+
code = "egress_blocked";
|
|
37328
|
+
destinationClass;
|
|
37329
|
+
constructor(destinationClass, reason) {
|
|
37330
|
+
super(`egress blocked (${destinationClass}): ${reason}`);
|
|
37331
|
+
this.name = "EgressBlockedError";
|
|
37332
|
+
this.destinationClass = destinationClass;
|
|
37333
|
+
}
|
|
37334
|
+
};
|
|
37335
|
+
EgressLimitError = class EgressLimitError extends Error {
|
|
37336
|
+
code = "egress_limit";
|
|
37337
|
+
constructor(reason) {
|
|
37338
|
+
super(`egress limit exceeded: ${reason}`);
|
|
37339
|
+
this.name = "EgressLimitError";
|
|
37340
|
+
}
|
|
37341
|
+
};
|
|
37342
|
+
CROSS_ORIGIN_CREDENTIAL_HEADERS = ["authorization", "cookie", "proxy-authorization"];
|
|
37343
|
+
sharedBroker = new TenantEgressBroker;
|
|
37344
|
+
});
|
|
37345
|
+
|
|
37346
|
+
// ../core/src/egress/index.ts
|
|
37347
|
+
var init_egress = __esm(() => {
|
|
37348
|
+
init_policy();
|
|
37349
|
+
init_broker();
|
|
37350
|
+
});
|
|
37351
|
+
|
|
36427
37352
|
// ../core/src/automations/actions.ts
|
|
36428
37353
|
function buildWebhookHeaders(config2, context) {
|
|
36429
37354
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -36438,18 +37363,23 @@ async function parseWebhookResponse(response) {
|
|
|
36438
37363
|
const contentType = response.headers.get("content-type") ?? "";
|
|
36439
37364
|
return contentType.includes("application/json") ? response.json() : response.text();
|
|
36440
37365
|
}
|
|
36441
|
-
async function executeWebhookAction(config2, context, _deps) {
|
|
37366
|
+
async function executeWebhookAction(config2, context, _deps, trustedTenantId) {
|
|
36442
37367
|
try {
|
|
36443
37368
|
const url = substituteTemplate(config2.url, context);
|
|
36444
37369
|
const method = config2.method ?? "POST";
|
|
36445
37370
|
const headers = buildWebhookHeaders(config2, context);
|
|
36446
37371
|
const body = config2.bodyTemplate ? substituteTemplate(config2.bodyTemplate, context) : JSON.stringify(context.payload);
|
|
36447
37372
|
logger2.debug(`Webhook ${method} ${url}`, { method, url, waitForResponse: config2.waitForResponse });
|
|
36448
|
-
const response = await
|
|
37373
|
+
const response = await brokeredFetch(url, {
|
|
36449
37374
|
method,
|
|
36450
37375
|
headers,
|
|
36451
37376
|
body: method !== "GET" ? body : undefined,
|
|
36452
|
-
signal: AbortSignal.timeout(config2.timeoutMs ?? 30000)
|
|
37377
|
+
signal: AbortSignal.timeout(config2.timeoutMs ?? 30000),
|
|
37378
|
+
egress: {
|
|
37379
|
+
tenantId: trustedTenantId ?? resolveAmbientTenantId() ?? "(unbound)",
|
|
37380
|
+
actorCredentialId: null,
|
|
37381
|
+
integration: "automations.webhook"
|
|
37382
|
+
}
|
|
36453
37383
|
});
|
|
36454
37384
|
if (!config2.waitForResponse) {
|
|
36455
37385
|
return {
|
|
@@ -36469,7 +37399,7 @@ async function executeWebhookAction(config2, context, _deps) {
|
|
|
36469
37399
|
};
|
|
36470
37400
|
}
|
|
36471
37401
|
}
|
|
36472
|
-
async function executeSendMessageAction(config2, context, deps) {
|
|
37402
|
+
async function executeSendMessageAction(config2, context, deps, trustedTenantId) {
|
|
36473
37403
|
try {
|
|
36474
37404
|
if (!deps.sendMessage) {
|
|
36475
37405
|
return {
|
|
@@ -36490,7 +37420,7 @@ async function executeSendMessageAction(config2, context, deps) {
|
|
|
36490
37420
|
return { success: false, error: "content is empty" };
|
|
36491
37421
|
}
|
|
36492
37422
|
logger2.debug("Sending message", { instanceId, to, contentLength: content.length });
|
|
36493
|
-
await deps.sendMessage(instanceId, to, content);
|
|
37423
|
+
await deps.sendMessage(instanceId, to, content, trustedTenantId);
|
|
36494
37424
|
return {
|
|
36495
37425
|
success: true,
|
|
36496
37426
|
result: { instanceId, to, contentLength: content.length }
|
|
@@ -36504,7 +37434,7 @@ async function executeSendMessageAction(config2, context, deps) {
|
|
|
36504
37434
|
};
|
|
36505
37435
|
}
|
|
36506
37436
|
}
|
|
36507
|
-
async function executeEmitEventAction(config2, context, deps) {
|
|
37437
|
+
async function executeEmitEventAction(config2, context, deps, trustedTenantId) {
|
|
36508
37438
|
try {
|
|
36509
37439
|
if (!deps.eventBus) {
|
|
36510
37440
|
return {
|
|
@@ -36522,7 +37452,8 @@ async function executeEmitEventAction(config2, context, deps) {
|
|
|
36522
37452
|
logger2.debug("Emitting event", { eventType });
|
|
36523
37453
|
const result = await deps.eventBus.publishGeneric(eventType, payload, {
|
|
36524
37454
|
correlationId: context.payload.correlationId ?? undefined,
|
|
36525
|
-
source: "automation"
|
|
37455
|
+
source: "automation",
|
|
37456
|
+
...trustedTenantId ? { tenantId: trustedTenantId } : {}
|
|
36526
37457
|
});
|
|
36527
37458
|
return {
|
|
36528
37459
|
success: true,
|
|
@@ -36614,7 +37545,7 @@ function extractAgentCallContext(config2, context) {
|
|
|
36614
37545
|
}
|
|
36615
37546
|
};
|
|
36616
37547
|
}
|
|
36617
|
-
async function executeCallAgentAction(config2, context, deps) {
|
|
37548
|
+
async function executeCallAgentAction(config2, context, deps, trustedTenantId) {
|
|
36618
37549
|
if (!deps.callAgent) {
|
|
36619
37550
|
return { success: false, error: "callAgent dependency not provided" };
|
|
36620
37551
|
}
|
|
@@ -36630,7 +37561,7 @@ async function executeCallAgentAction(config2, context, deps) {
|
|
|
36630
37561
|
agentId: config2.agentId
|
|
36631
37562
|
});
|
|
36632
37563
|
try {
|
|
36633
|
-
const result = await deps.callAgent(agentContext, config2);
|
|
37564
|
+
const result = await deps.callAgent(agentContext, config2, trustedTenantId);
|
|
36634
37565
|
logger2.info("Agent call completed", {
|
|
36635
37566
|
runId: result.metadata.runId,
|
|
36636
37567
|
status: result.metadata.status,
|
|
@@ -36651,24 +37582,24 @@ async function executeCallAgentAction(config2, context, deps) {
|
|
|
36651
37582
|
return { success: false, error: errorMessage };
|
|
36652
37583
|
}
|
|
36653
37584
|
}
|
|
36654
|
-
async function executeAction(action, context, deps) {
|
|
37585
|
+
async function executeAction(action, context, deps, trustedTenantId) {
|
|
36655
37586
|
const start = Date.now();
|
|
36656
37587
|
let result;
|
|
36657
37588
|
switch (action.type) {
|
|
36658
37589
|
case "webhook":
|
|
36659
|
-
result = await executeWebhookAction(action.config, context, deps);
|
|
37590
|
+
result = await executeWebhookAction(action.config, context, deps, trustedTenantId);
|
|
36660
37591
|
break;
|
|
36661
37592
|
case "send_message":
|
|
36662
|
-
result = await executeSendMessageAction(action.config, context, deps);
|
|
37593
|
+
result = await executeSendMessageAction(action.config, context, deps, trustedTenantId);
|
|
36663
37594
|
break;
|
|
36664
37595
|
case "emit_event":
|
|
36665
|
-
result = await executeEmitEventAction(action.config, context, deps);
|
|
37596
|
+
result = await executeEmitEventAction(action.config, context, deps, trustedTenantId);
|
|
36666
37597
|
break;
|
|
36667
37598
|
case "log":
|
|
36668
37599
|
result = await executeLogAction(action.config, context, deps);
|
|
36669
37600
|
break;
|
|
36670
37601
|
case "call_agent":
|
|
36671
|
-
result = await executeCallAgentAction(action.config, context, deps);
|
|
37602
|
+
result = await executeCallAgentAction(action.config, context, deps, trustedTenantId);
|
|
36672
37603
|
break;
|
|
36673
37604
|
default:
|
|
36674
37605
|
result = { success: false, error: `Unknown action type: ${action.type}` };
|
|
@@ -36682,7 +37613,7 @@ async function executeAction(action, context, deps) {
|
|
|
36682
37613
|
durationMs
|
|
36683
37614
|
};
|
|
36684
37615
|
}
|
|
36685
|
-
async function executeActions(actions, context, deps) {
|
|
37616
|
+
async function executeActions(actions, context, deps, trustedTenantId) {
|
|
36686
37617
|
const results = [];
|
|
36687
37618
|
const variables = { ...context.variables };
|
|
36688
37619
|
for (const action of actions) {
|
|
@@ -36690,7 +37621,7 @@ async function executeActions(actions, context, deps) {
|
|
|
36690
37621
|
...context,
|
|
36691
37622
|
variables
|
|
36692
37623
|
};
|
|
36693
|
-
const result = await executeAction(action, actionContext, deps);
|
|
37624
|
+
const result = await executeAction(action, actionContext, deps, trustedTenantId);
|
|
36694
37625
|
results.push(result);
|
|
36695
37626
|
if (action.type === "webhook" && action.config.responseAs && result.status === "success" && result.result) {
|
|
36696
37627
|
variables[action.config.responseAs] = result.result;
|
|
@@ -36704,12 +37635,19 @@ async function executeActions(actions, context, deps) {
|
|
|
36704
37635
|
}
|
|
36705
37636
|
var logger2;
|
|
36706
37637
|
var init_actions = __esm(() => {
|
|
37638
|
+
init_egress();
|
|
37639
|
+
init_envelope();
|
|
36707
37640
|
init_logger();
|
|
36708
37641
|
init_templates();
|
|
36709
37642
|
logger2 = createLogger("automations:actions");
|
|
36710
37643
|
});
|
|
36711
37644
|
|
|
36712
37645
|
// ../core/src/automations/debounce.ts
|
|
37646
|
+
function stampsEqual(a, b3) {
|
|
37647
|
+
if (a === null || b3 === null)
|
|
37648
|
+
return a === b3;
|
|
37649
|
+
return a.tenantId === b3.tenantId && a.envelopeVersion === b3.envelopeVersion;
|
|
37650
|
+
}
|
|
36713
37651
|
function buildConversationKey(instanceId, personId) {
|
|
36714
37652
|
return `${instanceId}:${personId}`;
|
|
36715
37653
|
}
|
|
@@ -36726,12 +37664,21 @@ class DebounceManager {
|
|
|
36726
37664
|
this.config = config2;
|
|
36727
37665
|
this.callback = callback;
|
|
36728
37666
|
}
|
|
36729
|
-
addMessage(key, message2, from, instanceId) {
|
|
37667
|
+
addMessage(key, message2, from, instanceId, stamp = null) {
|
|
36730
37668
|
if (this.config.mode === "none") {
|
|
36731
|
-
this.callback(key, [message2], from, instanceId);
|
|
37669
|
+
this.callback(key, [message2], from, instanceId, stamp);
|
|
36732
37670
|
return;
|
|
36733
37671
|
}
|
|
36734
37672
|
let window2 = this.windows.get(key);
|
|
37673
|
+
if (window2 && !stampsEqual(window2.stamp, stamp)) {
|
|
37674
|
+
logger3.warn("Debounce window stamp changed \u2014 flushing old window before starting a new one", {
|
|
37675
|
+
key,
|
|
37676
|
+
oldTenant: window2.stamp?.tenantId ?? null,
|
|
37677
|
+
newTenant: stamp?.tenantId ?? null
|
|
37678
|
+
});
|
|
37679
|
+
this.fireWindow(key);
|
|
37680
|
+
window2 = undefined;
|
|
37681
|
+
}
|
|
36735
37682
|
if (!window2) {
|
|
36736
37683
|
window2 = {
|
|
36737
37684
|
messages: [],
|
|
@@ -36739,7 +37686,8 @@ class DebounceManager {
|
|
|
36739
37686
|
lastActivityAt: Date.now(),
|
|
36740
37687
|
timer: null,
|
|
36741
37688
|
from,
|
|
36742
|
-
instanceId
|
|
37689
|
+
instanceId,
|
|
37690
|
+
stamp
|
|
36743
37691
|
};
|
|
36744
37692
|
this.windows.set(key, window2);
|
|
36745
37693
|
}
|
|
@@ -36807,9 +37755,9 @@ class DebounceManager {
|
|
|
36807
37755
|
clearTimeout(window2.timer);
|
|
36808
37756
|
}
|
|
36809
37757
|
this.windows.delete(key);
|
|
36810
|
-
const { messages: messages2, from, instanceId } = window2;
|
|
37758
|
+
const { messages: messages2, from, instanceId, stamp } = window2;
|
|
36811
37759
|
logger3.debug("Debounce window fired", { key, messageCount: messages2.length });
|
|
36812
|
-
this.callback(key, messages2, from, instanceId);
|
|
37760
|
+
this.callback(key, messages2, from, instanceId, stamp);
|
|
36813
37761
|
}
|
|
36814
37762
|
flushAll() {
|
|
36815
37763
|
for (const key of this.windows.keys()) {
|
|
@@ -36860,7 +37808,8 @@ class AutomationEngine {
|
|
|
36860
37808
|
eventBus,
|
|
36861
37809
|
sendMessage: deps.sendMessage,
|
|
36862
37810
|
callAgent: deps.callAgent,
|
|
36863
|
-
staleIdleTimeoutGate: deps.staleIdleTimeoutGate
|
|
37811
|
+
staleIdleTimeoutGate: deps.staleIdleTimeoutGate,
|
|
37812
|
+
releaseIdleTimeoutClaim: deps.releaseIdleTimeoutClaim
|
|
36864
37813
|
};
|
|
36865
37814
|
this.automations = automations.filter((a) => a.enabled);
|
|
36866
37815
|
await this.reconcileSubscriptions();
|
|
@@ -36999,15 +37948,17 @@ class AutomationEngine {
|
|
|
36999
37948
|
}
|
|
37000
37949
|
async shouldSkipStaleIdleTimeout(event) {
|
|
37001
37950
|
if (event.type !== "chat.idle_timeout" || !this.deps.staleIdleTimeoutGate)
|
|
37002
|
-
return false;
|
|
37951
|
+
return { skip: false };
|
|
37003
37952
|
const payload = event.payload;
|
|
37004
37953
|
const chatId = payload?.chatId;
|
|
37005
37954
|
const payloadInstanceId = payload?.instanceId ?? event.metadata.instanceId;
|
|
37006
37955
|
if (!chatId || !payloadInstanceId)
|
|
37007
|
-
return false;
|
|
37956
|
+
return { skip: false };
|
|
37008
37957
|
const eventSequenceIndex = typeof payload?.sequenceIndex === "number" ? payload.sequenceIndex : null;
|
|
37009
37958
|
try {
|
|
37010
|
-
const
|
|
37959
|
+
const classification = classifyEnvelope(event.metadata);
|
|
37960
|
+
const trustedTenantId = classification.world === "tenant" ? classification.tenantId : null;
|
|
37961
|
+
const verdict = await this.deps.staleIdleTimeoutGate(chatId, payloadInstanceId, eventSequenceIndex, trustedTenantId);
|
|
37011
37962
|
if (verdict.skip) {
|
|
37012
37963
|
logger4.info("Skipping stale chat.idle_timeout event", {
|
|
37013
37964
|
eventId: event.id,
|
|
@@ -37016,8 +37967,9 @@ class AutomationEngine {
|
|
|
37016
37967
|
eventSequenceIndex,
|
|
37017
37968
|
reason: verdict.reason ?? "unknown"
|
|
37018
37969
|
});
|
|
37019
|
-
return true;
|
|
37970
|
+
return { skip: true };
|
|
37020
37971
|
}
|
|
37972
|
+
return { skip: false, ...verdict.claimToken ? { claimToken: verdict.claimToken } : {} };
|
|
37021
37973
|
} catch (err2) {
|
|
37022
37974
|
logger4.warn("staleIdleTimeoutGate threw, proceeding without skip", {
|
|
37023
37975
|
eventId: event.id,
|
|
@@ -37025,7 +37977,19 @@ class AutomationEngine {
|
|
|
37025
37977
|
error: err2 instanceof Error ? err2.message : String(err2)
|
|
37026
37978
|
});
|
|
37027
37979
|
}
|
|
37028
|
-
return false;
|
|
37980
|
+
return { skip: false };
|
|
37981
|
+
}
|
|
37982
|
+
async releaseIdleTimeoutClaim(claimToken, event) {
|
|
37983
|
+
if (!this.deps.releaseIdleTimeoutClaim)
|
|
37984
|
+
return;
|
|
37985
|
+
try {
|
|
37986
|
+
await this.deps.releaseIdleTimeoutClaim(claimToken);
|
|
37987
|
+
} catch (err2) {
|
|
37988
|
+
logger4.warn("releaseIdleTimeoutClaim failed", {
|
|
37989
|
+
eventId: event.id,
|
|
37990
|
+
error: err2 instanceof Error ? err2.message : String(err2)
|
|
37991
|
+
});
|
|
37992
|
+
}
|
|
37029
37993
|
}
|
|
37030
37994
|
async handleEvent(event) {
|
|
37031
37995
|
const eventType = event.type;
|
|
@@ -37034,7 +37998,8 @@ class AutomationEngine {
|
|
|
37034
37998
|
if (matchingAutomations.length === 0) {
|
|
37035
37999
|
return;
|
|
37036
38000
|
}
|
|
37037
|
-
|
|
38001
|
+
const gate = await this.shouldSkipStaleIdleTimeout(event);
|
|
38002
|
+
if (gate.skip) {
|
|
37038
38003
|
return;
|
|
37039
38004
|
}
|
|
37040
38005
|
logger4.debug(`Processing event ${eventType} for ${matchingAutomations.length} automation(s)`, {
|
|
@@ -37042,12 +38007,18 @@ class AutomationEngine {
|
|
|
37042
38007
|
instanceId
|
|
37043
38008
|
});
|
|
37044
38009
|
const sortedAutomations = [...matchingAutomations].sort((a, b3) => b3.priority - a.priority);
|
|
37045
|
-
|
|
37046
|
-
|
|
37047
|
-
|
|
37048
|
-
|
|
37049
|
-
|
|
38010
|
+
try {
|
|
38011
|
+
for (const automation of sortedAutomations) {
|
|
38012
|
+
if (automation.debounce && automation.debounce.mode !== "none") {
|
|
38013
|
+
await this.handleDebounced(automation, event);
|
|
38014
|
+
} else {
|
|
38015
|
+
await this.handleImmediate(automation, event);
|
|
38016
|
+
}
|
|
37050
38017
|
}
|
|
38018
|
+
} catch (err2) {
|
|
38019
|
+
if (gate.claimToken)
|
|
38020
|
+
await this.releaseIdleTimeoutClaim(gate.claimToken, event);
|
|
38021
|
+
throw err2;
|
|
37051
38022
|
}
|
|
37052
38023
|
}
|
|
37053
38024
|
async handleDebounced(automation, event) {
|
|
@@ -37068,6 +38039,12 @@ class AutomationEngine {
|
|
|
37068
38039
|
manager.handlePresenceEvent(key, event.type);
|
|
37069
38040
|
return;
|
|
37070
38041
|
}
|
|
38042
|
+
const classification = classifyEnvelope(event.metadata);
|
|
38043
|
+
if (classification.world === "quarantine") {
|
|
38044
|
+
await this.handleImmediate(automation, event);
|
|
38045
|
+
return;
|
|
38046
|
+
}
|
|
38047
|
+
const stamp = classification.world === "tenant" ? { envelopeVersion: classification.envelopeVersion, tenantId: classification.tenantId } : null;
|
|
37071
38048
|
const content = payload.content;
|
|
37072
38049
|
const message2 = {
|
|
37073
38050
|
type: content?.type ?? "unknown",
|
|
@@ -37075,7 +38052,7 @@ class AutomationEngine {
|
|
|
37075
38052
|
timestamp: event.timestamp,
|
|
37076
38053
|
payload
|
|
37077
38054
|
};
|
|
37078
|
-
manager.addMessage(key, message2, from, instanceId);
|
|
38055
|
+
manager.addMessage(key, message2, from, instanceId, stamp);
|
|
37079
38056
|
}
|
|
37080
38057
|
async handleImmediate(automation, event) {
|
|
37081
38058
|
const instanceId = event.metadata.instanceId ?? "global";
|
|
@@ -37083,7 +38060,7 @@ class AutomationEngine {
|
|
|
37083
38060
|
await this.queueExecution(automation, event, context, instanceId);
|
|
37084
38061
|
}
|
|
37085
38062
|
setupDebounceManager(automation) {
|
|
37086
|
-
const callback = async (key, messages2, from, instanceId) => {
|
|
38063
|
+
const callback = async (key, messages2, from, instanceId, stamp) => {
|
|
37087
38064
|
const lastMessage = messages2[messages2.length - 1];
|
|
37088
38065
|
if (!lastMessage) {
|
|
37089
38066
|
logger4.warn("Debounce callback fired with empty messages array", { key });
|
|
@@ -37106,7 +38083,8 @@ class AutomationEngine {
|
|
|
37106
38083
|
payload: lastMessage.payload,
|
|
37107
38084
|
metadata: {
|
|
37108
38085
|
correlationId: generateId(),
|
|
37109
|
-
instanceId
|
|
38086
|
+
instanceId,
|
|
38087
|
+
...stamp ? { envelopeVersion: stamp.envelopeVersion, tenantId: stamp.tenantId } : {}
|
|
37110
38088
|
},
|
|
37111
38089
|
timestamp: Date.now()
|
|
37112
38090
|
};
|
|
@@ -37157,7 +38135,28 @@ class AutomationEngine {
|
|
|
37157
38135
|
async executeAutomation(automation, event, context, queue) {
|
|
37158
38136
|
const start = Date.now();
|
|
37159
38137
|
queue.activeCount++;
|
|
38138
|
+
const classification = classifyEnvelope(event.metadata);
|
|
38139
|
+
const trustedTenantId = classification.world === "tenant" ? classification.tenantId : null;
|
|
37160
38140
|
try {
|
|
38141
|
+
if (classification.world === "quarantine") {
|
|
38142
|
+
logger4.error("Refusing to execute automation for a quarantine-class envelope", {
|
|
38143
|
+
automationId: automation.id,
|
|
38144
|
+
eventId: event.id,
|
|
38145
|
+
reason: classification.reason
|
|
38146
|
+
});
|
|
38147
|
+
const result2 = {
|
|
38148
|
+
automationId: automation.id,
|
|
38149
|
+
automationName: automation.name,
|
|
38150
|
+
eventId: event.id,
|
|
38151
|
+
status: "failed",
|
|
38152
|
+
conditionsMatched: false,
|
|
38153
|
+
actionsExecuted: [],
|
|
38154
|
+
error: `refused quarantine-class envelope (${classification.reason})`,
|
|
38155
|
+
executionTimeMs: Date.now() - start
|
|
38156
|
+
};
|
|
38157
|
+
await this.logExecution(result2, null);
|
|
38158
|
+
return result2;
|
|
38159
|
+
}
|
|
37161
38160
|
const conditionPayload = {
|
|
37162
38161
|
...event.metadata,
|
|
37163
38162
|
...event.payload
|
|
@@ -37173,10 +38172,10 @@ class AutomationEngine {
|
|
|
37173
38172
|
actionsExecuted: [],
|
|
37174
38173
|
executionTimeMs: Date.now() - start
|
|
37175
38174
|
};
|
|
37176
|
-
await this.logExecution(result2);
|
|
38175
|
+
await this.logExecution(result2, trustedTenantId);
|
|
37177
38176
|
return result2;
|
|
37178
38177
|
}
|
|
37179
|
-
const actionsExecuted = await executeActions(automation.actions, context, this.deps);
|
|
38178
|
+
const actionsExecuted = await executeActions(automation.actions, context, this.deps, trustedTenantId);
|
|
37180
38179
|
const allSucceeded = actionsExecuted.every((a) => a.status === "success");
|
|
37181
38180
|
const status = allSucceeded ? "success" : "failed";
|
|
37182
38181
|
const result = {
|
|
@@ -37188,7 +38187,7 @@ class AutomationEngine {
|
|
|
37188
38187
|
actionsExecuted,
|
|
37189
38188
|
executionTimeMs: Date.now() - start
|
|
37190
38189
|
};
|
|
37191
|
-
await this.logExecution(result);
|
|
38190
|
+
await this.logExecution(result, trustedTenantId);
|
|
37192
38191
|
return result;
|
|
37193
38192
|
} catch (error2) {
|
|
37194
38193
|
const errorMessage = error2 instanceof Error ? error2.message : "Unknown error";
|
|
@@ -37202,7 +38201,7 @@ class AutomationEngine {
|
|
|
37202
38201
|
error: errorMessage,
|
|
37203
38202
|
executionTimeMs: Date.now() - start
|
|
37204
38203
|
};
|
|
37205
|
-
await this.logExecution(result);
|
|
38204
|
+
await this.logExecution(result, trustedTenantId);
|
|
37206
38205
|
return result;
|
|
37207
38206
|
} finally {
|
|
37208
38207
|
queue.activeCount--;
|
|
@@ -37215,7 +38214,7 @@ class AutomationEngine {
|
|
|
37215
38214
|
}
|
|
37216
38215
|
}
|
|
37217
38216
|
}
|
|
37218
|
-
async logExecution(result) {
|
|
38217
|
+
async logExecution(result, trustedTenantId = null) {
|
|
37219
38218
|
if (this.logger) {
|
|
37220
38219
|
await this.logger({
|
|
37221
38220
|
automationId: result.automationId,
|
|
@@ -37225,7 +38224,7 @@ class AutomationEngine {
|
|
|
37225
38224
|
actionsExecuted: result.actionsExecuted,
|
|
37226
38225
|
error: result.error,
|
|
37227
38226
|
executionTimeMs: result.executionTimeMs
|
|
37228
|
-
});
|
|
38227
|
+
}, trustedTenantId);
|
|
37229
38228
|
}
|
|
37230
38229
|
logger4.info("Automation executed", {
|
|
37231
38230
|
automationId: result.automationId,
|
|
@@ -37272,6 +38271,7 @@ function createAutomationEngine(config2) {
|
|
|
37272
38271
|
}
|
|
37273
38272
|
var logger4, QueueFullError;
|
|
37274
38273
|
var init_engine = __esm(() => {
|
|
38274
|
+
init_envelope();
|
|
37275
38275
|
init_ids();
|
|
37276
38276
|
init_logger();
|
|
37277
38277
|
init_actions();
|
|
@@ -37432,7 +38432,8 @@ async function armSequence(deps, input) {
|
|
|
37432
38432
|
try {
|
|
37433
38433
|
await deps.eventBus.publish("follow_up.armed", payload, {
|
|
37434
38434
|
instanceId: input.instanceId,
|
|
37435
|
-
...input.agentId ? { agentId: input.agentId } : {}
|
|
38435
|
+
...input.agentId ? { agentId: input.agentId } : {},
|
|
38436
|
+
...input.tenantId ? { tenantId: input.tenantId } : {}
|
|
37436
38437
|
});
|
|
37437
38438
|
} catch (err2) {
|
|
37438
38439
|
deps.logger.warn("follow-up lifecycle: failed to emit follow_up.armed", {
|
|
@@ -37465,7 +38466,8 @@ async function disarmSequence(deps, input) {
|
|
|
37465
38466
|
try {
|
|
37466
38467
|
await deps.eventBus.publish("follow_up.disarmed", payload, {
|
|
37467
38468
|
instanceId: input.instanceId,
|
|
37468
|
-
...input.agentId ? { agentId: input.agentId } : {}
|
|
38469
|
+
...input.agentId ? { agentId: input.agentId } : {},
|
|
38470
|
+
...input.tenantId ? { tenantId: input.tenantId } : {}
|
|
37469
38471
|
});
|
|
37470
38472
|
} catch (err2) {
|
|
37471
38473
|
deps.logger.warn("follow-up lifecycle: failed to emit follow_up.disarmed", {
|
|
@@ -37494,6 +38496,13 @@ function resolveFollowUpConfig(inputs) {
|
|
|
37494
38496
|
function renderSyntheticPrompt(template, context) {
|
|
37495
38497
|
return template.replace(/\{\{\s*minutes\s*\}\}/g, String(context.minutes)).replace(/\{\{\s*sequenceIndex\s*\}\}/g, String(context.sequenceIndex)).replace(/\{\{\s*attemptNumber\s*\}\}/g, String(context.sequenceIndex + 1)).replace(/\{\{\s*totalAttempts\s*\}\}/g, String(context.totalAttempts)).replace(/\{\{\s*chatName\s*\}\}/g, context.chatName ?? "");
|
|
37496
38498
|
}
|
|
38499
|
+
function rowEventMetadata(row) {
|
|
38500
|
+
return {
|
|
38501
|
+
instanceId: row.instanceId,
|
|
38502
|
+
...row.agentId ? { agentId: row.agentId } : {},
|
|
38503
|
+
...row.tenantId ? { tenantId: row.tenantId } : {}
|
|
38504
|
+
};
|
|
38505
|
+
}
|
|
37497
38506
|
async function sweepFollowUps(deps) {
|
|
37498
38507
|
const limit = deps.batchLimit ?? DEFAULT_BATCH_LIMIT;
|
|
37499
38508
|
const clock = deps.now ?? (() => new Date);
|
|
@@ -37557,10 +38566,7 @@ async function processRow(row, now, deps, stats) {
|
|
|
37557
38566
|
syntheticPrompt,
|
|
37558
38567
|
...row.chatName ? { chatName: row.chatName } : {}
|
|
37559
38568
|
};
|
|
37560
|
-
await deps.eventBus.publish("chat.idle_timeout", idlePayload,
|
|
37561
|
-
instanceId: row.instanceId,
|
|
37562
|
-
...row.agentId ? { agentId: row.agentId } : {}
|
|
37563
|
-
});
|
|
38569
|
+
await deps.eventBus.publish("chat.idle_timeout", idlePayload, rowEventMetadata(row));
|
|
37564
38570
|
const firedPayload = {
|
|
37565
38571
|
chatId: row.chatId,
|
|
37566
38572
|
instanceId: row.instanceId,
|
|
@@ -37569,10 +38575,7 @@ async function processRow(row, now, deps, stats) {
|
|
|
37569
38575
|
firedAt: now.getTime(),
|
|
37570
38576
|
syntheticPrompt
|
|
37571
38577
|
};
|
|
37572
|
-
await deps.eventBus.publish("follow_up.fired", firedPayload,
|
|
37573
|
-
instanceId: row.instanceId,
|
|
37574
|
-
...row.agentId ? { agentId: row.agentId } : {}
|
|
37575
|
-
});
|
|
38578
|
+
await deps.eventBus.publish("follow_up.fired", firedPayload, rowEventMetadata(row));
|
|
37576
38579
|
const nextFireAtMs = computeNextFireAt(row.sequenceConfig, row.sequenceIndex, now.getTime());
|
|
37577
38580
|
const nextIndex = row.sequenceIndex + 1;
|
|
37578
38581
|
if (nextFireAtMs === null) {
|
|
@@ -37602,10 +38605,7 @@ async function processRow(row, now, deps, stats) {
|
|
|
37602
38605
|
sequenceIndex: nextIndex,
|
|
37603
38606
|
nextFireAt: nextFireAtMs
|
|
37604
38607
|
};
|
|
37605
|
-
await deps.eventBus.publish("follow_up.armed", armedPayload,
|
|
37606
|
-
instanceId: row.instanceId,
|
|
37607
|
-
...row.agentId ? { agentId: row.agentId } : {}
|
|
37608
|
-
});
|
|
38608
|
+
await deps.eventBus.publish("follow_up.armed", armedPayload, rowEventMetadata(row));
|
|
37609
38609
|
stats.fired += 1;
|
|
37610
38610
|
}
|
|
37611
38611
|
async function disarm(deps, row, reason, now) {
|
|
@@ -37620,10 +38620,7 @@ async function emitDisarmed(deps, row, reason, sequenceIndex) {
|
|
|
37620
38620
|
sequenceIndex,
|
|
37621
38621
|
reason
|
|
37622
38622
|
};
|
|
37623
|
-
await deps.eventBus.publish("follow_up.disarmed", payload,
|
|
37624
|
-
instanceId: row.instanceId,
|
|
37625
|
-
...row.agentId ? { agentId: row.agentId } : {}
|
|
37626
|
-
});
|
|
38623
|
+
await deps.eventBus.publish("follow_up.disarmed", payload, rowEventMetadata(row));
|
|
37627
38624
|
}
|
|
37628
38625
|
async function emitSkipped(deps, row, reason) {
|
|
37629
38626
|
const payload = {
|
|
@@ -37634,10 +38631,7 @@ async function emitSkipped(deps, row, reason) {
|
|
|
37634
38631
|
reason
|
|
37635
38632
|
};
|
|
37636
38633
|
try {
|
|
37637
|
-
await deps.eventBus.publish("follow_up.skipped", payload,
|
|
37638
|
-
instanceId: row.instanceId,
|
|
37639
|
-
...row.agentId ? { agentId: row.agentId } : {}
|
|
37640
|
-
});
|
|
38634
|
+
await deps.eventBus.publish("follow_up.skipped", payload, rowEventMetadata(row));
|
|
37641
38635
|
} catch (err2) {
|
|
37642
38636
|
deps.logger.error("follow-up sweeper: failed to emit follow_up.skipped", {
|
|
37643
38637
|
id: row.id,
|
|
@@ -37874,12 +38868,12 @@ function buildProviderRequestContext(context) {
|
|
|
37874
38868
|
var OMNI_EXECUTION_CONTEXT_EXTENSION_URI = "https://omni.dev/extensions/execution-context/v1";
|
|
37875
38869
|
|
|
37876
38870
|
// ../core/src/providers/trace-context.ts
|
|
37877
|
-
import { createHash as
|
|
38871
|
+
import { createHash as createHash4 } from "crypto";
|
|
37878
38872
|
function isNonZeroHex(value) {
|
|
37879
38873
|
return value.length > 0 && !/^0+$/.test(value);
|
|
37880
38874
|
}
|
|
37881
38875
|
function hashHex(value, length) {
|
|
37882
|
-
return
|
|
38876
|
+
return createHash4("sha256").update(value).digest("hex").slice(0, length);
|
|
37883
38877
|
}
|
|
37884
38878
|
function normalizeTraceId(value) {
|
|
37885
38879
|
const lower = value.toLowerCase();
|
|
@@ -64753,7 +65747,7 @@ var init_a2a_provider = __esm(() => {
|
|
|
64753
65747
|
});
|
|
64754
65748
|
|
|
64755
65749
|
// ../core/src/providers/nats-genie-provider.ts
|
|
64756
|
-
import { createHash as
|
|
65750
|
+
import { createHash as createHash6 } from "crypto";
|
|
64757
65751
|
import { mkdir, writeFile } from "fs/promises";
|
|
64758
65752
|
import { homedir as homedir10 } from "os";
|
|
64759
65753
|
import { join as join16 } from "path";
|
|
@@ -64985,7 +65979,7 @@ class NatsGenieProvider {
|
|
|
64985
65979
|
return metadata;
|
|
64986
65980
|
}
|
|
64987
65981
|
safeHash(value) {
|
|
64988
|
-
return
|
|
65982
|
+
return createHash6("sha256").update(value).digest("hex").slice(0, 12);
|
|
64989
65983
|
}
|
|
64990
65984
|
buildMessage(context) {
|
|
64991
65985
|
let message2 = "";
|
|
@@ -65704,21 +66698,39 @@ __export(exports_src, {
|
|
|
65704
66698
|
updateOpenClawCircuitBreaker: () => updateOpenClawCircuitBreaker,
|
|
65705
66699
|
updateNatsStatus: () => updateNatsStatus,
|
|
65706
66700
|
updateDbPoolMetrics: () => updateDbPoolMetrics,
|
|
66701
|
+
tenantTraceAttributes: () => tenantTraceAttributes,
|
|
66702
|
+
tenantLabelBucketCount: () => tenantLabelBucketCount,
|
|
66703
|
+
tenantEventsProcessed: () => tenantEventsProcessed,
|
|
65707
66704
|
sweepFollowUps: () => sweepFollowUps,
|
|
65708
66705
|
substituteTemplateObject: () => substituteTemplateObject,
|
|
65709
66706
|
substituteTemplate: () => substituteTemplate,
|
|
66707
|
+
stampsEqual: () => stampsEqual,
|
|
66708
|
+
stampTenantEnvelope: () => stampTenantEnvelope,
|
|
65710
66709
|
shouldStoreStage: () => shouldStoreStage,
|
|
66710
|
+
setTenantSecretMasterKey: () => setTenantSecretMasterKey,
|
|
66711
|
+
setEnvelopeTenantResolver: () => setEnvelopeTenantResolver,
|
|
66712
|
+
setEnvelopeInstanceTenantResolver: () => setEnvelopeInstanceTenantResolver,
|
|
66713
|
+
setEgressPolicyResolver: () => setEgressPolicyResolver,
|
|
66714
|
+
sealTenantSecretJson: () => sealTenantSecretJson,
|
|
66715
|
+
sealTenantSecret: () => sealTenantSecret,
|
|
65711
66716
|
scheduledJobRuns: () => scheduledJobRuns,
|
|
65712
66717
|
scheduledJobNextRun: () => scheduledJobNextRun,
|
|
65713
66718
|
scheduledJobDuration: () => scheduledJobDuration,
|
|
65714
66719
|
rootLogger: () => rootLogger,
|
|
65715
66720
|
resolveResetConfig: () => resolveResetConfig,
|
|
66721
|
+
resolvePublishTenantId: () => resolvePublishTenantId,
|
|
66722
|
+
resolveInstanceOwnerTenantId: () => resolveInstanceOwnerTenantId,
|
|
65716
66723
|
resolveFollowUpConfig: () => resolveFollowUpConfig,
|
|
66724
|
+
resolveEgressPolicy: () => resolveEgressPolicy,
|
|
66725
|
+
resolveAmbientTenantId: () => resolveAmbientTenantId,
|
|
66726
|
+
resetTenantLabelConfig: () => resetTenantLabelConfig,
|
|
65717
66727
|
resetScheduler: () => resetScheduler,
|
|
65718
66728
|
resetMetrics: () => resetMetrics,
|
|
65719
66729
|
resetJourneyTracker: () => resetJourneyTracker,
|
|
65720
66730
|
renderSyntheticPrompt: () => renderSyntheticPrompt,
|
|
65721
66731
|
registerSchemas: () => registerSchemas,
|
|
66732
|
+
redactSecrets: () => redactSecrets,
|
|
66733
|
+
recordTenantEventProcessed: () => recordTenantEventProcessed,
|
|
65722
66734
|
recordScheduledJob: () => recordScheduledJob,
|
|
65723
66735
|
recordPayloadOp: () => recordPayloadOp,
|
|
65724
66736
|
recordOpenClawTrigger: () => recordOpenClawTrigger,
|
|
@@ -65742,6 +66754,8 @@ __export(exports_src, {
|
|
|
65742
66754
|
openclawTimeToFirstDelta: () => openclawTimeToFirstDelta,
|
|
65743
66755
|
openclawReconnects: () => openclawReconnects,
|
|
65744
66756
|
openclawCircuitBreakerState: () => openclawCircuitBreakerState,
|
|
66757
|
+
openTenantSecretJson: () => openTenantSecretJson,
|
|
66758
|
+
openTenantSecret: () => openTenantSecret,
|
|
65745
66759
|
ok: () => ok,
|
|
65746
66760
|
natsPublishLatency: () => natsPublishLatency,
|
|
65747
66761
|
natsPendingMessages: () => natsPendingMessages,
|
|
@@ -65750,11 +66764,15 @@ __export(exports_src, {
|
|
|
65750
66764
|
natsConnectionStatus: () => natsConnectionStatus,
|
|
65751
66765
|
matchesPattern: () => matchesPattern,
|
|
65752
66766
|
isValidUuid: () => isValidUuid,
|
|
66767
|
+
isTenantSecretSealingEnabled: () => isTenantSecretSealingEnabled,
|
|
65753
66768
|
isSystemEvent: () => isSystemEvent,
|
|
66769
|
+
isStampableTenantId: () => isStampableTenantId,
|
|
66770
|
+
isSealedSecret: () => isSealedSecret,
|
|
65754
66771
|
isProviderSchemaSupported: () => isProviderSchemaSupported,
|
|
65755
66772
|
isOmniError: () => isOmniError,
|
|
65756
66773
|
isCustomEvent: () => isCustomEvent,
|
|
65757
66774
|
isCoreEvent: () => isCoreEvent,
|
|
66775
|
+
isAllowedClass: () => isAllowedClass,
|
|
65758
66776
|
intervalMinutesForIndex: () => intervalMinutesForIndex,
|
|
65759
66777
|
httpRequests: () => httpRequests,
|
|
65760
66778
|
httpRequestDuration: () => httpRequestDuration,
|
|
@@ -65825,15 +66843,22 @@ __export(exports_src, {
|
|
|
65825
66843
|
createAgUiProvider: () => createAgUiProvider,
|
|
65826
66844
|
createA2AProvider: () => createA2AProvider,
|
|
65827
66845
|
connectEventBus: () => connectEventBus,
|
|
66846
|
+
configureTenantLabelBuckets: () => configureTenantLabelBuckets,
|
|
65828
66847
|
configureLogging: () => configureLogging,
|
|
65829
66848
|
computeNextFireAt: () => computeNextFireAt,
|
|
65830
66849
|
computeInitialFireAt: () => computeInitialFireAt,
|
|
65831
66850
|
compressPayload: () => compressPayload,
|
|
66851
|
+
classifyUrl: () => classifyUrl,
|
|
66852
|
+
classifyResolvedAddress: () => classifyResolvedAddress,
|
|
66853
|
+
classifyEnvelope: () => classifyEnvelope,
|
|
65832
66854
|
checkSessionReset: () => checkSessionReset,
|
|
65833
66855
|
channelSupportsTypingIndicator: () => channelSupportsTypingIndicator,
|
|
65834
66856
|
channelHasMessagingWindow: () => channelHasMessagingWindow,
|
|
66857
|
+
canonicalizeIpv4: () => canonicalizeIpv4,
|
|
65835
66858
|
calculateNextAutoRetryAt: () => calculateNextAutoRetryAt,
|
|
65836
66859
|
calculateBackoffDelay: () => calculateBackoffDelay,
|
|
66860
|
+
buildTenantAuditRecord: () => buildTenantAuditRecord,
|
|
66861
|
+
buildTenantAuditFields: () => buildTenantAuditFields,
|
|
65837
66862
|
buildSubscribePattern: () => buildSubscribePattern,
|
|
65838
66863
|
buildSubject: () => buildSubject,
|
|
65839
66864
|
buildProviderRequestContext: () => buildProviderRequestContext,
|
|
@@ -65841,6 +66866,8 @@ __export(exports_src, {
|
|
|
65841
66866
|
buildOmniEnv: () => buildOmniEnv,
|
|
65842
66867
|
buildConversationKey: () => buildConversationKey,
|
|
65843
66868
|
buildConsumerConfig: () => buildConsumerConfig,
|
|
66869
|
+
brokeredFetch: () => brokeredFetch,
|
|
66870
|
+
boundedTenantLabel: () => boundedTenantLabel,
|
|
65844
66871
|
armSequence: () => armSequence,
|
|
65845
66872
|
appUptime: () => appUptime,
|
|
65846
66873
|
agentStateKey: () => agentStateKey,
|
|
@@ -65854,6 +66881,10 @@ __export(exports_src, {
|
|
|
65854
66881
|
UpdateAgentSchema: () => UpdateAgentSchema,
|
|
65855
66882
|
UpdateAgentRouteSchema: () => UpdateAgentRouteSchema,
|
|
65856
66883
|
TimestampSchema: () => TimestampSchema,
|
|
66884
|
+
TenantSecretUnconfiguredError: () => TenantSecretUnconfiguredError,
|
|
66885
|
+
TenantSecretError: () => TenantSecretError,
|
|
66886
|
+
TenantEgressBroker: () => TenantEgressBroker,
|
|
66887
|
+
TENANTLESS_LABEL: () => TENANTLESS_LABEL,
|
|
65857
66888
|
SystemEventSchemas: () => SystemEventSchemas,
|
|
65858
66889
|
SupersedeModeSchema: () => SupersedeModeSchema,
|
|
65859
66890
|
SubscriptionManager: () => SubscriptionManager,
|
|
@@ -65866,6 +66897,7 @@ __export(exports_src, {
|
|
|
65866
66897
|
STREAM_CONFIGS: () => STREAM_CONFIGS,
|
|
65867
66898
|
SPLIT_DELAY_MODES: () => SPLIT_DELAY_MODES,
|
|
65868
66899
|
SETTING_VALUE_TYPES: () => SETTING_VALUE_TYPES,
|
|
66900
|
+
SECRET_BOX_VERSION: () => SECRET_BOX_VERSION,
|
|
65869
66901
|
RuleTypeSchema: () => RuleTypeSchema,
|
|
65870
66902
|
ReplyFilterModeSchema: () => ReplyFilterModeSchema,
|
|
65871
66903
|
RULE_TYPES: () => RULE_TYPES,
|
|
@@ -65899,6 +66931,7 @@ __export(exports_src, {
|
|
|
65899
66931
|
ListAgentRoutesQuerySchema: () => ListAgentRoutesQuerySchema,
|
|
65900
66932
|
LinkIdentityToAgentSchema: () => LinkIdentityToAgentSchema,
|
|
65901
66933
|
LinkIdentitySchema: () => LinkIdentitySchema,
|
|
66934
|
+
KNOWN_ENVELOPE_VERSIONS: () => KNOWN_ENVELOPE_VERSIONS,
|
|
65902
66935
|
JourneyTracker: () => JourneyTracker,
|
|
65903
66936
|
JobStatusSchema: () => JobStatusSchema,
|
|
65904
66937
|
JOURNEY_STAGES: () => JOURNEY_STAGES,
|
|
@@ -65925,6 +66958,8 @@ __export(exports_src, {
|
|
|
65925
66958
|
EventRegistry: () => EventRegistry,
|
|
65926
66959
|
EventQuerySchema: () => EventQuerySchema,
|
|
65927
66960
|
EmailSchema: () => EmailSchema,
|
|
66961
|
+
EgressLimitError: () => EgressLimitError,
|
|
66962
|
+
EgressBlockedError: () => EgressBlockedError,
|
|
65928
66963
|
ERROR_CODES: () => ERROR_CODES,
|
|
65929
66964
|
ED25519_PKCS8_PREFIX: () => ED25519_PKCS8_PREFIX,
|
|
65930
66965
|
DisarmReasonSchema: () => DisarmReasonSchema,
|
|
@@ -65932,6 +66967,7 @@ __export(exports_src, {
|
|
|
65932
66967
|
DebounceModeSchema: () => DebounceModeSchema,
|
|
65933
66968
|
DebounceManager: () => DebounceManager,
|
|
65934
66969
|
DEFAULT_TYPING_INDICATOR_MS: () => DEFAULT_TYPING_INDICATOR_MS,
|
|
66970
|
+
DEFAULT_TENANT_LABEL_BUCKETS: () => DEFAULT_TENANT_LABEL_BUCKETS,
|
|
65935
66971
|
DEFAULT_STORAGE_CONFIG: () => DEFAULT_STORAGE_CONFIG,
|
|
65936
66972
|
DEFAULT_RETENTION_DAYS: () => DEFAULT_RETENTION_DAYS,
|
|
65937
66973
|
DEFAULT_RESET_CONFIG: () => DEFAULT_RESET_CONFIG,
|
|
@@ -65939,6 +66975,7 @@ __export(exports_src, {
|
|
|
65939
66975
|
DEFAULT_IDLE_MINUTES: () => DEFAULT_IDLE_MINUTES,
|
|
65940
66976
|
DEFAULT_HOOK_TIMEOUT_MS: () => DEFAULT_HOOK_TIMEOUT_MS,
|
|
65941
66977
|
DEFAULT_HOOK_PRIORITY: () => DEFAULT_HOOK_PRIORITY,
|
|
66978
|
+
DEFAULT_EGRESS_LIMITS: () => DEFAULT_EGRESS_LIMITS,
|
|
65942
66979
|
DEFAULT_DAILY_HOUR: () => DEFAULT_DAILY_HOUR,
|
|
65943
66980
|
DEFAULT_CONSUMER_CONFIG: () => DEFAULT_CONSUMER_CONFIG,
|
|
65944
66981
|
DEFAULT_CACHE_CONFIG: () => DEFAULT_CACHE_CONFIG,
|
|
@@ -65960,6 +66997,7 @@ __export(exports_src, {
|
|
|
65960
66997
|
ClaudeCodeAgentProvider: () => ClaudeCodeAgentProvider,
|
|
65961
66998
|
ChannelTypeSchema: () => ChannelTypeSchema,
|
|
65962
66999
|
ChannelError: () => ChannelError,
|
|
67000
|
+
CURRENT_ENVELOPE_VERSION: () => CURRENT_ENVELOPE_VERSION,
|
|
65963
67001
|
CORE_EVENT_TYPES: () => CORE_EVENT_TYPES,
|
|
65964
67002
|
CONTENT_TYPES: () => CONTENT_TYPES,
|
|
65965
67003
|
CONDITION_OPERATORS: () => CONDITION_OPERATORS,
|
|
@@ -66005,12 +67043,15 @@ var init_src2 = __esm(() => {
|
|
|
66005
67043
|
init_errors3();
|
|
66006
67044
|
init_ids();
|
|
66007
67045
|
init_metrics();
|
|
67046
|
+
init_observability();
|
|
67047
|
+
init_secrets();
|
|
66008
67048
|
init_automations();
|
|
66009
67049
|
init_reset();
|
|
66010
67050
|
init_providers();
|
|
66011
67051
|
init_cache();
|
|
66012
67052
|
init_tracing();
|
|
66013
67053
|
init_hooks();
|
|
67054
|
+
init_egress();
|
|
66014
67055
|
});
|
|
66015
67056
|
|
|
66016
67057
|
// ../../node_modules/.bun/drizzle-orm@0.38.4+db1fc555b1037084/node_modules/drizzle-orm/entity.js
|
|
@@ -67648,7 +68689,7 @@ var init_char = __esm(() => {
|
|
|
67648
68689
|
});
|
|
67649
68690
|
|
|
67650
68691
|
// ../../node_modules/.bun/drizzle-orm@0.38.4+db1fc555b1037084/node_modules/drizzle-orm/pg-core/columns/cidr.js
|
|
67651
|
-
function
|
|
68692
|
+
function cidr2(name) {
|
|
67652
68693
|
return new PgCidrBuilder(name ?? "");
|
|
67653
68694
|
}
|
|
67654
68695
|
var PgCidrBuilder, PgCidr;
|
|
@@ -68758,7 +69799,7 @@ function getPgColumnBuilders() {
|
|
|
68758
69799
|
bigserial,
|
|
68759
69800
|
boolean,
|
|
68760
69801
|
char,
|
|
68761
|
-
cidr,
|
|
69802
|
+
cidr: cidr2,
|
|
68762
69803
|
customType,
|
|
68763
69804
|
date,
|
|
68764
69805
|
doublePrecision,
|
|
@@ -73575,15 +74616,6 @@ var init_client3 = __esm(() => {
|
|
|
73575
74616
|
init_schema2();
|
|
73576
74617
|
});
|
|
73577
74618
|
|
|
73578
|
-
// ../db/src/migrate.ts
|
|
73579
|
-
var log19;
|
|
73580
|
-
var init_migrate = __esm(() => {
|
|
73581
|
-
init_src2();
|
|
73582
|
-
init_client3();
|
|
73583
|
-
log19 = createLogger("db:migrate");
|
|
73584
|
-
if (false) {}
|
|
73585
|
-
});
|
|
73586
|
-
|
|
73587
74619
|
// ../db/src/tenancy-ownership.ts
|
|
73588
74620
|
var TENANT_OWNERSHIP_SPECS, TENANT_TABLES, OWNERSHIP_ROOT_TABLES, COMPOSITE_FK_TARGETS, SPLIT_DESTINATIONS, G2_NEW_TABLES;
|
|
73589
74621
|
var init_tenancy_ownership = __esm(() => {
|
|
@@ -73982,8 +75014,23 @@ var init_tenancy_ownership = __esm(() => {
|
|
|
73982
75014
|
];
|
|
73983
75015
|
});
|
|
73984
75016
|
|
|
75017
|
+
// ../db/src/online-ddl.ts
|
|
75018
|
+
var init_online_ddl = __esm(() => {
|
|
75019
|
+
init_tenancy_ownership();
|
|
75020
|
+
});
|
|
75021
|
+
|
|
75022
|
+
// ../db/src/migrate.ts
|
|
75023
|
+
var log19;
|
|
75024
|
+
var init_migrate = __esm(() => {
|
|
75025
|
+
init_src2();
|
|
75026
|
+
init_client3();
|
|
75027
|
+
init_online_ddl();
|
|
75028
|
+
log19 = createLogger("db:migrate");
|
|
75029
|
+
if (false) {}
|
|
75030
|
+
});
|
|
75031
|
+
|
|
73985
75032
|
// ../db/src/tenancy-rls.ts
|
|
73986
|
-
var G1_TENANT_PLANE_TABLES, AUTH_PLANE_READABLE_TABLES, RLS_EXCLUSIONS, RLS_TENANT_TABLES;
|
|
75033
|
+
var G1_TENANT_PLANE_TABLES, AUTH_PLANE_READABLE_TABLES, RLS_EXCLUSIONS, RLS_TENANT_TABLES, TENANT_CONTEXT_FUNCTION = "omni_current_tenant_id", AUTH_PLANE_FUNCTION = "omni_is_auth_plane", AUTH_PLANE_ROW_FUNCTION = "omni_auth_plane_row_visible", TENANCY_FUNCTION_SCHEMA = "public", QUALIFIED_TENANT_CONTEXT_FUNCTION, QUALIFIED_AUTH_PLANE_FUNCTION, QUALIFIED_AUTH_PLANE_ROW_FUNCTION;
|
|
73987
75034
|
var init_tenancy_rls = __esm(() => {
|
|
73988
75035
|
init_tenancy_ownership();
|
|
73989
75036
|
G1_TENANT_PLANE_TABLES = [
|
|
@@ -74012,6 +75059,9 @@ var init_tenancy_rls = __esm(() => {
|
|
|
74012
75059
|
}
|
|
74013
75060
|
];
|
|
74014
75061
|
RLS_TENANT_TABLES = [...TENANT_TABLES, ...G1_TENANT_PLANE_TABLES];
|
|
75062
|
+
QUALIFIED_TENANT_CONTEXT_FUNCTION = `${TENANCY_FUNCTION_SCHEMA}.${TENANT_CONTEXT_FUNCTION}`;
|
|
75063
|
+
QUALIFIED_AUTH_PLANE_FUNCTION = `${TENANCY_FUNCTION_SCHEMA}.${AUTH_PLANE_FUNCTION}`;
|
|
75064
|
+
QUALIFIED_AUTH_PLANE_ROW_FUNCTION = `${TENANCY_FUNCTION_SCHEMA}.${AUTH_PLANE_ROW_FUNCTION}`;
|
|
74015
75065
|
});
|
|
74016
75066
|
|
|
74017
75067
|
// ../db/src/tenancy-roles.ts
|
|
@@ -74040,6 +75090,7 @@ var init_verify_schema = () => {};
|
|
|
74040
75090
|
var init_src3 = __esm(() => {
|
|
74041
75091
|
init_client3();
|
|
74042
75092
|
init_migrate();
|
|
75093
|
+
init_online_ddl();
|
|
74043
75094
|
init_tenancy_rls();
|
|
74044
75095
|
init_tenancy_roles();
|
|
74045
75096
|
init_tenancy_startup();
|
|
@@ -74047,6 +75098,12 @@ var init_src3 = __esm(() => {
|
|
|
74047
75098
|
init_schema2();
|
|
74048
75099
|
});
|
|
74049
75100
|
|
|
75101
|
+
// ../api/src/tenancy/feature-flag.ts
|
|
75102
|
+
function isMultitenancyEnabled(env2 = process.env) {
|
|
75103
|
+
return env2[MULTITENANCY_FLAG_ENV] === "true";
|
|
75104
|
+
}
|
|
75105
|
+
var MULTITENANCY_FLAG_ENV = "OMNI_MULTITENANCY_ENABLED";
|
|
75106
|
+
|
|
74050
75107
|
// ../api/src/cache/memory-cache.ts
|
|
74051
75108
|
class MemoryCache {
|
|
74052
75109
|
store = new Map;
|
|
@@ -74164,7 +75221,12 @@ var init_memory_cache = __esm(() => {
|
|
|
74164
75221
|
});
|
|
74165
75222
|
|
|
74166
75223
|
// ../api/src/cache/cache-keys.ts
|
|
74167
|
-
|
|
75224
|
+
function authCacheTtlMs(legacyTtlMs) {
|
|
75225
|
+
if (!isMultitenancyEnabled())
|
|
75226
|
+
return legacyTtlMs;
|
|
75227
|
+
return Math.min(legacyTtlMs, AUTH_CACHE_INVALIDATION_CEILING_SECONDS * 1000);
|
|
75228
|
+
}
|
|
75229
|
+
var AUTH_CACHE_INVALIDATION_CEILING_SECONDS = 15, CacheKeys, CacheTTL, apiKeyCache, accessCache;
|
|
74168
75230
|
var init_cache_keys = __esm(() => {
|
|
74169
75231
|
init_memory_cache();
|
|
74170
75232
|
CacheKeys = {
|
|
@@ -74275,7 +75337,7 @@ class ApiKeyService {
|
|
|
74275
75337
|
outboundRecipientAllowlist: apiKey.outboundRecipientAllowlist,
|
|
74276
75338
|
profileOverrides: apiKey.profileOverrides ?? null
|
|
74277
75339
|
};
|
|
74278
|
-
await apiKeyCache.set(cacheKey, cachedData, CacheTTL.API_KEY);
|
|
75340
|
+
await apiKeyCache.set(cacheKey, cachedData, authCacheTtlMs(CacheTTL.API_KEY));
|
|
74279
75341
|
this.updateUsageAsync(apiKey.id, ip);
|
|
74280
75342
|
return {
|
|
74281
75343
|
id: apiKey.id,
|
|
@@ -78001,12 +79063,12 @@ var require_envelope = __commonJS((exports) => {
|
|
|
78001
79063
|
function createEnvelope(headers, items = []) {
|
|
78002
79064
|
return [headers, items];
|
|
78003
79065
|
}
|
|
78004
|
-
function addItemToEnvelope(
|
|
78005
|
-
const [headers, items] =
|
|
79066
|
+
function addItemToEnvelope(envelope2, newItem) {
|
|
79067
|
+
const [headers, items] = envelope2;
|
|
78006
79068
|
return [headers, [...items, newItem]];
|
|
78007
79069
|
}
|
|
78008
|
-
function forEachEnvelopeItem(
|
|
78009
|
-
const envelopeItems =
|
|
79070
|
+
function forEachEnvelopeItem(envelope2, callback) {
|
|
79071
|
+
const envelopeItems = envelope2[1];
|
|
78010
79072
|
for (const envelopeItem of envelopeItems) {
|
|
78011
79073
|
const envelopeItemType = envelopeItem[0].type;
|
|
78012
79074
|
const result = callback(envelopeItem, envelopeItemType);
|
|
@@ -78016,8 +79078,8 @@ var require_envelope = __commonJS((exports) => {
|
|
|
78016
79078
|
}
|
|
78017
79079
|
return false;
|
|
78018
79080
|
}
|
|
78019
|
-
function envelopeContainsItemType(
|
|
78020
|
-
return forEachEnvelopeItem(
|
|
79081
|
+
function envelopeContainsItemType(envelope2, types8) {
|
|
79082
|
+
return forEachEnvelopeItem(envelope2, (_2, type) => types8.includes(type));
|
|
78021
79083
|
}
|
|
78022
79084
|
function encodeUTF8(input) {
|
|
78023
79085
|
const carrier$1 = carrier.getSentryCarrier(worldwide.GLOBAL_OBJ);
|
|
@@ -78027,8 +79089,8 @@ var require_envelope = __commonJS((exports) => {
|
|
|
78027
79089
|
const carrier$1 = carrier.getSentryCarrier(worldwide.GLOBAL_OBJ);
|
|
78028
79090
|
return carrier$1.decodePolyfill ? carrier$1.decodePolyfill(input) : new TextDecoder().decode(input);
|
|
78029
79091
|
}
|
|
78030
|
-
function serializeEnvelope(
|
|
78031
|
-
const [envHeaders, items] =
|
|
79092
|
+
function serializeEnvelope(envelope2) {
|
|
79093
|
+
const [envHeaders, items] = envelope2;
|
|
78032
79094
|
let parts = JSON.stringify(envHeaders);
|
|
78033
79095
|
function append(next) {
|
|
78034
79096
|
if (typeof parts === "string") {
|
|
@@ -78165,7 +79227,7 @@ var require_envelope2 = __commonJS((exports) => {
|
|
|
78165
79227
|
var dynamicSamplingContext = require_dynamicSamplingContext();
|
|
78166
79228
|
var beforeSendSpan = require_beforeSendSpan();
|
|
78167
79229
|
var dsn = require_dsn();
|
|
78168
|
-
var
|
|
79230
|
+
var envelope2 = require_envelope();
|
|
78169
79231
|
var shouldIgnoreSpan = require_should_ignore_span();
|
|
78170
79232
|
var spanUtils = require_spanUtils();
|
|
78171
79233
|
function _enhanceEventWithSdkInfo(event, newSdkInfo) {
|
|
@@ -78187,23 +79249,23 @@ var require_envelope2 = __commonJS((exports) => {
|
|
|
78187
79249
|
return event;
|
|
78188
79250
|
}
|
|
78189
79251
|
function createSessionEnvelope(session3, dsn$1, metadata, tunnel) {
|
|
78190
|
-
const sdkInfo =
|
|
79252
|
+
const sdkInfo = envelope2.getSdkMetadataForEnvelopeHeader(metadata);
|
|
78191
79253
|
const envelopeHeaders = {
|
|
78192
79254
|
sent_at: new Date().toISOString(),
|
|
78193
79255
|
...sdkInfo && { sdk: sdkInfo },
|
|
78194
79256
|
...!!tunnel && dsn$1 && { dsn: dsn.dsnToString(dsn$1) }
|
|
78195
79257
|
};
|
|
78196
79258
|
const envelopeItem = "aggregates" in session3 ? [{ type: "sessions" }, session3] : [{ type: "session" }, session3.toJSON()];
|
|
78197
|
-
return
|
|
79259
|
+
return envelope2.createEnvelope(envelopeHeaders, [envelopeItem]);
|
|
78198
79260
|
}
|
|
78199
79261
|
function createEventEnvelope(event, dsn2, metadata, tunnel) {
|
|
78200
|
-
const sdkInfo =
|
|
79262
|
+
const sdkInfo = envelope2.getSdkMetadataForEnvelopeHeader(metadata);
|
|
78201
79263
|
const eventType = event.type && event.type !== "replay_event" ? event.type : "event";
|
|
78202
79264
|
_enhanceEventWithSdkInfo(event, metadata?.sdk);
|
|
78203
|
-
const envelopeHeaders =
|
|
79265
|
+
const envelopeHeaders = envelope2.createEventEnvelopeHeaders(event, sdkInfo, tunnel, dsn2);
|
|
78204
79266
|
delete event.sdkProcessingMetadata;
|
|
78205
79267
|
const eventItem = [{ type: eventType }, event];
|
|
78206
|
-
return
|
|
79268
|
+
return envelope2.createEnvelope(envelopeHeaders, [eventItem]);
|
|
78207
79269
|
}
|
|
78208
79270
|
function createSpanEnvelope(spans, client) {
|
|
78209
79271
|
function dscHasRequiredProps(dsc2) {
|
|
@@ -78239,10 +79301,10 @@ var require_envelope2 = __commonJS((exports) => {
|
|
|
78239
79301
|
for (const span of filteredSpans) {
|
|
78240
79302
|
const spanJson = convertToSpanJSON(span);
|
|
78241
79303
|
if (spanJson) {
|
|
78242
|
-
items.push(
|
|
79304
|
+
items.push(envelope2.createSpanEnvelopeItem(spanJson));
|
|
78243
79305
|
}
|
|
78244
79306
|
}
|
|
78245
|
-
return
|
|
79307
|
+
return envelope2.createEnvelope(headers, items);
|
|
78246
79308
|
}
|
|
78247
79309
|
exports._enhanceEventWithSdkInfo = _enhanceEventWithSdkInfo;
|
|
78248
79310
|
exports.createEventEnvelope = createEventEnvelope;
|
|
@@ -78347,7 +79409,7 @@ var require_sentrySpan = __commonJS((exports) => {
|
|
|
78347
79409
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
78348
79410
|
var currentScopes = require_currentScopes();
|
|
78349
79411
|
var debugBuild = require_debug_build();
|
|
78350
|
-
var
|
|
79412
|
+
var envelope2 = require_envelope2();
|
|
78351
79413
|
var semanticAttributes = require_semanticAttributes();
|
|
78352
79414
|
var debugLogger = require_debug_logger();
|
|
78353
79415
|
var propagationContext = require_propagationContext();
|
|
@@ -78511,7 +79573,7 @@ var require_sentrySpan = __commonJS((exports) => {
|
|
|
78511
79573
|
}
|
|
78512
79574
|
if (this._isStandaloneSpan) {
|
|
78513
79575
|
if (this._sampled) {
|
|
78514
|
-
sendSpanEnvelope(
|
|
79576
|
+
sendSpanEnvelope(envelope2.createSpanEnvelope([this], client));
|
|
78515
79577
|
} else {
|
|
78516
79578
|
debugBuild.DEBUG_BUILD && debugLogger.debug.log("[Tracing] Discarding standalone span because its trace was not chosen to be sampled.");
|
|
78517
79579
|
if (client) {
|
|
@@ -78588,17 +79650,17 @@ var require_sentrySpan = __commonJS((exports) => {
|
|
|
78588
79650
|
function isStandaloneSpan(span) {
|
|
78589
79651
|
return span instanceof SentrySpan && span.isStandaloneSpan();
|
|
78590
79652
|
}
|
|
78591
|
-
function sendSpanEnvelope(
|
|
79653
|
+
function sendSpanEnvelope(envelope3) {
|
|
78592
79654
|
const client = currentScopes.getClient();
|
|
78593
79655
|
if (!client) {
|
|
78594
79656
|
return;
|
|
78595
79657
|
}
|
|
78596
|
-
const spanItems =
|
|
79658
|
+
const spanItems = envelope3[1];
|
|
78597
79659
|
if (!spanItems || spanItems.length === 0) {
|
|
78598
79660
|
client.recordDroppedEvent("before_send", "span");
|
|
78599
79661
|
return;
|
|
78600
79662
|
}
|
|
78601
|
-
client.sendEnvelope(
|
|
79663
|
+
client.sendEnvelope(envelope3);
|
|
78602
79664
|
}
|
|
78603
79665
|
exports.SentrySpan = SentrySpan;
|
|
78604
79666
|
});
|
|
@@ -80656,7 +81718,7 @@ var require_isBrowser = __commonJS((exports) => {
|
|
|
80656
81718
|
var require_envelope3 = __commonJS((exports) => {
|
|
80657
81719
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
80658
81720
|
var dsn = require_dsn();
|
|
80659
|
-
var
|
|
81721
|
+
var envelope2 = require_envelope();
|
|
80660
81722
|
var isBrowser = require_isBrowser();
|
|
80661
81723
|
function createLogContainerEnvelopeItem(items, inferUserData) {
|
|
80662
81724
|
const inferSetting = inferUserData ? "auto" : "never";
|
|
@@ -80686,7 +81748,7 @@ var require_envelope3 = __commonJS((exports) => {
|
|
|
80686
81748
|
if (!!tunnel && !!dsn$1) {
|
|
80687
81749
|
headers.dsn = dsn.dsnToString(dsn$1);
|
|
80688
81750
|
}
|
|
80689
|
-
return
|
|
81751
|
+
return envelope2.createEnvelope(headers, [createLogContainerEnvelopeItem(logs, inferUserData)]);
|
|
80690
81752
|
}
|
|
80691
81753
|
exports.createLogContainerEnvelopeItem = createLogContainerEnvelopeItem;
|
|
80692
81754
|
exports.createLogEnvelope = createLogEnvelope;
|
|
@@ -80707,7 +81769,7 @@ var require_internal = __commonJS((exports) => {
|
|
|
80707
81769
|
var timestampSequence = require_timestampSequence();
|
|
80708
81770
|
var traceInfo = require_trace_info();
|
|
80709
81771
|
var constants = require_constants2();
|
|
80710
|
-
var
|
|
81772
|
+
var envelope2 = require_envelope3();
|
|
80711
81773
|
var MAX_LOG_BUFFER_SIZE = 100;
|
|
80712
81774
|
function setLogAttribute(logAttributes, key, value, setEvenIfPresent = true) {
|
|
80713
81775
|
if (value && (!logAttributes[key] || setEvenIfPresent)) {
|
|
@@ -80805,7 +81867,7 @@ var require_internal = __commonJS((exports) => {
|
|
|
80805
81867
|
return;
|
|
80806
81868
|
}
|
|
80807
81869
|
const clientOptions = client.getOptions();
|
|
80808
|
-
const envelope$1 =
|
|
81870
|
+
const envelope$1 = envelope2.createLogEnvelope(logBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn(), clientOptions.sendDefaultPii);
|
|
80809
81871
|
_getBufferMap().set(client, []);
|
|
80810
81872
|
client.emit("flushLogs");
|
|
80811
81873
|
client.sendEnvelope(envelope$1);
|
|
@@ -80826,7 +81888,7 @@ var require_internal = __commonJS((exports) => {
|
|
|
80826
81888
|
var require_envelope4 = __commonJS((exports) => {
|
|
80827
81889
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
80828
81890
|
var dsn = require_dsn();
|
|
80829
|
-
var
|
|
81891
|
+
var envelope2 = require_envelope();
|
|
80830
81892
|
var isBrowser = require_isBrowser();
|
|
80831
81893
|
function createMetricContainerEnvelopeItem(items, inferUserData) {
|
|
80832
81894
|
const inferSetting = inferUserData ? "auto" : "never";
|
|
@@ -80856,7 +81918,7 @@ var require_envelope4 = __commonJS((exports) => {
|
|
|
80856
81918
|
if (!!tunnel && !!dsn$1) {
|
|
80857
81919
|
headers.dsn = dsn.dsnToString(dsn$1);
|
|
80858
81920
|
}
|
|
80859
|
-
return
|
|
81921
|
+
return envelope2.createEnvelope(headers, [createMetricContainerEnvelopeItem(metrics2, inferUserData)]);
|
|
80860
81922
|
}
|
|
80861
81923
|
exports.createMetricContainerEnvelopeItem = createMetricContainerEnvelopeItem;
|
|
80862
81924
|
exports.createMetricEnvelope = createMetricEnvelope;
|
|
@@ -80875,7 +81937,7 @@ var require_internal2 = __commonJS((exports) => {
|
|
|
80875
81937
|
var time3 = require_time();
|
|
80876
81938
|
var timestampSequence = require_timestampSequence();
|
|
80877
81939
|
var traceInfo = require_trace_info();
|
|
80878
|
-
var
|
|
81940
|
+
var envelope2 = require_envelope4();
|
|
80879
81941
|
var MAX_METRIC_BUFFER_SIZE = 1000;
|
|
80880
81942
|
function setMetricAttribute(metricAttributes, key, value, setEvenIfPresent = true) {
|
|
80881
81943
|
if (value && (setEvenIfPresent || !(key in metricAttributes))) {
|
|
@@ -80976,7 +82038,7 @@ var require_internal2 = __commonJS((exports) => {
|
|
|
80976
82038
|
return;
|
|
80977
82039
|
}
|
|
80978
82040
|
const clientOptions = client.getOptions();
|
|
80979
|
-
const envelope$1 =
|
|
82041
|
+
const envelope$1 = envelope2.createMetricEnvelope(metricBuffer, clientOptions._metadata, clientOptions.tunnel, client.getDsn(), clientOptions.sendDefaultPii);
|
|
80980
82042
|
_getBufferMap().set(client, []);
|
|
80981
82043
|
client.emit("flushMetrics");
|
|
80982
82044
|
client.sendEnvelope(envelope$1);
|
|
@@ -81120,7 +82182,7 @@ var require_base = __commonJS((exports) => {
|
|
|
81120
82182
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
81121
82183
|
var debugBuild = require_debug_build();
|
|
81122
82184
|
var debugLogger = require_debug_logger();
|
|
81123
|
-
var
|
|
82185
|
+
var envelope2 = require_envelope();
|
|
81124
82186
|
var promisebuffer = require_promisebuffer();
|
|
81125
82187
|
var ratelimit = require_ratelimit();
|
|
81126
82188
|
var DEFAULT_TRANSPORT_BUFFER_SIZE = 64;
|
|
@@ -81129,8 +82191,8 @@ var require_base = __commonJS((exports) => {
|
|
|
81129
82191
|
const flush = (timeout) => buffer3.drain(timeout);
|
|
81130
82192
|
function send(envelope$1) {
|
|
81131
82193
|
const filteredEnvelopeItems = [];
|
|
81132
|
-
|
|
81133
|
-
const dataCategory =
|
|
82194
|
+
envelope2.forEachEnvelopeItem(envelope$1, (item, type) => {
|
|
82195
|
+
const dataCategory = envelope2.envelopeItemTypeToDataCategory(type);
|
|
81134
82196
|
if (ratelimit.isRateLimited(rateLimits, dataCategory)) {
|
|
81135
82197
|
options3.recordDroppedEvent("ratelimit_backoff", dataCategory);
|
|
81136
82198
|
} else {
|
|
@@ -81140,17 +82202,17 @@ var require_base = __commonJS((exports) => {
|
|
|
81140
82202
|
if (filteredEnvelopeItems.length === 0) {
|
|
81141
82203
|
return Promise.resolve({});
|
|
81142
82204
|
}
|
|
81143
|
-
const filteredEnvelope =
|
|
82205
|
+
const filteredEnvelope = envelope2.createEnvelope(envelope$1[0], filteredEnvelopeItems);
|
|
81144
82206
|
const recordEnvelopeLoss = (reason) => {
|
|
81145
|
-
if (
|
|
82207
|
+
if (envelope2.envelopeContainsItemType(filteredEnvelope, ["client_report"])) {
|
|
81146
82208
|
debugBuild.DEBUG_BUILD && debugLogger.debug.warn(`Dropping client report. Will not send outcomes (reason: ${reason}).`);
|
|
81147
82209
|
return;
|
|
81148
82210
|
}
|
|
81149
|
-
|
|
81150
|
-
options3.recordDroppedEvent(reason,
|
|
82211
|
+
envelope2.forEachEnvelopeItem(filteredEnvelope, (item, type) => {
|
|
82212
|
+
options3.recordDroppedEvent(reason, envelope2.envelopeItemTypeToDataCategory(type));
|
|
81151
82213
|
});
|
|
81152
82214
|
};
|
|
81153
|
-
const requestTask = () => makeRequest({ body:
|
|
82215
|
+
const requestTask = () => makeRequest({ body: envelope2.serializeEnvelope(filteredEnvelope) }).then((response) => {
|
|
81154
82216
|
if (response.statusCode === 413) {
|
|
81155
82217
|
debugBuild.DEBUG_BUILD && debugLogger.debug.error("Sentry responded with status code 413. Envelope was discarded due to exceeding size limits.");
|
|
81156
82218
|
recordEnvelopeLoss("send_error");
|
|
@@ -81188,7 +82250,7 @@ var require_base = __commonJS((exports) => {
|
|
|
81188
82250
|
// ../../node_modules/.bun/@sentry+core@10.52.0/node_modules/@sentry/core/build/cjs/utils/clientreport.js
|
|
81189
82251
|
var require_clientreport = __commonJS((exports) => {
|
|
81190
82252
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
81191
|
-
var
|
|
82253
|
+
var envelope2 = require_envelope();
|
|
81192
82254
|
var time3 = require_time();
|
|
81193
82255
|
function createClientReportEnvelope(discarded_events, dsn, timestamp3) {
|
|
81194
82256
|
const clientReportItem = [
|
|
@@ -81198,7 +82260,7 @@ var require_clientreport = __commonJS((exports) => {
|
|
|
81198
82260
|
discarded_events
|
|
81199
82261
|
}
|
|
81200
82262
|
];
|
|
81201
|
-
return
|
|
82263
|
+
return envelope2.createEnvelope(dsn ? { dsn } : {}, [clientReportItem]);
|
|
81202
82264
|
}
|
|
81203
82265
|
exports.createClientReportEnvelope = createClientReportEnvelope;
|
|
81204
82266
|
});
|
|
@@ -81283,7 +82345,7 @@ var require_client = __commonJS((exports) => {
|
|
|
81283
82345
|
var constants = require_constants();
|
|
81284
82346
|
var currentScopes = require_currentScopes();
|
|
81285
82347
|
var debugBuild = require_debug_build();
|
|
81286
|
-
var
|
|
82348
|
+
var envelope2 = require_envelope2();
|
|
81287
82349
|
var integration = require_integration();
|
|
81288
82350
|
var internal = require_internal();
|
|
81289
82351
|
var internal$1 = require_internal2();
|
|
@@ -81488,7 +82550,7 @@ var require_client = __commonJS((exports) => {
|
|
|
81488
82550
|
}
|
|
81489
82551
|
sendEvent(event, hint = {}) {
|
|
81490
82552
|
this.emit("beforeSendEvent", event, hint);
|
|
81491
|
-
let env2 =
|
|
82553
|
+
let env2 = envelope2.createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);
|
|
81492
82554
|
for (const attachment of hint.attachments || []) {
|
|
81493
82555
|
env2 = envelope$1.addItemToEnvelope(env2, envelope$1.createAttachmentEnvelopeItem(attachment));
|
|
81494
82556
|
}
|
|
@@ -81514,7 +82576,7 @@ var require_client = __commonJS((exports) => {
|
|
|
81514
82576
|
session4.environment = session4.environment || clientEnvironmentOption;
|
|
81515
82577
|
}
|
|
81516
82578
|
this.emit("beforeSendSession", session4);
|
|
81517
|
-
const env2 =
|
|
82579
|
+
const env2 = envelope2.createSessionEnvelope(session4, this._dsn, this._options._metadata, this._options.tunnel);
|
|
81518
82580
|
this.sendEnvelope(env2);
|
|
81519
82581
|
}
|
|
81520
82582
|
recordDroppedEvent(reason, category, count = 1) {
|
|
@@ -81538,11 +82600,11 @@ var require_client = __commonJS((exports) => {
|
|
|
81538
82600
|
callbacks.forEach((callback) => callback(...rest));
|
|
81539
82601
|
}
|
|
81540
82602
|
}
|
|
81541
|
-
async sendEnvelope(
|
|
81542
|
-
this.emit("beforeEnvelope",
|
|
82603
|
+
async sendEnvelope(envelope3) {
|
|
82604
|
+
this.emit("beforeEnvelope", envelope3);
|
|
81543
82605
|
if (this._isEnabled() && this._transport) {
|
|
81544
82606
|
try {
|
|
81545
|
-
return await this._transport.send(
|
|
82607
|
+
return await this._transport.send(envelope3);
|
|
81546
82608
|
} catch (reason) {
|
|
81547
82609
|
debugBuild.DEBUG_BUILD && debugLogger.debug.error("Error while sending envelope:", reason);
|
|
81548
82610
|
return {};
|
|
@@ -81753,8 +82815,8 @@ Reason: ${reason}`);
|
|
|
81753
82815
|
return;
|
|
81754
82816
|
}
|
|
81755
82817
|
debugBuild.DEBUG_BUILD && debugLogger.debug.log("Sending outcomes:", outcomes);
|
|
81756
|
-
const
|
|
81757
|
-
this.sendEnvelope(
|
|
82818
|
+
const envelope3 = clientreport.createClientReportEnvelope(outcomes, this._options.tunnel && dsn.dsnToString(this._dsn));
|
|
82819
|
+
this.sendEnvelope(envelope3);
|
|
81758
82820
|
}
|
|
81759
82821
|
}
|
|
81760
82822
|
function getDataCategoryByType(type) {
|
|
@@ -81891,7 +82953,7 @@ Reason: ${reason}`);
|
|
|
81891
82953
|
var require_checkin = __commonJS((exports) => {
|
|
81892
82954
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
81893
82955
|
var dsn = require_dsn();
|
|
81894
|
-
var
|
|
82956
|
+
var envelope2 = require_envelope();
|
|
81895
82957
|
function createCheckInEnvelope(checkIn, dynamicSamplingContext, metadata, tunnel, dsn$1) {
|
|
81896
82958
|
const headers = {
|
|
81897
82959
|
sent_at: new Date().toISOString()
|
|
@@ -81909,7 +82971,7 @@ var require_checkin = __commonJS((exports) => {
|
|
|
81909
82971
|
headers.trace = dynamicSamplingContext;
|
|
81910
82972
|
}
|
|
81911
82973
|
const item = createCheckInEnvelopeItem(checkIn);
|
|
81912
|
-
return
|
|
82974
|
+
return envelope2.createEnvelope(headers, [item]);
|
|
81913
82975
|
}
|
|
81914
82976
|
function createCheckInEnvelopeItem(checkIn) {
|
|
81915
82977
|
const checkInHeaders = {
|
|
@@ -82162,9 +83224,9 @@ var require_server_runtime_client = __commonJS((exports) => {
|
|
|
82162
83224
|
trace: traceContext
|
|
82163
83225
|
};
|
|
82164
83226
|
}
|
|
82165
|
-
const
|
|
83227
|
+
const envelope2 = checkin.createCheckInEnvelope(serializedCheckIn, dynamicSamplingContext, this.getSdkMetadata(), tunnel, this.getDsn());
|
|
82166
83228
|
debugBuild.DEBUG_BUILD && debugLogger.debug.log("Sending checkin:", checkIn.monitorSlug, checkIn.status);
|
|
82167
|
-
this.sendEnvelope(
|
|
83229
|
+
this.sendEnvelope(envelope2);
|
|
82168
83230
|
return id;
|
|
82169
83231
|
}
|
|
82170
83232
|
registerCleanup(callback) {
|
|
@@ -82263,7 +83325,7 @@ var require_offline = __commonJS((exports) => {
|
|
|
82263
83325
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
82264
83326
|
var debugBuild = require_debug_build();
|
|
82265
83327
|
var debugLogger = require_debug_logger();
|
|
82266
|
-
var
|
|
83328
|
+
var envelope2 = require_envelope();
|
|
82267
83329
|
var ratelimit = require_ratelimit();
|
|
82268
83330
|
var timer2 = require_timer();
|
|
82269
83331
|
var MIN_DELAY = 100;
|
|
@@ -82282,7 +83344,7 @@ var require_offline = __commonJS((exports) => {
|
|
|
82282
83344
|
let retryDelay = START_DELAY;
|
|
82283
83345
|
let flushTimer;
|
|
82284
83346
|
function shouldQueue(env2, error2, retryDelay2) {
|
|
82285
|
-
if (
|
|
83347
|
+
if (envelope2.envelopeContainsItemType(env2, ["client_report"])) {
|
|
82286
83348
|
return false;
|
|
82287
83349
|
}
|
|
82288
83350
|
if (options3.shouldStore) {
|
|
@@ -82314,7 +83376,7 @@ var require_offline = __commonJS((exports) => {
|
|
|
82314
83376
|
retryDelay = Math.min(retryDelay * 2, MAX_DELAY);
|
|
82315
83377
|
}
|
|
82316
83378
|
async function send(envelope$1, isRetry = false) {
|
|
82317
|
-
if (!isRetry &&
|
|
83379
|
+
if (!isRetry && envelope2.envelopeContainsItemType(envelope$1, ["replay_event", "replay_recording"])) {
|
|
82318
83380
|
await store.push(envelope$1);
|
|
82319
83381
|
flushIn(MIN_DELAY);
|
|
82320
83382
|
return {};
|
|
@@ -82377,11 +83439,11 @@ var require_multiplexed = __commonJS((exports) => {
|
|
|
82377
83439
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
82378
83440
|
var api = require_api();
|
|
82379
83441
|
var dsn = require_dsn();
|
|
82380
|
-
var
|
|
83442
|
+
var envelope2 = require_envelope();
|
|
82381
83443
|
var MULTIPLEXED_TRANSPORT_EXTRA_KEY = "MULTIPLEXED_TRANSPORT_EXTRA_KEY";
|
|
82382
83444
|
function eventFromEnvelope(env2, types8) {
|
|
82383
83445
|
let event;
|
|
82384
|
-
|
|
83446
|
+
envelope2.forEachEnvelopeItem(env2, (item, type) => {
|
|
82385
83447
|
if (types8.includes(type)) {
|
|
82386
83448
|
event = Array.isArray(item) ? item[1] : undefined;
|
|
82387
83449
|
}
|
|
@@ -82394,18 +83456,18 @@ var require_multiplexed = __commonJS((exports) => {
|
|
|
82394
83456
|
const transport = createTransport(options3);
|
|
82395
83457
|
return {
|
|
82396
83458
|
...transport,
|
|
82397
|
-
send: async (
|
|
82398
|
-
const event = eventFromEnvelope(
|
|
83459
|
+
send: async (envelope3) => {
|
|
83460
|
+
const event = eventFromEnvelope(envelope3, ["event", "transaction", "profile", "replay_event"]);
|
|
82399
83461
|
if (event) {
|
|
82400
83462
|
event.release = release;
|
|
82401
83463
|
}
|
|
82402
|
-
return transport.send(
|
|
83464
|
+
return transport.send(envelope3);
|
|
82403
83465
|
}
|
|
82404
83466
|
};
|
|
82405
83467
|
};
|
|
82406
83468
|
}
|
|
82407
83469
|
function overrideDsn(envelope$1, dsn2) {
|
|
82408
|
-
return
|
|
83470
|
+
return envelope2.createEnvelope(dsn2 ? {
|
|
82409
83471
|
...envelope$1[0],
|
|
82410
83472
|
dsn: dsn2
|
|
82411
83473
|
} : envelope$1[0], envelope$1[1]);
|
|
@@ -82435,12 +83497,12 @@ var require_multiplexed = __commonJS((exports) => {
|
|
|
82435
83497
|
}
|
|
82436
83498
|
return [dsn$1, transport];
|
|
82437
83499
|
}
|
|
82438
|
-
async function send(
|
|
83500
|
+
async function send(envelope3) {
|
|
82439
83501
|
function getEvent(types8) {
|
|
82440
83502
|
const eventTypes2 = types8?.length ? types8 : ["event"];
|
|
82441
|
-
return eventFromEnvelope(
|
|
83503
|
+
return eventFromEnvelope(envelope3, eventTypes2);
|
|
82442
83504
|
}
|
|
82443
|
-
const transports = actualMatcher({ envelope:
|
|
83505
|
+
const transports = actualMatcher({ envelope: envelope3, getEvent }).map((result) => {
|
|
82444
83506
|
if (typeof result === "string") {
|
|
82445
83507
|
return getTransport(result, undefined);
|
|
82446
83508
|
} else {
|
|
@@ -82448,7 +83510,7 @@ var require_multiplexed = __commonJS((exports) => {
|
|
|
82448
83510
|
}
|
|
82449
83511
|
}).filter((t) => !!t);
|
|
82450
83512
|
const transportsWithFallback = transports.length ? transports : [["", fallbackTransport]];
|
|
82451
|
-
const results = await Promise.all(transportsWithFallback.map(([dsn2, transport]) => transport.send(overrideDsn(
|
|
83513
|
+
const results = await Promise.all(transportsWithFallback.map(([dsn2, transport]) => transport.send(overrideDsn(envelope3, dsn2))));
|
|
82452
83514
|
return results[0];
|
|
82453
83515
|
}
|
|
82454
83516
|
async function flush(timeout) {
|
|
@@ -82565,7 +83627,7 @@ var require_tunnel = __commonJS((exports) => {
|
|
|
82565
83627
|
var api = require_api();
|
|
82566
83628
|
var debugLogger = require_debug_logger();
|
|
82567
83629
|
var dsn = require_dsn();
|
|
82568
|
-
var
|
|
83630
|
+
var envelope2 = require_envelope();
|
|
82569
83631
|
async function handleTunnelRequest(options3) {
|
|
82570
83632
|
const { request, allowedDsns } = options3;
|
|
82571
83633
|
if (allowedDsns.length === 0) {
|
|
@@ -82574,7 +83636,7 @@ var require_tunnel = __commonJS((exports) => {
|
|
|
82574
83636
|
const body = new Uint8Array(await request.arrayBuffer());
|
|
82575
83637
|
let envelopeHeader;
|
|
82576
83638
|
try {
|
|
82577
|
-
[envelopeHeader] =
|
|
83639
|
+
[envelopeHeader] = envelope2.parseEnvelope(body);
|
|
82578
83640
|
} catch {
|
|
82579
83641
|
return new Response("Invalid envelope", { status: 400 });
|
|
82580
83642
|
}
|
|
@@ -83439,13 +84501,13 @@ var require_moduleMetadata = __commonJS((exports) => {
|
|
|
83439
84501
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
83440
84502
|
var integration = require_integration();
|
|
83441
84503
|
var metadata = require_metadata();
|
|
83442
|
-
var
|
|
84504
|
+
var envelope2 = require_envelope();
|
|
83443
84505
|
var moduleMetadataIntegration = integration.defineIntegration(() => {
|
|
83444
84506
|
return {
|
|
83445
84507
|
name: "ModuleMetadata",
|
|
83446
84508
|
setup(client) {
|
|
83447
84509
|
client.on("beforeEnvelope", (envelope$1) => {
|
|
83448
|
-
|
|
84510
|
+
envelope2.forEachEnvelopeItem(envelope$1, (item, type) => {
|
|
83449
84511
|
if (type === "event") {
|
|
83450
84512
|
const event = Array.isArray(item) ? item[1] : undefined;
|
|
83451
84513
|
if (event) {
|
|
@@ -83541,7 +84603,7 @@ var require_getIpAddress = __commonJS((exports) => {
|
|
|
83541
84603
|
}
|
|
83542
84604
|
return acc.concat(val);
|
|
83543
84605
|
}, []);
|
|
83544
|
-
const ipAddress = flattenedHeaderValues.find((ip) => ip !== null &&
|
|
84606
|
+
const ipAddress = flattenedHeaderValues.find((ip) => ip !== null && isIP3(ip));
|
|
83545
84607
|
return ipAddress || null;
|
|
83546
84608
|
}
|
|
83547
84609
|
function parseForwardedHeader(value) {
|
|
@@ -83555,7 +84617,7 @@ var require_getIpAddress = __commonJS((exports) => {
|
|
|
83555
84617
|
}
|
|
83556
84618
|
return null;
|
|
83557
84619
|
}
|
|
83558
|
-
function
|
|
84620
|
+
function isIP3(str) {
|
|
83559
84621
|
const regex2 = /(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)/;
|
|
83560
84622
|
return regex2.test(str);
|
|
83561
84623
|
}
|
|
@@ -85416,14 +86478,14 @@ var require_third_party_errors_filter = __commonJS((exports) => {
|
|
|
85416
86478
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
85417
86479
|
var integration = require_integration();
|
|
85418
86480
|
var metadata = require_metadata();
|
|
85419
|
-
var
|
|
86481
|
+
var envelope2 = require_envelope();
|
|
85420
86482
|
var stacktrace = require_stacktrace();
|
|
85421
86483
|
var thirdPartyErrorFilterIntegration = integration.defineIntegration((options3) => {
|
|
85422
86484
|
return {
|
|
85423
86485
|
name: "ThirdPartyErrorsFilter",
|
|
85424
86486
|
setup(client) {
|
|
85425
86487
|
client.on("beforeEnvelope", (envelope$1) => {
|
|
85426
|
-
|
|
86488
|
+
envelope2.forEachEnvelopeItem(envelope$1, (item, type) => {
|
|
85427
86489
|
if (type === "event") {
|
|
85428
86490
|
const event = Array.isArray(item) ? item[1] : undefined;
|
|
85429
86491
|
if (event) {
|
|
@@ -91199,13 +92261,13 @@ var require_langgraph = __commonJS((exports) => {
|
|
|
91199
92261
|
var require_envelope5 = __commonJS((exports) => {
|
|
91200
92262
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
91201
92263
|
var dsn = require_dsn();
|
|
91202
|
-
var
|
|
92264
|
+
var envelope2 = require_envelope();
|
|
91203
92265
|
var isBrowser = require_isBrowser();
|
|
91204
92266
|
function createStreamedSpanEnvelope(serializedSpans, dsc, client) {
|
|
91205
92267
|
const options3 = client.getOptions();
|
|
91206
92268
|
const dsn$1 = client.getDsn();
|
|
91207
92269
|
const tunnel = options3.tunnel;
|
|
91208
|
-
const sdk =
|
|
92270
|
+
const sdk = envelope2.getSdkMetadataForEnvelopeHeader(options3._metadata);
|
|
91209
92271
|
const headers = {
|
|
91210
92272
|
sent_at: new Date().toISOString(),
|
|
91211
92273
|
...dscHasRequiredProps(dsc) && { trace: dsc },
|
|
@@ -91223,7 +92285,7 @@ var require_envelope5 = __commonJS((exports) => {
|
|
|
91223
92285
|
items: serializedSpans
|
|
91224
92286
|
}
|
|
91225
92287
|
];
|
|
91226
|
-
return
|
|
92288
|
+
return envelope2.createEnvelope(headers, [spanContainer]);
|
|
91227
92289
|
}
|
|
91228
92290
|
function dscHasRequiredProps(dsc) {
|
|
91229
92291
|
return !!dsc.trace_id && !!dsc.public_key;
|
|
@@ -91257,7 +92319,7 @@ var require_spanBuffer = __commonJS((exports) => {
|
|
|
91257
92319
|
var debugLogger = require_debug_logger();
|
|
91258
92320
|
var timer2 = require_timer();
|
|
91259
92321
|
var dynamicSamplingContext = require_dynamicSamplingContext();
|
|
91260
|
-
var
|
|
92322
|
+
var envelope2 = require_envelope5();
|
|
91261
92323
|
var estimateSize = require_estimateSize();
|
|
91262
92324
|
var MAX_SPANS_PER_ENVELOPE = 1000;
|
|
91263
92325
|
var MAX_TRACE_WEIGHT_IN_BYTES = 5000000;
|
|
@@ -91329,7 +92391,7 @@ var require_spanBuffer = __commonJS((exports) => {
|
|
|
91329
92391
|
const { _segmentSpan, ...cleanSpanJSON } = spanJSON;
|
|
91330
92392
|
return cleanSpanJSON;
|
|
91331
92393
|
});
|
|
91332
|
-
const envelope$1 =
|
|
92394
|
+
const envelope$1 = envelope2.createStreamedSpanEnvelope(cleanedSpans, dsc, this._client);
|
|
91333
92395
|
debugBuild.DEBUG_BUILD && debugLogger.debug.log(`Sending span envelope for trace ${traceId} with ${cleanedSpans.length} spans`);
|
|
91334
92396
|
this._client.sendEnvelope(envelope$1).then(null, (reason) => {
|
|
91335
92397
|
debugBuild.DEBUG_BUILD && debugLogger.debug.error("Error while sending streamed span envelope:", reason);
|
|
@@ -92163,7 +93225,7 @@ var require_cjs = __commonJS((exports) => {
|
|
|
92163
93225
|
var time3 = require_time();
|
|
92164
93226
|
var tracing2 = require_tracing();
|
|
92165
93227
|
var env2 = require_env();
|
|
92166
|
-
var
|
|
93228
|
+
var envelope2 = require_envelope();
|
|
92167
93229
|
var clientreport = require_clientreport();
|
|
92168
93230
|
var ratelimit = require_ratelimit();
|
|
92169
93231
|
var baggage = require_baggage();
|
|
@@ -92535,17 +93597,17 @@ var require_cjs = __commonJS((exports) => {
|
|
|
92535
93597
|
exports.shouldContinueTrace = tracing2.shouldContinueTrace;
|
|
92536
93598
|
exports.getSDKSource = env2.getSDKSource;
|
|
92537
93599
|
exports.isBrowserBundle = env2.isBrowserBundle;
|
|
92538
|
-
exports.addItemToEnvelope =
|
|
92539
|
-
exports.createAttachmentEnvelopeItem =
|
|
92540
|
-
exports.createEnvelope =
|
|
92541
|
-
exports.createEventEnvelopeHeaders =
|
|
92542
|
-
exports.createSpanEnvelopeItem =
|
|
92543
|
-
exports.envelopeContainsItemType =
|
|
92544
|
-
exports.envelopeItemTypeToDataCategory =
|
|
92545
|
-
exports.forEachEnvelopeItem =
|
|
92546
|
-
exports.getSdkMetadataForEnvelopeHeader =
|
|
92547
|
-
exports.parseEnvelope =
|
|
92548
|
-
exports.serializeEnvelope =
|
|
93600
|
+
exports.addItemToEnvelope = envelope2.addItemToEnvelope;
|
|
93601
|
+
exports.createAttachmentEnvelopeItem = envelope2.createAttachmentEnvelopeItem;
|
|
93602
|
+
exports.createEnvelope = envelope2.createEnvelope;
|
|
93603
|
+
exports.createEventEnvelopeHeaders = envelope2.createEventEnvelopeHeaders;
|
|
93604
|
+
exports.createSpanEnvelopeItem = envelope2.createSpanEnvelopeItem;
|
|
93605
|
+
exports.envelopeContainsItemType = envelope2.envelopeContainsItemType;
|
|
93606
|
+
exports.envelopeItemTypeToDataCategory = envelope2.envelopeItemTypeToDataCategory;
|
|
93607
|
+
exports.forEachEnvelopeItem = envelope2.forEachEnvelopeItem;
|
|
93608
|
+
exports.getSdkMetadataForEnvelopeHeader = envelope2.getSdkMetadataForEnvelopeHeader;
|
|
93609
|
+
exports.parseEnvelope = envelope2.parseEnvelope;
|
|
93610
|
+
exports.serializeEnvelope = envelope2.serializeEnvelope;
|
|
92549
93611
|
exports.createClientReportEnvelope = clientreport.createClientReportEnvelope;
|
|
92550
93612
|
exports.DEFAULT_RETRY_AFTER = ratelimit.DEFAULT_RETRY_AFTER;
|
|
92551
93613
|
exports.disabledUntil = ratelimit.disabledUntil;
|
|
@@ -104387,12 +105449,12 @@ var require_spotlight = __commonJS((exports) => {
|
|
|
104387
105449
|
return;
|
|
104388
105450
|
}
|
|
104389
105451
|
let failedRequests = 0;
|
|
104390
|
-
client.on("beforeEnvelope", (
|
|
105452
|
+
client.on("beforeEnvelope", (envelope2) => {
|
|
104391
105453
|
if (failedRequests > 3) {
|
|
104392
105454
|
core.debug.warn("[Spotlight] Disabled Sentry -> Spotlight integration due to too many failed requests");
|
|
104393
105455
|
return;
|
|
104394
105456
|
}
|
|
104395
|
-
const serializedEnvelope = core.serializeEnvelope(
|
|
105457
|
+
const serializedEnvelope = core.serializeEnvelope(envelope2);
|
|
104396
105458
|
core.suppressTracing(() => {
|
|
104397
105459
|
const req = http.request({
|
|
104398
105460
|
method: "POST",
|
|
@@ -115790,16 +116852,16 @@ var require_tracingChannel = __commonJS((exports) => {
|
|
|
115790
116852
|
var debugBuild = require_debug_build_ntZrglYX();
|
|
115791
116853
|
function tracingChannel(channelNameOrInstance, transformStart) {
|
|
115792
116854
|
const channel2 = node_diagnostics_channel.tracingChannel(channelNameOrInstance);
|
|
115793
|
-
let
|
|
116855
|
+
let lookup2;
|
|
115794
116856
|
try {
|
|
115795
116857
|
const contextManager = api.context._getContextManager();
|
|
115796
|
-
|
|
116858
|
+
lookup2 = contextManager.getAsyncLocalStorageLookup();
|
|
115797
116859
|
} catch {}
|
|
115798
|
-
if (!
|
|
116860
|
+
if (!lookup2) {
|
|
115799
116861
|
debugBuild.DEBUG_BUILD && core.logger.warn("[TracingChannel] Could not access OpenTelemetry AsyncLocalStorage, context propagation will not work.");
|
|
115800
116862
|
return channel2;
|
|
115801
116863
|
}
|
|
115802
|
-
const otelStorage =
|
|
116864
|
+
const otelStorage = lookup2.asyncLocalStorage;
|
|
115803
116865
|
channel2.start.bindStore(otelStorage, (data2) => {
|
|
115804
116866
|
const span = transformStart(data2);
|
|
115805
116867
|
data2._sentrySpan = span;
|
|
@@ -126250,7 +127312,7 @@ import { fileURLToPath } from "url";
|
|
|
126250
127312
|
// package.json
|
|
126251
127313
|
var package_default = {
|
|
126252
127314
|
name: "@automagik/omni",
|
|
126253
|
-
version: "2.
|
|
127315
|
+
version: "2.260728.2",
|
|
126254
127316
|
description: "LLM-optimized CLI for Omni",
|
|
126255
127317
|
type: "module",
|
|
126256
127318
|
bin: {
|
|
@@ -134834,7 +135896,6 @@ async function promptAdminConfirmation() {
|
|
|
134834
135896
|
async function handleAdminCreate(options) {
|
|
134835
135897
|
if (process.env.OMNI_DB_ENFORCEMENT === "on") {
|
|
134836
135898
|
error("refusing to create an admin (god) key while OMNI_DB_ENFORCEMENT=on \u2014 a plaintext data-plane key with " + "every scope is not an admissible bootstrap under enforcement. Create a platform-class credential and " + "delegate a tenant-scoped key from it instead.", undefined, 1);
|
|
134837
|
-
return;
|
|
134838
135899
|
}
|
|
134839
135900
|
if (!process.stdin.isTTY) {
|
|
134840
135901
|
error("admin keys require a TTY \u2014 run this command interactively", undefined, 1);
|