@objectstack/core 14.8.0 → 15.1.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 +103 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +151 -1
- package/dist/index.d.ts +151 -1
- package/dist/index.js +95 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
ANONYMOUS_DENY_BODY: () => ANONYMOUS_DENY_BODY,
|
|
34
|
+
ANONYMOUS_DENY_CODE: () => ANONYMOUS_DENY_CODE,
|
|
35
|
+
ANONYMOUS_DENY_MESSAGE: () => ANONYMOUS_DENY_MESSAGE,
|
|
36
|
+
ANONYMOUS_DENY_STATUS: () => ANONYMOUS_DENY_STATUS,
|
|
33
37
|
API_KEY_PREFIX: () => API_KEY_PREFIX,
|
|
34
38
|
ApiRegistry: () => ApiRegistry,
|
|
35
39
|
CORE_FALLBACK_FACTORIES: () => CORE_FALLBACK_FACTORIES,
|
|
@@ -40,6 +44,9 @@ __export(index_exports, {
|
|
|
40
44
|
ObjectKernel: () => ObjectKernel,
|
|
41
45
|
ObjectKernelBase: () => ObjectKernelBase,
|
|
42
46
|
ObjectLogger: () => ObjectLogger,
|
|
47
|
+
POSTURE_INJECTION_RULE: () => POSTURE_INJECTION_RULE,
|
|
48
|
+
POSTURE_LADDER: () => POSTURE_LADDER,
|
|
49
|
+
POSTURE_RANK: () => POSTURE_RANK,
|
|
43
50
|
PluginConfigValidator: () => PluginConfigValidator,
|
|
44
51
|
PluginHealthMonitor: () => PluginHealthMonitor,
|
|
45
52
|
PluginLoader: () => PluginLoader,
|
|
@@ -69,6 +76,7 @@ __export(index_exports, {
|
|
|
69
76
|
createPluginPermissionEnforcer: () => createPluginPermissionEnforcer,
|
|
70
77
|
deepMerge: () => deepMerge,
|
|
71
78
|
defaultIsTransientError: () => defaultIsTransientError,
|
|
79
|
+
derivePosture: () => derivePosture,
|
|
72
80
|
evaluateAuthGate: () => evaluateAuthGate,
|
|
73
81
|
extractApiKey: () => extractApiKey,
|
|
74
82
|
generateApiKey: () => generateApiKey,
|
|
@@ -83,12 +91,14 @@ __export(index_exports, {
|
|
|
83
91
|
isNode: () => isNode,
|
|
84
92
|
parseScopes: () => parseScopes,
|
|
85
93
|
parseSignature: () => parseSignature,
|
|
94
|
+
postureVisibleRows: () => postureVisibleRows,
|
|
86
95
|
readAuthoredTranslationLayer: () => readAuthoredTranslationLayer,
|
|
87
96
|
resolveApiKeyPrincipal: () => resolveApiKeyPrincipal,
|
|
88
97
|
resolveAuthzContext: () => resolveAuthzContext,
|
|
89
98
|
resolveLocale: () => resolveLocale,
|
|
90
99
|
resolveLocalizationContext: () => resolveLocalizationContext,
|
|
91
100
|
safeExit: () => safeExit,
|
|
101
|
+
shouldDenyAnonymous: () => shouldDenyAnonymous,
|
|
92
102
|
signPayload: () => signPayload,
|
|
93
103
|
verifyPayload: () => verifyPayload,
|
|
94
104
|
verifyPlatformSignature: () => verifyPlatformSignature,
|
|
@@ -1637,6 +1647,8 @@ var ObjectKernel = class {
|
|
|
1637
1647
|
this.validateSystemRequirements();
|
|
1638
1648
|
this.logger.debug("Triggering kernel:ready hook");
|
|
1639
1649
|
await this.context.trigger("kernel:ready");
|
|
1650
|
+
this.logger.debug("Triggering kernel:bootstrapped hook");
|
|
1651
|
+
await this.context.trigger("kernel:bootstrapped");
|
|
1640
1652
|
this.logger.debug("Triggering kernel:listening hook");
|
|
1641
1653
|
await this.context.trigger("kernel:listening");
|
|
1642
1654
|
this.logger.info("\u2705 Bootstrap complete");
|
|
@@ -1920,6 +1932,7 @@ var LiteKernel = class extends ObjectKernelBase {
|
|
|
1920
1932
|
await this.runPluginStart(plugin);
|
|
1921
1933
|
}
|
|
1922
1934
|
await this.triggerHook("kernel:ready");
|
|
1935
|
+
await this.triggerHook("kernel:bootstrapped");
|
|
1923
1936
|
await this.triggerHook("kernel:listening");
|
|
1924
1937
|
this.logger.info("\u2705 Bootstrap complete", {
|
|
1925
1938
|
pluginCount: this.plugins.size
|
|
@@ -4243,6 +4256,62 @@ function isGrantExpired(row, nowMs) {
|
|
|
4243
4256
|
return !(nowMs < until);
|
|
4244
4257
|
}
|
|
4245
4258
|
|
|
4259
|
+
// src/security/posture-ladder.ts
|
|
4260
|
+
var POSTURE_LADDER = [
|
|
4261
|
+
"PLATFORM_ADMIN",
|
|
4262
|
+
"TENANT_ADMIN",
|
|
4263
|
+
"MEMBER",
|
|
4264
|
+
"EXTERNAL"
|
|
4265
|
+
];
|
|
4266
|
+
var POSTURE_RANK = {
|
|
4267
|
+
PLATFORM_ADMIN: 3,
|
|
4268
|
+
TENANT_ADMIN: 2,
|
|
4269
|
+
MEMBER: 1,
|
|
4270
|
+
EXTERNAL: 0
|
|
4271
|
+
};
|
|
4272
|
+
var POSTURE_INJECTION_RULE = {
|
|
4273
|
+
PLATFORM_ADMIN: "Layer 0 exemption where the object posture permits (private / platform-global / better-auth-managed) \u2014 crosses the tenant wall; org-scoped like TENANT_ADMIN on ordinary tenant business objects.",
|
|
4274
|
+
TENANT_ADMIN: "All rows within the active organization (organization_id == ctx.tenantId); no ownership / depth / sharing narrowing.",
|
|
4275
|
+
MEMBER: "Business RLS within the organization \u2014 ownership (owner / unit depth), the OWD baseline, and explicit sharing.",
|
|
4276
|
+
EXTERNAL: "Explicitly shared rows ONLY \u2014 OWD baselines and sharing rules never apply; a misconfiguration can only shrink visibility, never widen it."
|
|
4277
|
+
};
|
|
4278
|
+
function derivePosture(evidence) {
|
|
4279
|
+
if (evidence.isPlatformAdmin) return "PLATFORM_ADMIN";
|
|
4280
|
+
if (evidence.isTenantAdmin) return "TENANT_ADMIN";
|
|
4281
|
+
return "MEMBER";
|
|
4282
|
+
}
|
|
4283
|
+
function isSharedTo(row, userId) {
|
|
4284
|
+
return (row.sharedTo ?? []).includes(userId);
|
|
4285
|
+
}
|
|
4286
|
+
function externalVisible(rows, p) {
|
|
4287
|
+
return rows.filter((r) => isSharedTo(r, p.userId));
|
|
4288
|
+
}
|
|
4289
|
+
function memberVisible(rows, p) {
|
|
4290
|
+
const shared = new Set(externalVisible(rows, p));
|
|
4291
|
+
return rows.filter(
|
|
4292
|
+
(r) => shared.has(r) || r.organization_id === p.organizationId && (r.owner_id === p.userId || r.owdVisible === true)
|
|
4293
|
+
);
|
|
4294
|
+
}
|
|
4295
|
+
function tenantAdminVisible(rows, p) {
|
|
4296
|
+
const member = new Set(memberVisible(rows, p));
|
|
4297
|
+
return rows.filter((r) => member.has(r) || r.organization_id === p.organizationId);
|
|
4298
|
+
}
|
|
4299
|
+
function platformAdminVisible(rows) {
|
|
4300
|
+
return [...rows];
|
|
4301
|
+
}
|
|
4302
|
+
function postureVisibleRows(posture, rows, principal) {
|
|
4303
|
+
switch (posture) {
|
|
4304
|
+
case "PLATFORM_ADMIN":
|
|
4305
|
+
return platformAdminVisible(rows);
|
|
4306
|
+
case "TENANT_ADMIN":
|
|
4307
|
+
return tenantAdminVisible(rows, principal);
|
|
4308
|
+
case "MEMBER":
|
|
4309
|
+
return memberVisible(rows, principal);
|
|
4310
|
+
case "EXTERNAL":
|
|
4311
|
+
return externalVisible(rows, principal);
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
|
|
4246
4315
|
// src/security/resolve-authz-context.ts
|
|
4247
4316
|
function safeJsonParse2(s, fallback) {
|
|
4248
4317
|
try {
|
|
@@ -4389,6 +4458,10 @@ async function resolveAuthzContext(input) {
|
|
|
4389
4458
|
if (hasPlatformAdminGrant && !ctx.positions.includes(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN)) {
|
|
4390
4459
|
ctx.positions.unshift(import_spec.BUILTIN_IDENTITY_PLATFORM_ADMIN);
|
|
4391
4460
|
}
|
|
4461
|
+
ctx.posture = derivePosture({
|
|
4462
|
+
isPlatformAdmin: hasPlatformAdminGrant,
|
|
4463
|
+
isTenantAdmin: ctx.permissions.includes(import_spec.ORGANIZATION_ADMIN)
|
|
4464
|
+
});
|
|
4392
4465
|
if (!ctx.permissions.includes("ai_seat")) {
|
|
4393
4466
|
const aiAccess = (await getUserRow())?.ai_access;
|
|
4394
4467
|
if (aiAccess === true || aiAccess === 1 || aiAccess === "1") ctx.permissions.push("ai_seat");
|
|
@@ -4474,6 +4547,26 @@ function evaluateAuthGate(sessionUser, path) {
|
|
|
4474
4547
|
};
|
|
4475
4548
|
}
|
|
4476
4549
|
|
|
4550
|
+
// src/security/anonymous-deny.ts
|
|
4551
|
+
var ANONYMOUS_DENY_STATUS = 401;
|
|
4552
|
+
var ANONYMOUS_DENY_CODE = "unauthenticated";
|
|
4553
|
+
var ANONYMOUS_DENY_MESSAGE = "Authentication is required to access this endpoint.";
|
|
4554
|
+
var ANONYMOUS_DENY_BODY = {
|
|
4555
|
+
error: ANONYMOUS_DENY_CODE,
|
|
4556
|
+
message: ANONYMOUS_DENY_MESSAGE
|
|
4557
|
+
};
|
|
4558
|
+
function shouldDenyAnonymous(input) {
|
|
4559
|
+
if (!input.requireAuth) return false;
|
|
4560
|
+
if (typeof input.method === "string" && input.method.toUpperCase() === "OPTIONS") {
|
|
4561
|
+
return false;
|
|
4562
|
+
}
|
|
4563
|
+
if (input.userId || input.isSystem) return false;
|
|
4564
|
+
if (typeof input.path === "string" && input.path.length > 0 && isAuthGateAllowlisted(input.path)) {
|
|
4565
|
+
return false;
|
|
4566
|
+
}
|
|
4567
|
+
return true;
|
|
4568
|
+
}
|
|
4569
|
+
|
|
4477
4570
|
// src/utils/datetime.ts
|
|
4478
4571
|
function calendarPartsInTz(d, tz) {
|
|
4479
4572
|
const parts = new Intl.DateTimeFormat("en-US", {
|
|
@@ -5495,6 +5588,10 @@ var NamespaceResolver = class {
|
|
|
5495
5588
|
};
|
|
5496
5589
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5497
5590
|
0 && (module.exports = {
|
|
5591
|
+
ANONYMOUS_DENY_BODY,
|
|
5592
|
+
ANONYMOUS_DENY_CODE,
|
|
5593
|
+
ANONYMOUS_DENY_MESSAGE,
|
|
5594
|
+
ANONYMOUS_DENY_STATUS,
|
|
5498
5595
|
API_KEY_PREFIX,
|
|
5499
5596
|
ApiRegistry,
|
|
5500
5597
|
CORE_FALLBACK_FACTORIES,
|
|
@@ -5505,6 +5602,9 @@ var NamespaceResolver = class {
|
|
|
5505
5602
|
ObjectKernel,
|
|
5506
5603
|
ObjectKernelBase,
|
|
5507
5604
|
ObjectLogger,
|
|
5605
|
+
POSTURE_INJECTION_RULE,
|
|
5606
|
+
POSTURE_LADDER,
|
|
5607
|
+
POSTURE_RANK,
|
|
5508
5608
|
PluginConfigValidator,
|
|
5509
5609
|
PluginHealthMonitor,
|
|
5510
5610
|
PluginLoader,
|
|
@@ -5534,6 +5634,7 @@ var NamespaceResolver = class {
|
|
|
5534
5634
|
createPluginPermissionEnforcer,
|
|
5535
5635
|
deepMerge,
|
|
5536
5636
|
defaultIsTransientError,
|
|
5637
|
+
derivePosture,
|
|
5537
5638
|
evaluateAuthGate,
|
|
5538
5639
|
extractApiKey,
|
|
5539
5640
|
generateApiKey,
|
|
@@ -5548,12 +5649,14 @@ var NamespaceResolver = class {
|
|
|
5548
5649
|
isNode,
|
|
5549
5650
|
parseScopes,
|
|
5550
5651
|
parseSignature,
|
|
5652
|
+
postureVisibleRows,
|
|
5551
5653
|
readAuthoredTranslationLayer,
|
|
5552
5654
|
resolveApiKeyPrincipal,
|
|
5553
5655
|
resolveAuthzContext,
|
|
5554
5656
|
resolveLocale,
|
|
5555
5657
|
resolveLocalizationContext,
|
|
5556
5658
|
safeExit,
|
|
5659
|
+
shouldDenyAnonymous,
|
|
5557
5660
|
signPayload,
|
|
5558
5661
|
verifyPayload,
|
|
5559
5662
|
verifyPlatformSignature,
|