@rebasepro/server-core 0.7.0 → 0.9.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/README.md +2 -2
- package/dist/api/ast-schema-editor.d.ts +21 -0
- package/dist/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
- package/dist/api/errors.d.ts +53 -0
- package/dist/api/index.d.ts +7 -0
- package/dist/api/logs-routes.d.ts +37 -0
- package/dist/api/openapi-generator.d.ts +16 -0
- package/dist/api/rest/api-generator.d.ts +68 -0
- package/{src/api/rest/index.ts → dist/api/rest/index.d.ts} +0 -1
- package/dist/api/rest/query-parser.d.ts +6 -0
- package/dist/api/schema-editor-routes.d.ts +3 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/auth/adapter-middleware.d.ts +43 -0
- package/dist/auth/admin-roles-route.d.ts +18 -0
- package/dist/auth/admin-user-ops.d.ts +79 -0
- package/dist/auth/admin-users-route.d.ts +28 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +39 -0
- package/{src/auth/api-keys/api-key-permission-guard.ts → dist/auth/api-keys/api-key-permission-guard.d.ts} +2 -34
- package/dist/auth/api-keys/api-key-routes.d.ts +20 -0
- package/dist/auth/api-keys/api-key-store.d.ts +35 -0
- package/{src/auth/api-keys/api-key-types.ts → dist/auth/api-keys/api-key-types.d.ts} +0 -6
- package/{src/auth/api-keys/index.ts → dist/auth/api-keys/index.d.ts} +2 -22
- package/dist/auth/apple-oauth.d.ts +30 -0
- package/{src/auth/auth-hooks.ts → dist/auth/auth-hooks.d.ts} +15 -73
- package/dist/auth/bitbucket-oauth.d.ts +11 -0
- package/dist/auth/builtin-auth-adapter.d.ts +55 -0
- package/dist/auth/cookie-utils.d.ts +32 -0
- package/{src/auth/crypto-utils.ts → dist/auth/crypto-utils.d.ts} +1 -16
- package/dist/auth/custom-auth-adapter.d.ts +39 -0
- package/dist/auth/discord-oauth.d.ts +14 -0
- package/dist/auth/facebook-oauth.d.ts +14 -0
- package/dist/auth/github-oauth.d.ts +15 -0
- package/dist/auth/gitlab-oauth.d.ts +13 -0
- package/dist/auth/google-oauth.d.ts +47 -0
- package/{src/auth/index.ts → dist/auth/index.d.ts} +4 -22
- package/{src/auth/interfaces.ts → dist/auth/interfaces.d.ts} +20 -89
- package/dist/auth/jwt.d.ts +67 -0
- package/dist/auth/linkedin-oauth.d.ts +18 -0
- package/dist/auth/magic-link-routes.d.ts +32 -0
- package/dist/auth/mfa-crypto.d.ts +23 -0
- package/dist/auth/mfa-routes.d.ts +7 -0
- package/dist/auth/mfa.d.ts +49 -0
- package/dist/auth/microsoft-oauth.d.ts +16 -0
- package/dist/auth/middleware.d.ts +158 -0
- package/dist/auth/password.d.ts +22 -0
- package/dist/auth/rate-limiter.d.ts +50 -0
- package/dist/auth/reset-password-admin.d.ts +29 -0
- package/dist/auth/rls-scope.d.ts +31 -0
- package/dist/auth/routes.d.ts +66 -0
- package/dist/auth/session-routes.d.ts +29 -0
- package/dist/auth/slack-oauth.d.ts +12 -0
- package/dist/auth/spotify-oauth.d.ts +12 -0
- package/dist/auth/twitter-oauth.d.ts +18 -0
- package/dist/collections/BackendCollectionRegistry.d.ts +13 -0
- package/dist/collections/loader.d.ts +5 -0
- package/dist/cron/cron-loader.d.ts +18 -0
- package/dist/cron/cron-routes.d.ts +14 -0
- package/dist/cron/cron-scheduler.d.ts +106 -0
- package/dist/cron/cron-store.d.ts +32 -0
- package/dist/cron/define-cron.d.ts +28 -0
- package/{src/cron/index.ts → dist/cron/index.d.ts} +1 -0
- package/dist/db/interfaces.d.ts +18 -0
- package/dist/dynamic-import-Dvh-K5fl.js +22 -0
- package/dist/dynamic-import-Dvh-K5fl.js.map +1 -0
- package/dist/email/index.d.ts +6 -0
- package/dist/email/smtp-email-service.d.ts +30 -0
- package/dist/email/templates.d.ts +50 -0
- package/{src/email/types.ts → dist/email/types.d.ts} +40 -36
- package/dist/env.d.ts +102 -0
- package/dist/functions/define-function.d.ts +55 -0
- package/dist/functions/function-loader.d.ts +18 -0
- package/dist/functions/function-routes.d.ts +10 -0
- package/{src/functions/index.ts → dist/functions/index.d.ts} +2 -0
- package/dist/history/history-routes.d.ts +23 -0
- package/{src/history/index.ts → dist/history/index.d.ts} +0 -1
- package/dist/index.d.ts +35 -0
- package/dist/index.es.js +18184 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +48629 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/init/docs.d.ts +4 -0
- package/dist/init/health.d.ts +2 -0
- package/dist/init/middlewares.d.ts +10 -0
- package/dist/init/shutdown.d.ts +65 -0
- package/dist/init/storage.d.ts +5 -0
- package/dist/init.d.ts +344 -0
- package/dist/jwt-BwIn8xmk.js +4200 -0
- package/dist/jwt-BwIn8xmk.js.map +1 -0
- package/dist/logger-BYU66ENZ.js +94 -0
- package/dist/logger-BYU66ENZ.js.map +1 -0
- package/dist/ms-DnYXB-Wd.js +162 -0
- package/dist/ms-DnYXB-Wd.js.map +1 -0
- package/dist/openapi-generator-Z9oYWLf_.js +586 -0
- package/dist/openapi-generator-Z9oYWLf_.js.map +1 -0
- package/dist/schema-editor-routes-D3ef8zu1.js +219 -0
- package/dist/schema-editor-routes-D3ef8zu1.js.map +1 -0
- package/dist/serve-spa.d.ts +36 -0
- package/dist/services/driver-registry.d.ts +78 -0
- package/dist/services/routed-realtime-service.d.ts +43 -0
- package/dist/services/webhook-service.d.ts +29 -0
- package/dist/singleton.d.ts +51 -0
- package/dist/src-B4OLmNVa.js +437 -0
- package/dist/src-B4OLmNVa.js.map +1 -0
- package/dist/src-B5WkP1Rv.js +24778 -0
- package/dist/src-B5WkP1Rv.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +43 -0
- package/dist/storage/LocalStorageController.d.ts +46 -0
- package/dist/storage/S3StorageController.d.ts +40 -0
- package/dist/storage/image-transform.d.ts +50 -0
- package/{src/storage/index.ts → dist/storage/index.d.ts} +6 -21
- package/dist/storage/routes.d.ts +70 -0
- package/dist/storage/storage-registry.d.ts +78 -0
- package/dist/storage/tus-handler.d.ts +53 -0
- package/{src/storage/types.ts → dist/storage/types.d.ts} +32 -38
- package/dist/types/index.d.ts +11 -0
- package/dist/utils/dev-port.d.ts +45 -0
- package/dist/utils/dynamic-import.d.ts +25 -0
- package/dist/utils/logger.d.ts +31 -0
- package/dist/utils/logging.d.ts +9 -0
- package/dist/utils/request-id.d.ts +4 -0
- package/dist/utils/request-logger.d.ts +19 -0
- package/{src/utils/sql.ts → dist/utils/sql.d.ts} +5 -16
- package/package.json +49 -22
- package/coverage/clover.xml +0 -3739
- package/coverage/coverage-final.json +0 -31
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -266
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/src/api/ast-schema-editor.ts.html +0 -952
- package/coverage/lcov-report/src/api/errors.ts.html +0 -472
- package/coverage/lcov-report/src/api/graphql/graphql-schema-generator.ts.html +0 -1069
- package/coverage/lcov-report/src/api/graphql/index.html +0 -116
- package/coverage/lcov-report/src/api/index.html +0 -176
- package/coverage/lcov-report/src/api/openapi-generator.ts.html +0 -565
- package/coverage/lcov-report/src/api/rest/api-generator.ts.html +0 -994
- package/coverage/lcov-report/src/api/rest/index.html +0 -131
- package/coverage/lcov-report/src/api/rest/query-parser.ts.html +0 -550
- package/coverage/lcov-report/src/api/schema-editor-routes.ts.html +0 -202
- package/coverage/lcov-report/src/api/server.ts.html +0 -823
- package/coverage/lcov-report/src/auth/admin-routes.ts.html +0 -973
- package/coverage/lcov-report/src/auth/index.html +0 -176
- package/coverage/lcov-report/src/auth/jwt.ts.html +0 -574
- package/coverage/lcov-report/src/auth/middleware.ts.html +0 -745
- package/coverage/lcov-report/src/auth/password.ts.html +0 -310
- package/coverage/lcov-report/src/auth/services.ts.html +0 -2074
- package/coverage/lcov-report/src/collections/index.html +0 -116
- package/coverage/lcov-report/src/collections/loader.ts.html +0 -232
- package/coverage/lcov-report/src/db/auth-schema.ts.html +0 -523
- package/coverage/lcov-report/src/db/data-transformer.ts.html +0 -1753
- package/coverage/lcov-report/src/db/entityService.ts.html +0 -700
- package/coverage/lcov-report/src/db/index.html +0 -146
- package/coverage/lcov-report/src/db/services/EntityFetchService.ts.html +0 -4048
- package/coverage/lcov-report/src/db/services/EntityPersistService.ts.html +0 -883
- package/coverage/lcov-report/src/db/services/RelationService.ts.html +0 -3121
- package/coverage/lcov-report/src/db/services/entity-helpers.ts.html +0 -442
- package/coverage/lcov-report/src/db/services/index.html +0 -176
- package/coverage/lcov-report/src/db/services/index.ts.html +0 -124
- package/coverage/lcov-report/src/generate-drizzle-schema-logic.ts.html +0 -1960
- package/coverage/lcov-report/src/index.html +0 -116
- package/coverage/lcov-report/src/services/driver-registry.ts.html +0 -631
- package/coverage/lcov-report/src/services/index.html +0 -131
- package/coverage/lcov-report/src/services/postgresDataDriver.ts.html +0 -3025
- package/coverage/lcov-report/src/storage/LocalStorageController.ts.html +0 -1189
- package/coverage/lcov-report/src/storage/S3StorageController.ts.html +0 -970
- package/coverage/lcov-report/src/storage/index.html +0 -161
- package/coverage/lcov-report/src/storage/storage-registry.ts.html +0 -646
- package/coverage/lcov-report/src/storage/types.ts.html +0 -451
- package/coverage/lcov-report/src/utils/drizzle-conditions.ts.html +0 -3082
- package/coverage/lcov-report/src/utils/index.html +0 -116
- package/coverage/lcov.info +0 -7179
- package/jest.config.cjs +0 -19
- package/src/api/ast-schema-editor.ts +0 -289
- package/src/api/collections_for_test/callbacks_test_collection.ts +0 -61
- package/src/api/errors.ts +0 -278
- package/src/api/graphql/graphql-schema-generator.ts +0 -383
- package/src/api/graphql/index.ts +0 -2
- package/src/api/index.ts +0 -11
- package/src/api/logs-routes.ts +0 -132
- package/src/api/openapi-generator.ts +0 -727
- package/src/api/rest/api-generator-count.test.ts +0 -126
- package/src/api/rest/api-generator.ts +0 -747
- package/src/api/rest/query-parser.ts +0 -300
- package/src/api/schema-editor-routes.ts +0 -41
- package/src/api/server.ts +0 -271
- package/src/api/types.ts +0 -104
- package/src/auth/adapter-middleware.ts +0 -114
- package/src/auth/admin-roles-route.ts +0 -36
- package/src/auth/admin-user-ops.ts +0 -236
- package/src/auth/admin-users-route.ts +0 -302
- package/src/auth/api-keys/api-key-middleware.ts +0 -133
- package/src/auth/api-keys/api-key-routes.ts +0 -193
- package/src/auth/api-keys/api-key-store.ts +0 -340
- package/src/auth/apple-oauth.ts +0 -122
- package/src/auth/bitbucket-oauth.ts +0 -84
- package/src/auth/builtin-auth-adapter.ts +0 -380
- package/src/auth/custom-auth-adapter.ts +0 -86
- package/src/auth/discord-oauth.ts +0 -85
- package/src/auth/facebook-oauth.ts +0 -74
- package/src/auth/github-oauth.ts +0 -112
- package/src/auth/gitlab-oauth.ts +0 -72
- package/src/auth/google-oauth.ts +0 -223
- package/src/auth/jwt.ts +0 -208
- package/src/auth/linkedin-oauth.ts +0 -83
- package/src/auth/magic-link-routes.ts +0 -167
- package/src/auth/mfa-crypto.ts +0 -91
- package/src/auth/mfa-routes.ts +0 -323
- package/src/auth/mfa.ts +0 -161
- package/src/auth/microsoft-oauth.ts +0 -90
- package/src/auth/middleware.ts +0 -369
- package/src/auth/password.ts +0 -77
- package/src/auth/rate-limiter.ts +0 -225
- package/src/auth/reset-password-admin.ts +0 -160
- package/src/auth/rls-scope.ts +0 -58
- package/src/auth/routes.ts +0 -802
- package/src/auth/session-routes.ts +0 -353
- package/src/auth/slack-oauth.ts +0 -73
- package/src/auth/spotify-oauth.ts +0 -69
- package/src/auth/twitter-oauth.ts +0 -128
- package/src/collections/BackendCollectionRegistry.ts +0 -20
- package/src/collections/loader.ts +0 -50
- package/src/cron/cron-loader.ts +0 -84
- package/src/cron/cron-routes.test.ts +0 -265
- package/src/cron/cron-routes.ts +0 -85
- package/src/cron/cron-scheduler.test.ts +0 -559
- package/src/cron/cron-scheduler.ts +0 -581
- package/src/cron/cron-store.ts +0 -166
- package/src/db/interfaces.ts +0 -60
- package/src/email/index.ts +0 -19
- package/src/email/smtp-email-service.ts +0 -123
- package/src/email/templates.ts +0 -470
- package/src/env.ts +0 -227
- package/src/functions/function-loader.ts +0 -116
- package/src/functions/function-routes.ts +0 -31
- package/src/history/history-routes.ts +0 -129
- package/src/index.ts +0 -70
- package/src/init/docs.ts +0 -47
- package/src/init/health.ts +0 -37
- package/src/init/middlewares.ts +0 -61
- package/src/init/shutdown.ts +0 -56
- package/src/init/storage.ts +0 -57
- package/src/init.ts +0 -1041
- package/src/serve-spa.ts +0 -89
- package/src/services/driver-registry.ts +0 -183
- package/src/services/routed-realtime-service.ts +0 -113
- package/src/services/webhook-service.ts +0 -155
- package/src/singleton.ts +0 -70
- package/src/storage/LocalStorageController.ts +0 -389
- package/src/storage/S3StorageController.ts +0 -300
- package/src/storage/image-transform.ts +0 -218
- package/src/storage/routes.ts +0 -368
- package/src/storage/storage-registry.ts +0 -188
- package/src/storage/tus-handler.ts +0 -315
- package/src/types/index.ts +0 -27
- package/src/utils/dev-port.ts +0 -196
- package/src/utils/logger.ts +0 -143
- package/src/utils/logging.ts +0 -40
- package/src/utils/request-id.ts +0 -40
- package/src/utils/request-logger.ts +0 -72
- package/test/api-generator.test.ts +0 -588
- package/test/api-key-permission-guard.test.ts +0 -144
- package/test/ast-schema-editor.test.ts +0 -89
- package/test/auth-middleware-hono.test.ts +0 -556
- package/test/auth-routes.test.ts +0 -1098
- package/test/backend-hooks-data.test.ts +0 -477
- package/test/custom-auth-adapter.test.ts +0 -189
- package/test/driver-registry.test.ts +0 -282
- package/test/email-templates.test.ts +0 -174
- package/test/env.test.ts +0 -128
- package/test/error-propagation.test.ts +0 -226
- package/test/errors-hono.test.ts +0 -133
- package/test/errors.test.ts +0 -155
- package/test/function-loader.test.ts +0 -127
- package/test/graphql-schema-generator.test.ts +0 -554
- package/test/jwt-security.test.ts +0 -182
- package/test/jwt.test.ts +0 -326
- package/test/mfa.test.ts +0 -197
- package/test/middleware.test.ts +0 -305
- package/test/multi-datasource-routing.test.ts +0 -113
- package/test/password.test.ts +0 -165
- package/test/query-parser.test.ts +0 -233
- package/test/rate-limiter.test.ts +0 -102
- package/test/reset-password-admin.test.ts +0 -113
- package/test/routed-realtime-service.test.ts +0 -86
- package/test/safe-compare.test.ts +0 -66
- package/test/singleton.test.ts +0 -59
- package/test/smtp-email-service.test.ts +0 -169
- package/test/storage-local.test.ts +0 -271
- package/test/storage-registry.test.ts +0 -282
- package/test/storage-routes.test.ts +0 -222
- package/test/storage-s3.test.ts +0 -304
- package/test/transform-auth-response.test.ts +0 -305
- package/test/webhook-service.test.ts +0 -260
- package/tsconfig.json +0 -54
- package/tsconfig.prod.json +0 -23
- package/vite.config.ts +0 -86
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ pnpm add @rebasepro/server-core
|
|
|
10
10
|
|
|
11
11
|
## What This Package Does
|
|
12
12
|
|
|
13
|
-
This is the central orchestrator for any Rebase backend. It provides the framework-level plumbing — HTTP routing (Hono), authentication middleware, storage, email, cron jobs, custom functions, and the REST
|
|
13
|
+
This is the central orchestrator for any Rebase backend. It provides the framework-level plumbing — HTTP routing (Hono), authentication middleware, storage, email, cron jobs, custom functions, and the REST API generator — without being coupled to any specific database. Database implementations are plugged in via driver packages like `@rebasepro/server-postgresql` or `@rebasepro/server-mongodb`.
|
|
14
14
|
|
|
15
15
|
## Key Exports
|
|
16
16
|
|
|
@@ -72,6 +72,6 @@ serveSPA(app, { frontendPath: "./frontend/dist" });
|
|
|
72
72
|
|---------|------|
|
|
73
73
|
| `@rebasepro/server-postgresql` | PostgreSQL database driver (Drizzle ORM) |
|
|
74
74
|
| `@rebasepro/server-mongodb` | MongoDB database driver |
|
|
75
|
-
| `@rebasepro/types` | Shared type definitions (`DataDriver`, `
|
|
75
|
+
| `@rebasepro/types` | Shared type definitions (`DataDriver`, `CollectionConfig`, etc.) |
|
|
76
76
|
| `@rebasepro/client` | Client SDK used internally by the `rebase` singleton |
|
|
77
77
|
| `@rebasepro/common` | Shared utilities and default collections |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class AstSchemaEditor {
|
|
2
|
+
private project;
|
|
3
|
+
private collectionsDir;
|
|
4
|
+
constructor(collectionsDir: string);
|
|
5
|
+
/**
|
|
6
|
+
* Sanitize collectionId to prevent path traversal attacks.
|
|
7
|
+
* Only allows alphanumeric characters, underscores, and hyphens.
|
|
8
|
+
*/
|
|
9
|
+
private sanitizeCollectionId;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a file path and ensure it falls within the collectionsDir.
|
|
12
|
+
*/
|
|
13
|
+
private safePath;
|
|
14
|
+
private getCollectionFile;
|
|
15
|
+
private getCollectionObject;
|
|
16
|
+
private convertJsonToAstString;
|
|
17
|
+
saveProperty(collectionId: string, propertyKey: string, propertyConfig: Record<string, unknown>): Promise<void>;
|
|
18
|
+
deleteProperty(collectionId: string, propertyKey: string): Promise<void>;
|
|
19
|
+
saveCollection(collectionId: string, collectionData: Record<string, unknown>): Promise<void>;
|
|
20
|
+
deleteCollection(collectionId: string): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ErrorHandler } from "hono";
|
|
2
|
+
import type { HonoEnv } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Standardized API error class.
|
|
5
|
+
* Throw this from any route handler — the errorHandler middleware
|
|
6
|
+
* will format it into `{ error: { message, code, details? } }`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class ApiError extends Error {
|
|
9
|
+
readonly statusCode: number;
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly details?: unknown;
|
|
12
|
+
constructor(statusCode: number, code: string, message: string, details?: unknown);
|
|
13
|
+
static badRequest(message: string, code?: string, details?: unknown): ApiError;
|
|
14
|
+
static unauthorized(message: string, code?: string): ApiError;
|
|
15
|
+
static forbidden(message: string, code?: string): ApiError;
|
|
16
|
+
static notFound(message: string, code?: string): ApiError;
|
|
17
|
+
static conflict(message: string, code?: string): ApiError;
|
|
18
|
+
static internal(message: string, code?: string): ApiError;
|
|
19
|
+
static serviceUnavailable(message: string, code?: string): ApiError;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Canonical error response shape:
|
|
23
|
+
* `{ error: { message: string, code: string, details?: unknown } }`
|
|
24
|
+
*/
|
|
25
|
+
export interface ErrorResponse {
|
|
26
|
+
error: {
|
|
27
|
+
message: string;
|
|
28
|
+
code: string;
|
|
29
|
+
details?: unknown;
|
|
30
|
+
/** Request correlation ID for tracing (echoes X-Request-ID). */
|
|
31
|
+
requestId?: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* General shape of errors that flow through the API error handler.
|
|
36
|
+
* Extends Error with optional HTTP status, error code, and details.
|
|
37
|
+
*/
|
|
38
|
+
export interface RebaseApiError extends Error {
|
|
39
|
+
statusCode?: number;
|
|
40
|
+
code?: string;
|
|
41
|
+
details?: unknown;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Type guard for errors that carry optional API metadata (statusCode, code, details).
|
|
45
|
+
* Returns true for any Error instance — the optional properties are then
|
|
46
|
+
* checked via normal property access.
|
|
47
|
+
*/
|
|
48
|
+
export declare function isRebaseApiError(error: unknown): error is RebaseApiError;
|
|
49
|
+
/**
|
|
50
|
+
* Hono error-handling middleware (`app.onError`).
|
|
51
|
+
* Converts any error into the canonical `{ error: { message, code } }` shape.
|
|
52
|
+
*/
|
|
53
|
+
export declare const errorHandler: ErrorHandler<HonoEnv>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { MiddlewareHandler } from "hono";
|
|
3
|
+
import type { HonoEnv } from "./types";
|
|
4
|
+
export interface LogEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
level: "debug" | "info" | "warn" | "error";
|
|
8
|
+
source: "api" | "auth" | "storage" | "realtime" | "system";
|
|
9
|
+
message: string;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
declare class LogRingBuffer {
|
|
13
|
+
private buffer;
|
|
14
|
+
private maxSize;
|
|
15
|
+
private idCounter;
|
|
16
|
+
constructor(maxSize?: number);
|
|
17
|
+
push(entry: Omit<LogEntry, "id">): void;
|
|
18
|
+
query(options: {
|
|
19
|
+
level?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
search?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
since?: string;
|
|
25
|
+
}): {
|
|
26
|
+
entries: LogEntry[];
|
|
27
|
+
total: number;
|
|
28
|
+
};
|
|
29
|
+
getLatest(count?: number): LogEntry[];
|
|
30
|
+
}
|
|
31
|
+
export declare const logBuffer: LogRingBuffer;
|
|
32
|
+
/** Add a log entry */
|
|
33
|
+
export declare function addLog(level: LogEntry["level"], source: LogEntry["source"], message: string, metadata?: Record<string, unknown>): void;
|
|
34
|
+
/** Hono middleware to log API requests */
|
|
35
|
+
export declare function logMiddleware(): MiddlewareHandler<HonoEnv>;
|
|
36
|
+
declare const app: Hono<HonoEnv, import("hono/types").BlankSchema, "/">;
|
|
37
|
+
export default app;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CollectionConfig } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAPI 3.0.3 specification generator.
|
|
4
|
+
*
|
|
5
|
+
* Produces a spec that exactly mirrors the REST API consumed by the
|
|
6
|
+
* Rebase SDK client (`@rebasepro/client`).
|
|
7
|
+
*
|
|
8
|
+
* Routes are mounted at `{basePath}/data/{slug}` by `initializeRebaseBackend`.
|
|
9
|
+
*/
|
|
10
|
+
export interface OpenApiGeneratorOptions {
|
|
11
|
+
/** Base path for the API (e.g. "/api"). Defaults to "/api". */
|
|
12
|
+
basePath?: string;
|
|
13
|
+
/** Whether auth is enabled on data routes. Defaults to true. */
|
|
14
|
+
requireAuth?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function generateOpenApiSpec(collections: CollectionConfig[], options?: OpenApiGeneratorOptions): Record<string, unknown>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { AuthAdapter, DataDriver, CollectionConfig } from "@rebasepro/types";
|
|
3
|
+
import { HonoEnv } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight REST API generator that leverages existing Rebase DataDriver.
|
|
6
|
+
* Supports `include` query parameter for eager-loading relations via Drizzle.
|
|
7
|
+
*/
|
|
8
|
+
export declare class RestApiGenerator {
|
|
9
|
+
private collections;
|
|
10
|
+
private router;
|
|
11
|
+
private driver;
|
|
12
|
+
private authAdapter?;
|
|
13
|
+
constructor(collections: CollectionConfig[], driver: DataDriver, authAdapter?: AuthAdapter);
|
|
14
|
+
/**
|
|
15
|
+
* Generate REST routes using existing DataDriver
|
|
16
|
+
*/
|
|
17
|
+
generateRoutes(): Hono<HonoEnv>;
|
|
18
|
+
/**
|
|
19
|
+
* Check API key permissions for a collection operation.
|
|
20
|
+
* Throws 403 if the key doesn't have the required permission.
|
|
21
|
+
* No-ops if the request is not authenticated via an API key.
|
|
22
|
+
*/
|
|
23
|
+
private enforceApiKeyPermission;
|
|
24
|
+
/**
|
|
25
|
+
* Get the request-scoped driver. Throws if none is set — never falls
|
|
26
|
+
* back to the unscoped `this.driver` to avoid bypassing RLS/auth.
|
|
27
|
+
*/
|
|
28
|
+
private getScopedDriver;
|
|
29
|
+
/**
|
|
30
|
+
* Create REST routes for a collection using existing Rebase patterns
|
|
31
|
+
*/
|
|
32
|
+
private createCollectionRoutes;
|
|
33
|
+
/**
|
|
34
|
+
* Catch-all routes for subcollection paths.
|
|
35
|
+
*
|
|
36
|
+
* Matches URL patterns like:
|
|
37
|
+
* GET /authors/111094/posts → list child collection
|
|
38
|
+
* GET /authors/111094/posts/43 → get child entity
|
|
39
|
+
* POST /authors/111094/posts → create child entity
|
|
40
|
+
* PUT /authors/111094/posts/43 → update child entity
|
|
41
|
+
* DELETE /authors/111094/posts/43 → delete child entity
|
|
42
|
+
*
|
|
43
|
+
* The `:rest{.+}` regex param captures the full remainder of the URL
|
|
44
|
+
* path (Hono v4 `*` wildcard does not populate `c.req.param("*")`).
|
|
45
|
+
* We split it into segments and reconstruct the `collectionPath`
|
|
46
|
+
* (e.g. "authors/111094/posts") and optional `id` (e.g. "43").
|
|
47
|
+
*
|
|
48
|
+
* The DataDriver.save / fetchCollection / etc. already know how to
|
|
49
|
+
* resolve multi-segment relation paths, so we just forward to them.
|
|
50
|
+
*/
|
|
51
|
+
private createSubcollectionRoutes;
|
|
52
|
+
/**
|
|
53
|
+
* Format successful API response
|
|
54
|
+
*/
|
|
55
|
+
private formatResponse;
|
|
56
|
+
/**
|
|
57
|
+
* Fetch raw collection data without Entity wrapper (fallback for non-Postgres)
|
|
58
|
+
*/
|
|
59
|
+
private fetchRawCollection;
|
|
60
|
+
/**
|
|
61
|
+
* Count raw entities for a collection
|
|
62
|
+
*/
|
|
63
|
+
private countRawEntities;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch single entity raw data without Entity wrapper (fallback)
|
|
66
|
+
*/
|
|
67
|
+
private fetchRawEntity;
|
|
68
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { QueryOptions } from "../types";
|
|
2
|
+
export declare const mapOperator: (op: string) => import("@rebasepro/types").WhereFilterOp | null;
|
|
3
|
+
/**
|
|
4
|
+
* Parse query parameters into QueryOptions
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseQueryOptions(query: Record<string, unknown>): QueryOptions;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { VectorSearchParams, LogicalCondition, FilterValues } from "@rebasepro/types";
|
|
2
|
+
import { AuthResult } from "../auth/middleware";
|
|
3
|
+
import { DataDriver } from "@rebasepro/types";
|
|
4
|
+
import type { ApiKeyMasked } from "../auth/api-keys/api-key-types";
|
|
5
|
+
/**
|
|
6
|
+
* Hono Environment Variables
|
|
7
|
+
* Passed to generic Hono<HonoEnv> to type `c.get()`
|
|
8
|
+
*/
|
|
9
|
+
export type HonoEnv = {
|
|
10
|
+
Variables: {
|
|
11
|
+
user?: AuthResult | {
|
|
12
|
+
userId?: string;
|
|
13
|
+
roles?: string[];
|
|
14
|
+
};
|
|
15
|
+
driver?: DataDriver;
|
|
16
|
+
/** Set when the request is authenticated via a Service API Key. */
|
|
17
|
+
apiKey?: ApiKeyMasked;
|
|
18
|
+
/** Unique request correlation ID (generated or propagated from X-Request-ID header). */
|
|
19
|
+
requestId?: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Standard API response format
|
|
24
|
+
*/
|
|
25
|
+
export interface ApiResponse<T = unknown> {
|
|
26
|
+
data?: T;
|
|
27
|
+
error?: {
|
|
28
|
+
message: string;
|
|
29
|
+
code?: string;
|
|
30
|
+
details?: unknown;
|
|
31
|
+
};
|
|
32
|
+
meta?: {
|
|
33
|
+
total?: number;
|
|
34
|
+
page?: number;
|
|
35
|
+
limit?: number;
|
|
36
|
+
hasMore?: boolean;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Query options for API endpoints
|
|
41
|
+
*/
|
|
42
|
+
export interface QueryOptions {
|
|
43
|
+
limit?: number;
|
|
44
|
+
offset?: number;
|
|
45
|
+
where?: FilterValues<string>;
|
|
46
|
+
logical?: LogicalCondition;
|
|
47
|
+
orderBy?: Array<{
|
|
48
|
+
field: string;
|
|
49
|
+
direction: "asc" | "desc";
|
|
50
|
+
}>;
|
|
51
|
+
include?: string[];
|
|
52
|
+
/** Columns to return in the response (field-level selection) */
|
|
53
|
+
fields?: string[];
|
|
54
|
+
/** Vector similarity search configuration */
|
|
55
|
+
vectorSearch?: VectorSearchParams;
|
|
56
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapter Auth Middleware
|
|
3
|
+
*
|
|
4
|
+
* Creates a Hono middleware that delegates authentication to an `AuthAdapter`
|
|
5
|
+
* instead of hardcoded JWT verification. This is used when the user passes
|
|
6
|
+
* an `AuthAdapter` to `initializeRebaseBackend()`.
|
|
7
|
+
*
|
|
8
|
+
* The middleware:
|
|
9
|
+
* 1. Checks for API key tokens (`rk_` prefix) first — these are Rebase-level
|
|
10
|
+
* 2. Falls back to `adapter.verifyRequest(request)` to resolve the user
|
|
11
|
+
* 3. Scopes the DataDriver via `withAuth()` for RLS
|
|
12
|
+
* 4. Enforces auth (401) when `requireAuth` is true and no user is found
|
|
13
|
+
*
|
|
14
|
+
* The behavior is identical to `createAuthMiddleware()` — only the
|
|
15
|
+
* token verification strategy is pluggable.
|
|
16
|
+
*/
|
|
17
|
+
import type { MiddlewareHandler, Context } from "hono";
|
|
18
|
+
import type { DataDriver, AuthAdapter } from "@rebasepro/types";
|
|
19
|
+
import type { HonoEnv } from "../api/types";
|
|
20
|
+
import type { ApiKeyStore } from "./api-keys/api-key-store";
|
|
21
|
+
export interface AdapterAuthMiddlewareOptions {
|
|
22
|
+
/** The auth adapter to delegate verification to. */
|
|
23
|
+
adapter: AuthAdapter;
|
|
24
|
+
/** The DataDriver to scope via withAuth() for RLS. */
|
|
25
|
+
driver: DataDriver;
|
|
26
|
+
/**
|
|
27
|
+
* Optional per-request driver resolver for multi-data-source backends.
|
|
28
|
+
* Returns the unscoped delegate to use for this request (e.g. Postgres vs
|
|
29
|
+
* Mongo). When omitted, `driver` is used for every request.
|
|
30
|
+
*/
|
|
31
|
+
resolveDriver?: (c: Context<HonoEnv>) => DataDriver;
|
|
32
|
+
/**
|
|
33
|
+
* If true, return 401 when no valid user is resolved.
|
|
34
|
+
* Defaults to `true` (secure by default).
|
|
35
|
+
*/
|
|
36
|
+
requireAuth?: boolean;
|
|
37
|
+
/** Optional API key store — when provided, `rk_` bearer tokens are accepted. */
|
|
38
|
+
apiKeyStore?: ApiKeyStore;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create a Hono middleware that uses an `AuthAdapter` for request verification.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createAdapterAuthMiddleware(options: AdapterAuthMiddlewareOptions): MiddlewareHandler<HonoEnv>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin endpoint for listing all roles.
|
|
3
|
+
*
|
|
4
|
+
* Mounts: GET /roles
|
|
5
|
+
*/
|
|
6
|
+
import { Hono } from "hono";
|
|
7
|
+
import type { AuthRepository } from "./interfaces";
|
|
8
|
+
import type { HonoEnv } from "../api/types";
|
|
9
|
+
export interface AdminRolesRouteConfig {
|
|
10
|
+
authRepo: AuthRepository;
|
|
11
|
+
serviceKey?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a standalone admin route for listing roles.
|
|
15
|
+
*
|
|
16
|
+
* Mounts: GET /roles
|
|
17
|
+
*/
|
|
18
|
+
export declare function createAdminRolesRoute(config: AdminRolesRouteConfig): Hono<HonoEnv>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin User Operations
|
|
3
|
+
*
|
|
4
|
+
* Shared utilities and orchestration for admin-initiated user management
|
|
5
|
+
* (user creation via REST API, password reset via admin panel).
|
|
6
|
+
*
|
|
7
|
+
* Hook resolution order:
|
|
8
|
+
* 1. Collection-level hook (`auth.onCreateUser` on the collection) — closest to the data
|
|
9
|
+
* 2. Backend-level hook (`AuthHooks.onAdminCreateUser`) — global override
|
|
10
|
+
* 3. Built-in default — framework fallback
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthRepository } from "./interfaces";
|
|
13
|
+
import type { EmailService, EmailConfig } from "../email";
|
|
14
|
+
import type { ResolvedAuthHooks } from "./auth-hooks";
|
|
15
|
+
import type { AuthCollectionConfig } from "@rebasepro/types";
|
|
16
|
+
/**
|
|
17
|
+
* Generate a cryptographically secure random password that meets strength requirements.
|
|
18
|
+
*
|
|
19
|
+
* 16 characters, guaranteed at least one uppercase, one lowercase, one digit.
|
|
20
|
+
* Ambiguous characters (0, O, 1, l, I) are excluded.
|
|
21
|
+
*/
|
|
22
|
+
export declare function generateSecurePassword(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Generate a cryptographically secure random token (80 hex characters).
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateSecureToken(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Hash a token for database storage using SHA-256.
|
|
29
|
+
*/
|
|
30
|
+
export declare function hashToken(token: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Context needed by admin user creation / password reset operations.
|
|
33
|
+
*/
|
|
34
|
+
export interface AdminUserContext {
|
|
35
|
+
authRepo: AuthRepository;
|
|
36
|
+
emailService?: EmailService;
|
|
37
|
+
emailConfig?: EmailConfig;
|
|
38
|
+
resolvedHooks: ResolvedAuthHooks;
|
|
39
|
+
/** The parsed auth config from the collection (if `auth` is an object, not just `true`). */
|
|
40
|
+
collectionAuthConfig?: AuthCollectionConfig;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Result of preparing user values for admin-initiated creation.
|
|
44
|
+
*/
|
|
45
|
+
export interface AdminUserPrepareResult {
|
|
46
|
+
/** Values ready for `driver.save()`. */
|
|
47
|
+
values: Record<string, unknown>;
|
|
48
|
+
/** The cleartext password (for returning to admin or sending via email). */
|
|
49
|
+
clearPassword?: string;
|
|
50
|
+
/** Whether the hook already handled the invitation email. */
|
|
51
|
+
hookHandledEmail: boolean;
|
|
52
|
+
/** Whether an invitation was sent (only relevant when hookHandledEmail is true). */
|
|
53
|
+
invitationSent: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Prepare user values for an admin-initiated user creation.
|
|
57
|
+
*
|
|
58
|
+
* Resolution order:
|
|
59
|
+
* 1. Collection-level `auth.onCreateUser` — closest to the data
|
|
60
|
+
* 2. Backend-level `AuthHooks.onAdminCreateUser` — global override
|
|
61
|
+
* 3. Built-in default — generate password → hash → normalize email
|
|
62
|
+
*
|
|
63
|
+
* The caller is responsible for persisting (via `driver.save()`).
|
|
64
|
+
*/
|
|
65
|
+
export declare function prepareAdminUserValues(body: Record<string, unknown>, ctx: AdminUserContext): Promise<AdminUserPrepareResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Handle post-creation work for admin-created users.
|
|
68
|
+
*
|
|
69
|
+
* Sends an invitation email (password-reset link) if email is configured
|
|
70
|
+
* and no explicit password was provided. Falls back to returning the
|
|
71
|
+
* temporary password if email fails or is not configured.
|
|
72
|
+
*/
|
|
73
|
+
export declare function finalizeAdminUserCreation(entity: {
|
|
74
|
+
id: string;
|
|
75
|
+
values: Record<string, unknown>;
|
|
76
|
+
}, clearPassword: string | undefined, ctx: AdminUserContext): Promise<{
|
|
77
|
+
temporaryPassword?: string;
|
|
78
|
+
invitationSent: boolean;
|
|
79
|
+
}>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone admin endpoint for user management.
|
|
3
|
+
*
|
|
4
|
+
* Mounts:
|
|
5
|
+
* GET /users
|
|
6
|
+
* GET /users/:userId
|
|
7
|
+
* POST /users
|
|
8
|
+
* PUT /users/:userId
|
|
9
|
+
* DELETE /users/:userId
|
|
10
|
+
* POST /bootstrap
|
|
11
|
+
*/
|
|
12
|
+
import { Hono } from "hono";
|
|
13
|
+
import type { AuthRepository } from "./interfaces";
|
|
14
|
+
import type { AuthHooks } from "./auth-hooks";
|
|
15
|
+
import type { EmailService, EmailConfig } from "../email";
|
|
16
|
+
import type { HonoEnv } from "../api/types";
|
|
17
|
+
import type { AuthCollectionConfig } from "@rebasepro/types";
|
|
18
|
+
export interface AdminUsersRouteConfig {
|
|
19
|
+
authRepo: AuthRepository;
|
|
20
|
+
emailService?: EmailService;
|
|
21
|
+
emailConfig?: EmailConfig;
|
|
22
|
+
serviceKey?: string;
|
|
23
|
+
authHooks?: AuthHooks;
|
|
24
|
+
collectionAuthConfig?: AuthCollectionConfig;
|
|
25
|
+
isBootstrapCompleted?: () => Promise<boolean>;
|
|
26
|
+
setBootstrapCompleted?: () => Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare function createAdminUsersRoute(config: AdminUsersRouteConfig): Hono<HonoEnv>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono middleware for authenticating requests via Service API Keys.
|
|
3
|
+
*
|
|
4
|
+
* This middleware is integrated into `createAuthMiddleware()` and
|
|
5
|
+
* activates only when the bearer token starts with `rk_`. It:
|
|
6
|
+
*
|
|
7
|
+
* 1. Hashes the token with SHA-256
|
|
8
|
+
* 2. Looks up the hash in the `rebase.api_keys` table
|
|
9
|
+
* 3. Validates the key is not revoked and not expired
|
|
10
|
+
* 4. Sets `c.set("user", ...)` and `c.set("apiKey", ...)` for downstream use
|
|
11
|
+
* 5. Scopes the DataDriver via `withAuth()` using the API key's service identity
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import type { Context } from "hono";
|
|
16
|
+
import type { DataDriver } from "@rebasepro/types";
|
|
17
|
+
import type { HonoEnv } from "../../api/types";
|
|
18
|
+
import type { ApiKeyStore } from "./api-key-store";
|
|
19
|
+
/**
|
|
20
|
+
* Check whether a token looks like a Rebase API key.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isApiKeyToken(token: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Options for the API key authentication handler.
|
|
25
|
+
*/
|
|
26
|
+
export interface ApiKeyAuthOptions {
|
|
27
|
+
store: ApiKeyStore;
|
|
28
|
+
driver: DataDriver;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validate an API key token and populate the Hono context.
|
|
32
|
+
*
|
|
33
|
+
* Returns `true` if the key is valid and context has been populated,
|
|
34
|
+
* or returns an error Response if the key is invalid.
|
|
35
|
+
*
|
|
36
|
+
* This is NOT a standalone middleware — it's called from within
|
|
37
|
+
* `createAuthMiddleware()` when a `rk_` prefixed token is detected.
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateApiKey(c: Context<HonoEnv>, token: string, options: ApiKeyAuthOptions): Promise<Response | true>;
|
|
@@ -7,12 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
-
|
|
11
10
|
import type { ApiKeyPermission } from "./api-key-types";
|
|
12
|
-
|
|
13
11
|
/** Operations that map to HTTP methods. */
|
|
14
12
|
export type ApiKeyOperation = "read" | "write" | "delete";
|
|
15
|
-
|
|
16
13
|
/**
|
|
17
14
|
* Map an HTTP method string to an `ApiKeyOperation`.
|
|
18
15
|
*
|
|
@@ -20,24 +17,7 @@ export type ApiKeyOperation = "read" | "write" | "delete";
|
|
|
20
17
|
* - `POST`, `PUT`, `PATCH` → `"write"`
|
|
21
18
|
* - `DELETE` → `"delete"`
|
|
22
19
|
*/
|
|
23
|
-
export function httpMethodToOperation(method: string): ApiKeyOperation
|
|
24
|
-
const upper = method.toUpperCase();
|
|
25
|
-
switch (upper) {
|
|
26
|
-
case "GET":
|
|
27
|
-
case "HEAD":
|
|
28
|
-
case "OPTIONS":
|
|
29
|
-
return "read";
|
|
30
|
-
case "POST":
|
|
31
|
-
case "PUT":
|
|
32
|
-
case "PATCH":
|
|
33
|
-
return "write";
|
|
34
|
-
case "DELETE":
|
|
35
|
-
return "delete";
|
|
36
|
-
default:
|
|
37
|
-
return "read";
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
20
|
+
export declare function httpMethodToOperation(method: string): ApiKeyOperation;
|
|
41
21
|
/**
|
|
42
22
|
* Check whether the given permissions array allows `operation` on `collection`.
|
|
43
23
|
*
|
|
@@ -49,16 +29,4 @@ export function httpMethodToOperation(method: string): ApiKeyOperation {
|
|
|
49
29
|
* @param operation - The requested operation.
|
|
50
30
|
* @returns `true` if the operation is permitted.
|
|
51
31
|
*/
|
|
52
|
-
export function isOperationAllowed(
|
|
53
|
-
permissions: ApiKeyPermission[],
|
|
54
|
-
collection: string,
|
|
55
|
-
operation: ApiKeyOperation
|
|
56
|
-
): boolean {
|
|
57
|
-
for (const perm of permissions) {
|
|
58
|
-
const collectionMatch = perm.collection === "*" || perm.collection === collection;
|
|
59
|
-
if (collectionMatch && perm.operations.includes(operation)) {
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
32
|
+
export declare function isOperationAllowed(permissions: ApiKeyPermission[], collection: string, operation: ApiKeyOperation): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin routes for managing Service API Keys.
|
|
3
|
+
*
|
|
4
|
+
* Mounted under `/api/admin/api-keys` with `requireAuth` + `requireAdmin`.
|
|
5
|
+
* All routes return masked keys (never the hash). The full plaintext key
|
|
6
|
+
* is returned exactly once in the POST response.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { Hono } from "hono";
|
|
11
|
+
import type { HonoEnv } from "../../api/types";
|
|
12
|
+
import type { ApiKeyStore } from "./api-key-store";
|
|
13
|
+
export interface ApiKeyRouteOptions {
|
|
14
|
+
store: ApiKeyStore;
|
|
15
|
+
serviceKey?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create admin routes for API key management.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createApiKeyRoutes(options: ApiKeyRouteOptions): Hono<HonoEnv>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database operations for Service API Keys.
|
|
3
|
+
*
|
|
4
|
+
* Uses the DataDriver's `admin.executeSql` capability (same pattern as
|
|
5
|
+
* the cron-store and ensure-tables modules). All data lives in the
|
|
6
|
+
* `rebase.api_keys` table.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { DataDriver } from "@rebasepro/types";
|
|
11
|
+
import type { ApiKey, ApiKeyMasked, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest } from "./api-key-types";
|
|
12
|
+
export interface ApiKeyStore {
|
|
13
|
+
/** Ensure the `rebase.api_keys` table exists. Called once on startup. */
|
|
14
|
+
ensureTable(): Promise<void>;
|
|
15
|
+
/** Create a new API key. Returns the full plaintext key exactly once. */
|
|
16
|
+
createApiKey(request: CreateApiKeyRequest, createdBy: string): Promise<ApiKeyWithSecret>;
|
|
17
|
+
/** Look up an API key by its SHA-256 hash. Returns `null` if not found. */
|
|
18
|
+
findByKeyHash(hash: string): Promise<ApiKey | null>;
|
|
19
|
+
/** List all API keys (masked, never includes hash). */
|
|
20
|
+
listApiKeys(): Promise<ApiKeyMasked[]>;
|
|
21
|
+
/** Get a single API key by ID (masked). */
|
|
22
|
+
getApiKeyById(id: string): Promise<ApiKeyMasked | null>;
|
|
23
|
+
/** Update name, permissions, rate_limit, or expires_at. */
|
|
24
|
+
updateApiKey(id: string, updates: UpdateApiKeyRequest): Promise<ApiKeyMasked | null>;
|
|
25
|
+
/** Soft-delete: set `revoked_at` to now. */
|
|
26
|
+
revokeApiKey(id: string): Promise<boolean>;
|
|
27
|
+
/** Touch `last_used_at` to the current timestamp. */
|
|
28
|
+
updateLastUsed(id: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Create an `ApiKeyStore` backed by the driver's SQL admin capability.
|
|
32
|
+
*
|
|
33
|
+
* Returns `undefined` if the driver does not support `executeSql`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createApiKeyStore(driver: DataDriver): ApiKeyStore | undefined;
|