@rebasepro/server-core 0.0.1-canary.4d4fb3e → 0.0.1-canary.ca2cb6e

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 (176) hide show
  1. package/dist/common/src/collections/CollectionRegistry.d.ts +8 -0
  2. package/dist/common/src/util/entities.d.ts +22 -0
  3. package/dist/common/src/util/relations.d.ts +14 -4
  4. package/dist/common/src/util/resolutions.d.ts +1 -1
  5. package/dist/index-DXVBFp5V.js +37 -0
  6. package/dist/index-DXVBFp5V.js.map +1 -0
  7. package/dist/index.es.js +49931 -55
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/index.umd.js +28475 -34569
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/server-core/src/api/openapi-generator.d.ts +15 -1
  12. package/dist/server-core/src/api/types.d.ts +1 -1
  13. package/dist/server-core/src/auth/admin-routes.d.ts +10 -1
  14. package/dist/server-core/src/auth/apple-oauth.d.ts +30 -0
  15. package/dist/server-core/src/auth/bitbucket-oauth.d.ts +11 -0
  16. package/dist/server-core/src/auth/discord-oauth.d.ts +14 -0
  17. package/dist/server-core/src/auth/facebook-oauth.d.ts +14 -0
  18. package/dist/server-core/src/auth/github-oauth.d.ts +15 -0
  19. package/dist/server-core/src/auth/gitlab-oauth.d.ts +13 -0
  20. package/dist/server-core/src/auth/google-oauth.d.ts +5 -11
  21. package/dist/server-core/src/auth/index.d.ts +13 -2
  22. package/dist/server-core/src/auth/interfaces.d.ts +45 -6
  23. package/dist/server-core/src/auth/jwt.d.ts +1 -0
  24. package/dist/server-core/src/auth/linkedin-oauth.d.ts +18 -0
  25. package/dist/server-core/src/auth/microsoft-oauth.d.ts +16 -0
  26. package/dist/server-core/src/auth/middleware.d.ts +36 -11
  27. package/dist/server-core/src/auth/rate-limiter.d.ts +2 -2
  28. package/dist/server-core/src/auth/routes.d.ts +13 -3
  29. package/dist/server-core/src/auth/slack-oauth.d.ts +12 -0
  30. package/dist/server-core/src/auth/spotify-oauth.d.ts +12 -0
  31. package/dist/server-core/src/auth/twitter-oauth.d.ts +18 -0
  32. package/dist/server-core/src/cron/cron-loader.d.ts +17 -0
  33. package/dist/server-core/src/cron/cron-routes.d.ts +14 -0
  34. package/dist/server-core/src/cron/cron-scheduler.d.ts +61 -0
  35. package/dist/server-core/src/cron/cron-store.d.ts +32 -0
  36. package/dist/server-core/src/cron/index.d.ts +6 -0
  37. package/dist/server-core/src/email/index.d.ts +2 -2
  38. package/dist/server-core/src/email/templates.d.ts +9 -0
  39. package/dist/server-core/src/email/types.d.ts +20 -23
  40. package/dist/server-core/src/history/history-routes.d.ts +2 -2
  41. package/dist/server-core/src/index.d.ts +5 -0
  42. package/dist/server-core/src/init.d.ts +112 -2
  43. package/dist/server-core/src/singleton.d.ts +35 -0
  44. package/dist/server-core/src/storage/LocalStorageController.d.ts +9 -9
  45. package/dist/server-core/src/storage/S3StorageController.d.ts +8 -8
  46. package/dist/server-core/src/storage/index.d.ts +18 -11
  47. package/dist/server-core/src/storage/routes.d.ts +3 -3
  48. package/dist/server-core/src/storage/types.d.ts +28 -16
  49. package/dist/server-core/src/utils/dev-port.d.ts +35 -0
  50. package/dist/server-core/src/utils/logger.d.ts +31 -0
  51. package/dist/server-core/src/utils/request-logger.d.ts +19 -0
  52. package/dist/types/src/controllers/auth.d.ts +2 -0
  53. package/dist/types/src/controllers/client.d.ts +119 -7
  54. package/dist/types/src/controllers/collection_registry.d.ts +4 -3
  55. package/dist/types/src/controllers/customization_controller.d.ts +7 -1
  56. package/dist/types/src/controllers/data.d.ts +34 -7
  57. package/dist/types/src/controllers/data_driver.d.ts +20 -28
  58. package/dist/types/src/controllers/database_admin.d.ts +2 -2
  59. package/dist/types/src/controllers/email.d.ts +34 -0
  60. package/dist/types/src/controllers/index.d.ts +1 -0
  61. package/dist/types/src/controllers/local_config_persistence.d.ts +4 -4
  62. package/dist/types/src/controllers/navigation.d.ts +5 -5
  63. package/dist/types/src/controllers/registry.d.ts +6 -3
  64. package/dist/types/src/controllers/side_entity_controller.d.ts +7 -6
  65. package/dist/types/src/controllers/storage.d.ts +24 -26
  66. package/dist/types/src/rebase_context.d.ts +8 -4
  67. package/dist/types/src/types/backend.d.ts +4 -1
  68. package/dist/types/src/types/builders.d.ts +5 -4
  69. package/dist/types/src/types/chips.d.ts +1 -1
  70. package/dist/types/src/types/collections.d.ts +169 -125
  71. package/dist/types/src/types/cron.d.ts +102 -0
  72. package/dist/types/src/types/data_source.d.ts +1 -1
  73. package/dist/types/src/types/entity_actions.d.ts +8 -8
  74. package/dist/types/src/types/entity_callbacks.d.ts +15 -15
  75. package/dist/types/src/types/entity_link_builder.d.ts +1 -1
  76. package/dist/types/src/types/entity_overrides.d.ts +2 -1
  77. package/dist/types/src/types/entity_views.d.ts +8 -8
  78. package/dist/types/src/types/export_import.d.ts +3 -3
  79. package/dist/types/src/types/index.d.ts +1 -0
  80. package/dist/types/src/types/plugins.d.ts +72 -18
  81. package/dist/types/src/types/properties.d.ts +118 -33
  82. package/dist/types/src/types/relations.d.ts +1 -1
  83. package/dist/types/src/types/slots.d.ts +30 -6
  84. package/dist/types/src/types/translations.d.ts +44 -0
  85. package/dist/types/src/types/user_management_delegate.d.ts +1 -0
  86. package/package.json +84 -84
  87. package/scratch.ts +6 -5
  88. package/src/api/ast-schema-editor.ts +11 -11
  89. package/src/api/collections_for_test/callbacks_test_collection.ts +5 -2
  90. package/src/api/errors.ts +38 -14
  91. package/src/api/graphql/graphql-schema-generator.ts +5 -3
  92. package/src/api/openapi-generator.ts +613 -58
  93. package/src/api/rest/api-generator.ts +17 -11
  94. package/src/api/rest/query-parser.ts +1 -1
  95. package/src/api/schema-editor-routes.ts +2 -0
  96. package/src/api/server.ts +8 -5
  97. package/src/api/types.ts +1 -1
  98. package/src/auth/admin-routes.ts +58 -17
  99. package/src/auth/apple-oauth.ts +130 -0
  100. package/src/auth/bitbucket-oauth.ts +82 -0
  101. package/src/auth/discord-oauth.ts +83 -0
  102. package/src/auth/facebook-oauth.ts +72 -0
  103. package/src/auth/github-oauth.ts +110 -0
  104. package/src/auth/gitlab-oauth.ts +70 -0
  105. package/src/auth/google-oauth.ts +34 -46
  106. package/src/auth/index.ts +15 -2
  107. package/src/auth/interfaces.ts +54 -7
  108. package/src/auth/jwt.ts +22 -5
  109. package/src/auth/linkedin-oauth.ts +81 -0
  110. package/src/auth/microsoft-oauth.ts +88 -0
  111. package/src/auth/middleware.ts +194 -45
  112. package/src/auth/password.ts +3 -1
  113. package/src/auth/rate-limiter.ts +4 -4
  114. package/src/auth/routes.ts +197 -139
  115. package/src/auth/slack-oauth.ts +71 -0
  116. package/src/auth/spotify-oauth.ts +67 -0
  117. package/src/auth/twitter-oauth.ts +120 -0
  118. package/src/collections/loader.ts +6 -6
  119. package/src/cron/cron-loader.ts +89 -0
  120. package/src/cron/cron-routes.test.ts +265 -0
  121. package/src/cron/cron-routes.ts +85 -0
  122. package/src/cron/cron-scheduler.test.ts +421 -0
  123. package/src/cron/cron-scheduler.ts +413 -0
  124. package/src/cron/cron-store.ts +163 -0
  125. package/src/cron/index.ts +6 -0
  126. package/src/db/interfaces.ts +2 -2
  127. package/src/email/index.ts +3 -2
  128. package/src/email/smtp-email-service.ts +5 -2
  129. package/src/email/templates.ts +93 -6
  130. package/src/email/types.ts +17 -24
  131. package/src/functions/function-loader.ts +34 -6
  132. package/src/functions/function-routes.ts +2 -2
  133. package/src/history/history-routes.ts +4 -3
  134. package/src/index.ts +10 -0
  135. package/src/init.ts +475 -57
  136. package/src/services/driver-registry.ts +1 -1
  137. package/src/singleton.test.ts +28 -0
  138. package/src/singleton.ts +70 -0
  139. package/src/storage/LocalStorageController.ts +50 -53
  140. package/src/storage/S3StorageController.ts +49 -46
  141. package/src/storage/index.ts +27 -16
  142. package/src/storage/routes.ts +76 -59
  143. package/src/storage/storage-registry.ts +5 -5
  144. package/src/storage/types.ts +44 -32
  145. package/src/types/index.ts +4 -4
  146. package/src/utils/dev-port.ts +176 -0
  147. package/src/utils/logger.ts +143 -0
  148. package/src/utils/logging.ts +5 -2
  149. package/src/utils/request-logger.ts +66 -0
  150. package/test/admin-routes.test.ts +114 -65
  151. package/test/api-generator.test.ts +73 -30
  152. package/test/ast-schema-editor.test.ts +5 -3
  153. package/test/auth-middleware-hono.test.ts +268 -33
  154. package/test/auth-routes.test.ts +325 -146
  155. package/test/driver-registry.test.ts +4 -2
  156. package/test/error-propagation.test.ts +226 -0
  157. package/test/errors.test.ts +12 -7
  158. package/test/jwt-security.test.ts +18 -9
  159. package/test/jwt.test.ts +26 -13
  160. package/test/middleware.test.ts +13 -8
  161. package/test/query-parser.test.ts +13 -8
  162. package/test/rate-limiter.test.ts +7 -7
  163. package/test/safe-compare.test.ts +66 -0
  164. package/test/singleton.test.ts +59 -0
  165. package/test/storage-local.test.ts +36 -43
  166. package/test/storage-registry.test.ts +38 -36
  167. package/test/storage-routes.test.ts +9 -5
  168. package/test/storage-s3.test.ts +51 -48
  169. package/test.ts +6 -0
  170. package/tsconfig.json +1 -1
  171. package/vite.config.ts +7 -5
  172. package/dist/index-BeMqpmfQ.js +0 -239
  173. package/dist/index-BeMqpmfQ.js.map +0 -1
  174. package/dist/index-bl4J3lNb.js +0 -55823
  175. package/dist/index-bl4J3lNb.js.map +0 -1
  176. package/vite.config.ts.timestamp-1775065397568-8a853255edf6e.mjs +0 -46
@@ -1,2 +1,16 @@
1
1
  import { EntityCollection } from "@rebasepro/types";
2
- export declare function generateOpenApiSpec(collections: EntityCollection[], basePath?: string): Record<string, unknown>;
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: EntityCollection[], options?: OpenApiGeneratorOptions): Record<string, unknown>;
@@ -74,7 +74,7 @@ export interface QueryOptions {
74
74
  where?: Record<string, unknown>;
75
75
  orderBy?: Array<{
76
76
  field: string;
77
- direction: 'asc' | 'desc';
77
+ direction: "asc" | "desc";
78
78
  }>;
79
79
  include?: string[];
80
80
  /** Columns to return in the response (field-level selection) */
@@ -1,7 +1,16 @@
1
1
  import { Hono } from "hono";
2
2
  import { AuthModuleConfig } from "./routes";
3
+ interface AdminRouteOptions extends AuthModuleConfig {
4
+ serviceKey?: string;
5
+ /**
6
+ * Callback to persistently mark bootstrap as completed.
7
+ * Invoked after the first admin user is promoted via POST /admin/bootstrap.
8
+ */
9
+ setBootstrapCompleted?: () => Promise<void>;
10
+ }
3
11
  import { HonoEnv } from "../api/types";
4
12
  /**
5
13
  * Create admin routes for user and role management
6
14
  */
7
- export declare function createAdminRoutes(config: AuthModuleConfig): Hono<HonoEnv>;
15
+ export declare function createAdminRoutes(config: AdminRouteOptions): Hono<HonoEnv>;
16
+ export {};
@@ -0,0 +1,30 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates an Apple Sign In OAuth Provider integration.
4
+ *
5
+ * Apple requires a client secret that is a signed JWT, regenerated on each
6
+ * token exchange (valid up to 6 months). This provider handles that automatically.
7
+ *
8
+ * Required Apple Developer configuration:
9
+ * - Services ID (clientId)
10
+ * - Key ID from the private key registered with Apple
11
+ * - Team ID from Apple Developer account
12
+ * - Private key (.p8 file contents) downloaded from Apple Developer portal
13
+ */
14
+ export declare function createAppleProvider(config: {
15
+ clientId: string;
16
+ teamId: string;
17
+ keyId: string;
18
+ /** The raw PEM contents of the .p8 private key file */
19
+ privateKey: string;
20
+ }): OAuthProvider<{
21
+ code: string;
22
+ redirectUri: string;
23
+ user?: {
24
+ name?: {
25
+ firstName?: string;
26
+ lastName?: string;
27
+ };
28
+ email?: string;
29
+ };
30
+ }>;
@@ -0,0 +1,11 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Bitbucket OAuth Provider integration (OAuth 2.0 consumer).
4
+ */
5
+ export declare function createBitbucketProvider(config: {
6
+ clientId: string;
7
+ clientSecret: string;
8
+ }): OAuthProvider<{
9
+ code: string;
10
+ redirectUri: string;
11
+ }>;
@@ -0,0 +1,14 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Discord OAuth2 Provider integration.
4
+ *
5
+ * Uses the authorization code flow. Requires the "identify" and "email"
6
+ * scopes to retrieve the user's email and profile information.
7
+ */
8
+ export declare function createDiscordProvider(config: {
9
+ clientId: string;
10
+ clientSecret: string;
11
+ }): OAuthProvider<{
12
+ code: string;
13
+ redirectUri: string;
14
+ }>;
@@ -0,0 +1,14 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Facebook / Meta OAuth Provider integration.
4
+ *
5
+ * Uses the authorization code flow to exchange a code for an access token,
6
+ * then fetches user profile from the Facebook Graph API.
7
+ */
8
+ export declare function createFacebookProvider(config: {
9
+ clientId: string;
10
+ clientSecret: string;
11
+ }): OAuthProvider<{
12
+ code: string;
13
+ redirectUri: string;
14
+ }>;
@@ -0,0 +1,15 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a GitHub OAuth Provider integration.
4
+ *
5
+ * Flow: Frontend receives an authorization `code` via the GitHub OAuth redirect.
6
+ * This provider exchanges the code for an access token, then fetches the user's
7
+ * profile and primary email from the GitHub API.
8
+ */
9
+ export declare function createGitHubProvider(config: {
10
+ clientId: string;
11
+ clientSecret: string;
12
+ }): OAuthProvider<{
13
+ code: string;
14
+ redirectUri: string;
15
+ }>;
@@ -0,0 +1,13 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a GitLab OAuth Provider integration.
4
+ * Works with both GitLab.com and self-hosted instances.
5
+ */
6
+ export declare function createGitLabProvider(config: {
7
+ clientId: string;
8
+ clientSecret: string;
9
+ baseUrl?: string;
10
+ }): OAuthProvider<{
11
+ code: string;
12
+ redirectUri: string;
13
+ }>;
@@ -1,3 +1,4 @@
1
+ import type { OAuthProvider } from "./interfaces";
1
2
  export interface GoogleUserInfo {
2
3
  googleId: string;
3
4
  email: string;
@@ -6,15 +7,8 @@ export interface GoogleUserInfo {
6
7
  emailVerified: boolean;
7
8
  }
8
9
  /**
9
- * Configure Google OAuth - call this during initialization
10
+ * Creates a Google OAuth Provider integration
10
11
  */
11
- export declare function configureGoogleOAuth(clientId: string): void;
12
- /**
13
- * Verify a Google ID token and extract user information
14
- * @param idToken The ID token from Google Sign-In on the frontend
15
- */
16
- export declare function verifyGoogleIdToken(idToken: string): Promise<GoogleUserInfo | null>;
17
- /**
18
- * Check if Google OAuth is configured
19
- */
20
- export declare function isGoogleOAuthConfigured(): boolean;
12
+ export declare function createGoogleProvider(clientId: string): OAuthProvider<{
13
+ idToken: string;
14
+ }>;
@@ -1,9 +1,20 @@
1
+ export * from "./interfaces";
1
2
  export { configureJwt, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry } from "./jwt";
2
3
  export type { JwtConfig, AccessTokenPayload } from "./jwt";
3
4
  export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
4
5
  export type { PasswordValidationResult } from "./password";
5
- export { configureGoogleOAuth, verifyGoogleIdToken, isGoogleOAuthConfigured } from "./google-oauth";
6
- export type { GoogleUserInfo } from "./google-oauth";
6
+ export { createGoogleProvider } from "./google-oauth";
7
+ export { createLinkedinProvider } from "./linkedin-oauth";
8
+ export { createGitHubProvider } from "./github-oauth";
9
+ export { createMicrosoftProvider } from "./microsoft-oauth";
10
+ export { createAppleProvider } from "./apple-oauth";
11
+ export { createFacebookProvider } from "./facebook-oauth";
12
+ export { createTwitterProvider } from "./twitter-oauth";
13
+ export { createDiscordProvider } from "./discord-oauth";
14
+ export { createGitLabProvider } from "./gitlab-oauth";
15
+ export { createBitbucketProvider } from "./bitbucket-oauth";
16
+ export { createSlackProvider } from "./slack-oauth";
17
+ export { createSpotifyProvider } from "./spotify-oauth";
7
18
  export { requireAuth, requireAdmin, optionalAuth, extractUserFromToken, createAuthMiddleware } from "./middleware";
8
19
  export type { AuthMiddlewareOptions, AuthResult } from "./middleware";
9
20
  export { createAuthRoutes } from "./routes";
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  /**
2
3
  * Authentication Abstraction Interfaces
3
4
  *
@@ -14,8 +15,6 @@ export interface UserData {
14
15
  passwordHash?: string | null;
15
16
  displayName?: string | null;
16
17
  photoUrl?: string | null;
17
- provider: string;
18
- googleId?: string | null;
19
18
  emailVerified: boolean;
20
19
  emailVerificationToken?: string | null;
21
20
  emailVerificationSentAt?: Date | null;
@@ -30,10 +29,40 @@ export interface CreateUserData {
30
29
  passwordHash?: string;
31
30
  displayName?: string;
32
31
  photoUrl?: string;
33
- provider?: string;
34
- googleId?: string;
35
32
  emailVerified?: boolean;
36
33
  }
34
+ /**
35
+ * User Identity Data (OAuth accounts linked to user)
36
+ */
37
+ export interface UserIdentityData {
38
+ id: string;
39
+ userId: string;
40
+ provider: string;
41
+ providerId: string;
42
+ profileData?: Record<string, unknown> | null;
43
+ createdAt: Date;
44
+ updatedAt: Date;
45
+ }
46
+ /**
47
+ * Standardized profile data returned by an OAuth provider verification payload
48
+ */
49
+ export interface OAuthProviderProfile {
50
+ providerId: string;
51
+ email: string;
52
+ displayName?: string | null;
53
+ photoUrl?: string | null;
54
+ }
55
+ /**
56
+ * Pluggable OAuth Provider integration strategy
57
+ */
58
+ export interface OAuthProvider<T = unknown> {
59
+ /** The identifier of the provider (e.g. "github", "google") */
60
+ id: string;
61
+ /** Zod schema validating the expected request payload (e.g. { code: string }) */
62
+ schema: z.ZodSchema<T>;
63
+ /** Verify external tokens/codes and return a standardized user profile */
64
+ verify: (payload: T) => Promise<OAuthProviderProfile | null>;
65
+ }
37
66
  /**
38
67
  * Role data structure
39
68
  */
@@ -99,6 +128,8 @@ export interface ListUsersOptions {
99
128
  orderBy?: string;
100
129
  /** Sort direction (default "desc") */
101
130
  orderDir?: "asc" | "desc";
131
+ /** Filter by role ID */
132
+ roleId?: string;
102
133
  }
103
134
  /**
104
135
  * Result of a paginated user listing
@@ -128,9 +159,17 @@ export interface UserRepository {
128
159
  */
129
160
  getUserByEmail(email: string): Promise<UserData | null>;
130
161
  /**
131
- * Get a user by Google ID
162
+ * Get a user by an OAuth identity
163
+ */
164
+ getUserByIdentity(provider: string, providerId: string): Promise<UserData | null>;
165
+ /**
166
+ * Get all identities linked to a user
167
+ */
168
+ getUserIdentities(userId: string): Promise<UserIdentityData[]>;
169
+ /**
170
+ * Link a new OAuth identity to a user
132
171
  */
133
- getUserByGoogleId(googleId: string): Promise<UserData | null>;
172
+ linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void>;
134
173
  /**
135
174
  * Update a user
136
175
  */
@@ -6,6 +6,7 @@ export interface JwtConfig {
6
6
  export interface AccessTokenPayload {
7
7
  userId: string;
8
8
  roles: string[];
9
+ uid?: string;
9
10
  }
10
11
  /**
11
12
  * Configure JWT settings - call this during initialization.
@@ -0,0 +1,18 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ export interface LinkedinUserInfo {
3
+ linkedinId: string;
4
+ email: string;
5
+ displayName: string | null;
6
+ photoUrl: string | null;
7
+ emailVerified: boolean;
8
+ }
9
+ /**
10
+ * Creates a LinkedIn OAuth Provider integration
11
+ */
12
+ export declare function createLinkedinProvider(config: {
13
+ clientId: string;
14
+ clientSecret: string;
15
+ }): OAuthProvider<{
16
+ code: string;
17
+ redirectUri: string;
18
+ }>;
@@ -0,0 +1,16 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Microsoft / Entra ID (Azure AD) OAuth Provider integration.
4
+ *
5
+ * Supports both personal Microsoft accounts and work/school (Azure AD) accounts
6
+ * via the "common" tenant endpoint. Uses the authorization code flow.
7
+ */
8
+ export declare function createMicrosoftProvider(config: {
9
+ clientId: string;
10
+ clientSecret: string;
11
+ /** Tenant ID. Defaults to "common" which allows both personal and organizational accounts. */
12
+ tenantId?: string;
13
+ }): OAuthProvider<{
14
+ code: string;
15
+ redirectUri: string;
16
+ }>;
@@ -20,16 +20,50 @@ export type AuthResult = boolean | null | undefined | {
20
20
  export interface AuthMiddlewareOptions {
21
21
  /** DataDriver to scope via withAuth() for RLS */
22
22
  driver: DataDriver;
23
- /** If true, return 401 when no valid token is present (default: false) */
23
+ /**
24
+ * If true, return 401 when no valid token is present.
25
+ *
26
+ * **Defaults to `true` (secure by default).** Set to `false` only for
27
+ * intentionally public endpoints where access control is fully delegated
28
+ * to Postgres Row-Level Security policies.
29
+ */
24
30
  requireAuth?: boolean;
25
31
  /** Optional custom validator (for non-JWT auth, e.g. Firebase Auth) */
26
32
  validator?: (c: Context<HonoEnv>) => Promise<AuthResult>;
33
+ /**
34
+ * A static secret key for server-to-server / script authentication.
35
+ *
36
+ * When a request sends `Authorization: Bearer <key>` and the key matches
37
+ * this value, the request is granted admin-level access (uid: `service`,
38
+ * roles: `["admin"]`) **without** JWT verification. The driver is scoped
39
+ * via `withAuth()` with the service identity.
40
+ *
41
+ * This is the Rebase equivalent of a Firebase Service Account key.
42
+ * Set via `REBASE_SERVICE_KEY` in `.env` and pass through the backend config.
43
+ *
44
+ * **Security:** The comparison uses constant-time equality to prevent
45
+ * timing attacks. The key must be at least 32 characters.
46
+ */
47
+ serviceKey?: string;
27
48
  }
28
49
  /**
29
- * Express middleware that requires a valid JWT token
50
+ * Hono middleware that requires a valid JWT token
30
51
  * Returns 401 if token is missing or invalid
31
52
  */
32
53
  export declare const requireAuth: MiddlewareHandler<HonoEnv>;
54
+ /**
55
+ * Factory that creates a requireAuth middleware with optional service key support.
56
+ *
57
+ * When `serviceKey` is provided, the middleware will check if the Bearer token
58
+ * matches the service key using constant-time comparison. If it matches, the
59
+ * request is authenticated as a service user with admin privileges.
60
+ *
61
+ * This allows admin routes (which use standalone requireAuth + requireAdmin)
62
+ * to be accessed via service keys for scripts and server-to-server calls.
63
+ */
64
+ export declare function createRequireAuth(options?: {
65
+ serviceKey?: string;
66
+ }): MiddlewareHandler<HonoEnv>;
33
67
  /**
34
68
  * Middleware that requires the user to have an admin or schema-admin role.
35
69
  * Must be used AFTER requireAuth or on a route where user is guaranteed.
@@ -44,13 +78,4 @@ export declare const optionalAuth: MiddlewareHandler<HonoEnv>;
44
78
  * Extract user from token - for WebSocket authentication
45
79
  */
46
80
  export declare function extractUserFromToken(token: string): AccessTokenPayload | null;
47
- /**
48
- * Create a configurable auth middleware that handles:
49
- * 1. Token extraction (via custom validator or JWT Bearer token)
50
- * 2. RLS-scoped DataDriver via withAuth()
51
- * 3. Optional enforcement (401 when requireAuth is true and no user)
52
- *
53
- * This is the single source of truth for HTTP auth in Rebase.
54
- * Use this instead of manually parsing tokens in route handlers.
55
- */
56
81
  export declare function createAuthMiddleware(options: AuthMiddlewareOptions): MiddlewareHandler<HonoEnv>;
@@ -20,12 +20,12 @@ interface RateLimiterOptions {
20
20
  export declare function createRateLimiter(options?: RateLimiterOptions): MiddlewareHandler<HonoEnv>;
21
21
  /**
22
22
  * Pre-configured rate limiter for general auth endpoints (login, register).
23
- * 20 requests per 15 minutes per IP.
23
+ * 200 requests per 15 minutes per IP.
24
24
  */
25
25
  export declare const defaultAuthLimiter: MiddlewareHandler<HonoEnv>;
26
26
  /**
27
27
  * Pre-configured strict rate limiter for sensitive endpoints (password reset, verification).
28
- * 5 requests per 15 minutes per IP.
28
+ * 50 requests per 15 minutes per IP.
29
29
  */
30
30
  export declare const strictAuthLimiter: MiddlewareHandler<HonoEnv>;
31
31
  export {};
@@ -1,5 +1,5 @@
1
1
  import { Hono } from "hono";
2
- import type { AuthRepository } from "./interfaces";
2
+ import type { AuthRepository, OAuthProvider } from "./interfaces";
3
3
  import { EmailService, EmailConfig } from "../email";
4
4
  import { HonoEnv } from "../api/types";
5
5
  /**
@@ -9,9 +9,19 @@ export interface AuthModuleConfig {
9
9
  authRepo: AuthRepository;
10
10
  emailService?: EmailService;
11
11
  emailConfig?: EmailConfig;
12
- /** Allow new user registration (default: false). First user can always register for bootstrap. */
12
+ /** Allow new user registration (default: false). */
13
13
  allowRegistration?: boolean;
14
- /** Default role ID to assign to new users (default: none). The first user always gets "admin". */
14
+ /** Default role ID to assign to new users (default: none). Must NOT be "admin". */
15
15
  defaultRole?: string;
16
+ /** Optional array of OAuth providers */
17
+ oauthProviders?: OAuthProvider[];
18
+ /** When true, blocks all self-registration regardless of `allowRegistration`. */
19
+ disableSelfRegistration?: boolean;
20
+ /**
21
+ * Callback that checks if bootstrap has already been completed.
22
+ * Used by GET /auth/config to report `needsSetup` status.
23
+ * When not provided, falls back to checking if any users exist.
24
+ */
25
+ isBootstrapCompleted?: () => Promise<boolean>;
16
26
  }
17
27
  export declare function createAuthRoutes(config: AuthModuleConfig): Hono<HonoEnv>;
@@ -0,0 +1,12 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Slack OAuth Provider integration (OAuth 2.0 / "Sign in with Slack").
4
+ * Uses the OpenID Connect flow with the "openid,email,profile" scopes.
5
+ */
6
+ export declare function createSlackProvider(config: {
7
+ clientId: string;
8
+ clientSecret: string;
9
+ }): OAuthProvider<{
10
+ code: string;
11
+ redirectUri: string;
12
+ }>;
@@ -0,0 +1,12 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Spotify OAuth Provider integration.
4
+ * Uses the authorization code flow with the "user-read-email" scope.
5
+ */
6
+ export declare function createSpotifyProvider(config: {
7
+ clientId: string;
8
+ clientSecret: string;
9
+ }): OAuthProvider<{
10
+ code: string;
11
+ redirectUri: string;
12
+ }>;
@@ -0,0 +1,18 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ /**
3
+ * Creates a Twitter/X OAuth 2.0 Provider integration.
4
+ *
5
+ * Uses OAuth 2.0 with PKCE (authorization code flow). The frontend must include
6
+ * the PKCE `code_verifier` when sending the authorization code.
7
+ *
8
+ * Twitter API v2 requires the "tweet.read" and "users.read" scopes at minimum,
9
+ * plus "offline.access" if refresh tokens are needed on Twitter's side.
10
+ */
11
+ export declare function createTwitterProvider(config: {
12
+ clientId: string;
13
+ clientSecret: string;
14
+ }): OAuthProvider<{
15
+ code: string;
16
+ redirectUri: string;
17
+ codeVerifier: string;
18
+ }>;
@@ -0,0 +1,17 @@
1
+ import type { CronJobDefinition } from "@rebasepro/types";
2
+ export interface LoadedCronJob {
3
+ /** Job ID derived from filename (e.g. "cleanup-sessions"). */
4
+ id: string;
5
+ /** The full definition. */
6
+ definition: CronJobDefinition;
7
+ }
8
+ /**
9
+ * Auto-discover cron job files from a directory.
10
+ *
11
+ * Each file should default-export a `CronJobDefinition`.
12
+ * The filename (without extension) becomes the job ID:
13
+ * `crons/cleanup-sessions.ts` → id = "cleanup-sessions"
14
+ *
15
+ * Follows the same discovery pattern as `loadFunctionsFromDirectory`.
16
+ */
17
+ export declare function loadCronJobsFromDirectory(directory: string): Promise<LoadedCronJob[]>;
@@ -0,0 +1,14 @@
1
+ import { Hono } from "hono";
2
+ import type { HonoEnv } from "../api/types";
3
+ import type { CronScheduler } from "./cron-scheduler";
4
+ /**
5
+ * Create admin REST routes for managing cron jobs.
6
+ *
7
+ * Routes:
8
+ * GET / → list all cron jobs
9
+ * GET /:id → get a single job's status
10
+ * POST /:id/trigger → manually trigger a job
11
+ * GET /:id/logs → get execution logs for a job
12
+ * PUT /:id → update job (enable/disable)
13
+ */
14
+ export declare function createCronRoutes(scheduler: CronScheduler): Hono<HonoEnv>;
@@ -0,0 +1,61 @@
1
+ import type { CronJobStatus, CronJobLogEntry } from "@rebasepro/types";
2
+ import type { RebaseClient } from "@rebasepro/client";
3
+ import type { LoadedCronJob } from "./cron-loader";
4
+ import type { CronStore } from "./cron-store";
5
+ export declare class CronScheduler {
6
+ private jobs;
7
+ private started;
8
+ private store?;
9
+ private client?;
10
+ /**
11
+ * Set the RebaseClient instance to make it available to cron job handlers.
12
+ */
13
+ setClient(client: RebaseClient): void;
14
+ /**
15
+ * Attach a persistence store for cron logs.
16
+ * When set, execution logs are written to the database after each run,
17
+ * and counters are seeded from the database on start.
18
+ */
19
+ setStore(store: CronStore): void;
20
+ /**
21
+ * Register a batch of loaded cron jobs.
22
+ */
23
+ registerJobs(loadedJobs: LoadedCronJob[]): void;
24
+ /**
25
+ * Start the scheduler — begins ticking all enabled jobs.
26
+ */
27
+ start(): void;
28
+ /**
29
+ * Stop the scheduler and clear all timers.
30
+ */
31
+ stop(): void;
32
+ /**
33
+ * List all registered jobs with their current status.
34
+ */
35
+ listJobs(): CronJobStatus[];
36
+ /**
37
+ * Get a single job status by ID.
38
+ */
39
+ getJob(id: string): CronJobStatus | undefined;
40
+ /**
41
+ * Get log entries for a job.
42
+ */
43
+ getJobLogs(id: string, limit?: number): CronJobLogEntry[];
44
+ /**
45
+ * Get log entries for a job from the database (if store is available).
46
+ * Falls back to in-memory logs if no store is configured.
47
+ */
48
+ getJobLogsFromDb(id: string, limit?: number): Promise<CronJobLogEntry[]>;
49
+ /**
50
+ * Enable or disable a job at runtime.
51
+ */
52
+ setJobEnabled(id: string, enabled: boolean): CronJobStatus | undefined;
53
+ /**
54
+ * Manually trigger a job execution immediately.
55
+ */
56
+ triggerJob(id: string): Promise<CronJobLogEntry | undefined>;
57
+ private scheduleNext;
58
+ private stopJob;
59
+ private executeJob;
60
+ private toStatus;
61
+ }
@@ -0,0 +1,32 @@
1
+ import type { CronJobLogEntry } from "@rebasepro/types";
2
+ import type { DataDriver } from "@rebasepro/types";
3
+ /**
4
+ * Persistence layer for cron job execution logs.
5
+ *
6
+ * Uses the DataDriver's `admin.executeSql` capability to store logs in a
7
+ * `rebase.cron_logs` table. Falls back gracefully if the driver doesn't
8
+ * support SQL (e.g. MongoDB) — in that case, no persistence occurs.
9
+ */
10
+ export interface CronStore {
11
+ /** Ensure the backing table exists. Called once on startup. */
12
+ ensureTable(): Promise<void>;
13
+ /** Persist a single log entry after execution. */
14
+ insertLog(entry: CronJobLogEntry): Promise<void>;
15
+ /**
16
+ * Fetch the most recent logs for a job.
17
+ * @param jobId The job identifier
18
+ * @param limit Max entries to return (default 50)
19
+ * @returns Logs sorted newest-first
20
+ */
21
+ fetchLogs(jobId: string, limit?: number): Promise<CronJobLogEntry[]>;
22
+ /**
23
+ * Fetch aggregate stats for all jobs (totalRuns, totalFailures, lastRunAt).
24
+ * Used to seed in-memory counters on startup.
25
+ */
26
+ fetchJobStats(): Promise<Map<string, {
27
+ totalRuns: number;
28
+ totalFailures: number;
29
+ lastRunAt?: string;
30
+ }>>;
31
+ }
32
+ export declare function createCronStore(driver: DataDriver): CronStore | undefined;
@@ -0,0 +1,6 @@
1
+ export { loadCronJobsFromDirectory } from "./cron-loader";
2
+ export type { LoadedCronJob } from "./cron-loader";
3
+ export { CronScheduler } from "./cron-scheduler";
4
+ export { createCronRoutes } from "./cron-routes";
5
+ export { createCronStore } from "./cron-store";
6
+ export type { CronStore } from "./cron-store";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Email module exports
3
3
  */
4
- export type { EmailService, EmailSendOptions, SMTPConfig, EmailConfig, PasswordResetTemplateFunction, EmailVerificationTemplateFunction, UserInvitationTemplateFunction } from "./types";
4
+ export type { EmailService, EmailSendOptions, SMTPConfig, EmailConfig, PasswordResetTemplateFunction, EmailVerificationTemplateFunction, UserInvitationTemplateFunction, WelcomeEmailTemplateFunction } from "./types";
5
5
  export { SMTPEmailService, createEmailService } from "./smtp-email-service";
6
- export { getPasswordResetTemplate, getEmailVerificationTemplate, getUserInvitationTemplate } from "./templates";
6
+ export { getPasswordResetTemplate, getEmailVerificationTemplate, getUserInvitationTemplate, getWelcomeEmailTemplate } from "./templates";
@@ -30,4 +30,13 @@ export declare function getUserInvitationTemplate(setPasswordUrl: string, user:
30
30
  html: string;
31
31
  text: string;
32
32
  };
33
+ /**
34
+ * Default welcome email template
35
+ * Sent automatically when a new user registers
36
+ */
37
+ export declare function getWelcomeEmailTemplate(user: TemplateUser, appName?: string, loginUrl?: string): {
38
+ subject: string;
39
+ html: string;
40
+ text: string;
41
+ };
33
42
  export {};