@rebasepro/server 0.20.1-canary.g4d882ca → 0.21.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/api/rest/api-generator.d.ts +28 -0
- package/dist/auth/jwt.d.ts +67 -0
- package/dist/auth/rls-scope.d.ts +14 -0
- package/dist/{auth-DJsLXsCR.js → auth-gzoRjnuh.js} +24 -12
- package/dist/auth-gzoRjnuh.js.map +1 -0
- package/dist/boot/env.d.ts +8 -2
- package/dist/boot/fetch-bundle.d.ts +19 -0
- package/dist/boot/role.d.ts +2 -0
- package/dist/contract-routes-eLxV0le1.js.map +1 -1
- package/dist/{cron-routes-Bfwni8Zg.js → cron-routes-BamgO0Xr.js} +2 -2
- package/dist/{cron-routes-Bfwni8Zg.js.map → cron-routes-BamgO0Xr.js.map} +1 -1
- package/dist/{cron-store-Bsiw4Q6u.js → cron-store-yXOyIEmn.js} +2 -3
- package/dist/{cron-store-Bsiw4Q6u.js.map → cron-store-yXOyIEmn.js.map} +1 -1
- package/dist/db/ambient-transaction.d.ts +48 -0
- package/dist/ddl-bootstrap-CfNvxMuK.js.map +1 -1
- package/dist/deploy/pod-contract.d.ts +1 -1
- package/dist/errors-DMImyqyR.js.map +1 -1
- package/dist/functions/index.js.map +1 -1
- package/dist/{history-recorder-r5_IzSHK.js → history-recorder-hBGuXcZc.js} +2 -2
- package/dist/{history-recorder-r5_IzSHK.js.map → history-recorder-hBGuXcZc.js.map} +1 -1
- package/dist/{history-store-D4RVK-uZ.js → history-store-C9EtGtoL.js} +5 -6
- package/dist/history-store-C9EtGtoL.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.es.js +2263 -90
- package/dist/index.es.js.map +1 -1
- package/dist/init/callback-client.d.ts +16 -0
- package/dist/init/surfaces.d.ts +37 -7
- package/dist/jobs/types.d.ts +5 -0
- package/dist/{jobs-CW5lm_Ix.js → jobs-DZ8DLLcU.js} +82 -13
- package/dist/jobs-DZ8DLLcU.js.map +1 -0
- package/dist/{jwt-DATvkKB_.js → jwt-C4OW-DNq.js} +136 -4
- package/dist/jwt-C4OW-DNq.js.map +1 -0
- package/dist/logger-DO2PZc4i.js.map +1 -1
- package/dist/mcp/consent-page.d.ts +75 -0
- package/dist/mcp/mcp-routes.d.ts +52 -0
- package/dist/mcp/mcp-tools.d.ts +51 -0
- package/dist/mcp/oauth-metadata.d.ts +123 -0
- package/dist/mcp/oauth-routes.d.ts +52 -0
- package/dist/mcp/oauth-store.d.ts +157 -0
- package/dist/metrics/index.d.ts +16 -1
- package/dist/{openapi-generator-DGyLbISS.js → openapi-generator-CAFKF36E.js} +2 -8
- package/dist/openapi-generator-CAFKF36E.js.map +1 -0
- package/dist/{query-parser-BQiPZrM-.js → query-parser-uqzkZ82i.js} +2 -2
- package/dist/{query-parser-BQiPZrM-.js.map → query-parser-uqzkZ82i.js.map} +1 -1
- package/dist/services/webhook-service.d.ts +11 -8
- package/dist/sql-rows-C6GEc2oE.js +45 -0
- package/dist/sql-rows-C6GEc2oE.js.map +1 -0
- package/dist/src-Br6ARbs6.js.map +1 -1
- package/dist/{src-DqZ9YiGA.js → src-DW1cQ_28.js} +261 -17
- package/dist/src-DW1cQ_28.js.map +1 -0
- package/dist/utils/portable-crypto.d.ts +8 -0
- package/package.json +5 -5
- package/dist/auth-DJsLXsCR.js.map +0 -1
- package/dist/history-store-D4RVK-uZ.js.map +0 -1
- package/dist/internal-tables-DYVcFFSv.js +0 -117
- package/dist/internal-tables-DYVcFFSv.js.map +0 -1
- package/dist/jobs-CW5lm_Ix.js.map +0 -1
- package/dist/jwt-DATvkKB_.js.map +0 -1
- package/dist/openapi-generator-DGyLbISS.js.map +0 -1
- package/dist/src-DqZ9YiGA.js.map +0 -1
|
@@ -141,6 +141,34 @@ export declare class RestApiGenerator {
|
|
|
141
141
|
* it here would report a resolution failure as a validation failure.
|
|
142
142
|
*/
|
|
143
143
|
private resolveNestedWriteCollection;
|
|
144
|
+
/**
|
|
145
|
+
* `PATCH <collection>/<id>/<relation>/<targetId>` with a `_pivot` body: set
|
|
146
|
+
* the columns that one many-to-many link carries.
|
|
147
|
+
*
|
|
148
|
+
* The membership array on the parent (`PATCH posts/1 { tags: [...] }`) sets
|
|
149
|
+
* *which* links exist; this sets what one of them holds. They are separate
|
|
150
|
+
* because the array cannot express a single-link edit without either
|
|
151
|
+
* unlinking everything it omits or re-sending the whole set — and re-sending
|
|
152
|
+
* the set to change one `role` is exactly the lost update that the
|
|
153
|
+
* membership diff exists to avoid.
|
|
154
|
+
*
|
|
155
|
+
* Validated against the junction's own properties, through the same
|
|
156
|
+
* `assertWriteRequestValid` a row's values go through: `required`, `enum`,
|
|
157
|
+
* `min`/`max`/`matches` and per-field `access.write` mean the same thing on
|
|
158
|
+
* a payload column as on a collection's, or the promise that they are
|
|
159
|
+
* "declared exactly like collection properties" is not one.
|
|
160
|
+
*/
|
|
161
|
+
private updateRelationPivotFromBody;
|
|
162
|
+
/**
|
|
163
|
+
* The synthetic collection standing in for the junction a nested path's last
|
|
164
|
+
* hop reaches through, or `undefined` when that hop is not a `manyToMany`
|
|
165
|
+
* carrying `through.properties`.
|
|
166
|
+
*
|
|
167
|
+
* Built from the relation rather than by walking every collection: the same
|
|
168
|
+
* `getJunctionConfigForRelation` the schema planner and the driver use, so
|
|
169
|
+
* the shape validated here is the shape the columns were emitted from.
|
|
170
|
+
*/
|
|
171
|
+
private resolveJunctionCollection;
|
|
144
172
|
/**
|
|
145
173
|
* Get the request-scoped driver. Throws if none is set — never falls
|
|
146
174
|
* back to the unscoped `this.driver` to avoid bypassing RLS/auth.
|
package/dist/auth/jwt.d.ts
CHANGED
|
@@ -249,3 +249,70 @@ export declare function generateDownloadToken(path: string, expiresInSeconds?: n
|
|
|
249
249
|
* for a *named* source is refused and the client re-fetches `/metadata`.
|
|
250
250
|
*/
|
|
251
251
|
export declare function verifyDownloadToken(token: string): Promise<DownloadTokenPayload | null>;
|
|
252
|
+
/**
|
|
253
|
+
* Sign a short-lived token that carries state across a redirect.
|
|
254
|
+
*
|
|
255
|
+
* The generalisation of the MFA-pending token: a signed blob the server hands
|
|
256
|
+
* out and expects back, where the point is that the holder cannot edit it. The
|
|
257
|
+
* OAuth authorize flow needs one to carry the authorization request across the
|
|
258
|
+
* sign-in hop — without it, the endpoint the consent page posts to would mint a
|
|
259
|
+
* code for whatever `client_id` and `redirect_uri` its caller typed, skipping
|
|
260
|
+
* every check the authorize endpoint performs.
|
|
261
|
+
*
|
|
262
|
+
* The `purpose` is not decoration. {@link verifyAccessToken} refuses any token
|
|
263
|
+
* that has one, so nothing minted here can be replayed as a session, and
|
|
264
|
+
* {@link verifyPurposeToken} refuses a token whose purpose is not the one the
|
|
265
|
+
* caller named — so a token minted for one hop cannot be spent on another.
|
|
266
|
+
*/
|
|
267
|
+
export declare function signPurposeToken(purpose: string, claims: Record<string, unknown>, expiresInSeconds: number): Promise<string>;
|
|
268
|
+
/** Verify a token minted by {@link signPurposeToken}, for one named purpose. */
|
|
269
|
+
export declare function verifyPurposeToken<T>(purpose: string, token: string): Promise<T | null>;
|
|
270
|
+
/** The `purpose` that marks a token as belonging to the MCP resource. */
|
|
271
|
+
export declare const MCP_ACCESS_PURPOSE = "mcp-access";
|
|
272
|
+
export interface McpAccessTokenPayload {
|
|
273
|
+
purpose: typeof MCP_ACCESS_PURPOSE;
|
|
274
|
+
/** The person the token acts for. Fed straight to `withAuth()`, so RLS sees them. */
|
|
275
|
+
uid: string;
|
|
276
|
+
roles: string[];
|
|
277
|
+
/** Granted OAuth scope, space-separated. */
|
|
278
|
+
scope: string;
|
|
279
|
+
/** Which registered client holds this token — carried for audit and revocation. */
|
|
280
|
+
clientId: string;
|
|
281
|
+
/** The resource this token is bound to (RFC 8707). */
|
|
282
|
+
aud: string;
|
|
283
|
+
iss: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Mint an access token for the MCP endpoint.
|
|
287
|
+
*
|
|
288
|
+
* Deliberately **not** an ordinary session token, and the `purpose` claim is
|
|
289
|
+
* what enforces that: {@link verifyAccessToken} refuses any token carrying one,
|
|
290
|
+
* so a credential issued to a third-party MCP client — Claude, an IDE, anything
|
|
291
|
+
* that completed the OAuth flow — cannot be replayed against `/api/data`,
|
|
292
|
+
* `/api/admin` or the websocket. It buys exactly the one resource it names.
|
|
293
|
+
*
|
|
294
|
+
* That asymmetry matters more than it first looks. These tokens are handed to
|
|
295
|
+
* software the user authorized but the operator never vetted, they live in that
|
|
296
|
+
* software's storage, and they are the only credential in this system minted
|
|
297
|
+
* for a third party. Without the purpose separation, "connect Claude to your
|
|
298
|
+
* data" would silently mean "give Claude a full session".
|
|
299
|
+
*
|
|
300
|
+
* The audience is the canonical resource URI, and {@link verifyMcpAccessToken}
|
|
301
|
+
* requires the caller to say which resource it is checking for. A token minted
|
|
302
|
+
* for another Rebase project — or another path on this one — fails there.
|
|
303
|
+
*
|
|
304
|
+
* HS256 with the shared secret, like the download token: the authorization
|
|
305
|
+
* server and the resource server are the same process, so nothing outside it
|
|
306
|
+
* ever needs to verify one, and an asymmetric key here would be a second key
|
|
307
|
+
* surface bought for nobody.
|
|
308
|
+
*/
|
|
309
|
+
export declare function generateMcpAccessToken(payload: Omit<McpAccessTokenPayload, "purpose">, expiresInSeconds: number): Promise<string>;
|
|
310
|
+
/**
|
|
311
|
+
* Verify an MCP access token **for a specific resource**.
|
|
312
|
+
*
|
|
313
|
+
* `expectedAudience` has no default. The MCP specification requires a resource
|
|
314
|
+
* server to validate that a token was issued for it specifically, and a default
|
|
315
|
+
* would be the thing that quietly turns that check off — the caller has to say
|
|
316
|
+
* what it is, every time, so a new call site cannot forget by omission.
|
|
317
|
+
*/
|
|
318
|
+
export declare function verifyMcpAccessToken(token: string, expectedAudience: string): Promise<McpAccessTokenPayload | null>;
|
package/dist/auth/rls-scope.d.ts
CHANGED
|
@@ -37,6 +37,20 @@ export declare const SERVICE_IDENTITY: {
|
|
|
37
37
|
uid: string;
|
|
38
38
|
roles: string[];
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Can this driver run a request as a specific user?
|
|
42
|
+
*
|
|
43
|
+
* The same question `scopeDataDriver` asks internally, exported because one
|
|
44
|
+
* caller must act on the answer BEFORE it has a request to scope.
|
|
45
|
+
*
|
|
46
|
+
* `scopeDataDriver` returns the driver unscoped when the answer is no, which is
|
|
47
|
+
* the right behaviour for `/api/data` — Mongo has no row-level security and
|
|
48
|
+
* never claimed to, and the route's own checks still apply. It is the wrong
|
|
49
|
+
* behaviour for a surface whose entire promise is "this runs as you": there,
|
|
50
|
+
* an unscoped driver silently means "runs as the database owner". So the MCP
|
|
51
|
+
* surface asks this at boot and declines to mount rather than degrade.
|
|
52
|
+
*/
|
|
53
|
+
export declare function supportsRlsScoping(driver: DataDriver): boolean;
|
|
40
54
|
/**
|
|
41
55
|
* Scope a DataDriver via `withAuth()` for RLS.
|
|
42
56
|
*
|
|
@@ -3,14 +3,14 @@ import __rebaseProcess from "process";
|
|
|
3
3
|
globalThis.process ??= __rebaseProcess;
|
|
4
4
|
__rebaseCreateRequire(import.meta.url);
|
|
5
5
|
import { i as __toESM, n as __exportAll } from "./rolldown-runtime-dW7B1o5h.js";
|
|
6
|
-
import {
|
|
6
|
+
import { P as revokeInternalTableSql, at as isAnonymousUid, it as ANONYMOUS_USER_ID } from "./src-DW1cQ_28.js";
|
|
7
7
|
import "./src-Br6ARbs6.js";
|
|
8
8
|
import { n as createDdlBootstrapper, o as isSQLAdmin } from "./ddl-bootstrap-CfNvxMuK.js";
|
|
9
|
-
import { t as
|
|
9
|
+
import { t as firstSqlRow } from "./sql-rows-C6GEc2oE.js";
|
|
10
10
|
import { r as logger } from "./logger-DO2PZc4i.js";
|
|
11
11
|
import { n as errorHandler, t as ApiError } from "./errors-DMImyqyR.js";
|
|
12
|
-
import { a as resolveListLimitParam } from "./query-parser-
|
|
13
|
-
import {
|
|
12
|
+
import { a as resolveListLimitParam } from "./query-parser-uqzkZ82i.js";
|
|
13
|
+
import { C as require_jsonwebtoken, E as randomInt$1, O as sha256Hex, _ as verifyAccessToken, b as verifyMfaPendingToken, c as getAccessTokenExpiry, d as getRefreshTokenTtlMs, f as hasAsymmetricSigningKey, i as generateDownloadToken, l as getJwks, m as isJwtConfigured, n as configureJwt, o as generateMfaPendingToken, p as hashRefreshToken, r as generateAccessToken, s as generateRefreshToken, t as MAX_COOKIE_AGE_MS, u as getRefreshTokenExpiry, v as verifyDownloadToken, w as constantTimeEqual } from "./jwt-C4OW-DNq.js";
|
|
14
14
|
import { n as hasAdministrativeRole, r as isAdministrativeRole, t as ADMINISTRATIVE_ROLES } from "./admin-roles-vYdp_Pil.js";
|
|
15
15
|
import { c as tryCanonicalStorageKey, i as canonicalStorageId } from "./keys-Qfc4XieN.js";
|
|
16
16
|
import { createHash, randomBytes, randomInt } from "node:crypto";
|
|
@@ -241,6 +241,22 @@ function isRLSScopedDriver(driver) {
|
|
|
241
241
|
return "withAuth" in driver && typeof driver.withAuth === "function";
|
|
242
242
|
}
|
|
243
243
|
/**
|
|
244
|
+
* Can this driver run a request as a specific user?
|
|
245
|
+
*
|
|
246
|
+
* The same question `scopeDataDriver` asks internally, exported because one
|
|
247
|
+
* caller must act on the answer BEFORE it has a request to scope.
|
|
248
|
+
*
|
|
249
|
+
* `scopeDataDriver` returns the driver unscoped when the answer is no, which is
|
|
250
|
+
* the right behaviour for `/api/data` — Mongo has no row-level security and
|
|
251
|
+
* never claimed to, and the route's own checks still apply. It is the wrong
|
|
252
|
+
* behaviour for a surface whose entire promise is "this runs as you": there,
|
|
253
|
+
* an unscoped driver silently means "runs as the database owner". So the MCP
|
|
254
|
+
* surface asks this at boot and declines to mount rather than degrade.
|
|
255
|
+
*/
|
|
256
|
+
function supportsRlsScoping(driver) {
|
|
257
|
+
return isRLSScopedDriver(driver);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
244
260
|
* Scope a DataDriver via `withAuth()` for RLS.
|
|
245
261
|
*
|
|
246
262
|
* SECURITY: If `withAuth()` is available but fails, the error is re-thrown
|
|
@@ -3544,7 +3560,7 @@ function mountSessionRoutes(opts) {
|
|
|
3544
3560
|
clearRefreshCookie(c, config.cookieAuth);
|
|
3545
3561
|
const accessToken = extractBearerToken(c.req.header("authorization"));
|
|
3546
3562
|
if (ops.afterLogout && accessToken !== void 0) {
|
|
3547
|
-
const { verifyAccessToken } = await import("./jwt-
|
|
3563
|
+
const { verifyAccessToken } = await import("./jwt-C4OW-DNq.js").then((n) => n.h);
|
|
3548
3564
|
const payload = await verifyAccessToken(accessToken);
|
|
3549
3565
|
if (payload) ops.afterLogout(payload.uid).catch((err) => {
|
|
3550
3566
|
logger.error("[AuthHooks] afterLogout error", { error: err instanceof Error ? err.message : err });
|
|
@@ -6572,11 +6588,7 @@ function createSqlRateLimitStore(driver, options = {}) {
|
|
|
6572
6588
|
* being on their first request — a limiter that never limits, with no error
|
|
6573
6589
|
* anywhere. Tolerating both costs one line.
|
|
6574
6590
|
*/
|
|
6575
|
-
|
|
6576
|
-
if (Array.isArray(result)) return result[0];
|
|
6577
|
-
const rows = result?.rows;
|
|
6578
|
-
return Array.isArray(rows) ? rows[0] : void 0;
|
|
6579
|
-
}
|
|
6591
|
+
var firstRow = firstSqlRow;
|
|
6580
6592
|
//#endregion
|
|
6581
6593
|
//#region src/auth/resolve-rate-limit-store.ts
|
|
6582
6594
|
/**
|
|
@@ -7093,6 +7105,6 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
7093
7105
|
verifyPassword: () => verifyPassword
|
|
7094
7106
|
});
|
|
7095
7107
|
//#endregion
|
|
7096
|
-
export {
|
|
7108
|
+
export { RawHtml as $, defaultAuthLimiter as A, resolveEmailLinkBase as B, providerVerifiedEmail as C, httpMethodToOperation as Ct, DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT as D, isBootstrapWindowOpen as E, isPublicStoragePath as Et, extractLinks as F, generateSecurePassword as G, hashPassword as H, registerDevEmailSink as I, getMagicLinkTemplate as J, getEmailOtpTemplate as K, SMTPEmailService as L, activeDevEmailSink as M, clearActiveDevEmailSink as N, createDataRateLimiter as O, createDevEmailSink as P, resolveEmailBranding as Q, createEmailService as R, pkceTokenParams as S, supportsRlsScoping as St, createBuiltinAuthAdapter as T, PUBLIC_STORAGE_PREFIX as Tt, validatePasswordStrength as U, resolveAuthHooks as V, verifyPassword as W, getUserInvitationTemplate as X, getPasswordResetTemplate as Y, getWelcomeEmailTemplate as Z, verifyOidcIdToken as _, validateApiKey as _t, resolveRateLimitStoreKind as a, createRequireAuth as at, createGoogleProvider as b, SERVICE_IDENTITY as bt, createSlackProvider as c, optionalAuth as ct, createDiscordProvider as d, requireAdmin as dt, escapeHtml as et, createTwitterProvider as f, requireAuth as ft, tryVerifyOidcIdToken as g, isApiKeyToken as gt, createMicrosoftProvider as h, createStorageApiKeyGuard as ht, createApiKeyStore as i, createAuthMiddleware as it, MemoryRateLimitStore as j, createRateLimiter as k, createBitbucketProvider as l, publicObjectAuth as lt, createAppleProvider as m, createFunctionApiKeyGuard as mt, createCustomAuthAdapter as n, raw as nt, createSqlRateLimitStore as o, extractUserFromToken as ot, createFacebookProvider as p, createApiKeyPreAuth as pt, getEmailVerificationTemplate as q, createApiKeyRoutes as r, createAdapterAuthMiddleware as rt, createSpotifyProvider as s, fileTokenAuth as st, auth_exports as t, html as tt, createGitLabProvider as u, queryTokenAuth as ut, createGitHubProvider as v, extractBearerToken as vt, createJwksRoutes as w, isOperationAllowed as wt, oauthCodeFlowSchema as x, scopeDataDriver as xt, createLinkedinProvider as y, safeCompare as yt, assertEmailLinkBases as z };
|
|
7097
7109
|
|
|
7098
|
-
//# sourceMappingURL=auth-
|
|
7110
|
+
//# sourceMappingURL=auth-gzoRjnuh.js.map
|