@forumone/throughline-integrations 0.8.0 → 0.8.1
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/CHANGELOG.md +35 -0
- package/dist/collection.d.ts +3 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +41 -2
- package/dist/collection.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @forumone/throughline-integrations
|
|
2
2
|
|
|
3
|
+
## 0.8.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 45724ee: The credentials come out of an editor's read of an integration
|
|
8
|
+
|
|
9
|
+
`integrations` grants document read to an admin _or_ an editor, and it should:
|
|
10
|
+
the reason an editor opens this collection is to see whether last night's sync
|
|
11
|
+
ran. The collection's docblock has always said so — "editors can read instance
|
|
12
|
+
status" — but a document read hands over the whole document, and `config` is one
|
|
13
|
+
JSON column holding whatever an integration needs to authenticate. A HubSpot
|
|
14
|
+
private app token, a webhook signing secret, a target URL. So _status_ was a
|
|
15
|
+
description of the intent, not of the code, and every editor could read every
|
|
16
|
+
credential from `GET /api/<slug>` and from the admin screen.
|
|
17
|
+
|
|
18
|
+
`config` now carries its own `read` / `create` / `update`, admin-only. An
|
|
19
|
+
editor's read returns the row without it: `name`, `enabled`, `lastSyncAt`,
|
|
20
|
+
`lastSyncStatus` and `lastError` are untouched, which is the whole of what the
|
|
21
|
+
status view and the `list_integrations` / `get_integration_status` tools project
|
|
22
|
+
anyway.
|
|
23
|
+
|
|
24
|
+
Nothing that needs the value loses it. Every reader of `config` goes through the
|
|
25
|
+
Local API — `loadInstances` here, and a host's sync and form endpoints — which
|
|
26
|
+
overrides access. The MCP tools never emitted the field.
|
|
27
|
+
|
|
28
|
+
`create` and `update` are redundant today, since the collection's own create and
|
|
29
|
+
update are already admin-only. They are there for the day document write is
|
|
30
|
+
widened so an editor can correct a status, and are the reason that day does not
|
|
31
|
+
also hand over the credential.
|
|
32
|
+
|
|
33
|
+
A `configFields` entry cannot do this itself: those drive the admin UI, and the
|
|
34
|
+
schema has one `json` column behind them, so there is no per-key field for
|
|
35
|
+
Payload to gate. Anything secret in `config` is protected by this rule or not at
|
|
36
|
+
all.
|
|
37
|
+
|
|
3
38
|
## 0.8.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/dist/collection.d.ts
CHANGED
|
@@ -12,7 +12,9 @@ export interface CreateIntegrationsCollectionOptions {
|
|
|
12
12
|
* would let an attacker re-target webhook URLs or rotate signing secrets.
|
|
13
13
|
*
|
|
14
14
|
* Editors can read instance status (used by the listing/status MCP tools);
|
|
15
|
-
* write operations are reserved for admins editing in the Payload UI.
|
|
15
|
+
* write operations are reserved for admins editing in the Payload UI. *Status*
|
|
16
|
+
* is the operative word: `config` carries its own admin-only field access, so
|
|
17
|
+
* an editor's read returns the row without the credentials in it.
|
|
16
18
|
*
|
|
17
19
|
* The one control on the document that is not a field is the sidebar's Sync
|
|
18
20
|
* now button, which POSTs to the `:id/sync` endpoint passed in `endpoints`.
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,gBAAgB,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,gBAAgB,EAAE,QAAQ,EAAe,MAAM,SAAS,CAAA;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AASxD,MAAM,WAAW,mCAAmC;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,mEAAmE;IACnE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;CACvB;AAsBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,mCAAmC,GAC3C,gBAAgB,CAiKlB"}
|
package/dist/collection.js
CHANGED
|
@@ -12,13 +12,24 @@ const adminOnly = ({ req }) => {
|
|
|
12
12
|
const roles = req.user?.['roles'] ?? [];
|
|
13
13
|
return roles.includes('admin');
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* The same rule, at the field. `FieldAccess` is a different signature from
|
|
17
|
+
* `Access` — it may only answer a boolean, never a `where` query — so it cannot
|
|
18
|
+
* be the same function.
|
|
19
|
+
*/
|
|
20
|
+
const adminOnlyField = ({ req }) => {
|
|
21
|
+
const roles = req.user?.['roles'] ?? [];
|
|
22
|
+
return roles.includes('admin');
|
|
23
|
+
};
|
|
15
24
|
/**
|
|
16
25
|
* Collection that persists per-instance integration configuration. Configuration
|
|
17
26
|
* is admin-only by design: prompt injection that gave Claude write access here
|
|
18
27
|
* would let an attacker re-target webhook URLs or rotate signing secrets.
|
|
19
28
|
*
|
|
20
29
|
* Editors can read instance status (used by the listing/status MCP tools);
|
|
21
|
-
* write operations are reserved for admins editing in the Payload UI.
|
|
30
|
+
* write operations are reserved for admins editing in the Payload UI. *Status*
|
|
31
|
+
* is the operative word: `config` carries its own admin-only field access, so
|
|
32
|
+
* an editor's read returns the row without the credentials in it.
|
|
22
33
|
*
|
|
23
34
|
* The one control on the document that is not a field is the sidebar's Sync
|
|
24
35
|
* now button, which POSTs to the `:id/sync` endpoint passed in `endpoints`.
|
|
@@ -66,8 +77,36 @@ export function createIntegrationsCollection(options) {
|
|
|
66
77
|
{
|
|
67
78
|
name: 'config',
|
|
68
79
|
type: 'json',
|
|
80
|
+
/*
|
|
81
|
+
Admin-only at the field, because this is where the credentials are.
|
|
82
|
+
|
|
83
|
+
Document read is admin *or* editor, and deliberately so — the reason an
|
|
84
|
+
editor opens this collection is to see whether last night's sync ran.
|
|
85
|
+
But a document read hands over the whole document, and `config` is one
|
|
86
|
+
JSON column holding whatever an integration needs to authenticate: a
|
|
87
|
+
HubSpot private app token, a signing secret, a webhook URL. The
|
|
88
|
+
docblock above has always said editors read instance *status*; without
|
|
89
|
+
this, that was a description of the intent rather than of the code.
|
|
90
|
+
|
|
91
|
+
Nothing that needs the value loses it. Every reader of `config` goes
|
|
92
|
+
through the Local API — `loadInstances` here, and the host's sync and
|
|
93
|
+
form endpoints — which overrides access. The MCP tools project a fixed
|
|
94
|
+
field list that never included `config`. What changes is `GET /api/<slug>`
|
|
95
|
+
and the admin screen for a non-admin, which now show status and no
|
|
96
|
+
secrets.
|
|
97
|
+
|
|
98
|
+
`create` and `update` as well, so the credential cannot be replaced by
|
|
99
|
+
somebody who could not read it. Redundant today, since the collection's
|
|
100
|
+
own create and update are already admin-only, and cheap insurance
|
|
101
|
+
against the day document write is widened for status edits.
|
|
102
|
+
*/
|
|
103
|
+
access: {
|
|
104
|
+
read: adminOnlyField,
|
|
105
|
+
create: adminOnlyField,
|
|
106
|
+
update: adminOnlyField,
|
|
107
|
+
},
|
|
69
108
|
admin: {
|
|
70
|
-
description: 'Integration-specific configuration. The integration\'s configFields drive the admin UI; this JSON store carries the validated payload.',
|
|
109
|
+
description: 'Integration-specific configuration. The integration\'s configFields drive the admin UI; this JSON store carries the validated payload. Admin-only: it holds the credentials.',
|
|
71
110
|
},
|
|
72
111
|
},
|
|
73
112
|
{
|
package/dist/collection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAExD;;;GAGG;AACH,MAAM,YAAY,GAAG,2CAA2C,CAAA;AAShE,MAAM,aAAa,GAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACxC,MAAM,KAAK,GAAI,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAA0B,IAAI,EAAE,CAAA;IACjE,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AAC5D,CAAC,CAAA;AAED,MAAM,SAAS,GAAW,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACpC,MAAM,KAAK,GAAI,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAA0B,IAAI,EAAE,CAAA;IACjE,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forumone/throughline-integrations",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Plugin architecture for connecting Throughline-powered Payload sites to external systems. Ships the Integration contract, registry, collection, MCP tools, and a generic outbound-webhook integration as the first concrete example.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"zod": "^3.23.0",
|
|
59
|
-
"@forumone/throughline-
|
|
60
|
-
"@forumone/throughline-
|
|
59
|
+
"@forumone/throughline-core": "0.8.0",
|
|
60
|
+
"@forumone/throughline-plugin-contract": "0.4.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@payloadcms/ui": "^3.83.0",
|