@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.
Files changed (125) hide show
  1. package/dist/{admin_block-CcSGdH7M.js → admin_block-H86dCPsj.js} +62 -2
  2. package/dist/admin_block-H86dCPsj.js.map +1 -0
  3. package/dist/api/ast-schema-editor.d.ts +74 -6
  4. package/dist/api/errors.d.ts +0 -6
  5. package/dist/api/openapi-generator.d.ts +14 -0
  6. package/dist/api/rest/api-generator.d.ts +1 -1
  7. package/dist/api/rest/idempotency.d.ts +62 -4
  8. package/dist/api/rest/query-parser.d.ts +15 -1
  9. package/dist/api/rest/write-validation.d.ts +52 -9
  10. package/dist/auth/adapter-middleware.d.ts +3 -1
  11. package/dist/auth/apple-oauth.d.ts +16 -11
  12. package/dist/auth/bitbucket-oauth.d.ts +2 -4
  13. package/dist/auth/builtin-auth-adapter.d.ts +2 -0
  14. package/dist/auth/discord-oauth.d.ts +5 -6
  15. package/dist/auth/facebook-oauth.d.ts +2 -4
  16. package/dist/auth/github-oauth.d.ts +2 -4
  17. package/dist/auth/gitlab-oauth.d.ts +6 -4
  18. package/dist/auth/google-oauth.d.ts +1 -0
  19. package/dist/auth/index.d.ts +8 -1
  20. package/dist/auth/interfaces.d.ts +68 -1
  21. package/dist/auth/jwt.d.ts +40 -0
  22. package/dist/auth/linkedin-oauth.d.ts +2 -4
  23. package/dist/auth/mfa-gate.d.ts +42 -0
  24. package/dist/auth/mfa-routes.d.ts +26 -1
  25. package/dist/auth/mfa.d.ts +16 -0
  26. package/dist/auth/microsoft-oauth.d.ts +19 -4
  27. package/dist/auth/oauth-code-flow.d.ts +66 -0
  28. package/dist/auth/oauth-signin-policy.d.ts +61 -0
  29. package/dist/auth/oidc-id-token.d.ts +61 -0
  30. package/dist/auth/rate-limiter.d.ts +37 -2
  31. package/dist/auth/rls-scope.d.ts +25 -0
  32. package/dist/auth/routes.d.ts +8 -0
  33. package/dist/auth/slack-oauth.d.ts +2 -4
  34. package/dist/auth/spotify-oauth.d.ts +2 -4
  35. package/dist/auth/twitter-oauth.d.ts +2 -5
  36. package/dist/{auth-CuC9M2x6.js → auth-DkAHqvf5.js} +1604 -391
  37. package/dist/auth-DkAHqvf5.js.map +1 -0
  38. package/dist/{backup-CVggVhR2.js → backup-DLluVyuA.js} +2 -2
  39. package/dist/{backup-CVggVhR2.js.map → backup-DLluVyuA.js.map} +1 -1
  40. package/dist/boot/boot.d.ts +19 -0
  41. package/dist/boot/ddl-bootstrap.d.ts +70 -0
  42. package/dist/{contract-routes-Dj8i5AiM.js → contract-routes-BB1U05sS.js} +3 -3
  43. package/dist/{contract-routes-Dj8i5AiM.js.map → contract-routes-BB1U05sS.js.map} +1 -1
  44. package/dist/cron/cron-scheduler.d.ts +8 -3
  45. package/dist/cron/define-cron.d.ts +17 -3
  46. package/dist/{cron-loader-B1S2MCSl.js → cron-loader-3U5aGILy.js} +2 -2
  47. package/dist/{cron-loader-B1S2MCSl.js.map → cron-loader-3U5aGILy.js.map} +1 -1
  48. package/dist/{cron-routes-CrQ0tK-_.js → cron-routes-rZgwlOz4.js} +2 -2
  49. package/dist/{cron-routes-CrQ0tK-_.js.map → cron-routes-rZgwlOz4.js.map} +1 -1
  50. package/dist/{cron-scheduler-B3RFt0HS.js → cron-scheduler-FJAaCAXm.js} +30 -5
  51. package/dist/cron-scheduler-FJAaCAXm.js.map +1 -0
  52. package/dist/{cron-store-BywZsyfZ.js → cron-store-9NmUDfzL.js} +66 -47
  53. package/dist/cron-store-9NmUDfzL.js.map +1 -0
  54. package/dist/ddl-bootstrap-BhXbTnBl.js +183 -0
  55. package/dist/ddl-bootstrap-BhXbTnBl.js.map +1 -0
  56. package/dist/email/html.d.ts +54 -0
  57. package/dist/email/index.d.ts +3 -0
  58. package/dist/email/link-base.d.ts +39 -0
  59. package/dist/email/smtp-email-service.d.ts +7 -1
  60. package/dist/email/templates.d.ts +9 -1
  61. package/dist/email/types.d.ts +11 -1
  62. package/dist/{errors-CgkCzoj7.js → errors-B1WZEdsK.js} +3 -11
  63. package/dist/errors-B1WZEdsK.js.map +1 -0
  64. package/dist/function-loader-D1SwtCa5.js +139 -0
  65. package/dist/function-loader-D1SwtCa5.js.map +1 -0
  66. package/dist/{function-routes-C0cLIy3N.js → function-routes-Btcez1T-.js} +18 -6
  67. package/dist/function-routes-Btcez1T-.js.map +1 -0
  68. package/dist/functions/define-function.d.ts +25 -6
  69. package/dist/functions/function-loader.d.ts +23 -0
  70. package/dist/functions/function-routes.d.ts +7 -1
  71. package/dist/functions/request-timeout.d.ts +34 -0
  72. package/dist/history/history-routes.d.ts +6 -0
  73. package/dist/index.d.ts +2 -1
  74. package/dist/index.es.js +1960 -794
  75. package/dist/index.es.js.map +1 -1
  76. package/dist/init/docs.d.ts +10 -1
  77. package/dist/init/process-safety.d.ts +25 -0
  78. package/dist/init.d.ts +27 -0
  79. package/dist/{jwt-DD6EtpGj.js → jwt-Cuq6MwNy.js} +70 -8
  80. package/dist/jwt-Cuq6MwNy.js.map +1 -0
  81. package/dist/logger-DfvF_8r-.js +190 -0
  82. package/dist/logger-DfvF_8r-.js.map +1 -0
  83. package/dist/openapi-generator-BQxxxDpb.js +865 -0
  84. package/dist/openapi-generator-BQxxxDpb.js.map +1 -0
  85. package/dist/request-timeout-RivJsME0.js +65 -0
  86. package/dist/request-timeout-RivJsME0.js.map +1 -0
  87. package/dist/schema-editor-routes-DZFKGXgq.js +437 -0
  88. package/dist/schema-editor-routes-DZFKGXgq.js.map +1 -0
  89. package/dist/serve-spa.d.ts +5 -4
  90. package/dist/services/outbound-url-guard.d.ts +53 -0
  91. package/dist/services/routed-realtime-service.d.ts +10 -2
  92. package/dist/services/webhook-service.d.ts +76 -1
  93. package/dist/singleton.d.ts +25 -8
  94. package/dist/{src-Cum9kox5.js → src-By48Ffg0.js} +322 -70
  95. package/dist/src-By48Ffg0.js.map +1 -0
  96. package/dist/{src-_qQ3RNCK.js → src-Ca6NhxKs.js} +79 -2
  97. package/dist/src-Ca6NhxKs.js.map +1 -0
  98. package/dist/storage/LocalStorageController.d.ts +12 -1
  99. package/dist/storage/image-transform.d.ts +57 -0
  100. package/dist/storage/keys.d.ts +98 -0
  101. package/dist/storage/routes.d.ts +11 -0
  102. package/dist/storage/tus-handler.d.ts +7 -1
  103. package/dist/utils/logger.d.ts +18 -0
  104. package/dist/utils/logging.d.ts +0 -4
  105. package/dist/utils/sql.d.ts +11 -6
  106. package/package.json +7 -6
  107. package/dist/admin_block-CcSGdH7M.js.map +0 -1
  108. package/dist/auth-CuC9M2x6.js.map +0 -1
  109. package/dist/backend-CIxN4FVm.js +0 -15
  110. package/dist/backend-CIxN4FVm.js.map +0 -1
  111. package/dist/cron-scheduler-B3RFt0HS.js.map +0 -1
  112. package/dist/cron-store-BywZsyfZ.js.map +0 -1
  113. package/dist/errors-CgkCzoj7.js.map +0 -1
  114. package/dist/function-loader-B_1fYfUY.js +0 -86
  115. package/dist/function-loader-B_1fYfUY.js.map +0 -1
  116. package/dist/function-routes-C0cLIy3N.js.map +0 -1
  117. package/dist/jwt-DD6EtpGj.js.map +0 -1
  118. package/dist/logger-BYU66ENZ.js +0 -94
  119. package/dist/logger-BYU66ENZ.js.map +0 -1
  120. package/dist/openapi-generator-BEwyiaAr.js +0 -597
  121. package/dist/openapi-generator-BEwyiaAr.js.map +0 -1
  122. package/dist/schema-editor-routes-CbF20Mf1.js +0 -248
  123. package/dist/schema-editor-routes-CbF20Mf1.js.map +0 -1
  124. package/dist/src-Cum9kox5.js.map +0 -1
  125. package/dist/src-_qQ3RNCK.js.map +0 -1
@@ -1,4 +1,13 @@
1
1
  import { Hono } from "hono";
2
2
  import { CollectionConfig } from "@rebasepro/types";
3
3
  import { HonoEnv } from "../api/types";
4
- export declare function mountOpenApiDocs(app: Hono<HonoEnv>, basePath: string, enableSwagger: boolean | undefined, activeCollections: CollectionConfig[], requireAuth: boolean): Promise<void>;
4
+ /**
5
+ * Serve the OpenAPI document, and Swagger UI outside production.
6
+ *
7
+ * `serverCollections` must be the collections the REST routes were generated
8
+ * from — the ones whose data source has a `"server"` transport — not every
9
+ * active collection. A direct-transport collection is served by the client
10
+ * against its own backend; documenting it here publishes a full set of CRUD
11
+ * paths that 404, with a Try-It button next to each.
12
+ */
13
+ export declare function mountOpenApiDocs(app: Hono<HonoEnv>, basePath: string, enableSwagger: boolean | undefined, serverCollections: CollectionConfig[], requireAuth: boolean): Promise<void>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Log unhandled promise rejections instead of letting Node terminate the
3
+ * process.
4
+ *
5
+ * Node has terminated on an unhandled rejection since v15. Hono catches
6
+ * anything thrown or rejected inside an awaited handler, so the ordinary
7
+ * request path is covered — but a fire-and-forget `void syncToCrm(body)`, a
8
+ * `setTimeout(async () => …)`, or an unawaited `.then()` in one custom function
9
+ * rejects outside Hono's frame. The default outcome is that one project's
10
+ * floating promise ends the process; on the managed runtime that process is
11
+ * shared, so every other tenant on the pod goes with it, and the request log
12
+ * points nowhere because the request itself succeeded.
13
+ *
14
+ * A logged rejection is the better trade here: the process keeps serving, and
15
+ * the stack reaches the operator. `uncaughtException` is deliberately **not**
16
+ * handled — a synchronous throw that escaped every frame leaves the process in
17
+ * a state we cannot reason about, and swallowing it would be a worse bargain
18
+ * than a restart.
19
+ *
20
+ * Set `REBASE_EXIT_ON_UNHANDLED_REJECTION=1` to restore Node's default.
21
+ *
22
+ * @returns An uninstall function (used by tests), or `undefined` when nothing
23
+ * was installed.
24
+ */
25
+ export declare function installUnhandledRejectionHandler(): (() => void) | undefined;
package/dist/init.d.ts CHANGED
@@ -149,6 +149,22 @@ export interface RebaseAuthConfig {
149
149
  * ```
150
150
  */
151
151
  providers?: OAuthProvider<unknown>[];
152
+ /**
153
+ * Redirect URIs the OAuth sign-in routes will accept, for every provider.
154
+ *
155
+ * Left unset, the only check is the provider's own registered-URI match —
156
+ * which authorises *every* URI registered on that OAuth client, including
157
+ * the `localhost` entry someone added for development and the staging host
158
+ * nobody removed. List the origins this backend actually serves to narrow
159
+ * it. Compared on origin plus path; query, fragment and a trailing slash
160
+ * are ignored.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * auth: { allowedRedirectUris: ["https://admin.example.com/"] }
165
+ * ```
166
+ */
167
+ allowedRedirectUris?: string[];
152
168
  /**
153
169
  * Override specific parts of the built-in auth implementation.
154
170
  *
@@ -344,6 +360,17 @@ export interface RebaseBackendConfig {
344
360
  history?: HistoryConfig;
345
361
  enableSwagger?: boolean;
346
362
  functionsDir?: string;
363
+ /**
364
+ * Per-request ceiling for `/api/functions/*`, in milliseconds.
365
+ *
366
+ * Custom functions run code the framework did not write, and nothing else
367
+ * in the stack bounds it. Defaults to 30000 (or
368
+ * `REBASE_FUNCTIONS_TIMEOUT_MS`). `0` disables the ceiling — for a function
369
+ * that legitimately runs long, or a deployment whose proxy already imposes
370
+ * one. Timed-out requests answer 504; the handler itself cannot be
371
+ * cancelled, so give outbound calls an `AbortSignal`.
372
+ */
373
+ functionsTimeoutMs?: number;
347
374
  cronsDir?: string;
348
375
  /**
349
376
  * Enable/disable database persistence for cron job execution logs.
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from "module";
2
2
  import process from "process";
3
3
  __createRequire(import.meta.url);
4
4
  import { i as __toESM, n as __exportAll, r as __require, t as __commonJSMin } from "./rolldown-runtime-DSJWtz9O.js";
5
- import { t as logger } from "./logger-BYU66ENZ.js";
5
+ import { t as logger } from "./logger-DfvF_8r-.js";
6
6
  import { createHash, randomBytes } from "crypto";
7
7
  //#region ../../node_modules/.pnpm/safe-buffer@5.2.1/node_modules/safe-buffer/index.js
8
8
  var require_safe_buffer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -2275,7 +2275,7 @@ var require_verify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2275
2275
  var validateAsymmetricKey = require_validateAsymmetricKey();
2276
2276
  var PS_SUPPORTED = require_psSupported();
2277
2277
  var jws = require_jws();
2278
- var { KeyObject: KeyObject$1, createSecretKey: createSecretKey$1, createPublicKey } = __require("crypto");
2278
+ var { KeyObject: KeyObject$1, createSecretKey: createSecretKey$1, createPublicKey: createPublicKey$1 } = __require("crypto");
2279
2279
  var PUB_KEY_ALGS = [
2280
2280
  "RS256",
2281
2281
  "RS384",
@@ -2343,7 +2343,7 @@ var require_verify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
2343
2343
  if (hasSignature && !secretOrPublicKey) return done(new JsonWebTokenError("secret or public key must be provided"));
2344
2344
  if (!hasSignature && !options.algorithms) return done(new JsonWebTokenError("please specify \"none\" in \"algorithms\" to verify unsigned tokens"));
2345
2345
  if (secretOrPublicKey != null && !(secretOrPublicKey instanceof KeyObject$1)) try {
2346
- secretOrPublicKey = createPublicKey(secretOrPublicKey);
2346
+ secretOrPublicKey = createPublicKey$1(secretOrPublicKey);
2347
2347
  } catch (_) {
2348
2348
  try {
2349
2349
  secretOrPublicKey = createSecretKey$1(typeof secretOrPublicKey === "string" ? Buffer.from(secretOrPublicKey) : secretOrPublicKey);
@@ -4150,17 +4150,21 @@ var require_jsonwebtoken = /* @__PURE__ */ __commonJSMin(((exports, module) => {
4150
4150
  //#region src/auth/jwt.ts
4151
4151
  var jwt_exports = /* @__PURE__ */ __exportAll({
4152
4152
  MAX_COOKIE_AGE_MS: () => MAX_COOKIE_AGE_MS,
4153
+ MFA_PENDING_PURPOSE: () => MFA_PENDING_PURPOSE,
4153
4154
  configureJwt: () => configureJwt,
4154
4155
  generateAccessToken: () => generateAccessToken,
4155
4156
  generateDownloadToken: () => generateDownloadToken,
4157
+ generateMfaPendingToken: () => generateMfaPendingToken,
4156
4158
  generateRefreshToken: () => generateRefreshToken,
4157
4159
  getAccessTokenExpiry: () => getAccessTokenExpiry,
4158
4160
  getAccessTokenExpiryMs: () => getAccessTokenExpiryMs,
4159
4161
  getRefreshTokenExpiry: () => getRefreshTokenExpiry,
4160
4162
  getRefreshTokenTtlMs: () => getRefreshTokenTtlMs,
4161
4163
  hashRefreshToken: () => hashRefreshToken,
4164
+ isJwtConfigured: () => isJwtConfigured,
4162
4165
  verifyAccessToken: () => verifyAccessToken,
4163
- verifyDownloadToken: () => verifyDownloadToken
4166
+ verifyDownloadToken: () => verifyDownloadToken,
4167
+ verifyMfaPendingToken: () => verifyMfaPendingToken
4164
4168
  });
4165
4169
  var import_jsonwebtoken = /* @__PURE__ */ __toESM(require_jsonwebtoken(), 1);
4166
4170
  var jwtConfig = {
@@ -4202,6 +4206,20 @@ function configureJwt(config) {
4202
4206
  };
4203
4207
  }
4204
4208
  /**
4209
+ * Has this server been given a JWT secret?
4210
+ *
4211
+ * False on every backend that authenticates through an adapter — Firebase,
4212
+ * Clerk, anything with its own tokens — because nothing calls
4213
+ * {@link configureJwt} there. Signing paths still throw when it is false, since
4214
+ * asking for a token from a server that cannot mint one is a mistake worth
4215
+ * hearing about. Paths whose contract is *"tolerate the absence of auth"* must
4216
+ * ask first: `optionalAuth` crashing a request because this backend does not do
4217
+ * JWT is a 500 on a route that had already decided anonymous was acceptable.
4218
+ */
4219
+ function isJwtConfigured() {
4220
+ return Boolean(jwtConfig.secret);
4221
+ }
4222
+ /**
4205
4223
  * Generate an access token (short-lived, 1 hour by default)
4206
4224
  */
4207
4225
  function generateAccessToken(uid, roles, aal = "aal1", customClaims) {
@@ -4209,8 +4227,8 @@ function generateAccessToken(uid, roles, aal = "aal1", customClaims) {
4209
4227
  const payload = {
4210
4228
  uid,
4211
4229
  roles,
4212
- aal,
4213
- ...customClaims
4230
+ ...customClaims,
4231
+ aal
4214
4232
  };
4215
4233
  return import_jsonwebtoken.default.sign(payload, jwtConfig.secret, {
4216
4234
  expiresIn: jwtConfig.accessExpiresIn,
@@ -4328,6 +4346,50 @@ function getRefreshTokenExpiry() {
4328
4346
  return new Date(Date.now() + getRefreshTokenTtlMs());
4329
4347
  }
4330
4348
  /**
4349
+ * The `purpose` claim carried by a credential that stands between "first factor
4350
+ * accepted" and "session issued".
4351
+ *
4352
+ * A pre-auth token is NOT a session and must never be usable as one:
4353
+ * {@link verifyAccessToken} refuses any token carrying a `purpose`, so this
4354
+ * value cannot authenticate a request no matter which route it is presented to.
4355
+ * The only thing that reads it is the MFA challenge pair, which exchanges it —
4356
+ * plus a second factor — for a real session.
4357
+ */
4358
+ var MFA_PENDING_PURPOSE = "mfa-pending";
4359
+ /**
4360
+ * Mint the short-lived credential handed back with an `MFA_REQUIRED` response.
4361
+ *
4362
+ * Short-lived on purpose: it is the window in which a caller who has proven the
4363
+ * first factor may present the second, not a session to be carried around. Five
4364
+ * minutes matches the challenge TTL.
4365
+ */
4366
+ function generateMfaPendingToken(uid, expiresInSeconds = 300) {
4367
+ if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
4368
+ return import_jsonwebtoken.default.sign({
4369
+ purpose: MFA_PENDING_PURPOSE,
4370
+ uid
4371
+ }, jwtConfig.secret, {
4372
+ expiresIn: expiresInSeconds,
4373
+ algorithm: "HS256"
4374
+ });
4375
+ }
4376
+ /**
4377
+ * Verify a pre-auth token and return the user it was minted for.
4378
+ *
4379
+ * Returns `null` for anything else — including a perfectly valid *access*
4380
+ * token, which must not be interchangeable with this one in either direction.
4381
+ */
4382
+ function verifyMfaPendingToken(token) {
4383
+ if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
4384
+ try {
4385
+ const decoded = import_jsonwebtoken.default.verify(token, jwtConfig.secret, { algorithms: ["HS256"] });
4386
+ if (decoded.purpose !== "mfa-pending" || !decoded.uid) return null;
4387
+ return { uid: decoded.uid };
4388
+ } catch {
4389
+ return null;
4390
+ }
4391
+ }
4392
+ /**
4331
4393
  * Generate a short-lived download token scoped to a specific file path or prefix
4332
4394
  */
4333
4395
  function generateDownloadToken(path, expiresInSeconds = 300) {
@@ -4359,6 +4421,6 @@ function verifyDownloadToken(token) {
4359
4421
  }
4360
4422
  }
4361
4423
  //#endregion
4362
- export { generateRefreshToken as a, getRefreshTokenTtlMs as c, verifyAccessToken as d, verifyDownloadToken as f, generateDownloadToken as i, hashRefreshToken as l, configureJwt as n, getAccessTokenExpiry as o, require_jsonwebtoken as p, generateAccessToken as r, getRefreshTokenExpiry as s, MAX_COOKIE_AGE_MS as t, jwt_exports as u };
4424
+ export { generateMfaPendingToken as a, getRefreshTokenExpiry as c, isJwtConfigured as d, jwt_exports as f, require_jsonwebtoken as g, verifyMfaPendingToken as h, generateDownloadToken as i, getRefreshTokenTtlMs as l, verifyDownloadToken as m, configureJwt as n, generateRefreshToken as o, verifyAccessToken as p, generateAccessToken as r, getAccessTokenExpiry as s, MAX_COOKIE_AGE_MS as t, hashRefreshToken as u };
4363
4425
 
4364
- //# sourceMappingURL=jwt-DD6EtpGj.js.map
4426
+ //# sourceMappingURL=jwt-Cuq6MwNy.js.map