@malloy-publisher/server 0.0.241 → 0.0.242
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/server.mjs +39 -8
- package/package.json +1 -1
package/dist/server.mjs
CHANGED
|
@@ -269317,7 +269317,7 @@ class QueryController {
|
|
|
269317
269317
|
constructor(environmentStore) {
|
|
269318
269318
|
this.environmentStore = environmentStore;
|
|
269319
269319
|
}
|
|
269320
|
-
async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata) {
|
|
269320
|
+
async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata, bypassAuthorize) {
|
|
269321
269321
|
let requestMetadata;
|
|
269322
269322
|
let queryClass;
|
|
269323
269323
|
try {
|
|
@@ -269357,7 +269357,7 @@ class QueryController {
|
|
|
269357
269357
|
return null;
|
|
269358
269358
|
}
|
|
269359
269359
|
}
|
|
269360
|
-
}, compactJson ? "compact" : "full"), getQueryTimeoutMs());
|
|
269360
|
+
}, compactJson ? "compact" : "full", bypassAuthorize), getQueryTimeoutMs());
|
|
269361
269361
|
const renderLogs = import_render_validator.validateRenderTags(result);
|
|
269362
269362
|
return {
|
|
269363
269363
|
result: serializedResult,
|
|
@@ -277169,12 +277169,19 @@ function unwrapQuotedExpression(body) {
|
|
|
277169
277169
|
|
|
277170
277170
|
// src/authorize_metrics.ts
|
|
277171
277171
|
var guardRejectionCounter = null;
|
|
277172
|
+
var bypassCounter = null;
|
|
277172
277173
|
function recordAuthorizeGuardRejection(field) {
|
|
277173
277174
|
guardRejectionCounter ??= publisherMeter().createCounter("publisher_authorize_guard_rejected_total", {
|
|
277174
277175
|
description: "Requests rejected with 400 for declaring an `#(authorize)` annotation in caller-submitted Malloy text. Label: field ('query'|'source_name'|'query_name'|'compile_source')."
|
|
277175
277176
|
});
|
|
277176
277177
|
guardRejectionCounter.add(1, { field });
|
|
277177
277178
|
}
|
|
277179
|
+
function recordAuthorizeBypass(entryPoint) {
|
|
277180
|
+
bypassCounter ??= publisherMeter().createCounter("publisher_authorize_bypass_total", {
|
|
277181
|
+
description: "Gate evaluations skipped because the request carried an authorize bypass (private data-management path). Label: entry_point ('source'|'runnable'). Any nonzero value on a path that should not use the bypass is a finding — see the paired `authorize bypass` audit log line for org/package/model/source."
|
|
277182
|
+
});
|
|
277183
|
+
bypassCounter.add(1, { entry_point: entryPoint });
|
|
277184
|
+
}
|
|
277178
277185
|
|
|
277179
277186
|
// src/service/environment.ts
|
|
277180
277187
|
init_logger();
|
|
@@ -278733,7 +278740,11 @@ class Model {
|
|
|
278733
278740
|
}
|
|
278734
278741
|
return this.fileLevelAuthorize;
|
|
278735
278742
|
}
|
|
278736
|
-
async assertAuthorized(sourceName, givens) {
|
|
278743
|
+
async assertAuthorized(sourceName, givens, bypassAuthorize = false) {
|
|
278744
|
+
if (bypassAuthorize) {
|
|
278745
|
+
this.noteAuthorizeBypass("source", sourceName);
|
|
278746
|
+
return;
|
|
278747
|
+
}
|
|
278737
278748
|
const gates = sourceName ? this.entryPointGatesBySource.get(sourceName) : undefined;
|
|
278738
278749
|
if (gates) {
|
|
278739
278750
|
for (const { label, exprs, selfContained, ambientPrefix } of gates) {
|
|
@@ -278743,6 +278754,15 @@ class Model {
|
|
|
278743
278754
|
}
|
|
278744
278755
|
await this.assertAuthorizedExprs(sourceName ?? "(query)", this.effectiveAuthorizeFor(sourceName), givens);
|
|
278745
278756
|
}
|
|
278757
|
+
noteAuthorizeBypass(entryPoint, sourceName) {
|
|
278758
|
+
recordAuthorizeBypass(entryPoint);
|
|
278759
|
+
logger.info("authorize bypass", {
|
|
278760
|
+
entryPoint,
|
|
278761
|
+
sourceName: sourceName ?? "(query)",
|
|
278762
|
+
modelPath: this.modelPath,
|
|
278763
|
+
packageName: this.packageName
|
|
278764
|
+
});
|
|
278765
|
+
}
|
|
278746
278766
|
async assertAuthorizedExprs(label, exprs, givens, selfContainedFirst = false, ambientPrefix = 0) {
|
|
278747
278767
|
if (exprs.length === 0)
|
|
278748
278768
|
return;
|
|
@@ -278765,7 +278785,11 @@ class Model {
|
|
|
278765
278785
|
if (!passed)
|
|
278766
278786
|
deny();
|
|
278767
278787
|
}
|
|
278768
|
-
async assertAuthorizedForAllSources(runnable, givens) {
|
|
278788
|
+
async assertAuthorizedForAllSources(runnable, givens, bypassAuthorize = false) {
|
|
278789
|
+
if (bypassAuthorize) {
|
|
278790
|
+
this.noteAuthorizeBypass("runnable", await this.resolveAuthorizeSourceFromRunnable(runnable));
|
|
278791
|
+
return;
|
|
278792
|
+
}
|
|
278769
278793
|
const ownSourceName = await this.resolveAuthorizeSourceFromRunnable(runnable);
|
|
278770
278794
|
await this.assertAuthorized(ownSourceName, givens);
|
|
278771
278795
|
const { struct, modelDef, compositeResolvedSourceDef } = await this.resolveRunTargetStruct(runnable);
|
|
@@ -279342,7 +279366,7 @@ class Model {
|
|
|
279342
279366
|
return { ...b, schema, refinements };
|
|
279343
279367
|
}).filter((b) => b.schema.length > 0);
|
|
279344
279368
|
}
|
|
279345
|
-
async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full") {
|
|
279369
|
+
async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full", bypassAuthorize = false) {
|
|
279346
279370
|
const startTime = performance.now();
|
|
279347
279371
|
if (this.compilationError) {
|
|
279348
279372
|
if (this.compilationError instanceof MalloyError2 || this.compilationError instanceof ModelCompilationError) {
|
|
@@ -279361,7 +279385,7 @@ class Model {
|
|
|
279361
279385
|
const surfaceName = extractRunTargetSourceName(query);
|
|
279362
279386
|
const earlySource = sourceName || (queryName ? this.queries?.find((q) => q.name === queryName)?.sourceName : undefined) || (surfaceName && !this.sources?.some((s) => s.name === surfaceName) ? this.queries?.find((q) => q.name === surfaceName)?.sourceName : undefined) || surfaceName;
|
|
279363
279387
|
if (earlySource) {
|
|
279364
|
-
await this.assertAuthorized(earlySource, givens ?? {});
|
|
279388
|
+
await this.assertAuthorized(earlySource, givens ?? {}, bypassAuthorize);
|
|
279365
279389
|
}
|
|
279366
279390
|
try {
|
|
279367
279391
|
for (const [field, callerText] of [
|
|
@@ -279456,7 +279480,7 @@ run: ${sourceName ? `${quoteMalloyIdentifier(sourceName)} -> ` : ""}${quoteMallo
|
|
|
279456
279480
|
if (boundary === "deferred") {
|
|
279457
279481
|
this.assertQueryBoundaryCompiled(compiledSource, query);
|
|
279458
279482
|
}
|
|
279459
|
-
await this.assertAuthorizedForAllSources(runnable, givens ?? {});
|
|
279483
|
+
await this.assertAuthorizedForAllSources(runnable, givens ?? {}, bypassAuthorize);
|
|
279460
279484
|
const maxRows = getMaxQueryRows();
|
|
279461
279485
|
const maxBytes = getMaxResponseBytes();
|
|
279462
279486
|
const buildManifest = this.resolveFreshBuildManifest();
|
|
@@ -284408,6 +284432,13 @@ class WatchModeController {
|
|
|
284408
284432
|
init_errors();
|
|
284409
284433
|
init_logger();
|
|
284410
284434
|
|
|
284435
|
+
// src/authorize_bypass_header.ts
|
|
284436
|
+
var BYPASS_AUTHORIZE_HEADER = "x-publisher-bypass-authorize";
|
|
284437
|
+
var readBypassAuthorize = (req) => {
|
|
284438
|
+
const raw = req.headers[BYPASS_AUTHORIZE_HEADER];
|
|
284439
|
+
return typeof raw === "string" && raw.trim().toLowerCase() === "true" ? true : undefined;
|
|
284440
|
+
};
|
|
284441
|
+
|
|
284411
284442
|
// src/filter_deprecation.ts
|
|
284412
284443
|
var setFilterDeprecationHeaders = (res, options) => {
|
|
284413
284444
|
const hasFilterParams = options.filterParams !== undefined && options.filterParams !== null && !(typeof options.filterParams === "object" && !Array.isArray(options.filterParams) && Object.keys(options.filterParams).length === 0);
|
|
@@ -295580,7 +295611,7 @@ app.post(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/mod
|
|
|
295580
295611
|
queryMetadata: req.body?.queryMetadata,
|
|
295581
295612
|
queryClass: req.body?.queryClass,
|
|
295582
295613
|
versionId: req.body?.versionId
|
|
295583
|
-
});
|
|
295614
|
+
}, readBypassAuthorize(req));
|
|
295584
295615
|
setFilterDeprecationHeaders(res, {
|
|
295585
295616
|
filterParams: req.body.filterParams ?? req.body.sourceFilters,
|
|
295586
295617
|
bypassFilters: req.body.bypassFilters === true ? true : undefined
|