@rebasepro/server 0.13.0 → 0.13.1-canary.g06dbe5b
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/{admin_block-CcSGdH7M.js → admin_block-H86dCPsj.js} +62 -2
- package/dist/admin_block-H86dCPsj.js.map +1 -0
- package/dist/api/ast-schema-editor.d.ts +74 -6
- package/dist/api/errors.d.ts +0 -6
- package/dist/api/openapi-generator.d.ts +14 -0
- package/dist/api/rest/api-generator.d.ts +1 -1
- package/dist/api/rest/idempotency.d.ts +62 -4
- package/dist/api/rest/query-parser.d.ts +15 -1
- package/dist/api/rest/write-validation.d.ts +52 -9
- package/dist/auth/adapter-middleware.d.ts +3 -1
- package/dist/auth/apple-oauth.d.ts +16 -11
- package/dist/auth/bitbucket-oauth.d.ts +2 -4
- package/dist/auth/builtin-auth-adapter.d.ts +2 -0
- package/dist/auth/discord-oauth.d.ts +5 -6
- package/dist/auth/facebook-oauth.d.ts +2 -4
- package/dist/auth/github-oauth.d.ts +2 -4
- package/dist/auth/gitlab-oauth.d.ts +6 -4
- package/dist/auth/google-oauth.d.ts +1 -0
- package/dist/auth/index.d.ts +8 -1
- package/dist/auth/interfaces.d.ts +68 -1
- package/dist/auth/jwt.d.ts +40 -0
- package/dist/auth/linkedin-oauth.d.ts +2 -4
- package/dist/auth/mfa-gate.d.ts +42 -0
- package/dist/auth/mfa-routes.d.ts +26 -1
- package/dist/auth/mfa.d.ts +16 -0
- package/dist/auth/microsoft-oauth.d.ts +19 -4
- package/dist/auth/oauth-code-flow.d.ts +66 -0
- package/dist/auth/oauth-signin-policy.d.ts +61 -0
- package/dist/auth/oidc-id-token.d.ts +61 -0
- package/dist/auth/rate-limiter.d.ts +37 -2
- package/dist/auth/rls-scope.d.ts +25 -0
- package/dist/auth/routes.d.ts +8 -0
- package/dist/auth/slack-oauth.d.ts +2 -4
- package/dist/auth/spotify-oauth.d.ts +2 -4
- package/dist/auth/twitter-oauth.d.ts +2 -5
- package/dist/{auth-CuC9M2x6.js → auth-DkAHqvf5.js} +1604 -391
- package/dist/auth-DkAHqvf5.js.map +1 -0
- package/dist/{backup-CVggVhR2.js → backup-DLluVyuA.js} +2 -2
- package/dist/{backup-CVggVhR2.js.map → backup-DLluVyuA.js.map} +1 -1
- package/dist/boot/boot.d.ts +19 -0
- package/dist/boot/ddl-bootstrap.d.ts +70 -0
- package/dist/{contract-routes-Dj8i5AiM.js → contract-routes-BB1U05sS.js} +3 -3
- package/dist/{contract-routes-Dj8i5AiM.js.map → contract-routes-BB1U05sS.js.map} +1 -1
- package/dist/cron/cron-scheduler.d.ts +8 -3
- package/dist/cron/define-cron.d.ts +17 -3
- package/dist/{cron-loader-B1S2MCSl.js → cron-loader-3U5aGILy.js} +2 -2
- package/dist/{cron-loader-B1S2MCSl.js.map → cron-loader-3U5aGILy.js.map} +1 -1
- package/dist/{cron-routes-CrQ0tK-_.js → cron-routes-rZgwlOz4.js} +2 -2
- package/dist/{cron-routes-CrQ0tK-_.js.map → cron-routes-rZgwlOz4.js.map} +1 -1
- package/dist/{cron-scheduler-B3RFt0HS.js → cron-scheduler-FJAaCAXm.js} +30 -5
- package/dist/cron-scheduler-FJAaCAXm.js.map +1 -0
- package/dist/{cron-store-BywZsyfZ.js → cron-store-9NmUDfzL.js} +66 -47
- package/dist/cron-store-9NmUDfzL.js.map +1 -0
- package/dist/ddl-bootstrap-BhXbTnBl.js +183 -0
- package/dist/ddl-bootstrap-BhXbTnBl.js.map +1 -0
- package/dist/email/html.d.ts +54 -0
- package/dist/email/index.d.ts +3 -0
- package/dist/email/link-base.d.ts +39 -0
- package/dist/email/smtp-email-service.d.ts +7 -1
- package/dist/email/templates.d.ts +9 -1
- package/dist/email/types.d.ts +11 -1
- package/dist/{errors-CgkCzoj7.js → errors-B1WZEdsK.js} +3 -11
- package/dist/errors-B1WZEdsK.js.map +1 -0
- package/dist/function-loader-D1SwtCa5.js +139 -0
- package/dist/function-loader-D1SwtCa5.js.map +1 -0
- package/dist/{function-routes-C0cLIy3N.js → function-routes-Btcez1T-.js} +18 -6
- package/dist/function-routes-Btcez1T-.js.map +1 -0
- package/dist/functions/define-function.d.ts +25 -6
- package/dist/functions/function-loader.d.ts +23 -0
- package/dist/functions/function-routes.d.ts +7 -1
- package/dist/functions/request-timeout.d.ts +34 -0
- package/dist/history/history-routes.d.ts +6 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.es.js +1960 -794
- package/dist/index.es.js.map +1 -1
- package/dist/init/docs.d.ts +10 -1
- package/dist/init/process-safety.d.ts +25 -0
- package/dist/init.d.ts +27 -0
- package/dist/{jwt-DD6EtpGj.js → jwt-Cuq6MwNy.js} +70 -8
- package/dist/jwt-Cuq6MwNy.js.map +1 -0
- package/dist/logger-DfvF_8r-.js +190 -0
- package/dist/logger-DfvF_8r-.js.map +1 -0
- package/dist/openapi-generator-BQxxxDpb.js +865 -0
- package/dist/openapi-generator-BQxxxDpb.js.map +1 -0
- package/dist/request-timeout-RivJsME0.js +65 -0
- package/dist/request-timeout-RivJsME0.js.map +1 -0
- package/dist/schema-editor-routes-DZFKGXgq.js +437 -0
- package/dist/schema-editor-routes-DZFKGXgq.js.map +1 -0
- package/dist/serve-spa.d.ts +5 -4
- package/dist/services/outbound-url-guard.d.ts +53 -0
- package/dist/services/routed-realtime-service.d.ts +10 -2
- package/dist/services/webhook-service.d.ts +76 -1
- package/dist/singleton.d.ts +25 -8
- package/dist/{src-Cum9kox5.js → src-By48Ffg0.js} +322 -70
- package/dist/src-By48Ffg0.js.map +1 -0
- package/dist/{src-_qQ3RNCK.js → src-Ca6NhxKs.js} +79 -2
- package/dist/src-Ca6NhxKs.js.map +1 -0
- package/dist/storage/LocalStorageController.d.ts +12 -1
- package/dist/storage/image-transform.d.ts +57 -0
- package/dist/storage/keys.d.ts +98 -0
- package/dist/storage/routes.d.ts +11 -0
- package/dist/storage/tus-handler.d.ts +7 -1
- package/dist/utils/logger.d.ts +18 -0
- package/dist/utils/logging.d.ts +0 -4
- package/dist/utils/sql.d.ts +11 -6
- package/package.json +7 -6
- package/dist/admin_block-CcSGdH7M.js.map +0 -1
- package/dist/auth-CuC9M2x6.js.map +0 -1
- package/dist/backend-CIxN4FVm.js +0 -15
- package/dist/backend-CIxN4FVm.js.map +0 -1
- package/dist/cron-scheduler-B3RFt0HS.js.map +0 -1
- package/dist/cron-store-BywZsyfZ.js.map +0 -1
- package/dist/errors-CgkCzoj7.js.map +0 -1
- package/dist/function-loader-B_1fYfUY.js +0 -86
- package/dist/function-loader-B_1fYfUY.js.map +0 -1
- package/dist/function-routes-C0cLIy3N.js.map +0 -1
- package/dist/jwt-DD6EtpGj.js.map +0 -1
- package/dist/logger-BYU66ENZ.js +0 -94
- package/dist/logger-BYU66ENZ.js.map +0 -1
- package/dist/openapi-generator-BEwyiaAr.js +0 -597
- package/dist/openapi-generator-BEwyiaAr.js.map +0 -1
- package/dist/schema-editor-routes-CbF20Mf1.js +0 -248
- package/dist/schema-editor-routes-CbF20Mf1.js.map +0 -1
- package/dist/src-Cum9kox5.js.map +0 -1
- package/dist/src-_qQ3RNCK.js.map +0 -1
|
@@ -16,14 +16,89 @@ export interface WebhookDeliveryResult {
|
|
|
16
16
|
success: boolean;
|
|
17
17
|
attemptNumber: number;
|
|
18
18
|
}
|
|
19
|
+
export interface WebhookDispatcherOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Deliver to destinations that resolve to loopback, link-local or private
|
|
22
|
+
* addresses. Off by default. Turning it on re-opens SSRF: anyone who can
|
|
23
|
+
* choose a webhook URL can then reach the pod's metadata endpoint, the
|
|
24
|
+
* cluster API server and the database — and read the first 1000 bytes of
|
|
25
|
+
* the answer back out of `responseBody`. Only for a receiver you run
|
|
26
|
+
* yourself on the same host or network.
|
|
27
|
+
*/
|
|
28
|
+
allowPrivateNetworks?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Deadline for one attempt, covering the response body as well as the
|
|
31
|
+
* headers. Defaults to 10s.
|
|
32
|
+
*/
|
|
33
|
+
timeoutMs?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Called with the final result of every delivery, including the ones
|
|
36
|
+
* started by {@link WebhookDispatcher.enqueueEntityChange} — which return
|
|
37
|
+
* nothing to their caller, so this is the only place their failures
|
|
38
|
+
* surface.
|
|
39
|
+
*/
|
|
40
|
+
onDelivery?: (result: WebhookDeliveryResult) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Hostname resolver used by the destination guard. Defaults to
|
|
43
|
+
* `dns.lookup`; injected by tests so a unit suite never asks a resolver.
|
|
44
|
+
*/
|
|
45
|
+
lookup?: (hostname: string) => Promise<string[]>;
|
|
46
|
+
}
|
|
19
47
|
export declare class WebhookDispatcher {
|
|
20
48
|
private webhooks;
|
|
21
49
|
private maxRetries;
|
|
22
50
|
private retryDelays;
|
|
51
|
+
private readonly options;
|
|
52
|
+
private readonly timeoutMs;
|
|
53
|
+
private queue;
|
|
54
|
+
private draining;
|
|
55
|
+
constructor(options?: WebhookDispatcherOptions);
|
|
23
56
|
/** Register webhooks to watch */
|
|
24
57
|
setWebhooks(webhooks: WebhookConfig[]): void;
|
|
25
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Called when a entity changes — checks if any webhook matches, and awaits
|
|
60
|
+
* every delivery, retries included.
|
|
61
|
+
*
|
|
62
|
+
* **Do not await this inside a collection callback.** `afterSave` and
|
|
63
|
+
* `afterDelete` run inside the write's Postgres transaction, so awaiting a
|
|
64
|
+
* delivery here holds a pooled connection and the row's locks for as long
|
|
65
|
+
* as the receiver takes to answer — up to ~36s across three attempts, per
|
|
66
|
+
* matching webhook. Use {@link enqueueEntityChange} there; this method is
|
|
67
|
+
* for a custom function or a job that wants the results.
|
|
68
|
+
*/
|
|
26
69
|
onEntityChange(table: string, event: "INSERT" | "UPDATE" | "DELETE", id: string, entity: Record<string, unknown> | null, previousEntity?: Record<string, unknown> | null): Promise<WebhookDeliveryResult[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Queue the same deliveries and return immediately.
|
|
72
|
+
*
|
|
73
|
+
* This is the form a collection callback wants. `afterSave` is awaited
|
|
74
|
+
* *inside* the transaction that wrote the row, so anything it awaits is
|
|
75
|
+
* transaction time; queueing hands the HTTP to a drain loop that runs
|
|
76
|
+
* after the callback returns, and the transaction commits without waiting
|
|
77
|
+
* for a third party. It also means a receiver that is down can no longer
|
|
78
|
+
* fail the customer's write.
|
|
79
|
+
*
|
|
80
|
+
* The cost, stated plainly: the queue is in-process and in-memory. A crash
|
|
81
|
+
* or a deploy between the enqueue and the delivery drops the event, and a
|
|
82
|
+
* receiver may see the notification a few milliseconds before the row it
|
|
83
|
+
* describes is committed. Use {@link flush} on shutdown, and
|
|
84
|
+
* `onDelivery` to record failures.
|
|
85
|
+
*/
|
|
86
|
+
enqueueEntityChange(table: string, event: "INSERT" | "UPDATE" | "DELETE", id: string, entity: Record<string, unknown> | null, previousEntity?: Record<string, unknown> | null): void;
|
|
87
|
+
/**
|
|
88
|
+
* Wait for every queued delivery to finish. For graceful shutdown, and for
|
|
89
|
+
* tests that need to observe what {@link enqueueEntityChange} sent.
|
|
90
|
+
*/
|
|
91
|
+
flush(): Promise<void>;
|
|
92
|
+
private startDraining;
|
|
93
|
+
private drainQueue;
|
|
94
|
+
/** The payload each matching webhook gets for this change. */
|
|
95
|
+
private buildDeliveries;
|
|
27
96
|
private deliverWithRetry;
|
|
28
97
|
private deliver;
|
|
98
|
+
/**
|
|
99
|
+
* Read at most {@link MAX_RESPONSE_BYTES} of the response and cancel the
|
|
100
|
+
* rest, so a receiver cannot buffer a 10 GB body into the pod before the
|
|
101
|
+
* caller truncates it to 1000 characters.
|
|
102
|
+
*/
|
|
103
|
+
private readCappedBody;
|
|
29
104
|
}
|
package/dist/singleton.d.ts
CHANGED
|
@@ -22,14 +22,30 @@ export declare function _resetRebaseMock(): void;
|
|
|
22
22
|
* **Admin data plane** (`rebase.dataAsAdmin`):
|
|
23
23
|
* Backed by the native DataDriver — calls go directly to the database without
|
|
24
24
|
* JSON serialization, HTTP dispatch, or middleware overhead. The driver is
|
|
25
|
-
* scoped as `{ uid: "service", roles: ["admin"] }
|
|
26
|
-
*
|
|
25
|
+
* scoped once as `{ uid: "service", roles: ["admin"] }` (`SERVICE_IDENTITY`),
|
|
26
|
+
* which makes it **admin-scoped, not RLS-bypassing**: every read and write runs
|
|
27
|
+
* in a transaction that has done `SET LOCAL ROLE rebase_user` with
|
|
28
|
+
* `app.uid = 'service'`, and policies are evaluated against that. No
|
|
29
|
+
* `REBASE_SERVICE_KEY` is required.
|
|
27
30
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
31
|
+
* It clears the default policies through their `rolesOverlap(['admin'])` arm —
|
|
32
|
+
* which is why the difference rarely shows. It shows when you write your own:
|
|
33
|
+
*
|
|
34
|
+
* - `policy.serverContext()` compiles to `auth.uid() IS NULL` and is therefore
|
|
35
|
+
* **false** for this accessor. A collection with `disableDefaultPolicies:
|
|
36
|
+
* true` whose rule is `serverContext()` denies these writes (`42501`) and
|
|
37
|
+
* returns zero rows — HTTP 200, empty — for these reads.
|
|
38
|
+
* - Its reach equals an `admin`-roled application user's reach. It is not a
|
|
39
|
+
* private door.
|
|
40
|
+
*
|
|
41
|
+
* `rebase.sql()` *is* an unconditional bypass — it runs on the owner connection
|
|
42
|
+
* and never goes through `withAuth`. Of the two accessors on this object, the
|
|
43
|
+
* quieter one is the more privileged.
|
|
44
|
+
*
|
|
45
|
+
* ⚠️ `rebase.dataAsAdmin` is for trusted background work (cron jobs,
|
|
46
|
+
* migrations, service tasks) — **not** for serving user-facing data. Inside a
|
|
47
|
+
* request handler, run user-scoped queries through the request-scoped driver
|
|
48
|
+
* (`c.var.driver`), which carries the caller's identity.
|
|
33
49
|
*
|
|
34
50
|
* `rebase.data` is **gone from the type**: `RebaseServerClient` omits it, so the
|
|
35
51
|
* admin-scoped accessor has exactly one name and the privilege is visible at the
|
|
@@ -45,7 +61,8 @@ export declare function _resetRebaseMock(): void;
|
|
|
45
61
|
* ```typescript
|
|
46
62
|
* import { rebase } from "@rebasepro/server";
|
|
47
63
|
*
|
|
48
|
-
* // In a cron job, hook, or trusted service file (admin scope,
|
|
64
|
+
* // In a cron job, hook, or trusted service file (admin scope, RLS evaluated
|
|
65
|
+
* // as `{ uid: "service", roles: ["admin"] }`):
|
|
49
66
|
* await rebase.email.send({ to: "admin@co.com", subject: "Alert", html: "<p>Hi</p>" });
|
|
50
67
|
* const jobs = await rebase.dataAsAdmin.jobs.find({ limit: 10 });
|
|
51
68
|
* ```
|