@objectstack/runtime 13.0.0 → 14.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +197 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -1
- package/dist/index.d.ts +55 -1
- package/dist/index.js +193 -17
- package/dist/index.js.map +1 -1
- package/package.json +20 -20
package/dist/index.cjs
CHANGED
|
@@ -2161,7 +2161,7 @@ function safeGet(ctx, name) {
|
|
|
2161
2161
|
var import_core5 = require("@objectstack/core");
|
|
2162
2162
|
var import_types3 = require("@objectstack/types");
|
|
2163
2163
|
var import_system = require("@objectstack/spec/system");
|
|
2164
|
-
var
|
|
2164
|
+
var import_ai2 = require("@objectstack/spec/ai");
|
|
2165
2165
|
var import_shared2 = require("@objectstack/spec/shared");
|
|
2166
2166
|
init_package_state_store();
|
|
2167
2167
|
|
|
@@ -2195,6 +2195,7 @@ function checkApiExposure(def, action) {
|
|
|
2195
2195
|
}
|
|
2196
2196
|
|
|
2197
2197
|
// src/security/resolve-execution-context.ts
|
|
2198
|
+
var import_ai = require("@objectstack/spec/ai");
|
|
2198
2199
|
var import_core3 = require("@objectstack/core");
|
|
2199
2200
|
function extractJwtBearer(headers) {
|
|
2200
2201
|
const auth = headers.get("authorization");
|
|
@@ -2255,7 +2256,15 @@ async function resolveExecutionContext(opts) {
|
|
|
2255
2256
|
isSystem: false
|
|
2256
2257
|
};
|
|
2257
2258
|
if (authz.userId) {
|
|
2258
|
-
|
|
2259
|
+
if (oauthPrincipal?.clientId) {
|
|
2260
|
+
ctx.principalKind = "agent";
|
|
2261
|
+
ctx.onBehalfOf = { userId: authz.userId, principalKind: "human" };
|
|
2262
|
+
ctx.permissions = (0, import_ai.scopesToAgentPermissionSets)(oauthPrincipal.scopes);
|
|
2263
|
+
ctx.positions = [];
|
|
2264
|
+
ctx.systemPermissions = oauthPrincipal.scopes?.includes(import_ai.MCP_OAUTH_SCOPE_ACTIONS) ? authz.systemPermissions ?? [] : [];
|
|
2265
|
+
} else {
|
|
2266
|
+
ctx.principalKind = "human";
|
|
2267
|
+
}
|
|
2259
2268
|
} else {
|
|
2260
2269
|
ctx.principalKind = "guest";
|
|
2261
2270
|
ctx.positions = ["guest"];
|
|
@@ -2331,6 +2340,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
2331
2340
|
}
|
|
2332
2341
|
};
|
|
2333
2342
|
this.enforceMembership = options?.enforceProjectMembership ?? true;
|
|
2343
|
+
this.requireAuth = options?.requireAuth ?? false;
|
|
2334
2344
|
this.kernelResolver = options?.kernelResolver ?? resolveService("kernel-resolver");
|
|
2335
2345
|
this.scopeManager = options?.scopeManager ?? resolveService("scope-manager");
|
|
2336
2346
|
}
|
|
@@ -2548,14 +2558,14 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
2548
2558
|
return { handled: true, response };
|
|
2549
2559
|
}
|
|
2550
2560
|
const grantedScopes = Array.isArray(ec.oauthScopes) ? ec.oauthScopes : void 0;
|
|
2551
|
-
if (grantedScopes && !grantedScopes.some((s) =>
|
|
2561
|
+
if (grantedScopes && !grantedScopes.some((s) => import_ai2.MCP_OAUTH_SCOPES.includes(s))) {
|
|
2552
2562
|
const resourceMetadataUrl = await this.getMcpResourceMetadataUrl(context);
|
|
2553
2563
|
const response = this.error(
|
|
2554
|
-
`Forbidden: the access token grants none of the MCP scopes (${
|
|
2564
|
+
`Forbidden: the access token grants none of the MCP scopes (${import_ai2.MCP_OAUTH_SCOPES.join(", ")})`,
|
|
2555
2565
|
403
|
|
2556
2566
|
);
|
|
2557
2567
|
response.headers = {
|
|
2558
|
-
"WWW-Authenticate": `Bearer error="insufficient_scope", scope="${
|
|
2568
|
+
"WWW-Authenticate": `Bearer error="insufficient_scope", scope="${import_ai2.MCP_OAUTH_SCOPES.join(" ")}"` + (resourceMetadataUrl ? `, resource_metadata="${resourceMetadataUrl}"` : "")
|
|
2559
2569
|
};
|
|
2560
2570
|
return { handled: true, response };
|
|
2561
2571
|
}
|
|
@@ -2622,6 +2632,73 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
2622
2632
|
return null;
|
|
2623
2633
|
}
|
|
2624
2634
|
}
|
|
2635
|
+
/**
|
|
2636
|
+
* `GET /mcp/skill` — the environment-customized portable Agent Skill
|
|
2637
|
+
* (`SKILL.md`), rendered by the MCP service (ADR-0036 Amendment C: ONE
|
|
2638
|
+
* generic skill; only the connection URL is environment-specific).
|
|
2639
|
+
*
|
|
2640
|
+
* Served PUBLIC like `/discovery`: the content is generic agent
|
|
2641
|
+
* instructions plus a URL the caller already knows — no schema, no
|
|
2642
|
+
* tenant data. Gated on the same default-on switch as the `/mcp` route
|
|
2643
|
+
* (404 when opted out, so the surface isn't advertised) and 501 when the
|
|
2644
|
+
* MCP plugin isn't loaded, mirroring `handleMcp`.
|
|
2645
|
+
*/
|
|
2646
|
+
async handleMcpSkill(method, context) {
|
|
2647
|
+
if (!_HttpDispatcher.isMcpEnabled()) {
|
|
2648
|
+
return { handled: true, response: this.error("MCP server is not enabled for this environment", 404) };
|
|
2649
|
+
}
|
|
2650
|
+
if (method !== "GET") {
|
|
2651
|
+
return {
|
|
2652
|
+
handled: true,
|
|
2653
|
+
response: {
|
|
2654
|
+
status: 405,
|
|
2655
|
+
headers: { Allow: "GET" },
|
|
2656
|
+
body: { success: false, error: { message: "Method not allowed \u2014 use GET", code: 405 } }
|
|
2657
|
+
}
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
const mcp = await this.resolveService("mcp", context.environmentId);
|
|
2661
|
+
if (!mcp || typeof mcp.renderSkill !== "function") {
|
|
2662
|
+
return { handled: true, response: this.error("MCP server is not available", 501) };
|
|
2663
|
+
}
|
|
2664
|
+
let mcpUrl;
|
|
2665
|
+
try {
|
|
2666
|
+
const authService = await this.resolveService("auth", context.environmentId);
|
|
2667
|
+
const url = authService?.getMcpResourceUrl?.();
|
|
2668
|
+
if (typeof url === "string" && url) mcpUrl = url;
|
|
2669
|
+
} catch {
|
|
2670
|
+
}
|
|
2671
|
+
if (!mcpUrl) {
|
|
2672
|
+
try {
|
|
2673
|
+
const webReq = this.toMcpWebRequest(context.request, void 0);
|
|
2674
|
+
const host = webReq?.headers.get("host");
|
|
2675
|
+
if (host) {
|
|
2676
|
+
const proto = webReq?.headers.get("x-forwarded-proto") || "http";
|
|
2677
|
+
mcpUrl = `${proto}://${host}/api/v1/mcp`;
|
|
2678
|
+
}
|
|
2679
|
+
} catch {
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
const markdown = mcp.renderSkill({ mcpUrl });
|
|
2683
|
+
return {
|
|
2684
|
+
handled: true,
|
|
2685
|
+
result: {
|
|
2686
|
+
type: "stream",
|
|
2687
|
+
status: 200,
|
|
2688
|
+
contentType: "text/markdown; charset=utf-8",
|
|
2689
|
+
headers: {
|
|
2690
|
+
"content-type": "text/markdown; charset=utf-8",
|
|
2691
|
+
"content-disposition": 'inline; filename="SKILL.md"',
|
|
2692
|
+
// Same reasoning as /discovery (cloud#152): reflects mutable
|
|
2693
|
+
// runtime config (base URL), must never be edge-cached stale.
|
|
2694
|
+
"cache-control": "no-store"
|
|
2695
|
+
},
|
|
2696
|
+
events: (async function* () {
|
|
2697
|
+
yield markdown;
|
|
2698
|
+
})()
|
|
2699
|
+
}
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2625
2702
|
/**
|
|
2626
2703
|
* Normalise the inbound request into a Web-standard `Request` for the MCP
|
|
2627
2704
|
* transport. Accepts an already-Web `Request`, or a node/Hono-style req
|
|
@@ -3429,6 +3506,15 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3429
3506
|
* Fallback for backward compat: /metadata (all objects), /metadata/:objectName (get object)
|
|
3430
3507
|
*/
|
|
3431
3508
|
async handleMetadata(path, _context, method, body, query) {
|
|
3509
|
+
if (this.requireAuth) {
|
|
3510
|
+
const ec = _context.executionContext;
|
|
3511
|
+
if (!ec?.userId && !ec?.isSystem) {
|
|
3512
|
+
return {
|
|
3513
|
+
handled: true,
|
|
3514
|
+
response: this.error("Authentication is required to access this endpoint.", 401, { code: "unauthenticated" })
|
|
3515
|
+
};
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3432
3518
|
const parts = path.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
3433
3519
|
if (parts[0] === "types") {
|
|
3434
3520
|
const protocol = await this.resolveService("protocol");
|
|
@@ -3728,13 +3814,13 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3728
3814
|
* Handles Analytics requests
|
|
3729
3815
|
* path: sub-path after /analytics/
|
|
3730
3816
|
*/
|
|
3731
|
-
async handleAnalytics(path, method, body,
|
|
3817
|
+
async handleAnalytics(path, method, body, context) {
|
|
3732
3818
|
const analyticsService = await this.getService(import_system.CoreServiceName.enum.analytics);
|
|
3733
3819
|
if (!analyticsService) return { handled: false };
|
|
3734
3820
|
const m = method.toUpperCase();
|
|
3735
3821
|
const subPath = path.replace(/^\/+/, "");
|
|
3736
3822
|
if (subPath === "query" && m === "POST") {
|
|
3737
|
-
const result = await analyticsService.query(body);
|
|
3823
|
+
const result = await analyticsService.query(body, context?.executionContext);
|
|
3738
3824
|
return { handled: true, response: this.success(result) };
|
|
3739
3825
|
}
|
|
3740
3826
|
if (subPath === "meta" && m === "GET") {
|
|
@@ -3742,7 +3828,7 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3742
3828
|
return { handled: true, response: this.success(result) };
|
|
3743
3829
|
}
|
|
3744
3830
|
if (subPath === "sql" && m === "POST") {
|
|
3745
|
-
const result = await analyticsService.generateSql(body);
|
|
3831
|
+
const result = await analyticsService.generateSql(body, context?.executionContext);
|
|
3746
3832
|
return { handled: true, response: this.success(result) };
|
|
3747
3833
|
}
|
|
3748
3834
|
return { handled: false };
|
|
@@ -3787,6 +3873,56 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
3787
3873
|
}
|
|
3788
3874
|
return { handled: false };
|
|
3789
3875
|
}
|
|
3876
|
+
/**
|
|
3877
|
+
* Handle the security admin surface (`/security/...`) — ADR-0090 D5/D9
|
|
3878
|
+
* suggested audience bindings. A package's `isDefault: true` permission
|
|
3879
|
+
* set is an install-time SUGGESTION to bind it to the `everyone` position;
|
|
3880
|
+
* these routes let an admin see and resolve those suggestions. The
|
|
3881
|
+
* `security` service does the real gating (tenant-admin pre-check, and the
|
|
3882
|
+
* confirm write runs under the audience-anchor + delegated-admin gates
|
|
3883
|
+
* with the caller's execution context — never auto-bound, never system).
|
|
3884
|
+
*
|
|
3885
|
+
* Routes:
|
|
3886
|
+
* GET /security/suggested-bindings?status=&packageId= → list (reconciles first)
|
|
3887
|
+
* POST /security/suggested-bindings/:id/confirm → create the anchor binding
|
|
3888
|
+
* POST /security/suggested-bindings/:id/dismiss → decline the suggestion
|
|
3889
|
+
*/
|
|
3890
|
+
async handleSecurity(path, method, _body, query, context) {
|
|
3891
|
+
const service = await this.resolveService("security", context.environmentId);
|
|
3892
|
+
if (!service || typeof service.listAudienceBindingSuggestions !== "function") {
|
|
3893
|
+
return { handled: true, response: this.error("Security service not available", 503) };
|
|
3894
|
+
}
|
|
3895
|
+
const ec = context.executionContext;
|
|
3896
|
+
if (!ec?.userId && !ec?.isSystem) {
|
|
3897
|
+
return { handled: true, response: this.error("Authentication required", 401) };
|
|
3898
|
+
}
|
|
3899
|
+
const m = method.toUpperCase();
|
|
3900
|
+
const parts = path.split("/").filter(Boolean);
|
|
3901
|
+
if (parts[0] !== "suggested-bindings") return { handled: false };
|
|
3902
|
+
try {
|
|
3903
|
+
if (parts.length === 1 && m === "GET") {
|
|
3904
|
+
const status = query?.status ? String(query.status) : void 0;
|
|
3905
|
+
const packageId = query?.packageId ? String(query.packageId) : void 0;
|
|
3906
|
+
const result = await service.listAudienceBindingSuggestions(ec, { status, packageId });
|
|
3907
|
+
return { handled: true, response: this.success(result) };
|
|
3908
|
+
}
|
|
3909
|
+
if (parts.length === 3 && m === "POST") {
|
|
3910
|
+
const id = decodeURIComponent(parts[1]);
|
|
3911
|
+
if (parts[2] === "confirm") {
|
|
3912
|
+
const result = await service.confirmAudienceBindingSuggestion(ec, id);
|
|
3913
|
+
return { handled: true, response: this.success(result) };
|
|
3914
|
+
}
|
|
3915
|
+
if (parts[2] === "dismiss") {
|
|
3916
|
+
const result = await service.dismissAudienceBindingSuggestion(ec, id);
|
|
3917
|
+
return { handled: true, response: this.success(result) };
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
return { handled: false };
|
|
3921
|
+
} catch (err) {
|
|
3922
|
+
const status = typeof err?.statusCode === "number" ? err.statusCode : 500;
|
|
3923
|
+
return { handled: true, response: this.error(err?.message ?? "Security operation failed", status) };
|
|
3924
|
+
}
|
|
3925
|
+
}
|
|
3790
3926
|
/**
|
|
3791
3927
|
* Handles i18n requests
|
|
3792
3928
|
* path: sub-path after /i18n/
|
|
@@ -4792,8 +4928,16 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
4792
4928
|
return Array.isArray(rows) ? rows : rows?.value ?? [];
|
|
4793
4929
|
}
|
|
4794
4930
|
};
|
|
4795
|
-
const
|
|
4796
|
-
const userFromAuth =
|
|
4931
|
+
const ec = _context?.executionContext;
|
|
4932
|
+
const userFromAuth = ec?.userId ? {
|
|
4933
|
+
id: ec.userId,
|
|
4934
|
+
name: ec.userId,
|
|
4935
|
+
email: ec.email,
|
|
4936
|
+
roles: Array.isArray(ec.positions) ? ec.positions : [],
|
|
4937
|
+
positions: Array.isArray(ec.positions) ? ec.positions : [],
|
|
4938
|
+
permissions: Array.isArray(ec.permissions) ? ec.permissions : [],
|
|
4939
|
+
tenantId: ec.tenantId
|
|
4940
|
+
} : { id: "system", name: "system", roles: [], positions: [], permissions: [] };
|
|
4797
4941
|
const actionContext = {
|
|
4798
4942
|
record,
|
|
4799
4943
|
user: userFromAuth,
|
|
@@ -4872,6 +5016,15 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
4872
5016
|
if (route.method !== method) continue;
|
|
4873
5017
|
const params = matchRoute(route.path, fullPath);
|
|
4874
5018
|
if (params === null) continue;
|
|
5019
|
+
if (this.requireAuth && route.auth !== false) {
|
|
5020
|
+
const gec = context.executionContext;
|
|
5021
|
+
if (!gec?.userId && !gec?.isSystem) {
|
|
5022
|
+
return {
|
|
5023
|
+
handled: true,
|
|
5024
|
+
response: this.error("Authentication is required to access this endpoint.", 401, { code: "unauthenticated" })
|
|
5025
|
+
};
|
|
5026
|
+
}
|
|
5027
|
+
}
|
|
4875
5028
|
const ec = context.executionContext;
|
|
4876
5029
|
const user = ec?.userId ? {
|
|
4877
5030
|
userId: ec.userId,
|
|
@@ -5175,6 +5328,9 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
5175
5328
|
if (cleanPath.startsWith("/data")) {
|
|
5176
5329
|
return this.handleData(cleanPath.substring(5), method, body, query, context);
|
|
5177
5330
|
}
|
|
5331
|
+
if (cleanPath === "/mcp/skill" || cleanPath.startsWith("/mcp/skill?")) {
|
|
5332
|
+
return this.handleMcpSkill(method, context);
|
|
5333
|
+
}
|
|
5178
5334
|
if (cleanPath === "/mcp" || cleanPath.startsWith("/mcp/") || cleanPath.startsWith("/mcp?")) {
|
|
5179
5335
|
return this.handleMcp(body, context);
|
|
5180
5336
|
}
|
|
@@ -5202,6 +5358,9 @@ var _HttpDispatcher = class _HttpDispatcher {
|
|
|
5202
5358
|
if (cleanPath.startsWith("/notifications")) {
|
|
5203
5359
|
return this.handleNotification(cleanPath.substring(14), method, body, query, context);
|
|
5204
5360
|
}
|
|
5361
|
+
if (cleanPath === "/security" || cleanPath.startsWith("/security/")) {
|
|
5362
|
+
return this.handleSecurity(cleanPath.substring(9), method, body, query, context);
|
|
5363
|
+
}
|
|
5205
5364
|
if (cleanPath.startsWith("/packages")) {
|
|
5206
5365
|
return this.handlePackages(cleanPath.substring(9), method, body, query, context);
|
|
5207
5366
|
}
|
|
@@ -5588,7 +5747,7 @@ function resolveErrorReporter(ctx, override) {
|
|
|
5588
5747
|
}
|
|
5589
5748
|
|
|
5590
5749
|
// src/dispatcher-plugin.ts
|
|
5591
|
-
function mountRouteOnServer(route, server, routePath, securityHeaders, resolveUser) {
|
|
5750
|
+
function mountRouteOnServer(route, server, routePath, securityHeaders, resolveUser, requireAuth = false) {
|
|
5592
5751
|
const handler = async (req, res) => {
|
|
5593
5752
|
try {
|
|
5594
5753
|
let user;
|
|
@@ -5598,6 +5757,17 @@ function mountRouteOnServer(route, server, routePath, securityHeaders, resolveUs
|
|
|
5598
5757
|
} catch {
|
|
5599
5758
|
}
|
|
5600
5759
|
}
|
|
5760
|
+
if (requireAuth && route.auth !== false && !user) {
|
|
5761
|
+
res.status(401);
|
|
5762
|
+
if (securityHeaders) {
|
|
5763
|
+
for (const [k, v] of Object.entries(securityHeaders)) res.header(k, v);
|
|
5764
|
+
}
|
|
5765
|
+
res.json({
|
|
5766
|
+
error: "unauthenticated",
|
|
5767
|
+
message: "Authentication is required to access this endpoint."
|
|
5768
|
+
});
|
|
5769
|
+
return;
|
|
5770
|
+
}
|
|
5601
5771
|
const result = await route.handler({
|
|
5602
5772
|
body: req.body,
|
|
5603
5773
|
params: req.params,
|
|
@@ -5781,8 +5951,10 @@ function createDispatcherPlugin(config = {}) {
|
|
|
5781
5951
|
if (!server) return;
|
|
5782
5952
|
const kernel = ctx.getKernel();
|
|
5783
5953
|
const enforceMembership = config.enforceProjectMembership ?? (config.scoping?.enableProjectScoping ?? false);
|
|
5954
|
+
const requireAuth = config.requireAuth ?? config.scoping?.requireAuth ?? false;
|
|
5784
5955
|
const dispatcher = new HttpDispatcher(kernel, void 0, {
|
|
5785
|
-
enforceProjectMembership: enforceMembership
|
|
5956
|
+
enforceProjectMembership: enforceMembership,
|
|
5957
|
+
requireAuth
|
|
5786
5958
|
});
|
|
5787
5959
|
const prefix = config.prefix || "/api/v1";
|
|
5788
5960
|
const securityHeaders = config.securityHeaders === false ? void 0 : buildSecurityHeaders(
|
|
@@ -5910,6 +6082,14 @@ function createDispatcherPlugin(config = {}) {
|
|
|
5910
6082
|
mountMcp("POST");
|
|
5911
6083
|
mountMcp("GET");
|
|
5912
6084
|
mountMcp("DELETE");
|
|
6085
|
+
server.get(`${prefix}/mcp/skill`, async (req, res) => {
|
|
6086
|
+
try {
|
|
6087
|
+
const result = await dispatcher.dispatch("GET", "/mcp/skill", req.body, req.query, { request: req });
|
|
6088
|
+
sendResult(result, res);
|
|
6089
|
+
} catch (err) {
|
|
6090
|
+
errorResponse(err, res);
|
|
6091
|
+
}
|
|
6092
|
+
});
|
|
5913
6093
|
server.post(`${prefix}/keys`, async (req, res) => {
|
|
5914
6094
|
try {
|
|
5915
6095
|
const result = await dispatcher.dispatch("POST", "/keys", req.body, req.query, { request: req });
|
|
@@ -6214,9 +6394,7 @@ function createDispatcherPlugin(config = {}) {
|
|
|
6214
6394
|
const registerActionRoutes = (base) => {
|
|
6215
6395
|
server.post(`${base}/actions/:object/:action`, async (req, res) => {
|
|
6216
6396
|
try {
|
|
6217
|
-
const
|
|
6218
|
-
if (req.params?.environmentId) ctx2.environmentId = req.params.environmentId;
|
|
6219
|
-
const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}`, "POST", req.body, ctx2);
|
|
6397
|
+
const result = await dispatcher.dispatch("POST", `/actions/${req.params.object}/${req.params.action}`, req.body, req.query, { request: req });
|
|
6220
6398
|
sendResult(result, res);
|
|
6221
6399
|
} catch (err) {
|
|
6222
6400
|
errorResponse(err, res);
|
|
@@ -6224,9 +6402,7 @@ function createDispatcherPlugin(config = {}) {
|
|
|
6224
6402
|
});
|
|
6225
6403
|
server.post(`${base}/actions/:object/:action/:recordId`, async (req, res) => {
|
|
6226
6404
|
try {
|
|
6227
|
-
const
|
|
6228
|
-
if (req.params?.environmentId) ctx2.environmentId = req.params.environmentId;
|
|
6229
|
-
const result = await dispatcher.handleActions(`/${req.params.object}/${req.params.action}/${req.params.recordId}`, "POST", req.body, ctx2);
|
|
6405
|
+
const result = await dispatcher.dispatch("POST", `/actions/${req.params.object}/${req.params.action}/${req.params.recordId}`, req.body, req.query, { request: req });
|
|
6230
6406
|
sendResult(result, res);
|
|
6231
6407
|
} catch (err) {
|
|
6232
6408
|
errorResponse(err, res);
|
|
@@ -6288,11 +6464,11 @@ function createDispatcherPlugin(config = {}) {
|
|
|
6288
6464
|
const routePath = route.path.startsWith("/api/v1") ? route.path : `${prefix}${route.path}`;
|
|
6289
6465
|
let count = 0;
|
|
6290
6466
|
if (enableProjectScoping && projectResolution === "required") {
|
|
6291
|
-
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;
|
|
6467
|
+
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser, requireAuth)) count++;
|
|
6292
6468
|
} else {
|
|
6293
|
-
if (mountRouteOnServer(route, server, routePath, securityHeaders, resolveRequestUser)) count++;
|
|
6469
|
+
if (mountRouteOnServer(route, server, routePath, securityHeaders, resolveRequestUser, requireAuth)) count++;
|
|
6294
6470
|
if (enableProjectScoping) {
|
|
6295
|
-
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser)) count++;
|
|
6471
|
+
if (mountRouteOnServer(route, server, toScopedPath(routePath), securityHeaders, resolveRequestUser, requireAuth)) count++;
|
|
6296
6472
|
}
|
|
6297
6473
|
}
|
|
6298
6474
|
return count;
|