@rebasepro/server-core 0.7.0 → 0.8.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.
Files changed (155) hide show
  1. package/build-errors.txt +52 -0
  2. package/dist/api/ast-schema-editor.d.ts +21 -0
  3. package/dist/api/collections_for_test/callbacks_test_collection.d.ts +2 -0
  4. package/dist/api/errors.d.ts +53 -0
  5. package/dist/api/graphql/graphql-schema-generator.d.ts +44 -0
  6. package/dist/api/graphql/index.d.ts +1 -0
  7. package/dist/api/index.d.ts +9 -0
  8. package/dist/api/logs-routes.d.ts +37 -0
  9. package/dist/api/openapi-generator.d.ts +16 -0
  10. package/dist/api/rest/api-generator.d.ts +76 -0
  11. package/dist/api/rest/index.d.ts +1 -0
  12. package/dist/api/rest/query-parser.d.ts +8 -0
  13. package/dist/api/schema-editor-routes.d.ts +3 -0
  14. package/dist/api/server.d.ts +40 -0
  15. package/dist/api/types.d.ts +104 -0
  16. package/dist/auth/adapter-middleware.d.ts +43 -0
  17. package/dist/auth/admin-roles-route.d.ts +18 -0
  18. package/dist/auth/admin-user-ops.d.ts +79 -0
  19. package/dist/auth/admin-users-route.d.ts +28 -0
  20. package/dist/auth/api-keys/api-key-middleware.d.ts +39 -0
  21. package/dist/auth/api-keys/api-key-permission-guard.d.ts +32 -0
  22. package/dist/auth/api-keys/api-key-routes.d.ts +20 -0
  23. package/dist/auth/api-keys/api-key-store.d.ts +35 -0
  24. package/dist/auth/api-keys/api-key-types.d.ts +96 -0
  25. package/dist/auth/api-keys/index.d.ts +17 -0
  26. package/dist/auth/apple-oauth.d.ts +30 -0
  27. package/dist/auth/auth-hooks.d.ts +242 -0
  28. package/dist/auth/bitbucket-oauth.d.ts +11 -0
  29. package/dist/auth/builtin-auth-adapter.d.ts +51 -0
  30. package/dist/auth/crypto-utils.d.ts +16 -0
  31. package/dist/auth/custom-auth-adapter.d.ts +39 -0
  32. package/dist/auth/discord-oauth.d.ts +14 -0
  33. package/dist/auth/facebook-oauth.d.ts +14 -0
  34. package/dist/auth/github-oauth.d.ts +15 -0
  35. package/dist/auth/gitlab-oauth.d.ts +13 -0
  36. package/dist/auth/google-oauth.d.ts +47 -0
  37. package/dist/auth/index.d.ts +37 -0
  38. package/dist/auth/interfaces.d.ts +431 -0
  39. package/dist/auth/jwt.d.ts +55 -0
  40. package/dist/auth/linkedin-oauth.d.ts +18 -0
  41. package/dist/auth/magic-link-routes.d.ts +30 -0
  42. package/dist/auth/mfa-crypto.d.ts +23 -0
  43. package/dist/auth/mfa-routes.d.ts +7 -0
  44. package/dist/auth/mfa.d.ts +49 -0
  45. package/dist/auth/microsoft-oauth.d.ts +16 -0
  46. package/dist/auth/middleware.d.ts +113 -0
  47. package/dist/auth/password.d.ts +22 -0
  48. package/dist/auth/rate-limiter.d.ts +50 -0
  49. package/dist/auth/reset-password-admin.d.ts +29 -0
  50. package/dist/auth/rls-scope.d.ts +31 -0
  51. package/dist/auth/routes.d.ts +35 -0
  52. package/dist/auth/session-routes.d.ts +27 -0
  53. package/dist/auth/slack-oauth.d.ts +12 -0
  54. package/dist/auth/spotify-oauth.d.ts +12 -0
  55. package/dist/auth/twitter-oauth.d.ts +18 -0
  56. package/dist/backend-CIxN4FVm.js +15 -0
  57. package/dist/backend-CIxN4FVm.js.map +1 -0
  58. package/dist/base64-js-C_frYBkI.js +1687 -0
  59. package/dist/base64-js-C_frYBkI.js.map +1 -0
  60. package/dist/chunk-Dze3rakg.js +42 -0
  61. package/dist/collections/BackendCollectionRegistry.d.ts +13 -0
  62. package/dist/collections/loader.d.ts +5 -0
  63. package/dist/cron/cron-loader.d.ts +17 -0
  64. package/dist/cron/cron-routes.d.ts +14 -0
  65. package/dist/cron/cron-scheduler.d.ts +106 -0
  66. package/dist/cron/cron-store.d.ts +32 -0
  67. package/dist/cron/index.d.ts +6 -0
  68. package/dist/db/interfaces.d.ts +18 -0
  69. package/dist/dist-DMO-zF6D.js +832 -0
  70. package/dist/dist-DMO-zF6D.js.map +1 -0
  71. package/dist/email/index.d.ts +6 -0
  72. package/dist/email/smtp-email-service.d.ts +25 -0
  73. package/dist/email/templates.d.ts +50 -0
  74. package/dist/email/types.d.ts +126 -0
  75. package/dist/env.d.ts +102 -0
  76. package/dist/from-VbwD7xRf.js +3849 -0
  77. package/dist/from-VbwD7xRf.js.map +1 -0
  78. package/dist/functions/define-function.d.ts +50 -0
  79. package/dist/functions/function-loader.d.ts +17 -0
  80. package/dist/functions/function-routes.d.ts +10 -0
  81. package/dist/functions/index.d.ts +5 -0
  82. package/dist/history/history-routes.d.ts +23 -0
  83. package/dist/history/index.d.ts +1 -0
  84. package/dist/index.d.ts +31 -0
  85. package/dist/index.es.js +61322 -0
  86. package/dist/index.es.js.map +1 -0
  87. package/dist/index.umd.js +103633 -0
  88. package/dist/index.umd.js.map +1 -0
  89. package/dist/init/docs.d.ts +4 -0
  90. package/dist/init/health.d.ts +2 -0
  91. package/dist/init/middlewares.d.ts +10 -0
  92. package/dist/init/shutdown.d.ts +11 -0
  93. package/dist/init/storage.d.ts +5 -0
  94. package/dist/init.d.ts +314 -0
  95. package/dist/jws-BqRRaK11.js +616 -0
  96. package/dist/jws-BqRRaK11.js.map +1 -0
  97. package/dist/jwt-BETC8a1J.js +3560 -0
  98. package/dist/jwt-BETC8a1J.js.map +1 -0
  99. package/dist/logger-BYU66ENZ.js +94 -0
  100. package/dist/logger-BYU66ENZ.js.map +1 -0
  101. package/dist/ms-BeBSuOXN.js +125 -0
  102. package/dist/ms-BeBSuOXN.js.map +1 -0
  103. package/dist/multipart-parser-CedBDOeC.js +299 -0
  104. package/dist/multipart-parser-CedBDOeC.js.map +1 -0
  105. package/dist/serve-spa.d.ts +30 -0
  106. package/dist/services/driver-registry.d.ts +78 -0
  107. package/dist/services/routed-realtime-service.d.ts +43 -0
  108. package/dist/services/webhook-service.d.ts +29 -0
  109. package/dist/singleton.d.ts +35 -0
  110. package/dist/src-CB2PIpBe.js +1182 -0
  111. package/dist/src-CB2PIpBe.js.map +1 -0
  112. package/dist/src-DjzOT1kG.js +29746 -0
  113. package/dist/src-DjzOT1kG.js.map +1 -0
  114. package/dist/storage/GCSStorageController.d.ts +43 -0
  115. package/dist/storage/LocalStorageController.d.ts +46 -0
  116. package/dist/storage/S3StorageController.d.ts +36 -0
  117. package/dist/storage/image-transform.d.ts +50 -0
  118. package/dist/storage/index.d.ts +31 -0
  119. package/dist/storage/routes.d.ts +70 -0
  120. package/dist/storage/storage-registry.d.ts +78 -0
  121. package/dist/storage/tus-handler.d.ts +53 -0
  122. package/dist/storage/types.d.ts +128 -0
  123. package/dist/types/index.d.ts +11 -0
  124. package/dist/utils/dev-port.d.ts +37 -0
  125. package/dist/utils/logger.d.ts +31 -0
  126. package/dist/utils/logging.d.ts +9 -0
  127. package/dist/utils/request-id.d.ts +4 -0
  128. package/dist/utils/request-logger.d.ts +19 -0
  129. package/dist/utils/sql.d.ts +27 -0
  130. package/package.json +22 -14
  131. package/src/api/graphql/graphql-schema-generator.ts +5 -5
  132. package/src/api/openapi-generator.ts +2 -2
  133. package/src/api/rest/api-generator.ts +44 -123
  134. package/src/api/rest/query-parser.ts +6 -23
  135. package/src/api/types.ts +2 -2
  136. package/src/auth/auth-hooks.ts +1 -1
  137. package/src/auth/builtin-auth-adapter.ts +1 -2
  138. package/src/auth/interfaces.ts +11 -2
  139. package/src/auth/middleware.ts +4 -4
  140. package/src/auth/routes.ts +1 -2
  141. package/src/functions/define-function.ts +59 -0
  142. package/src/functions/function-loader.ts +16 -0
  143. package/src/functions/index.ts +2 -0
  144. package/src/index.ts +70 -37
  145. package/src/init.ts +78 -21
  146. package/src/storage/GCSStorageController.ts +334 -0
  147. package/src/storage/index.ts +9 -3
  148. package/src/storage/routes.ts +191 -23
  149. package/src/storage/tus-handler.ts +16 -4
  150. package/src/storage/types.ts +25 -3
  151. package/test/api-generator.test.ts +1 -1
  152. package/test/auth-config-types.test.ts +40 -0
  153. package/test/define-function.test.ts +45 -0
  154. package/test/storage-routes.test.ts +160 -0
  155. package/test/backend-hooks-data.test.ts +0 -477
@@ -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
+ }>;
@@ -0,0 +1,47 @@
1
+ import type { OAuthProvider } from "./interfaces";
2
+ export interface GoogleUserInfo {
3
+ googleId: string;
4
+ email: string;
5
+ displayName: string | null;
6
+ photoUrl: string | null;
7
+ emailVerified: boolean;
8
+ }
9
+ export interface GoogleProviderConfig {
10
+ clientId: string;
11
+ /**
12
+ * The OAuth 2.0 client secret from Google Cloud Console.
13
+ *
14
+ * Required for the **authorization code flow** (Path 3), where the
15
+ * frontend sends an authorization `code` and the backend exchanges it
16
+ * server-side for tokens. This is the most secure flow because tokens
17
+ * never touch the browser.
18
+ *
19
+ * When omitted, only ID-token and access-token verification are available
20
+ * (Paths 1 & 2), which rely on the frontend obtaining tokens directly.
21
+ */
22
+ clientSecret?: string;
23
+ }
24
+ /**
25
+ * Creates a Google OAuth Provider integration.
26
+ *
27
+ * Supports three verification paths:
28
+ *
29
+ * **Path 1 – ID Token** (One Tap / Sign In With Google button):
30
+ * Frontend sends `idToken`. Backend verifies cryptographically using
31
+ * Google's public keys. No secret required.
32
+ *
33
+ * **Path 2 – Access Token** (popup via `initTokenClient`):
34
+ * Frontend sends `accessToken`. Backend validates by calling Google's
35
+ * userinfo endpoint. No secret required.
36
+ *
37
+ * **Path 3 – Authorization Code** (most secure, requires `clientSecret`):
38
+ * Frontend sends `code` + `redirectUri`. Backend exchanges the code
39
+ * server-side for an ID token using `clientId` + `clientSecret`, then
40
+ * verifies the ID token. Tokens never touch the browser.
41
+ */
42
+ export declare function createGoogleProvider(config: GoogleProviderConfig | string): OAuthProvider<{
43
+ idToken?: string;
44
+ accessToken?: string;
45
+ code?: string;
46
+ redirectUri?: string;
47
+ }>;
@@ -0,0 +1,37 @@
1
+ export * from "./interfaces";
2
+ export { configureJwt, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry } from "./jwt";
3
+ export type { JwtConfig, AccessTokenPayload } from "./jwt";
4
+ export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
5
+ export type { PasswordValidationResult } from "./password";
6
+ export type { AuthHooks, AuthMethod, ResolvedAuthHooks } from "./auth-hooks";
7
+ export { resolveAuthHooks } from "./auth-hooks";
8
+ export { generateSecurePassword, generateSecureToken, hashToken, prepareAdminUserValues, finalizeAdminUserCreation } from "./admin-user-ops";
9
+ export type { AdminUserContext, AdminUserPrepareResult } from "./admin-user-ops";
10
+ export { createGoogleProvider } from "./google-oauth";
11
+ export type { GoogleProviderConfig } from "./google-oauth";
12
+ export { createLinkedinProvider } from "./linkedin-oauth";
13
+ export { createGitHubProvider } from "./github-oauth";
14
+ export { createMicrosoftProvider } from "./microsoft-oauth";
15
+ export { createAppleProvider } from "./apple-oauth";
16
+ export { createFacebookProvider } from "./facebook-oauth";
17
+ export { createTwitterProvider } from "./twitter-oauth";
18
+ export { createDiscordProvider } from "./discord-oauth";
19
+ export { createGitLabProvider } from "./gitlab-oauth";
20
+ export { createBitbucketProvider } from "./bitbucket-oauth";
21
+ export { createSlackProvider } from "./slack-oauth";
22
+ export { createSpotifyProvider } from "./spotify-oauth";
23
+ export { requireAuth, requireAdmin, optionalAuth, extractUserFromToken, createAuthMiddleware } from "./middleware";
24
+ export type { AuthMiddlewareOptions, AuthResult } from "./middleware";
25
+ export { createAuthRoutes } from "./routes";
26
+ export type { AuthModuleConfig } from "./routes";
27
+ export { mountMagicLinkRoutes } from "./magic-link-routes";
28
+ export { createResetPasswordRoute } from "./reset-password-admin";
29
+ export type { ResetPasswordRouteConfig } from "./reset-password-admin";
30
+ export { createRateLimiter, defaultAuthLimiter, strictAuthLimiter, createApiKeyRateLimiter, apiKeyKeyGenerator } from "./rate-limiter";
31
+ export { createApiKeyStore, createApiKeyRoutes, isApiKeyToken, validateApiKey, httpMethodToOperation, isOperationAllowed } from "./api-keys";
32
+ export type { ApiKey, ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest, ApiKeyStore, ApiKeyOperation } from "./api-keys";
33
+ export { createBuiltinAuthAdapter } from "./builtin-auth-adapter";
34
+ export type { BuiltinAuthAdapterConfig } from "./builtin-auth-adapter";
35
+ export { createCustomAuthAdapter } from "./custom-auth-adapter";
36
+ export { createAdapterAuthMiddleware } from "./adapter-middleware";
37
+ export type { AdapterAuthMiddlewareOptions } from "./adapter-middleware";
@@ -0,0 +1,431 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Authentication Abstraction Interfaces
4
+ *
5
+ * These interfaces define the contracts for authentication-related operations.
6
+ * Implementations can use different databases (PostgreSQL, MongoDB, etc.) to
7
+ * store user, role, and token data.
8
+ */
9
+ /**
10
+ * User data structure
11
+ */
12
+ export interface UserData {
13
+ id: string;
14
+ email: string;
15
+ passwordHash?: string | null;
16
+ displayName?: string | null;
17
+ photoUrl?: string | null;
18
+ emailVerified: boolean;
19
+ emailVerificationToken?: string | null;
20
+ emailVerificationSentAt?: Date | null;
21
+ isAnonymous?: boolean;
22
+ metadata?: Record<string, unknown>;
23
+ createdAt: Date;
24
+ updatedAt: Date;
25
+ }
26
+ /**
27
+ * Data for creating a new user
28
+ */
29
+ export interface CreateUserData {
30
+ email: string;
31
+ passwordHash?: string;
32
+ displayName?: string;
33
+ photoUrl?: string;
34
+ emailVerified?: boolean;
35
+ isAnonymous?: boolean;
36
+ metadata?: Record<string, unknown>;
37
+ }
38
+ /**
39
+ * User Identity Data (OAuth accounts linked to user)
40
+ */
41
+ export interface UserIdentityData {
42
+ id: string;
43
+ userId: string;
44
+ provider: string;
45
+ providerId: string;
46
+ profileData?: Record<string, unknown> | null;
47
+ createdAt: Date;
48
+ updatedAt: Date;
49
+ }
50
+ /**
51
+ * Standardized profile data returned by an OAuth provider verification payload
52
+ */
53
+ export interface OAuthProviderProfile {
54
+ providerId: string;
55
+ email: string;
56
+ displayName?: string | null;
57
+ photoUrl?: string | null;
58
+ /** Whether the OAuth provider has verified the user's email address */
59
+ emailVerified?: boolean;
60
+ }
61
+ /**
62
+ * Pluggable OAuth Provider integration strategy
63
+ */
64
+ export interface OAuthProvider<T = unknown> {
65
+ /** The identifier of the provider (e.g. "github", "google") */
66
+ id: string;
67
+ /** Zod schema validating the expected request payload (e.g. { code: string }) */
68
+ schema: z.ZodSchema<T>;
69
+ /**
70
+ * Verify external tokens/codes and return a standardized user profile.
71
+ *
72
+ * NOTE: Declared as method syntax (not arrow property) intentionally.
73
+ * This makes `OAuthProvider` bivariant in `T`, which is correct because
74
+ * each provider is self-contained — `schema` validates the request body
75
+ * and `verify` consumes the same `T`. Bivariance lets heterogeneous
76
+ * providers (`OAuthProvider<SpecificPayload>`) coexist in a single
77
+ * `OAuthProvider<unknown>[]` array without resorting to `any`.
78
+ */
79
+ verify(payload: T): Promise<OAuthProviderProfile | null>;
80
+ }
81
+ /**
82
+ * Role data structure
83
+ */
84
+ export interface RoleData {
85
+ id: string;
86
+ name: string;
87
+ isAdmin: boolean;
88
+ defaultPermissions: {
89
+ read?: boolean;
90
+ create?: boolean;
91
+ edit?: boolean;
92
+ delete?: boolean;
93
+ } | null;
94
+ collectionPermissions: Record<string, {
95
+ read?: boolean;
96
+ create?: boolean;
97
+ edit?: boolean;
98
+ delete?: boolean;
99
+ }> | null;
100
+ }
101
+ /**
102
+ * Data for creating a new role
103
+ */
104
+ export interface CreateRoleData {
105
+ id: string;
106
+ name: string;
107
+ isAdmin?: boolean;
108
+ defaultPermissions?: RoleData["defaultPermissions"];
109
+ collectionPermissions?: RoleData["collectionPermissions"];
110
+ }
111
+ /**
112
+ * Refresh token info
113
+ */
114
+ export interface RefreshTokenInfo {
115
+ id: string;
116
+ userId: string;
117
+ tokenHash: string;
118
+ expiresAt: Date;
119
+ createdAt: Date;
120
+ userAgent?: string | null;
121
+ ipAddress?: string | null;
122
+ }
123
+ /**
124
+ * Password reset token info
125
+ */
126
+ export interface PasswordResetTokenInfo {
127
+ userId: string;
128
+ expiresAt: Date;
129
+ }
130
+ /**
131
+ * Magic link token info
132
+ */
133
+ export interface MagicLinkTokenInfo {
134
+ userId: string;
135
+ expiresAt: Date;
136
+ }
137
+ /**
138
+ * Options for paginated user listing
139
+ */
140
+ export interface ListUsersOptions {
141
+ /** Max results per page (default 25) */
142
+ limit?: number;
143
+ /** Number of results to skip (default 0) */
144
+ offset?: number;
145
+ /** Search term — matches against email and displayName (case-insensitive) */
146
+ search?: string;
147
+ /** Field to sort by (default "createdAt") */
148
+ orderBy?: string;
149
+ /** Sort direction (default "desc") */
150
+ orderDir?: "asc" | "desc";
151
+ /** Filter by role ID */
152
+ roleId?: string;
153
+ }
154
+ /**
155
+ * Result of a paginated user listing
156
+ */
157
+ export interface PaginatedUsersResult {
158
+ users: UserData[];
159
+ /** Total number of users matching the filters (ignoring limit/offset) */
160
+ total: number;
161
+ limit: number;
162
+ offset: number;
163
+ }
164
+ /**
165
+ * Abstract user repository interface.
166
+ * Handles all user-related database operations.
167
+ */
168
+ export interface UserRepository {
169
+ /**
170
+ * Create a new user
171
+ */
172
+ createUser(data: CreateUserData): Promise<UserData>;
173
+ /**
174
+ * Get a user by ID
175
+ */
176
+ getUserById(id: string): Promise<UserData | null>;
177
+ /**
178
+ * Get a user by email
179
+ */
180
+ getUserByEmail(email: string): Promise<UserData | null>;
181
+ /**
182
+ * Get a user by an OAuth identity
183
+ */
184
+ getUserByIdentity(provider: string, providerId: string): Promise<UserData | null>;
185
+ /**
186
+ * Get all identities linked to a user
187
+ */
188
+ getUserIdentities(userId: string): Promise<UserIdentityData[]>;
189
+ /**
190
+ * Link a new OAuth identity to a user
191
+ */
192
+ linkUserIdentity(userId: string, provider: string, providerId: string, profileData?: Record<string, unknown>): Promise<void>;
193
+ /**
194
+ * Update a user
195
+ */
196
+ updateUser(id: string, data: Partial<Omit<CreateUserData, "id">>): Promise<UserData | null>;
197
+ /**
198
+ * Delete a user
199
+ */
200
+ deleteUser(id: string): Promise<void>;
201
+ /**
202
+ * List all users (unbounded — use listUsersPaginated for large datasets)
203
+ */
204
+ listUsers(): Promise<UserData[]>;
205
+ /**
206
+ * List users with server-side pagination, search, and sorting.
207
+ */
208
+ listUsersPaginated(options?: ListUsersOptions): Promise<PaginatedUsersResult>;
209
+ /**
210
+ * Update user's password hash
211
+ */
212
+ updatePassword(id: string, passwordHash: string): Promise<void>;
213
+ /**
214
+ * Set email verification status
215
+ */
216
+ setEmailVerified(id: string, verified: boolean): Promise<void>;
217
+ /**
218
+ * Set email verification token
219
+ */
220
+ setVerificationToken(id: string, token: string | null): Promise<void>;
221
+ /**
222
+ * Find user by email verification token
223
+ */
224
+ getUserByVerificationToken(token: string): Promise<UserData | null>;
225
+ /**
226
+ * Get roles for a user
227
+ */
228
+ getUserRoles(userId: string): Promise<RoleData[]>;
229
+ /**
230
+ * Get role IDs for a user
231
+ */
232
+ getUserRoleIds(userId: string): Promise<string[]>;
233
+ /**
234
+ * Set roles for a user (replaces existing roles)
235
+ */
236
+ setUserRoles(userId: string, roleIds: string[]): Promise<void>;
237
+ /**
238
+ * Assign a specific role to a new user
239
+ */
240
+ assignDefaultRole(userId: string, roleId: string): Promise<void>;
241
+ /**
242
+ * Get user with their roles
243
+ */
244
+ getUserWithRoles(userId: string): Promise<{
245
+ user: UserData;
246
+ roles: RoleData[];
247
+ } | null>;
248
+ }
249
+ /**
250
+ * Abstract role repository interface.
251
+ * Handles all role-related database operations.
252
+ */
253
+ export interface RoleRepository {
254
+ /**
255
+ * Get a role by ID
256
+ */
257
+ getRoleById(id: string): Promise<RoleData | null>;
258
+ /**
259
+ * List all roles
260
+ */
261
+ listRoles(): Promise<RoleData[]>;
262
+ /**
263
+ * Create a new role
264
+ */
265
+ createRole(data: CreateRoleData): Promise<RoleData>;
266
+ /**
267
+ * Update a role
268
+ */
269
+ updateRole(id: string, data: Partial<Omit<RoleData, "id">>): Promise<RoleData | null>;
270
+ /**
271
+ * Delete a role
272
+ */
273
+ deleteRole(id: string): Promise<void>;
274
+ }
275
+ /**
276
+ * Abstract token repository interface.
277
+ * Handles refresh tokens and password reset tokens.
278
+ */
279
+ export interface TokenRepository {
280
+ /**
281
+ * Create a new refresh token
282
+ */
283
+ createRefreshToken(userId: string, tokenHash: string, expiresAt: Date, userAgent?: string, ipAddress?: string): Promise<void>;
284
+ /**
285
+ * Find a refresh token by hash
286
+ */
287
+ findRefreshTokenByHash(tokenHash: string): Promise<RefreshTokenInfo | null>;
288
+ /**
289
+ * Delete a refresh token by hash
290
+ */
291
+ deleteRefreshToken(tokenHash: string): Promise<void>;
292
+ /**
293
+ * Delete all refresh tokens for a user
294
+ */
295
+ deleteAllRefreshTokensForUser(userId: string): Promise<void>;
296
+ /**
297
+ * List all refresh tokens for a user
298
+ */
299
+ listRefreshTokensForUser(userId: string): Promise<RefreshTokenInfo[]>;
300
+ /**
301
+ * Delete a specific refresh token by its primary key ID
302
+ */
303
+ deleteRefreshTokenById(id: string, userId: string): Promise<void>;
304
+ /**
305
+ * Create a password reset token
306
+ */
307
+ createPasswordResetToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
308
+ /**
309
+ * Find a valid (not expired, not used) password reset token by hash
310
+ */
311
+ findValidPasswordResetToken(tokenHash: string): Promise<PasswordResetTokenInfo | null>;
312
+ /**
313
+ * Mark a password reset token as used
314
+ */
315
+ markPasswordResetTokenUsed(tokenHash: string): Promise<void>;
316
+ /**
317
+ * Delete all password reset tokens for a user
318
+ */
319
+ deleteAllPasswordResetTokensForUser(userId: string): Promise<void>;
320
+ /**
321
+ * Clean up expired tokens
322
+ */
323
+ deleteExpiredTokens(): Promise<void>;
324
+ /**
325
+ * Create a magic link token
326
+ */
327
+ createMagicLinkToken(userId: string, tokenHash: string, expiresAt: Date): Promise<void>;
328
+ /**
329
+ * Find a valid (not expired, not used) magic link token by hash
330
+ */
331
+ findValidMagicLinkToken(tokenHash: string): Promise<MagicLinkTokenInfo | null>;
332
+ /**
333
+ * Mark a magic link token as used
334
+ */
335
+ markMagicLinkTokenUsed(tokenHash: string): Promise<void>;
336
+ }
337
+ /**
338
+ * MFA factor data structure
339
+ */
340
+ export interface MfaFactor {
341
+ id: string;
342
+ userId: string;
343
+ factorType: "totp";
344
+ friendlyName?: string;
345
+ verified: boolean;
346
+ createdAt: Date;
347
+ updatedAt: Date;
348
+ }
349
+ /**
350
+ * MFA challenge information
351
+ */
352
+ export interface MfaChallengeInfo {
353
+ id: string;
354
+ factorId: string;
355
+ createdAt: Date;
356
+ verifiedAt?: Date;
357
+ ipAddress?: string;
358
+ }
359
+ /**
360
+ * Recovery code data structure
361
+ */
362
+ export interface RecoveryCode {
363
+ id: string;
364
+ userId: string;
365
+ usedAt?: Date;
366
+ }
367
+ /**
368
+ * Abstract MFA repository interface.
369
+ * Handles all MFA-related database operations.
370
+ */
371
+ export interface MfaRepository {
372
+ /**
373
+ * Create a new MFA factor for a user
374
+ */
375
+ createMfaFactor(userId: string, factorType: "totp", secretEncrypted: string, friendlyName?: string): Promise<MfaFactor>;
376
+ /**
377
+ * Get all MFA factors for a user
378
+ */
379
+ getMfaFactors(userId: string): Promise<MfaFactor[]>;
380
+ /**
381
+ * Get a specific MFA factor by ID
382
+ */
383
+ getMfaFactorById(factorId: string): Promise<(MfaFactor & {
384
+ secretEncrypted: string;
385
+ }) | null>;
386
+ /**
387
+ * Mark an MFA factor as verified
388
+ */
389
+ verifyMfaFactor(factorId: string): Promise<void>;
390
+ /**
391
+ * Delete an MFA factor
392
+ */
393
+ deleteMfaFactor(factorId: string, userId: string): Promise<void>;
394
+ /**
395
+ * Create an MFA challenge
396
+ */
397
+ createMfaChallenge(factorId: string, ipAddress?: string): Promise<MfaChallengeInfo>;
398
+ /**
399
+ * Get an MFA challenge by ID
400
+ */
401
+ getMfaChallengeById(challengeId: string): Promise<MfaChallengeInfo | null>;
402
+ /**
403
+ * Mark an MFA challenge as verified
404
+ */
405
+ verifyMfaChallenge(challengeId: string): Promise<void>;
406
+ /**
407
+ * Create recovery codes for a user
408
+ */
409
+ createRecoveryCodes(userId: string, codeHashes: string[]): Promise<void>;
410
+ /**
411
+ * Use a recovery code (mark as used)
412
+ */
413
+ useRecoveryCode(userId: string, codeHash: string): Promise<boolean>;
414
+ /**
415
+ * Get unused recovery code count for a user
416
+ */
417
+ getUnusedRecoveryCodeCount(userId: string): Promise<number>;
418
+ /**
419
+ * Delete all recovery codes for a user
420
+ */
421
+ deleteAllRecoveryCodes(userId: string): Promise<void>;
422
+ /**
423
+ * Check if a user has any verified MFA factors
424
+ */
425
+ hasVerifiedMfaFactors(userId: string): Promise<boolean>;
426
+ }
427
+ /**
428
+ * Combined auth repository interface for convenience
429
+ */
430
+ export interface AuthRepository extends UserRepository, RoleRepository, TokenRepository, MfaRepository {
431
+ }
@@ -0,0 +1,55 @@
1
+ export interface JwtConfig {
2
+ secret: string;
3
+ accessExpiresIn?: string;
4
+ refreshExpiresIn?: string;
5
+ }
6
+ export interface AccessTokenPayload {
7
+ userId: string;
8
+ roles: string[];
9
+ uid?: string;
10
+ /** Authentication Assurance Level: aal1 = password/oauth, aal2 = MFA verified */
11
+ aal?: "aal1" | "aal2";
12
+ /** Email claim from the JWT, if present */
13
+ email?: string;
14
+ /** Display name claim from the JWT, if present */
15
+ displayName?: string;
16
+ /** Photo URL claim from the JWT, if present */
17
+ photoURL?: string;
18
+ /** Whether MFA has been verified for this session */
19
+ mfa_verified?: boolean;
20
+ /** Authentication Methods Reference — list of methods used (e.g. 'pwd', 'otp') */
21
+ amr?: string[];
22
+ }
23
+ /**
24
+ * Configure JWT settings - call this during initialization.
25
+ * Validates the secret strength to prevent deployment with default/weak secrets.
26
+ */
27
+ export declare function configureJwt(config: JwtConfig): void;
28
+ /**
29
+ * Generate an access token (short-lived, 1 hour by default)
30
+ */
31
+ export declare function generateAccessToken(userId: string, roles: string[], aal?: "aal1" | "aal2", customClaims?: Record<string, unknown>): string;
32
+ /**
33
+ * Get the expiration time of an access token in milliseconds from now
34
+ */
35
+ export declare function getAccessTokenExpiryMs(): number;
36
+ /**
37
+ * Get the expiration timestamp for an access token
38
+ */
39
+ export declare function getAccessTokenExpiry(): number;
40
+ /**
41
+ * Verify and decode an access token
42
+ */
43
+ export declare function verifyAccessToken(token: string): AccessTokenPayload | null;
44
+ /**
45
+ * Generate a random refresh token (long-lived, 30 days by default)
46
+ */
47
+ export declare function generateRefreshToken(): string;
48
+ /**
49
+ * Hash a refresh token for database storage (don't store raw tokens)
50
+ */
51
+ export declare function hashRefreshToken(token: string): string;
52
+ /**
53
+ * Calculate refresh token expiration date
54
+ */
55
+ export declare function getRefreshTokenExpiry(): Date;
@@ -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,30 @@
1
+ import { Hono } from "hono";
2
+ import type { AuthModuleConfig } from "./routes";
3
+ import type { ResolvedAuthHooks } from "./auth-hooks";
4
+ import type { HonoEnv } from "../api/types";
5
+ import { z } from "zod";
6
+ import type { AuthResponsePayload, TransformAuthResponseContext } from "@rebasepro/types";
7
+ /**
8
+ * Mount magic link routes onto the auth router.
9
+ *
10
+ * Follows the same delegation pattern as `mountMfaRoutes()` and `mountSessionRoutes()`.
11
+ */
12
+ export declare function mountMagicLinkRoutes(deps: {
13
+ router: Hono<HonoEnv>;
14
+ config: AuthModuleConfig;
15
+ ops: ResolvedAuthHooks;
16
+ parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;
17
+ buildAuthResponse: (user: {
18
+ id: string;
19
+ email: string;
20
+ displayName?: string | null;
21
+ photoUrl?: string | null;
22
+ metadata?: Record<string, unknown> | null;
23
+ }, roleIds: string[], accessToken: string, refreshToken: string) => unknown;
24
+ createSessionAndTokens: (userId: string, userAgent: string, ipAddress: string) => Promise<{
25
+ roleIds: string[];
26
+ accessToken: string;
27
+ refreshToken: string;
28
+ }>;
29
+ applyTransformHook: (response: AuthResponsePayload, method: TransformAuthResponseContext["method"], request: Request, userId: string) => Promise<AuthResponsePayload>;
30
+ }): void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Envelope encryption for TOTP secrets using AES-256-GCM.
3
+ *
4
+ * - Derives a 32-byte key via SHA-256 from `MFA_ENCRYPTION_KEY` or `JWT_SECRET`.
5
+ * - Generates a random 12-byte IV per encryption call.
6
+ * - Returns ciphertexts in the format `iv_hex:authTag_hex:ciphertext_hex`.
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Encrypt a plaintext TOTP secret.
12
+ *
13
+ * @param plaintext - The Base32 TOTP secret to encrypt.
14
+ * @returns A string in the format `iv_hex:authTag_hex:ciphertext_hex`.
15
+ */
16
+ export declare function encryptTotpSecret(plaintext: string): string;
17
+ /**
18
+ * Decrypt a previously encrypted TOTP secret.
19
+ *
20
+ * @param ciphertext - A string in the format `iv_hex:authTag_hex:ciphertext_hex`.
21
+ * @returns The original Base32 TOTP secret.
22
+ */
23
+ export declare function decryptTotpSecret(ciphertext: string): string;
@@ -0,0 +1,7 @@
1
+ import { Hono } from "hono";
2
+ import { z } from "zod";
3
+ import { HonoEnv } from "../api/types";
4
+ import type { AuthModuleConfig } from "./routes";
5
+ import { resolveAuthHooks } from "./auth-hooks";
6
+ import type { AuthResponsePayload, TransformAuthResponseContext } from "@rebasepro/types";
7
+ export declare function mountMfaRoutes(router: Hono<HonoEnv>, config: AuthModuleConfig, ops: ReturnType<typeof resolveAuthHooks>, parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T, applyTransformHook?: (response: AuthResponsePayload, method: TransformAuthResponseContext["method"], request: Request, userId: string) => Promise<AuthResponsePayload>): void;