@objectstack/plugin-webhooks 17.1.0 → 17.2.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/CHANGELOG.md +212 -0
- package/dist/index.cjs +141 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -5
- package/dist/index.d.ts +74 -5
- package/dist/index.js +81 -32
- package/dist/index.js.map +1 -1
- package/dist/schema.d.cts +7 -0
- package/dist/schema.d.ts +7 -0
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,217 @@
|
|
|
1
1
|
# @objectstack/plugin-webhooks
|
|
2
2
|
|
|
3
|
+
## 17.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cdaa72f: fix(service-messaging,plugin-webhooks): the `update`-op tenant-audit surface on the delivery outboxes is classified — `ack` is a dispatcher sweep, `redeliver` threads the caller's tenant (#10740)
|
|
8
|
+
|
|
9
|
+
**BREAKING** signature change on `IHttpOutbox.redeliver` and
|
|
10
|
+
`MessagingService.redeliverHttp`, shipped as `minor` under the repo's
|
|
11
|
+
launch-window convention for breaking changes.
|
|
12
|
+
|
|
13
|
+
`sys_http_delivery` and `sys_notification_delivery` carry three single-record
|
|
14
|
+
(`multi: false`) writes that the SQL driver audits under the **`update`** op —
|
|
15
|
+
a different op, and a different throttle key, from the `updateMany` half
|
|
16
|
+
classified previously. Their correct classifications are **opposite**, and
|
|
17
|
+
treating them as one sweep is the dangerous reading:
|
|
18
|
+
|
|
19
|
+
| site | reachable from | classification |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| `SqlNotificationOutbox.ack` | dispatcher tick only | global sweep |
|
|
22
|
+
| `SqlHttpOutbox.ack` | dispatcher tick only | global sweep |
|
|
23
|
+
| `SqlHttpOutbox.redeliver` | `POST /api/v1/webhooks/redeliver` | request-contextual |
|
|
24
|
+
|
|
25
|
+
**The two `ack` sites** are declared global sweeps through a new
|
|
26
|
+
`dispatcherAckOptions()` helper, sibling to `dispatcherSweepOptions()` and
|
|
27
|
+
deliberately not the same function — that one returns `& { multi: true }`, so a
|
|
28
|
+
`multi: false` site cannot borrow it by accident. The warrant was re-derived
|
|
29
|
+
against the current tree rather than inherited: `ack` has exactly two callers,
|
|
30
|
+
both inside `runPartition()` on a `setInterval` tick holding a per-partition
|
|
31
|
+
cluster lock, so no request context exists to thread; and the row being acked
|
|
32
|
+
was claimed by a sweep that crosses organizations by construction
|
|
33
|
+
(`hash(refId | notificationId | digestKey) mod N` is a load-spreading key, and
|
|
34
|
+
one outbox per environment drains the whole queue). Passing the claimed row's
|
|
35
|
+
own `organization_id` is documented at the helper as the tempting wrong answer:
|
|
36
|
+
a predicate read off the row you are about to write matches exactly that row,
|
|
37
|
+
adds no isolation, and silences the audit anyway — the appearance of scoping
|
|
38
|
+
without the substance.
|
|
39
|
+
|
|
40
|
+
**`redeliver` is not that**, and it is the reason this shipped separately. The
|
|
41
|
+
route in front of it is served to any authenticated user, so on a walled
|
|
42
|
+
deployment (`OS_TENANCY_POSTURE=isolated|group`) an unscoped replay is an
|
|
43
|
+
authenticated user writing another organization's delivery row — the case the
|
|
44
|
+
tenant audit exists to catch. It now carries the caller's tenant, applied to
|
|
45
|
+
the rows it reads as well as the row it writes, and it must never be given
|
|
46
|
+
`bypassTenantAudit`: a scoped write and a bypassed write produce the same
|
|
47
|
+
silence in the log, so the flag would convert a detectable hole into an
|
|
48
|
+
undetectable one. The webhook route resolves the session's
|
|
49
|
+
`activeOrganizationId` and threads it.
|
|
50
|
+
|
|
51
|
+
Behaviour change at the endpoint: a delivery row outside the caller's
|
|
52
|
+
organization is now **not found** (`RESOURCE_NOT_FOUND`, HTTP 404) rather than
|
|
53
|
+
replayed. It is deliberately invisible rather than forbidden, so the endpoint
|
|
54
|
+
is not an existence oracle for other tenants' delivery ids. An in-tenant
|
|
55
|
+
redelivery is unchanged.
|
|
56
|
+
|
|
57
|
+
Migrating a caller: `redeliver(id, guard?)` becomes
|
|
58
|
+
`redeliver(id, { tenantId, guard? })`, and `redeliverHttp(id)` becomes
|
|
59
|
+
`redeliverHttp(id, { tenantId })`. `tenantId` is a **required** property typed
|
|
60
|
+
`string | undefined`, so omitting it does not compile — a caller with no tenant
|
|
61
|
+
has to write `tenantId: undefined` and mean it. That is the point of the shape:
|
|
62
|
+
an optional property would let the dangerous case, a request path that simply
|
|
63
|
+
forgot, type-check in silence. Passing `undefined` leaves the write unscoped
|
|
64
|
+
and the audit line still fires, which is the intended reporting behaviour on a
|
|
65
|
+
deployment that cannot resolve an organization for the caller.
|
|
66
|
+
|
|
67
|
+
<!-- adr-0087: not-required (runtime-interface-only packages/services/service-messaging/src/http-outbox.ts#IHttpOutbox, packages/services/service-messaging/src/http-outbox.ts#RedeliverOptions) The surface that changed shape is `IHttpOutbox.redeliver`, plus the new `RedeliverOptions` argument type beside it. Both are TypeScript declarations in a service package with no `packages/spec` schema behind them: no metadata author writes a `redeliver` key, there is no authorable spelling and no `retiredKey()` tombstone, so `os migrate meta` has no stack source to rewrite. The change is a required second argument on an in-process method — a compile error at every call site, which is the notification channel, not a silent runtime gap. `MessagingService.redeliverHttp` moves with it and is deliberately NOT in the list above: this gate refuses that symbol as unresolvable, because `packages/spec/src/api/protocol.zod.ts` mentions the class name in a prose comment about `MessagingService.listInbox` while neither declaring nor importing it. The claim would be true and the gate cannot check it, so it is stated here for a reviewer instead of asserted where it would read as verified. It is a thin delegate to `IHttpOutbox.redeliver` in the same package and carries no schema of its own either. -->
|
|
68
|
+
- e222a53: **BREAKING** (compile-time only): twelve logger sink types that declared an
|
|
69
|
+
optional `error` now declare a **non-optional** `warn`, so a durability report
|
|
70
|
+
always has somewhere to land (#9754, #10556).
|
|
71
|
+
|
|
72
|
+
`minor`, not `major`: during the launch window this stack ships breaking changes
|
|
73
|
+
as `minor` — every publishable package versions in lockstep, so a `major` would
|
|
74
|
+
promote the whole release. `patch` would be wrong in the other direction, because
|
|
75
|
+
this *can* break a consumer's build.
|
|
76
|
+
|
|
77
|
+
`error` stays optional on every one of these types — hosts legitimately inject
|
|
78
|
+
reduced sinks, and requiring `error` was measured and rejected as #9754 option C.
|
|
79
|
+
What changes is that its *absence* now has a declared, guaranteed destination.
|
|
80
|
+
Call sites keep the `logger?.warn?.(…)` spelling as the backstop for hosts the
|
|
81
|
+
type cannot reach, so **no runtime behaviour changes**: nothing that printed
|
|
82
|
+
before stops printing, and nothing silent starts printing.
|
|
83
|
+
|
|
84
|
+
### Who has to change, and what to do
|
|
85
|
+
|
|
86
|
+
Only a caller that hands one of these sinks an object with **no `warn` method** —
|
|
87
|
+
for example `{ info }` or `{ error }` alone. Add a `warn` member; there is no
|
|
88
|
+
rename, no removal, and no stored value or metadata key to rewrite. Every
|
|
89
|
+
construction site inside this repo already supplied one, so the in-repo cost was
|
|
90
|
+
zero; the compile error is reserved for the callers that were silently discarding
|
|
91
|
+
these reports.
|
|
92
|
+
|
|
93
|
+
The affected types, by package:
|
|
94
|
+
|
|
95
|
+
- `@objectstack/cloud-connection` — the internal `PluginContext['logger']`
|
|
96
|
+
- `@objectstack/metadata-protocol` — `IndexMigrationLogger`
|
|
97
|
+
- `@objectstack/plugin-approvals` — the internal `MinimalLogger` of `lifecycle-hooks`
|
|
98
|
+
- `@objectstack/plugin-audit` — `AuthEventAuditLogger`, `ReadAuditLogger`
|
|
99
|
+
- `@objectstack/plugin-auth` — `ReconcileMembershipDeps['logger']`, the internal
|
|
100
|
+
`LoggerLike` of `member-role-canonical`, and `AuthManagerOptions['logger']`
|
|
101
|
+
- `@objectstack/plugin-email` — `ReclaimLogger`, via `ReclaimAttachmentContentOptions`
|
|
102
|
+
- `@objectstack/plugin-reports` — `ReportServiceOptions['logger']`
|
|
103
|
+
- `@objectstack/plugin-sharing` — the internal `MinimalLogger` of `bulk-recompute`,
|
|
104
|
+
`rule-hooks` and `record-share-cascade`
|
|
105
|
+
- `@objectstack/plugin-webhooks` — `OptionalLogger`, via `AutoEnqueuerOptions`
|
|
106
|
+
- `@objectstack/service-knowledge` — `KnowledgeLogger`
|
|
107
|
+
|
|
108
|
+
`AuthManagerOptions['logger']` is the one most likely to be reached from outside:
|
|
109
|
+
`AuthManager` is public surface, its `logger` option stays optional, and a logger
|
|
110
|
+
that *is* supplied must now carry `warn`. The only non-test construction site in
|
|
111
|
+
this repo passes the kernel `Logger`, whose `warn` is already required.
|
|
112
|
+
|
|
113
|
+
`ReportService` and `AutoEnqueuer` additionally stopped defaulting their logger
|
|
114
|
+
field to `{}`. The field is now honestly optional rather than holding an empty
|
|
115
|
+
object that declared it could report and discarded everything. Behaviour is
|
|
116
|
+
unchanged in both directions.
|
|
117
|
+
|
|
118
|
+
<!-- adr-0087: not-required (runtime-interface-only packages/plugins/plugin-auth/src/auth-manager.ts#AuthManagerOptions, packages/plugins/plugin-auth/src/reconcile-membership.ts#ReconcileMembershipDeps, packages/metadata-protocol/src/migrations/partial-index-probe.ts#IndexMigrationLogger, packages/plugins/plugin-audit/src/auth-event-audit.ts#AuthEventAuditLogger, packages/plugins/plugin-audit/src/read-audit.ts#ReadAuditLogger, packages/plugins/plugin-reports/src/report-service.ts#ReportServiceOptions, packages/services/service-knowledge/src/knowledge-service.ts#KnowledgeLogger) every tightened type is a plain TypeScript logger interface -- no Zod projection, no metadata surface, and none is referenced by one -- so `objectstack migrate meta` has nothing to rewrite. Nothing is removed or renamed and no stored value moves; the only consumer action is adding a `warn` member at a construction site the compiler names. -->
|
|
119
|
+
|
|
120
|
+
### Patch Changes
|
|
121
|
+
|
|
122
|
+
- 047ac86: Five `Plugin` implementations now release their resources from `destroy()`, the
|
|
123
|
+
only teardown hook the kernel calls (#10772).
|
|
124
|
+
|
|
125
|
+
`Plugin` (`@objectstack/core`'s `types.ts`) declares `init()`, `start?(ctx)` and
|
|
126
|
+
`destroy?()`. `ObjectKernel.performShutdown()` and `LiteKernel.destroy()` walk
|
|
127
|
+
the plugins in reverse calling `plugin.destroy()` — and nothing anywhere calls
|
|
128
|
+
`stop()`, `dispose()`, `close()` or `shutdown()` on a plugin. Each of these five
|
|
129
|
+
spelled its teardown with one of those names instead, so what it released was
|
|
130
|
+
still held after `await kernel.shutdown()` had **resolved**:
|
|
131
|
+
|
|
132
|
+
| package | class | was spelled | what outlived shutdown |
|
|
133
|
+
|:--|:--|:--|:--|
|
|
134
|
+
| `@objectstack/metadata` | `MetadataPlugin` | `stop` (arrow property) | artifact watcher, `manager.dispose()`, repository handle |
|
|
135
|
+
| `@objectstack/runtime` | `AppPlugin` | `stop` (arrow property) | the `app:unregistered` catalog event, never emitted |
|
|
136
|
+
| `@objectstack/runtime` | `ExternalValidationPlugin` | `stop` (arrow property) | every armed drift-check `setInterval` |
|
|
137
|
+
| `@objectstack/plugin-email` | `EmailServicePlugin` | `dispose` | two metadata subscriptions, the SMTP transport, an engine binding |
|
|
138
|
+
| `@objectstack/plugin-webhooks` | `WebhookOutboxPlugin` | `dispose` | the auto-enqueuer (2 realtime subscriptions + a refresh interval) and two engine hooks |
|
|
139
|
+
|
|
140
|
+
`ExternalValidationPlugin` is the one with teeth: it is one of only two `Plugin`
|
|
141
|
+
implementations in the tree that own `setInterval` directly, it is mounted on
|
|
142
|
+
the real `os serve` path, and its `stop()`'s only caller anywhere was the class
|
|
143
|
+
itself re-arming. Measured against a real kernel, its drift checker performed
|
|
144
|
+
five further reads in the five intervals after a resolved shutdown — the #9371
|
|
145
|
+
mechanism verbatim. `WebhookOutboxPlugin.dispose()` had **zero** callers in the
|
|
146
|
+
entire repo, so its teardown had never run in any process at all.
|
|
147
|
+
|
|
148
|
+
**Nothing is removed and no signature narrows.** Each old name is retained as a
|
|
149
|
+
delegating alias, because it is public API of an exported class and an embedder
|
|
150
|
+
may have learned to call it directly precisely BECAUSE the kernel never did.
|
|
151
|
+
`stop` stays an arrow property where it was one (so a detached
|
|
152
|
+
`const { stop } = plugin` keeps working) and stays synchronous on
|
|
153
|
+
`ExternalValidationPlugin` (so a non-awaiting call site is unaffected). The two
|
|
154
|
+
`stop(ctx)` aliases widen their parameter to optional.
|
|
155
|
+
|
|
156
|
+
One behavioural note for direct callers, since `destroy()` takes no context:
|
|
157
|
+
`MetadataPlugin.stop(ctx)` and `AppPlugin.stop(ctx)` now use the context
|
|
158
|
+
captured in `init()` and ignore the argument. In a real composition these are
|
|
159
|
+
the same object. The visible difference is confined to a plugin whose `init()`
|
|
160
|
+
never ran — for `MetadataPlugin` a dropped `warn` line, for `AppPlugin` a
|
|
161
|
+
catalog event that is no longer emitted for an app that was never registered.
|
|
162
|
+
- Updated dependencies [6936d07]
|
|
163
|
+
- Updated dependencies [59eb04d]
|
|
164
|
+
- Updated dependencies [9f05b7d]
|
|
165
|
+
- Updated dependencies [3b2af5e]
|
|
166
|
+
- Updated dependencies [7d2d112]
|
|
167
|
+
- Updated dependencies [5fa0d72]
|
|
168
|
+
- Updated dependencies [8cc8401]
|
|
169
|
+
- Updated dependencies [02b3b07]
|
|
170
|
+
- Updated dependencies [8163a1c]
|
|
171
|
+
- Updated dependencies [cdaa72f]
|
|
172
|
+
- Updated dependencies [914c413]
|
|
173
|
+
- Updated dependencies [55809a0]
|
|
174
|
+
- Updated dependencies [ee2ff45]
|
|
175
|
+
- Updated dependencies [47cd3ec]
|
|
176
|
+
- Updated dependencies [52db1d1]
|
|
177
|
+
- Updated dependencies [5649efb]
|
|
178
|
+
- Updated dependencies [9d7d2de]
|
|
179
|
+
- Updated dependencies [c815c50]
|
|
180
|
+
- Updated dependencies [795ea05]
|
|
181
|
+
- Updated dependencies [900e489]
|
|
182
|
+
- Updated dependencies [2306a76]
|
|
183
|
+
- Updated dependencies [e5ea701]
|
|
184
|
+
- Updated dependencies [a40dcc1]
|
|
185
|
+
- Updated dependencies [def0d3e]
|
|
186
|
+
- Updated dependencies [8d0bb79]
|
|
187
|
+
- Updated dependencies [5acb58d]
|
|
188
|
+
- Updated dependencies [2e3cf95]
|
|
189
|
+
- Updated dependencies [4c93387]
|
|
190
|
+
- Updated dependencies [504c8d5]
|
|
191
|
+
- Updated dependencies [a037f7c]
|
|
192
|
+
- Updated dependencies [3ee8ddf]
|
|
193
|
+
- Updated dependencies [16cef97]
|
|
194
|
+
- Updated dependencies [a79bd35]
|
|
195
|
+
- Updated dependencies [6ceaa4b]
|
|
196
|
+
- Updated dependencies [15ea214]
|
|
197
|
+
- Updated dependencies [de19489]
|
|
198
|
+
- Updated dependencies [c684d00]
|
|
199
|
+
- Updated dependencies [923c424]
|
|
200
|
+
- Updated dependencies [1ec36b7]
|
|
201
|
+
- Updated dependencies [5f2e54c]
|
|
202
|
+
- Updated dependencies [189373b]
|
|
203
|
+
- Updated dependencies [35ad101]
|
|
204
|
+
- Updated dependencies [ceb33a9]
|
|
205
|
+
- Updated dependencies [73d9795]
|
|
206
|
+
- Updated dependencies [8012960]
|
|
207
|
+
- Updated dependencies [f34f56b]
|
|
208
|
+
- Updated dependencies [f399618]
|
|
209
|
+
- Updated dependencies [75e9301]
|
|
210
|
+
- Updated dependencies [2810695]
|
|
211
|
+
- @objectstack/spec@17.2.0
|
|
212
|
+
- @objectstack/core@17.2.0
|
|
213
|
+
- @objectstack/service-messaging@17.2.0
|
|
214
|
+
|
|
3
215
|
## 17.1.0
|
|
4
216
|
|
|
5
217
|
### Patch Changes
|