@3sln/trove 0.0.11 → 0.0.13
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/README.md +13 -1
- package/package.json +2 -1
- package/packages/core/src/collections/index.js +71 -10
- package/packages/core/src/encryption/keys.js +4 -3
- package/packages/core/src/encryption/policy.js +14 -7
- package/packages/core/src/encryption/rotation.js +46 -12
- package/packages/core/src/errors.js +8 -0
- package/packages/core/src/index.js +8 -2
- package/packages/core/src/indexers/contribution.js +18 -17
- package/packages/core/src/indexing.js +8 -4
- package/packages/core/src/issues.js +8 -0
- package/packages/core/src/links.js +21 -9
- package/packages/core/src/metadata/interface.js +22 -0
- package/packages/core/src/metadata/memory.js +15 -0
- package/packages/core/src/metadata/sqlite.js +23 -1
- package/packages/core/src/plugins/contributions.js +13 -0
- package/packages/core/src/rateLimit.js +253 -0
- package/packages/core/src/scan.js +44 -16
- package/packages/core/src/sidecar/document.js +18 -14
- package/packages/core/src/sidecar/index.js +9 -10
- package/packages/core/src/sidecar/manager.js +10 -15
- package/packages/core/src/uploads.js +40 -15
- package/packages/core/src/vfs.js +59 -34
- package/packages/plugin-sdk/src/browser.js +155 -0
- package/packages/plugin-sdk/src/protocol.js +13 -1
- package/packages/server/src/access/externalEvaluation.js +17 -0
- package/packages/server/src/adapters/bun.js +1 -2
- package/packages/server/src/adapters/node.js +1 -2
- package/packages/server/src/engine/index.js +1 -1
- package/packages/server/src/engine/providers/access.js +17 -34
- package/packages/server/src/engine/providers/core.js +112 -14
- package/packages/server/src/index.js +160 -105
- package/packages/server/src/mcp/index.js +7 -12
- package/packages/server/src/mcp/tools.js +24 -29
- package/packages/server/src/router.js +31 -8
- package/packages/server/src/routes.js +74 -113
- package/packages/server/src/scope.js +78 -0
- package/packages/web/dist/assets/main-828yzsr7.js +511 -0
- package/packages/web/dist/assets/main-828yzsr7.js.map +120 -0
- package/packages/web/dist/index.html +1 -1
- package/packages/web/dist/sw.js +1 -1
- package/packages/web/src/bl/actions.js +226 -104
- package/packages/web/src/bl/activity.js +32 -82
- package/packages/web/src/bl/index.js +23 -11
- package/packages/web/src/bl/launcher.js +2 -9
- package/packages/web/src/bl/links.js +31 -18
- package/packages/web/src/bl/offline.js +24 -10
- package/packages/web/src/bl/pluginInstall.js +29 -26
- package/packages/web/src/bl/queries.js +76 -68
- package/packages/web/src/bl/services.js +22 -14
- package/packages/web/src/bl/social.js +39 -25
- package/packages/web/src/bl/state.js +22 -4
- package/packages/web/src/bl/viewState.js +9 -0
- package/packages/web/src/bl/watchQuery.js +1 -8
- package/packages/web/src/dispatch.js +26 -0
- package/packages/web/src/platform/api.js +32 -0
- package/packages/web/src/platform/commands.js +14 -15
- package/packages/web/src/platform/context.js +3 -58
- package/packages/web/src/platform/contributions.js +1 -35
- package/packages/web/src/platform/fileChunks.js +281 -0
- package/packages/web/src/platform/index.js +8 -9
- package/packages/web/src/platform/mediaUrls.js +10 -0
- package/packages/web/src/platform/navigation.js +35 -21
- package/packages/web/src/platform/pickers.js +39 -19
- package/packages/web/src/platform/pluginHost.js +4 -1
- package/packages/web/src/platform/pluginRpc.js +47 -2
- package/packages/web/src/platform/spatialNav.js +1 -1
- package/packages/web/src/platform/viewport.js +14 -6
- package/packages/web/src/platform/voiceSearch.js +17 -9
- package/packages/web/src/platform/whenclause.js +9 -19
- package/packages/web/src/runtime.js +2 -37
- package/packages/web/src/ui/activate.js +18 -2
- package/packages/web/src/ui/components/activityPanel.js +1 -1
- package/packages/web/src/ui/components/adminView.js +4 -7
- package/packages/web/src/ui/components/editorArea.js +10 -1
- package/packages/web/src/ui/components/launcher.js +29 -13
- package/packages/web/src/ui/components/openers/index.js +17 -22
- package/packages/web/src/ui/components/openers/markdown.js +2 -2
- package/packages/web/src/ui/components/overlays.js +31 -5
- package/packages/web/src/ui/components/pluginReview.js +7 -4
- package/packages/web/src/ui/components/pluginsView.js +1 -1
- package/packages/web/src/ui/components/settingsView.js +30 -27
- package/packages/web/src/ui/components/statusBar.js +8 -6
- package/packages/web/src/ui/components/views/grid.js +2 -2
- package/packages/web/src/ui/components/views/parts.js +1 -1
- package/packages/web/src/ui/compositions/workbench.js +20 -6
- package/packages/web/src/ui/sanitize.js +0 -5
- package/packages/web/src/workbench.js +37 -19
- package/packages/web/dist/assets/main-c9dnnnc6.js +0 -356
- package/packages/web/dist/assets/main-c9dnnnc6.js.map +0 -118
|
@@ -9,6 +9,15 @@
|
|
|
9
9
|
// Both request surfaces need it. The HTTP router obviously; MCP just as much, because
|
|
10
10
|
// an agent holding Alice's token is Alice and there must be no MCP-shaped way around
|
|
11
11
|
// the ACL. Written once so the two cannot drift.
|
|
12
|
+
//
|
|
13
|
+
// The same goes for WHO IS ASKING and what that subject may reach. Those helpers lived in
|
|
14
|
+
// routes.js, and mcp/tools.js grew its own copies — which drifted, in the direction that
|
|
15
|
+
// surface makes worst: MCP filtered a named collection out of the readable list, so an
|
|
16
|
+
// agent asking about a collection it may not see was told "No files matched… Try different
|
|
17
|
+
// words" and burned turns rephrasing a permissions error. mcp/index.js claims "It is not a
|
|
18
|
+
// second access-control system to keep in sync with the first"; it was one.
|
|
19
|
+
|
|
20
|
+
import { TroveError } from '@3sln/trove/core';
|
|
12
21
|
|
|
13
22
|
/**
|
|
14
23
|
* @param {object|null} container the engine container, or null where there is none
|
|
@@ -41,3 +50,72 @@ export function leaseScope(container, principal, grant = null) {
|
|
|
41
50
|
},
|
|
42
51
|
};
|
|
43
52
|
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The collections this caller may read, optionally narrowed to one they asked for.
|
|
56
|
+
*
|
|
57
|
+
* Every drive-wide query needs this, and it has to be applied INSIDE the query rather
|
|
58
|
+
* than by filtering results: a LIMIT spent on rows the caller can't see would report
|
|
59
|
+
* "no matches" while matches they can see sit just past the cut.
|
|
60
|
+
*
|
|
61
|
+
* Always a list. It used to answer `undefined` for "don't scope" on a drive with ACLs
|
|
62
|
+
* switched off, and there is no such drive: `collections: false` is refused by
|
|
63
|
+
* `configFromEnv` and again by the provider.
|
|
64
|
+
*/
|
|
65
|
+
export async function readableCollectionIds(ctx, narrowTo) {
|
|
66
|
+
// A NAMED collection is asserted, not filtered. Filtering an unreadable id out of the
|
|
67
|
+
// list answers "no results" for a collection the caller may not see — indistinguishable
|
|
68
|
+
// from one that is simply empty, so a permissions problem reads as an indexing problem.
|
|
69
|
+
// `access.collection` throws the 403 that says what actually happened.
|
|
70
|
+
if (narrowTo) {
|
|
71
|
+
await ctx.access.collection(narrowTo, 'read');
|
|
72
|
+
return [narrowTo];
|
|
73
|
+
}
|
|
74
|
+
return (await listFor(ctx)).map((c) => c.id);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// --- who is asking ------------------------------------------------------------
|
|
78
|
+
//
|
|
79
|
+
// On a key request `ctx.principal` is NULL and the authority lives on `ctx.grant`, so
|
|
80
|
+
// handing the principal to CollectionService asks about the anonymous caller instead of
|
|
81
|
+
// about the key. That failed in both directions: on a locked drive a correctly-scoped
|
|
82
|
+
// key got `list(null) === []` and 403s from search, tags, backlinks, tasks and issues,
|
|
83
|
+
// while on a `defaultOpen` drive the `anyone` grant let a key scoped to one collection
|
|
84
|
+
// read and write every one of them through those same routes. engine/providers/access.js
|
|
85
|
+
// was the only place that had it right.
|
|
86
|
+
//
|
|
87
|
+
// One helper per question, so "does this surface understand API keys" has one answer
|
|
88
|
+
// rather than one per call site. Never a union of the two: a request bearing a key is
|
|
89
|
+
// the key's request, and falling back to whatever session is attached is how a weak
|
|
90
|
+
// credential borrows a strong one.
|
|
91
|
+
|
|
92
|
+
export const listFor = (ctx) =>
|
|
93
|
+
(ctx.grant ? ctx.collections.listForGrant(ctx.grant) : ctx.collections.list(ctx.principal));
|
|
94
|
+
|
|
95
|
+
export const wholeDriveFor = (ctx) =>
|
|
96
|
+
(ctx.grant ? ctx.collections.grantHasWholeDrive(ctx.grant) : ctx.collections.hasWholeDrive(ctx.principal));
|
|
97
|
+
|
|
98
|
+
/** Returns the collection record, so a caller that needs it does not assert twice. */
|
|
99
|
+
export async function assertCap(ctx, collectionId, capability) {
|
|
100
|
+
return ctx.grant
|
|
101
|
+
? ctx.collections.assertForGrant(ctx.grant, collectionId, capability)
|
|
102
|
+
: ctx.collections.assert(ctx.principal, collectionId, capability);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The `describe` that matches whoever asked, so the reported capabilities are theirs. */
|
|
106
|
+
export const describeFor = (ctx, c) =>
|
|
107
|
+
(ctx.grant ? ctx.collections.describeForGrant(c, ctx.grant) : ctx.collections.describe(c, ctx.principal));
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Refuse a request that arrived on an API key.
|
|
111
|
+
*
|
|
112
|
+
* For the collection-ADMINISTRATION verbs, whose authority CollectionService reads from
|
|
113
|
+
* the principal alone. A key request has no principal, so those methods judge it as the
|
|
114
|
+
* anonymous caller — allowing everything on a `defaultOpen` drive and nothing on a locked
|
|
115
|
+
* one. Rather than teach create/update/remove/setGrant about grants, keys stay out: a key
|
|
116
|
+
* that can rewrite a collection's ACL can grant itself whatever it lacks, which is the
|
|
117
|
+
* self-escalation shape `requireHumanAdmin` refuses for the same reason.
|
|
118
|
+
*/
|
|
119
|
+
export function refuseGrant(ctx, action) {
|
|
120
|
+
if (ctx.grant) throw TroveError.forbidden(`An API key cannot ${action} — sign in instead`);
|
|
121
|
+
}
|