alepha 0.14.4 → 0.15.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 +1 -4
- package/dist/api/audits/index.d.ts +619 -731
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +185 -298
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +0 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +245 -356
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +238 -350
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +499 -611
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +1 -2
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +1697 -1804
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +178 -151
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +132 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts +122 -122
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +1 -2
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +163 -163
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts +46 -46
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts +302 -299
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +966 -564
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +303 -299
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +11 -7
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +419 -99
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +718 -625
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +420 -99
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +419 -99
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +44 -44
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/datetime/index.js +4 -4
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +97 -50
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +129 -33
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +7981 -14
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/file/index.d.ts +523 -390
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +253 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +208 -208
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/logger/index.d.ts +25 -26
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/mcp/index.d.ts +197 -197
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/orm/chunk-DtkW-qnP.js +38 -0
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +2814 -0
- package/dist/orm/index.bun.js.map +1 -0
- package/dist/orm/index.d.ts +1205 -1057
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +2056 -1753
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +248 -248
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.bun.js +285 -0
- package/dist/redis/index.bun.js.map +1 -0
- package/dist/redis/index.d.ts +118 -136
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +18 -38
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +69 -69
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts +6 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +25 -25
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/security/index.browser.js +5 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +417 -254
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +386 -86
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +277 -277
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +20 -20
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +60 -57
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +1 -1
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +3 -3
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/cookies/index.d.ts +6 -6
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +242 -150
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +288 -122
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -12
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts +0 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts +2 -2
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +84 -85
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +1 -2
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/multipart/index.d.ts +6 -6
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +102 -103
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts +16 -16
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts +44 -44
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +48 -49
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +1 -2
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +13 -11
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +7 -7
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +71 -72
- package/dist/thread/index.d.ts.map +1 -1
- package/dist/topic/core/index.d.ts +318 -318
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts +6 -6
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +5720 -159
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +41 -18
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +6 -6
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +247 -247
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +6 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +9 -14
- package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
- package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
- package/src/api/users/entities/users.ts +1 -1
- package/src/api/users/index.ts +8 -8
- package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
- package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
- package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
- package/src/api/users/services/CredentialService.ts +7 -7
- package/src/api/users/services/IdentityService.ts +4 -4
- package/src/api/users/services/RegistrationService.spec.ts +25 -27
- package/src/api/users/services/RegistrationService.ts +38 -27
- package/src/api/users/services/SessionCrudService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +3 -3
- package/src/api/users/services/SessionService.ts +28 -9
- package/src/api/users/services/UserService.ts +7 -7
- package/src/batch/providers/BatchProvider.ts +1 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +38 -19
- package/src/cli/assets/apiHelloControllerTs.ts +18 -0
- package/src/cli/assets/apiIndexTs.ts +16 -0
- package/src/cli/assets/claudeMd.ts +303 -0
- package/src/cli/assets/mainBrowserTs.ts +2 -2
- package/src/cli/assets/mainServerTs.ts +24 -0
- package/src/cli/assets/webAppRouterTs.ts +15 -0
- package/src/cli/assets/webHelloComponentTsx.ts +16 -0
- package/src/cli/assets/webIndexTs.ts +16 -0
- package/src/cli/commands/build.ts +41 -21
- package/src/cli/commands/db.ts +21 -18
- package/src/cli/commands/deploy.ts +17 -5
- package/src/cli/commands/dev.ts +13 -17
- package/src/cli/commands/format.ts +8 -2
- package/src/cli/commands/init.ts +74 -29
- package/src/cli/commands/lint.ts +8 -2
- package/src/cli/commands/test.ts +8 -2
- package/src/cli/commands/typecheck.ts +5 -1
- package/src/cli/commands/verify.ts +4 -2
- package/src/cli/services/AlephaCliUtils.ts +39 -600
- package/src/cli/services/PackageManagerUtils.ts +301 -0
- package/src/cli/services/ProjectScaffolder.ts +306 -0
- package/src/command/helpers/Runner.ts +15 -3
- package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +2 -0
- package/src/core/primitives/$hook.ts +6 -2
- package/src/core/primitives/$module.spec.ts +4 -0
- package/src/core/providers/AlsProvider.ts +1 -1
- package/src/core/providers/CodecManager.spec.ts +12 -6
- package/src/core/providers/CodecManager.ts +26 -6
- package/src/core/providers/EventManager.ts +169 -13
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +621 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +407 -0
- package/src/core/providers/StateManager.spec.ts +27 -16
- package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
- package/src/email/providers/LocalEmailProvider.ts +52 -15
- package/src/email/providers/NodemailerEmailProvider.ts +167 -56
- package/src/file/errors/FileError.ts +7 -0
- package/src/file/index.ts +9 -1
- package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
- package/src/orm/index.browser.ts +1 -19
- package/src/orm/index.bun.ts +77 -0
- package/src/orm/index.shared-server.ts +22 -0
- package/src/orm/index.shared.ts +15 -0
- package/src/orm/index.ts +19 -39
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
- package/src/orm/services/Repository.ts +8 -0
- package/src/redis/index.bun.ts +35 -0
- package/src/redis/providers/BunRedisProvider.ts +12 -43
- package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
- package/src/redis/providers/NodeRedisProvider.ts +16 -34
- package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
- package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
- package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
- package/src/security/index.browser.ts +5 -0
- package/src/security/index.ts +90 -7
- package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
- package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
- package/src/security/primitives/$role.ts +5 -5
- package/src/security/primitives/$serviceAccount.spec.ts +5 -5
- package/src/security/primitives/$serviceAccount.ts +3 -3
- package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
- package/src/server/auth/primitives/$auth.ts +10 -10
- package/src/server/auth/primitives/$authCredentials.ts +3 -3
- package/src/server/auth/primitives/$authGithub.ts +3 -3
- package/src/server/auth/primitives/$authGoogle.ts +3 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
- package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
- package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
- package/src/server/core/providers/NodeHttpServerProvider.ts +25 -6
- package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
- package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
- package/src/server/core/providers/ServerProvider.ts +144 -21
- package/src/server/core/providers/ServerRouterProvider.ts +259 -115
- package/src/server/core/providers/ServerTimingProvider.ts +2 -2
- package/src/server/links/index.ts +1 -1
- package/src/server/links/providers/LinkProvider.ts +1 -1
- package/src/server/swagger/index.ts +1 -1
- package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
- package/src/sms/providers/LocalSmsProvider.ts +8 -7
- package/src/vite/helpers/boot.ts +28 -17
- package/src/vite/tasks/buildServer.ts +12 -1
- package/src/vite/tasks/devServer.ts +3 -1
- package/src/vite/tasks/generateCloudflare.ts +7 -0
- package/dist/server/security/index.browser.js +0 -13
- package/dist/server/security/index.browser.js.map +0 -1
- package/dist/server/security/index.d.ts +0 -173
- package/dist/server/security/index.d.ts.map +0 -1
- package/dist/server/security/index.js +0 -311
- package/dist/server/security/index.js.map +0 -1
- package/src/cli/assets/appRouterTs.ts +0 -9
- package/src/cli/assets/mainTs.ts +0 -13
- package/src/server/security/index.browser.ts +0 -10
- package/src/server/security/index.ts +0 -94
- /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
package/src/api/users/index.ts
CHANGED
|
@@ -7,10 +7,10 @@ import { AlephaServerHelmet } from "alepha/server/helmet";
|
|
|
7
7
|
import { AdminIdentityController } from "./controllers/AdminIdentityController.ts";
|
|
8
8
|
import { AdminSessionController } from "./controllers/AdminSessionController.ts";
|
|
9
9
|
import { AdminUserController } from "./controllers/AdminUserController.ts";
|
|
10
|
+
import { RealmController } from "./controllers/RealmController.ts";
|
|
10
11
|
import { UserController } from "./controllers/UserController.ts";
|
|
11
|
-
import { UserRealmController } from "./controllers/UserRealmController.ts";
|
|
12
12
|
import { UserNotifications } from "./notifications/UserNotifications.ts";
|
|
13
|
-
import {
|
|
13
|
+
import { RealmProvider } from "./providers/RealmProvider.ts";
|
|
14
14
|
import { CredentialService } from "./services/CredentialService.ts";
|
|
15
15
|
import { IdentityService } from "./services/IdentityService.ts";
|
|
16
16
|
import { RegistrationService } from "./services/RegistrationService.ts";
|
|
@@ -24,13 +24,13 @@ export * from "./atoms/realmAuthSettingsAtom.ts";
|
|
|
24
24
|
export * from "./controllers/AdminIdentityController.ts";
|
|
25
25
|
export * from "./controllers/AdminSessionController.ts";
|
|
26
26
|
export * from "./controllers/AdminUserController.ts";
|
|
27
|
+
export * from "./controllers/RealmController.ts";
|
|
27
28
|
export * from "./controllers/UserController.ts";
|
|
28
|
-
export * from "./controllers/UserRealmController.ts";
|
|
29
29
|
export * from "./entities/identities.ts";
|
|
30
30
|
export * from "./entities/sessions.ts";
|
|
31
31
|
export * from "./entities/users.ts";
|
|
32
|
-
export * from "./primitives/$
|
|
33
|
-
export * from "./providers/
|
|
32
|
+
export * from "./primitives/$realm.ts";
|
|
33
|
+
export * from "./providers/RealmProvider.ts";
|
|
34
34
|
export * from "./schemas/completePasswordResetRequestSchema.ts";
|
|
35
35
|
export * from "./schemas/completeRegistrationRequestSchema.ts";
|
|
36
36
|
export * from "./schemas/createUserSchema.ts";
|
|
@@ -38,6 +38,7 @@ export * from "./schemas/identityQuerySchema.ts";
|
|
|
38
38
|
export * from "./schemas/identityResourceSchema.ts";
|
|
39
39
|
export * from "./schemas/loginSchema.ts";
|
|
40
40
|
export * from "./schemas/passwordResetIntentResponseSchema.ts";
|
|
41
|
+
export * from "./schemas/realmConfigSchema.ts";
|
|
41
42
|
export * from "./schemas/registerSchema.ts";
|
|
42
43
|
export * from "./schemas/registrationIntentResponseSchema.ts";
|
|
43
44
|
export * from "./schemas/resetPasswordSchema.ts";
|
|
@@ -45,7 +46,6 @@ export * from "./schemas/sessionQuerySchema.ts";
|
|
|
45
46
|
export * from "./schemas/sessionResourceSchema.ts";
|
|
46
47
|
export * from "./schemas/updateUserSchema.ts";
|
|
47
48
|
export * from "./schemas/userQuerySchema.ts";
|
|
48
|
-
export * from "./schemas/userRealmConfigSchema.ts";
|
|
49
49
|
export * from "./schemas/userResourceSchema.ts";
|
|
50
50
|
export * from "./services/CredentialService.ts";
|
|
51
51
|
export * from "./services/IdentityService.ts";
|
|
@@ -72,7 +72,7 @@ export const AlephaApiUsers = $module({
|
|
|
72
72
|
AlephaServerHelmet,
|
|
73
73
|
AlephaServerCompress,
|
|
74
74
|
AlephaEmail,
|
|
75
|
-
|
|
75
|
+
RealmProvider,
|
|
76
76
|
SessionService,
|
|
77
77
|
SessionCrudService,
|
|
78
78
|
CredentialService,
|
|
@@ -83,7 +83,7 @@ export const AlephaApiUsers = $module({
|
|
|
83
83
|
AdminUserController,
|
|
84
84
|
AdminSessionController,
|
|
85
85
|
AdminIdentityController,
|
|
86
|
-
|
|
86
|
+
RealmController,
|
|
87
87
|
UserNotifications,
|
|
88
88
|
],
|
|
89
89
|
});
|
|
@@ -3,9 +3,9 @@ import { AlephaApiAudits } from "alepha/api/audits";
|
|
|
3
3
|
import { AlephaApiFiles } from "alepha/api/files";
|
|
4
4
|
import type { Repository } from "alepha/orm";
|
|
5
5
|
import {
|
|
6
|
-
$
|
|
7
|
-
type
|
|
8
|
-
type
|
|
6
|
+
$issuer,
|
|
7
|
+
type IssuerPrimitive,
|
|
8
|
+
type IssuerPrimitiveOptions,
|
|
9
9
|
SecurityProvider,
|
|
10
10
|
} from "alepha/security";
|
|
11
11
|
import {
|
|
@@ -22,10 +22,10 @@ import type { RealmAuthSettings } from "../atoms/realmAuthSettingsAtom.ts";
|
|
|
22
22
|
import type { identities } from "../entities/identities.ts";
|
|
23
23
|
import type { sessions } from "../entities/sessions.ts";
|
|
24
24
|
import { DEFAULT_USER_REALM_NAME, type users } from "../entities/users.ts";
|
|
25
|
-
import {
|
|
25
|
+
import { RealmProvider } from "../providers/RealmProvider.ts";
|
|
26
26
|
import { SessionService } from "../services/SessionService.ts";
|
|
27
27
|
|
|
28
|
-
export type
|
|
28
|
+
export type RealmPrimitive = IssuerPrimitive & WithLinkFn & WithLoginFn;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Already configured realm for user management.
|
|
@@ -41,15 +41,13 @@ export type UserRealmPrimitive = RealmPrimitive & WithLinkFn & WithLoginFn;
|
|
|
41
41
|
* - `APP_SECRET`: Secret key for signing tokens (if not provided in options).
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
|
-
export const $
|
|
45
|
-
options: UserRealmOptions = {},
|
|
46
|
-
): UserRealmPrimitive => {
|
|
44
|
+
export const $realm = (options: RealmOptions = {}): RealmPrimitive => {
|
|
47
45
|
const { alepha } = $context();
|
|
48
46
|
const sessionService = alepha.inject(SessionService);
|
|
49
47
|
const securityProvider = alepha.inject(SecurityProvider);
|
|
50
|
-
const
|
|
48
|
+
const realmProvider = alepha.inject(RealmProvider);
|
|
51
49
|
|
|
52
|
-
const name = options.
|
|
50
|
+
const name = options.issuer?.name ?? DEFAULT_USER_REALM_NAME;
|
|
53
51
|
|
|
54
52
|
options.settings ??= {};
|
|
55
53
|
|
|
@@ -65,16 +63,16 @@ export const $userRealm = (
|
|
|
65
63
|
options.settings.phoneEnabled = true;
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
const
|
|
66
|
+
const realmRegistration = realmProvider.register(name, options);
|
|
69
67
|
|
|
70
68
|
alepha.with(AlephaApiFiles);
|
|
71
69
|
alepha.with(AlephaApiAudits);
|
|
72
70
|
|
|
73
|
-
const realm:
|
|
74
|
-
...options.
|
|
71
|
+
const realm: RealmPrimitive = $issuer({
|
|
72
|
+
...options.issuer,
|
|
75
73
|
name,
|
|
76
74
|
secret: options.secret ?? securityProvider.secretKey,
|
|
77
|
-
roles: options.
|
|
75
|
+
roles: options.issuer?.roles ?? [
|
|
78
76
|
{
|
|
79
77
|
name: "admin",
|
|
80
78
|
permissions: [
|
|
@@ -110,7 +108,7 @@ export const $userRealm = (
|
|
|
110
108
|
onDeleteSession: async (refreshToken) => {
|
|
111
109
|
await sessionService.deleteSession(refreshToken);
|
|
112
110
|
},
|
|
113
|
-
...options.
|
|
111
|
+
...options.issuer?.settings,
|
|
114
112
|
},
|
|
115
113
|
});
|
|
116
114
|
|
|
@@ -140,7 +138,7 @@ export const $userRealm = (
|
|
|
140
138
|
auth.credentials = $authCredentials(realm);
|
|
141
139
|
} else {
|
|
142
140
|
// if credentials auth is disabled, disable registration as well
|
|
143
|
-
|
|
141
|
+
realmRegistration.settings.registrationAllowed = false;
|
|
144
142
|
}
|
|
145
143
|
|
|
146
144
|
if (identities.google) {
|
|
@@ -159,7 +157,7 @@ export const $userRealm = (
|
|
|
159
157
|
|
|
160
158
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
161
159
|
|
|
162
|
-
export interface
|
|
160
|
+
export interface RealmOptions {
|
|
163
161
|
/**
|
|
164
162
|
* Secret key for signing tokens.
|
|
165
163
|
*
|
|
@@ -168,11 +166,11 @@ export interface UserRealmOptions {
|
|
|
168
166
|
secret?: string;
|
|
169
167
|
|
|
170
168
|
/**
|
|
171
|
-
*
|
|
169
|
+
* Issuer configuration options.
|
|
172
170
|
*
|
|
173
171
|
* It's already pre-configured for user management with admin and user roles.
|
|
174
172
|
*/
|
|
175
|
-
|
|
173
|
+
issuer?: Partial<IssuerPrimitiveOptions>;
|
|
176
174
|
|
|
177
175
|
/**
|
|
178
176
|
* Override entities.
|
|
@@ -8,28 +8,28 @@ import {
|
|
|
8
8
|
import { identities } from "../entities/identities.ts";
|
|
9
9
|
import { sessions } from "../entities/sessions.ts";
|
|
10
10
|
import { DEFAULT_USER_REALM_NAME, users } from "../entities/users.ts";
|
|
11
|
-
import type {
|
|
11
|
+
import type { RealmOptions } from "../primitives/$realm.ts";
|
|
12
12
|
|
|
13
|
-
export interface
|
|
13
|
+
export interface RealmRepositories {
|
|
14
14
|
identities: Repository<typeof identities.schema>;
|
|
15
15
|
sessions: Repository<typeof sessions.schema>;
|
|
16
16
|
users: Repository<typeof users.schema>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export interface
|
|
19
|
+
export interface Realm {
|
|
20
20
|
name: string;
|
|
21
|
-
repositories:
|
|
21
|
+
repositories: RealmRepositories;
|
|
22
22
|
settings: RealmAuthSettings;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export class
|
|
25
|
+
export class RealmProvider {
|
|
26
26
|
protected readonly alepha = $inject(Alepha);
|
|
27
27
|
// Default repositories using $repository() for eager initialization
|
|
28
28
|
protected readonly defaultIdentities = $repository(identities);
|
|
29
29
|
protected readonly defaultSessions = $repository(sessions);
|
|
30
30
|
protected readonly defaultUsers = $repository(users);
|
|
31
31
|
|
|
32
|
-
protected realms = new Map<string,
|
|
32
|
+
protected realms = new Map<string, Realm>();
|
|
33
33
|
|
|
34
34
|
public avatars = $bucket({
|
|
35
35
|
maxSize: 5 * 1024 * 1024, // 5 MB
|
|
@@ -47,48 +47,44 @@ export class UserRealmProvider {
|
|
|
47
47
|
},
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
public register(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
) {
|
|
54
|
-
this.realms.set(userRealmName, {
|
|
55
|
-
name: userRealmName,
|
|
50
|
+
public register(realmName: string, realmOptions: RealmOptions = {}) {
|
|
51
|
+
this.realms.set(realmName, {
|
|
52
|
+
name: realmName,
|
|
56
53
|
repositories: {
|
|
57
|
-
identities:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
users: userRealmOptions.entities?.users ?? this.defaultUsers,
|
|
54
|
+
identities: realmOptions.entities?.identities ?? this.defaultIdentities,
|
|
55
|
+
sessions: realmOptions.entities?.sessions ?? this.defaultSessions,
|
|
56
|
+
users: realmOptions.entities?.users ?? this.defaultUsers,
|
|
61
57
|
},
|
|
62
58
|
// TODO: Remove deep merge when alepha supports it natively
|
|
63
59
|
settings: {
|
|
64
60
|
...realmAuthSettingsAtom.options.default,
|
|
65
|
-
...
|
|
61
|
+
...realmOptions.settings,
|
|
66
62
|
passwordPolicy: {
|
|
67
63
|
...realmAuthSettingsAtom.options.default.passwordPolicy,
|
|
68
|
-
...
|
|
64
|
+
...realmOptions.settings?.passwordPolicy,
|
|
69
65
|
},
|
|
70
66
|
},
|
|
71
67
|
});
|
|
72
|
-
return this.getRealm(
|
|
68
|
+
return this.getRealm(realmName);
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
/**
|
|
76
72
|
* Gets a registered realm by name, auto-creating default if needed.
|
|
77
73
|
*/
|
|
78
|
-
public getRealm(
|
|
79
|
-
let realm = this.realms.get(
|
|
74
|
+
public getRealm(realmName = DEFAULT_USER_REALM_NAME): Realm {
|
|
75
|
+
let realm = this.realms.get(realmName);
|
|
80
76
|
|
|
81
77
|
if (!realm) {
|
|
82
78
|
// Auto-register default realm for backward compatibility
|
|
83
79
|
const realms = Array.from(this.realms.values());
|
|
84
80
|
const firstRealm = realms[0];
|
|
85
|
-
if (
|
|
81
|
+
if (realmName === DEFAULT_USER_REALM_NAME && firstRealm) {
|
|
86
82
|
realm = firstRealm;
|
|
87
83
|
} else if (this.alepha.isTest()) {
|
|
88
|
-
realm = this.register(
|
|
84
|
+
realm = this.register(realmName); // Auto-create default realm in tests
|
|
89
85
|
} else {
|
|
90
86
|
throw new AlephaError(
|
|
91
|
-
`Missing
|
|
87
|
+
`Missing realm '${realmName}', please declare $realm in your application.`,
|
|
92
88
|
);
|
|
93
89
|
}
|
|
94
90
|
}
|
|
@@ -97,20 +93,20 @@ export class UserRealmProvider {
|
|
|
97
93
|
}
|
|
98
94
|
|
|
99
95
|
public identityRepository(
|
|
100
|
-
|
|
96
|
+
realmName = DEFAULT_USER_REALM_NAME,
|
|
101
97
|
): Repository<typeof identities.schema> {
|
|
102
|
-
return this.getRealm(
|
|
98
|
+
return this.getRealm(realmName).repositories.identities;
|
|
103
99
|
}
|
|
104
100
|
|
|
105
101
|
public sessionRepository(
|
|
106
|
-
|
|
102
|
+
realmName = DEFAULT_USER_REALM_NAME,
|
|
107
103
|
): Repository<typeof sessions.schema> {
|
|
108
|
-
return this.getRealm(
|
|
104
|
+
return this.getRealm(realmName).repositories.sessions;
|
|
109
105
|
}
|
|
110
106
|
|
|
111
107
|
public userRepository(
|
|
112
|
-
|
|
108
|
+
realmName = DEFAULT_USER_REALM_NAME,
|
|
113
109
|
): Repository<typeof users.schema> {
|
|
114
|
-
return this.getRealm(
|
|
110
|
+
return this.getRealm(realmName).repositories.users;
|
|
115
111
|
}
|
|
116
112
|
}
|
|
@@ -2,10 +2,10 @@ import { type Static, t } from "alepha";
|
|
|
2
2
|
import { authenticationProviderSchema } from "alepha/server/auth";
|
|
3
3
|
import { realmAuthSettingsAtom } from "../atoms/realmAuthSettingsAtom.ts";
|
|
4
4
|
|
|
5
|
-
export const
|
|
5
|
+
export const realmConfigSchema = t.object({
|
|
6
6
|
settings: realmAuthSettingsAtom.schema,
|
|
7
7
|
realmName: t.string(),
|
|
8
8
|
authenticationMethods: t.array(authenticationProviderSchema),
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
-
export type
|
|
11
|
+
export type RealmConfig = Static<typeof realmConfigSchema>;
|
|
@@ -9,7 +9,7 @@ import { CryptoProvider } from "alepha/security";
|
|
|
9
9
|
import { BadRequestError, HttpError } from "alepha/server";
|
|
10
10
|
import { $client } from "alepha/server/links";
|
|
11
11
|
import { UserNotifications } from "../notifications/UserNotifications.ts";
|
|
12
|
-
import {
|
|
12
|
+
import { RealmProvider } from "../providers/RealmProvider.ts";
|
|
13
13
|
import type { CompletePasswordResetRequest } from "../schemas/completePasswordResetRequestSchema.ts";
|
|
14
14
|
import type { PasswordResetIntentResponse } from "../schemas/passwordResetIntentResponseSchema.ts";
|
|
15
15
|
|
|
@@ -32,7 +32,7 @@ export class CredentialService {
|
|
|
32
32
|
protected readonly dateTimeProvider = $inject(DateTimeProvider);
|
|
33
33
|
protected readonly verificationController = $client<VerificationController>();
|
|
34
34
|
protected readonly userNotifications = $inject(UserNotifications);
|
|
35
|
-
protected readonly
|
|
35
|
+
protected readonly realmProvider = $inject(RealmProvider);
|
|
36
36
|
protected readonly auditService = $inject(AuditService);
|
|
37
37
|
|
|
38
38
|
protected readonly intentCache = $cache<PasswordResetIntent>({
|
|
@@ -41,15 +41,15 @@ export class CredentialService {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
public users(userRealmName?: string) {
|
|
44
|
-
return this.
|
|
44
|
+
return this.realmProvider.userRepository(userRealmName);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
public sessions(userRealmName?: string) {
|
|
48
|
-
return this.
|
|
48
|
+
return this.realmProvider.sessionRepository(userRealmName);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
public identities(userRealmName?: string) {
|
|
52
|
-
return this.
|
|
52
|
+
return this.realmProvider.identityRepository(userRealmName);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -222,7 +222,7 @@ export class CredentialService {
|
|
|
222
222
|
email: intent.email,
|
|
223
223
|
});
|
|
224
224
|
|
|
225
|
-
const realm = this.
|
|
225
|
+
const realm = this.realmProvider.getRealm(intent.realmName);
|
|
226
226
|
|
|
227
227
|
// Audit: password reset
|
|
228
228
|
await this.auditService.recordUser("update", {
|
|
@@ -330,7 +330,7 @@ export class CredentialService {
|
|
|
330
330
|
userId: { eq: user.id },
|
|
331
331
|
});
|
|
332
332
|
|
|
333
|
-
const realm = this.
|
|
333
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
334
334
|
|
|
335
335
|
// Audit: password reset (legacy method)
|
|
336
336
|
await this.auditService.recordUser("update", {
|
|
@@ -3,16 +3,16 @@ import { AuditService } from "alepha/api/audits";
|
|
|
3
3
|
import { $logger } from "alepha/logger";
|
|
4
4
|
import type { Page } from "alepha/orm";
|
|
5
5
|
import type { IdentityEntity } from "../entities/identities.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { RealmProvider } from "../providers/RealmProvider.ts";
|
|
7
7
|
import type { IdentityQuery } from "../schemas/identityQuerySchema.ts";
|
|
8
8
|
|
|
9
9
|
export class IdentityService {
|
|
10
10
|
protected readonly log = $logger();
|
|
11
|
-
protected readonly
|
|
11
|
+
protected readonly realmProvider = $inject(RealmProvider);
|
|
12
12
|
protected readonly auditService = $inject(AuditService);
|
|
13
13
|
|
|
14
14
|
public identities(userRealmName?: string) {
|
|
15
|
-
return this.
|
|
15
|
+
return this.realmProvider.identityRepository(userRealmName);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -85,7 +85,7 @@ export class IdentityService {
|
|
|
85
85
|
userId: identity.userId,
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
const realm = this.
|
|
88
|
+
const realm = this.realmProvider.getRealm(userRealmName);
|
|
89
89
|
|
|
90
90
|
await this.auditService.recordUser("update", {
|
|
91
91
|
userRealm: realm.name,
|
|
@@ -7,9 +7,9 @@ import { BadRequestError, ConflictError, HttpError } from "alepha/server";
|
|
|
7
7
|
import { describe, it } from "vitest";
|
|
8
8
|
import {
|
|
9
9
|
AlephaApiUsers,
|
|
10
|
+
RealmProvider,
|
|
10
11
|
RegistrationService,
|
|
11
12
|
SessionService,
|
|
12
|
-
UserRealmProvider,
|
|
13
13
|
UserService,
|
|
14
14
|
} from "../index.ts";
|
|
15
15
|
|
|
@@ -26,11 +26,11 @@ const setup = async (realmSettings?: Record<string, unknown>) => {
|
|
|
26
26
|
const emailProvider = alepha.inject(MemoryEmailProvider);
|
|
27
27
|
emailProvider.records = [];
|
|
28
28
|
|
|
29
|
-
const
|
|
29
|
+
const realmProvider = alepha.inject(RealmProvider);
|
|
30
30
|
|
|
31
31
|
// Configure realm settings if provided (applies to default realm)
|
|
32
32
|
if (realmSettings) {
|
|
33
|
-
|
|
33
|
+
realmProvider.register("default", {
|
|
34
34
|
settings: realmSettings as never,
|
|
35
35
|
});
|
|
36
36
|
}
|
|
@@ -43,7 +43,7 @@ const setup = async (realmSettings?: Record<string, unknown>) => {
|
|
|
43
43
|
cryptoProvider: alepha.inject(CryptoProvider),
|
|
44
44
|
dateTimeProvider: alepha.inject(DateTimeProvider),
|
|
45
45
|
emailProvider,
|
|
46
|
-
|
|
46
|
+
realmProvider,
|
|
47
47
|
};
|
|
48
48
|
};
|
|
49
49
|
|
|
@@ -79,11 +79,11 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
79
79
|
it("should create intent with email verification required when configured", async ({
|
|
80
80
|
expect,
|
|
81
81
|
}) => {
|
|
82
|
-
const { registrationService, emailProvider,
|
|
82
|
+
const { registrationService, emailProvider, realmProvider } =
|
|
83
83
|
await setup();
|
|
84
84
|
|
|
85
85
|
// Register realm with email verification required
|
|
86
|
-
|
|
86
|
+
realmProvider.register("verify-email-realm", {
|
|
87
87
|
settings: {
|
|
88
88
|
verifyEmailRequired: true,
|
|
89
89
|
} as never,
|
|
@@ -113,9 +113,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
113
113
|
it("should reject registration when disabled in realm settings", async ({
|
|
114
114
|
expect,
|
|
115
115
|
}) => {
|
|
116
|
-
const { registrationService,
|
|
116
|
+
const { registrationService, realmProvider } = await setup();
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
realmProvider.register("no-registration-realm", {
|
|
119
119
|
settings: {
|
|
120
120
|
registrationAllowed: false,
|
|
121
121
|
} as never,
|
|
@@ -135,9 +135,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
135
135
|
it("should reject when required username is missing", async ({
|
|
136
136
|
expect,
|
|
137
137
|
}) => {
|
|
138
|
-
const { registrationService,
|
|
138
|
+
const { registrationService, realmProvider } = await setup();
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
realmProvider.register("username-required-realm", {
|
|
141
141
|
settings: {
|
|
142
142
|
usernameRequired: true,
|
|
143
143
|
} as never,
|
|
@@ -169,9 +169,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
it("should reject when required phone is missing", async ({ expect }) => {
|
|
172
|
-
const { registrationService,
|
|
172
|
+
const { registrationService, realmProvider } = await setup();
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
realmProvider.register("phone-required-realm", {
|
|
175
175
|
settings: {
|
|
176
176
|
phoneRequired: true,
|
|
177
177
|
emailRequired: false,
|
|
@@ -229,10 +229,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
229
229
|
});
|
|
230
230
|
|
|
231
231
|
it("should reject duplicate phone number", async ({ expect }) => {
|
|
232
|
-
const { registrationService, userService,
|
|
233
|
-
await setup();
|
|
232
|
+
const { registrationService, userService, realmProvider } = await setup();
|
|
234
233
|
|
|
235
|
-
|
|
234
|
+
realmProvider.register("phone-realm", {
|
|
236
235
|
settings: {
|
|
237
236
|
phoneEnabled: true,
|
|
238
237
|
emailRequired: false,
|
|
@@ -312,10 +311,10 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
312
311
|
it("should complete registration with valid email verification code", async ({
|
|
313
312
|
expect,
|
|
314
313
|
}) => {
|
|
315
|
-
const { registrationService, emailProvider,
|
|
314
|
+
const { registrationService, emailProvider, realmProvider } =
|
|
316
315
|
await setup();
|
|
317
316
|
|
|
318
|
-
|
|
317
|
+
realmProvider.register("email-verify-realm", {
|
|
319
318
|
settings: {
|
|
320
319
|
verifyEmailRequired: true,
|
|
321
320
|
} as never,
|
|
@@ -379,9 +378,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
379
378
|
it("should reject when email code is required but not provided", async ({
|
|
380
379
|
expect,
|
|
381
380
|
}) => {
|
|
382
|
-
const { registrationService,
|
|
381
|
+
const { registrationService, realmProvider } = await setup();
|
|
383
382
|
|
|
384
|
-
|
|
383
|
+
realmProvider.register("email-required-realm", {
|
|
385
384
|
settings: {
|
|
386
385
|
verifyEmailRequired: true,
|
|
387
386
|
} as never,
|
|
@@ -404,9 +403,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
404
403
|
});
|
|
405
404
|
|
|
406
405
|
it("should reject invalid email verification code", async ({ expect }) => {
|
|
407
|
-
const { registrationService,
|
|
406
|
+
const { registrationService, realmProvider } = await setup();
|
|
408
407
|
|
|
409
|
-
|
|
408
|
+
realmProvider.register("email-verify-realm", {
|
|
410
409
|
settings: {
|
|
411
410
|
verifyEmailRequired: true,
|
|
412
411
|
} as never,
|
|
@@ -454,10 +453,9 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
454
453
|
it("should detect race condition when email is taken during verification", async ({
|
|
455
454
|
expect,
|
|
456
455
|
}) => {
|
|
457
|
-
const { registrationService, userService,
|
|
458
|
-
await setup();
|
|
456
|
+
const { registrationService, userService, realmProvider } = await setup();
|
|
459
457
|
|
|
460
|
-
|
|
458
|
+
realmProvider.register("race-realm", {
|
|
461
459
|
settings: {
|
|
462
460
|
verifyEmailRequired: false,
|
|
463
461
|
} as never,
|
|
@@ -490,7 +488,7 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
490
488
|
it("should create credentials identity with hashed password", async ({
|
|
491
489
|
expect,
|
|
492
490
|
}) => {
|
|
493
|
-
const { registrationService, sessionService,
|
|
491
|
+
const { registrationService, sessionService, realmProvider } =
|
|
494
492
|
await setup();
|
|
495
493
|
|
|
496
494
|
const intent = await registrationService.createRegistrationIntent({
|
|
@@ -584,10 +582,10 @@ describe("alepha/api/users - RegistrationService", () => {
|
|
|
584
582
|
registrationService,
|
|
585
583
|
sessionService,
|
|
586
584
|
emailProvider,
|
|
587
|
-
|
|
585
|
+
realmProvider,
|
|
588
586
|
} = await setup();
|
|
589
587
|
|
|
590
|
-
|
|
588
|
+
realmProvider.register("full-verify-realm", {
|
|
591
589
|
settings: {
|
|
592
590
|
verifyEmailRequired: true,
|
|
593
591
|
} as never,
|