alepha 0.14.3 → 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 +2 -5
- package/dist/api/audits/index.d.ts +620 -811
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +185 -377
- 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 -435
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +238 -429
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +236 -427
- 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 +1010 -1196
- 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 +17 -17
- 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 +384 -285
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1113 -623
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +299 -300
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +13 -9
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +445 -103
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +733 -625
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +446 -103
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +445 -103
- 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/logger/index.js +12 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +197 -197
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.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 +1228 -1216
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +2041 -1967
- 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 +110 -110
- 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 +62 -47
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +56 -3
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +6 -0
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +36 -1
- package/dist/server/compress/index.js.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.browser.js +2 -2
- package/dist/server/core/index.browser.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 +294 -125
- 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 +123 -124
- 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/static/index.js +4 -0
- package/dist/server/static/index.js.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 +3 -5
- 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 +5805 -249
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +599 -513
- 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/AlephaCli.ts +0 -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/atoms/buildOptions.ts +88 -0
- package/src/cli/commands/build.ts +70 -87
- package/src/cli/commands/db.ts +21 -22
- package/src/cli/commands/deploy.ts +17 -5
- package/src/cli/commands/dev.ts +22 -14
- package/src/cli/commands/format.ts +8 -2
- package/src/cli/commands/gen/env.ts +53 -0
- package/src/cli/commands/gen/openapi.ts +1 -1
- package/src/cli/commands/gen/resource.ts +15 -0
- package/src/cli/commands/gen.ts +7 -1
- package/src/cli/commands/init.ts +74 -30
- package/src/cli/commands/lint.ts +8 -2
- package/src/cli/commands/test.ts +8 -3
- package/src/cli/commands/typecheck.ts +5 -1
- package/src/cli/commands/verify.ts +5 -3
- package/src/cli/defineConfig.ts +49 -7
- package/src/cli/index.ts +0 -1
- package/src/cli/services/AlephaCliUtils.ts +39 -589
- package/src/cli/services/PackageManagerUtils.ts +301 -0
- package/src/cli/services/ProjectScaffolder.ts +306 -0
- package/src/command/helpers/Runner.spec.ts +2 -2
- package/src/command/helpers/Runner.ts +16 -4
- package/src/command/primitives/$command.ts +0 -6
- package/src/command/providers/CliProvider.ts +1 -3
- package/src/core/Alepha.ts +42 -0
- 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/logger/index.ts +15 -3
- package/src/mcp/transports/StdioMcpTransport.ts +1 -1
- 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 +13 -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/queue/core/providers/WorkerProvider.spec.ts +48 -32
- 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.spec.ts +183 -0
- package/src/server/cache/providers/ServerCacheProvider.ts +95 -10
- package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
- package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
- package/src/server/core/helpers/ServerReply.ts +2 -2
- 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 +155 -22
- 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/static/providers/ServerStaticProvider.ts +10 -0
- package/src/server/swagger/index.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
- 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/helpers/importViteReact.ts +13 -0
- package/src/vite/index.ts +1 -21
- package/src/vite/plugins/viteAlephaDev.ts +16 -1
- package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
- package/src/vite/tasks/buildClient.ts +11 -0
- package/src/vite/tasks/buildServer.ts +59 -4
- package/src/vite/tasks/devServer.ts +71 -0
- package/src/vite/tasks/generateCloudflare.ts +7 -0
- package/src/vite/tasks/index.ts +2 -1
- 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/cli/assets/viteConfigTs.ts +0 -14
- package/src/cli/commands/run.ts +0 -24
- package/src/server/security/index.browser.ts +0 -10
- package/src/server/security/index.ts +0 -94
- package/src/vite/plugins/viteAlepha.ts +0 -37
- package/src/vite/plugins/viteAlephaBuild.ts +0 -281
- /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
|
@@ -4,19 +4,23 @@ import {
|
|
|
4
4
|
type RedisClientType,
|
|
5
5
|
type SetOptions,
|
|
6
6
|
} from "@redis/client";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
$env,
|
|
9
|
+
$hook,
|
|
10
|
+
$inject,
|
|
11
|
+
Alepha,
|
|
12
|
+
AlephaError,
|
|
13
|
+
type Static,
|
|
14
|
+
t,
|
|
15
|
+
} from "alepha";
|
|
8
16
|
import { $logger } from "alepha/logger";
|
|
9
17
|
import { RedisProvider, type RedisSetOptions } from "./RedisProvider.ts";
|
|
10
18
|
|
|
11
19
|
const envSchema = t.object({
|
|
12
|
-
REDIS_URL: t.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}),
|
|
16
|
-
REDIS_HOST: t.text({
|
|
17
|
-
default: "localhost",
|
|
20
|
+
REDIS_URL: t.text({
|
|
21
|
+
default: "redis://localhost:6379",
|
|
22
|
+
description: "Redis connection URL",
|
|
18
23
|
}),
|
|
19
|
-
REDIS_PASSWORD: t.optional(t.text()),
|
|
20
24
|
});
|
|
21
25
|
|
|
22
26
|
declare module "alepha" {
|
|
@@ -39,10 +43,8 @@ export type NodeRedisClientOptions = Parameters<typeof createClient>[0];
|
|
|
39
43
|
*
|
|
40
44
|
* @example
|
|
41
45
|
* ```ts
|
|
42
|
-
* // Set REDIS_URL environment variable
|
|
43
|
-
* // REDIS_URL=redis
|
|
44
|
-
*
|
|
45
|
-
* // Or configure via REDIS_HOST, REDIS_PORT, REDIS_PASSWORD
|
|
46
|
+
* // Set REDIS_URL environment variable (default: redis://localhost:6379)
|
|
47
|
+
* // REDIS_URL=redis://:password@myredis.example.com:6379
|
|
46
48
|
*
|
|
47
49
|
* // Or configure programmatically
|
|
48
50
|
* alepha.with({
|
|
@@ -59,7 +61,7 @@ export class NodeRedisProvider extends RedisProvider {
|
|
|
59
61
|
|
|
60
62
|
public get publisher(): NodeRedisClient {
|
|
61
63
|
if (!this.client.isReady) {
|
|
62
|
-
throw new
|
|
64
|
+
throw new AlephaError("Redis client is not ready");
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
return this.client;
|
|
@@ -235,27 +237,7 @@ export class NodeRedisProvider extends RedisProvider {
|
|
|
235
237
|
* Get the Redis connection URL.
|
|
236
238
|
*/
|
|
237
239
|
protected getUrl(): string {
|
|
238
|
-
|
|
239
|
-
if (this.env.REDIS_URL) {
|
|
240
|
-
return this.env.REDIS_URL;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Build URL from components
|
|
244
|
-
const url = new URL("redis://127.0.0.1:6379");
|
|
245
|
-
|
|
246
|
-
if (this.env.REDIS_PASSWORD) {
|
|
247
|
-
url.password = this.env.REDIS_PASSWORD;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (this.env.REDIS_HOST) {
|
|
251
|
-
url.hostname = this.env.REDIS_HOST;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (this.env.REDIS_PORT) {
|
|
255
|
-
url.port = String(this.env.REDIS_PORT);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
return url.toString();
|
|
240
|
+
return this.env.REDIS_URL;
|
|
259
241
|
}
|
|
260
242
|
|
|
261
243
|
/**
|
|
@@ -3,7 +3,7 @@ import { $action, AlephaServer } from "alepha/server";
|
|
|
3
3
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
4
|
import {
|
|
5
5
|
$basicAuth,
|
|
6
|
-
|
|
6
|
+
AlephaSecurity,
|
|
7
7
|
ServerBasicAuthProvider,
|
|
8
8
|
} from "../index.ts";
|
|
9
9
|
|
|
@@ -58,7 +58,7 @@ describe("Basic Authentication", () => {
|
|
|
58
58
|
beforeEach(async () => {
|
|
59
59
|
alepha = Alepha.create()
|
|
60
60
|
.with(AlephaServer)
|
|
61
|
-
.with(
|
|
61
|
+
.with(AlephaSecurity)
|
|
62
62
|
.with(TestApp);
|
|
63
63
|
|
|
64
64
|
await alepha.start();
|
|
@@ -269,7 +269,7 @@ describe("Basic Authentication", () => {
|
|
|
269
269
|
|
|
270
270
|
const edgeAlepha = Alepha.create()
|
|
271
271
|
.with(AlephaServer)
|
|
272
|
-
.with(
|
|
272
|
+
.with(AlephaSecurity)
|
|
273
273
|
.with(EdgeCaseApp);
|
|
274
274
|
|
|
275
275
|
await edgeAlepha.start();
|
|
@@ -301,7 +301,7 @@ describe("Basic Authentication", () => {
|
|
|
301
301
|
|
|
302
302
|
const emptyAlepha = Alepha.create()
|
|
303
303
|
.with(AlephaServer)
|
|
304
|
-
.with(
|
|
304
|
+
.with(AlephaSecurity)
|
|
305
305
|
.with(EmptyPasswordApp);
|
|
306
306
|
|
|
307
307
|
await emptyAlepha.start();
|
|
@@ -333,7 +333,7 @@ describe("Basic Authentication", () => {
|
|
|
333
333
|
|
|
334
334
|
const specialAlepha = Alepha.create()
|
|
335
335
|
.with(AlephaServer)
|
|
336
|
-
.with(
|
|
336
|
+
.with(AlephaSecurity)
|
|
337
337
|
.with(SpecialCharsApp);
|
|
338
338
|
|
|
339
339
|
await specialAlepha.start();
|
|
@@ -365,7 +365,7 @@ describe("Basic Authentication", () => {
|
|
|
365
365
|
|
|
366
366
|
const unicodeAlepha = Alepha.create()
|
|
367
367
|
.with(AlephaServer)
|
|
368
|
-
.with(
|
|
368
|
+
.with(AlephaSecurity)
|
|
369
369
|
.with(UnicodeApp);
|
|
370
370
|
|
|
371
371
|
await unicodeAlepha.start();
|
|
@@ -397,7 +397,7 @@ describe("Basic Authentication", () => {
|
|
|
397
397
|
|
|
398
398
|
const unicodeAlepha = Alepha.create()
|
|
399
399
|
.with(AlephaServer)
|
|
400
|
-
.with(
|
|
400
|
+
.with(AlephaSecurity)
|
|
401
401
|
.with(UnicodeApp);
|
|
402
402
|
|
|
403
403
|
await unicodeAlepha.start();
|
|
@@ -434,7 +434,7 @@ describe("Basic Authentication", () => {
|
|
|
434
434
|
|
|
435
435
|
const longAlepha = Alepha.create()
|
|
436
436
|
.with(AlephaServer)
|
|
437
|
-
.with(
|
|
437
|
+
.with(AlephaSecurity)
|
|
438
438
|
.with(LongCredsApp);
|
|
439
439
|
|
|
440
440
|
await longAlepha.start();
|
|
@@ -466,7 +466,7 @@ describe("Basic Authentication", () => {
|
|
|
466
466
|
|
|
467
467
|
const emptyUserAlepha = Alepha.create()
|
|
468
468
|
.with(AlephaServer)
|
|
469
|
-
.with(
|
|
469
|
+
.with(AlephaSecurity)
|
|
470
470
|
.with(EmptyUsernameApp);
|
|
471
471
|
|
|
472
472
|
await emptyUserAlepha.start();
|
|
@@ -549,7 +549,7 @@ describe("Basic Authentication", () => {
|
|
|
549
549
|
|
|
550
550
|
const wsAlepha = Alepha.create()
|
|
551
551
|
.with(AlephaServer)
|
|
552
|
-
.with(
|
|
552
|
+
.with(AlephaSecurity)
|
|
553
553
|
.with(WhitespaceApp);
|
|
554
554
|
|
|
555
555
|
await wsAlepha.start();
|
|
@@ -582,7 +582,7 @@ describe("Basic Authentication", () => {
|
|
|
582
582
|
|
|
583
583
|
const wsAlepha = Alepha.create()
|
|
584
584
|
.with(AlephaServer)
|
|
585
|
-
.with(
|
|
585
|
+
.with(AlephaSecurity)
|
|
586
586
|
.with(WhitespaceApp);
|
|
587
587
|
|
|
588
588
|
await wsAlepha.start();
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { Alepha } from "alepha";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
$action,
|
|
5
|
+
$route,
|
|
6
|
+
AlephaServer,
|
|
7
|
+
ForbiddenError,
|
|
8
|
+
ServerProvider,
|
|
9
|
+
} from "alepha/server";
|
|
5
10
|
import { describe, expect, it } from "vitest";
|
|
6
|
-
import {
|
|
11
|
+
import { $issuer, AlephaSecurity } from "../index.ts";
|
|
7
12
|
|
|
8
13
|
describe("ServerSecurityProvider - Realm Protection", () => {
|
|
9
14
|
it("should allow access when user belongs to the required realm", async () => {
|
|
10
15
|
class TestApp {
|
|
11
|
-
realmA = $
|
|
16
|
+
realmA = $issuer({
|
|
12
17
|
secret: "test-realm-a",
|
|
13
18
|
roles: [
|
|
14
19
|
{
|
|
@@ -18,7 +23,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
18
23
|
],
|
|
19
24
|
});
|
|
20
25
|
|
|
21
|
-
realmB = $
|
|
26
|
+
realmB = $issuer({
|
|
22
27
|
secret: "test-realm-b",
|
|
23
28
|
roles: [
|
|
24
29
|
{
|
|
@@ -43,7 +48,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
43
48
|
});
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
const alepha = Alepha.create().with(
|
|
51
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
47
52
|
const app = alepha.inject(TestApp);
|
|
48
53
|
await alepha.start();
|
|
49
54
|
|
|
@@ -85,7 +90,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
85
90
|
|
|
86
91
|
it("should deny access when user does not belong to the required realm", async () => {
|
|
87
92
|
class TestApp {
|
|
88
|
-
realmA = $
|
|
93
|
+
realmA = $issuer({
|
|
89
94
|
secret: "test-realm-a",
|
|
90
95
|
roles: [
|
|
91
96
|
{
|
|
@@ -95,7 +100,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
95
100
|
],
|
|
96
101
|
});
|
|
97
102
|
|
|
98
|
-
realmB = $
|
|
103
|
+
realmB = $issuer({
|
|
99
104
|
secret: "test-realm-b",
|
|
100
105
|
roles: [
|
|
101
106
|
{
|
|
@@ -120,7 +125,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
120
125
|
});
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
const alepha = Alepha.create().with(
|
|
128
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
124
129
|
const app = alepha.inject(TestApp);
|
|
125
130
|
await alepha.start();
|
|
126
131
|
|
|
@@ -172,7 +177,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
172
177
|
|
|
173
178
|
it("should work with actions when user has no realm attribute", async () => {
|
|
174
179
|
class TestApp {
|
|
175
|
-
realmA = $
|
|
180
|
+
realmA = $issuer({
|
|
176
181
|
secret: "test-realm-a",
|
|
177
182
|
roles: [
|
|
178
183
|
{
|
|
@@ -188,7 +193,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
188
193
|
});
|
|
189
194
|
}
|
|
190
195
|
|
|
191
|
-
const alepha = Alepha.create().with(
|
|
196
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
192
197
|
const app = alepha.inject(TestApp);
|
|
193
198
|
await alepha.start();
|
|
194
199
|
|
|
@@ -215,7 +220,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
215
220
|
|
|
216
221
|
it("should combine realm and permission checks", async () => {
|
|
217
222
|
class TestApp {
|
|
218
|
-
realmA = $
|
|
223
|
+
realmA = $issuer({
|
|
219
224
|
secret: "test-realm-a",
|
|
220
225
|
roles: [
|
|
221
226
|
{
|
|
@@ -229,7 +234,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
229
234
|
],
|
|
230
235
|
});
|
|
231
236
|
|
|
232
|
-
realmB = $
|
|
237
|
+
realmB = $issuer({
|
|
233
238
|
secret: "test-realm-b",
|
|
234
239
|
});
|
|
235
240
|
|
|
@@ -248,7 +253,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
248
253
|
});
|
|
249
254
|
}
|
|
250
255
|
|
|
251
|
-
const alepha = Alepha.create().with(
|
|
256
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
252
257
|
const app = alepha.inject(TestApp);
|
|
253
258
|
await alepha.start();
|
|
254
259
|
|
|
@@ -336,7 +341,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
336
341
|
|
|
337
342
|
it("should work with fetch requests when realm is valid", async () => {
|
|
338
343
|
class TestApp {
|
|
339
|
-
realmA = $
|
|
344
|
+
realmA = $issuer({
|
|
340
345
|
secret: "test-realm-a",
|
|
341
346
|
roles: [
|
|
342
347
|
{
|
|
@@ -352,7 +357,7 @@ describe("ServerSecurityProvider - Realm Protection", () => {
|
|
|
352
357
|
});
|
|
353
358
|
}
|
|
354
359
|
|
|
355
|
-
const alepha = Alepha.create().with(
|
|
360
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
356
361
|
const app = alepha.inject(TestApp);
|
|
357
362
|
await alepha.start();
|
|
358
363
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { Alepha } from "alepha";
|
|
3
|
-
import { $realm } from "alepha/security";
|
|
4
3
|
import {
|
|
5
4
|
$action,
|
|
5
|
+
AlephaServer,
|
|
6
6
|
ForbiddenError,
|
|
7
7
|
HttpError,
|
|
8
8
|
ServerProvider,
|
|
9
9
|
UnauthorizedError,
|
|
10
10
|
} from "alepha/server";
|
|
11
11
|
import { describe, expect, it } from "vitest";
|
|
12
|
-
import {
|
|
12
|
+
import { $issuer, AlephaSecurity } from "../index.ts";
|
|
13
13
|
|
|
14
14
|
describe("ServerSecurityProvider", () => {
|
|
15
15
|
it("should protect action from unauthorized users", async () => {
|
|
@@ -19,7 +19,7 @@ describe("ServerSecurityProvider", () => {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const alepha = Alepha.create().with(
|
|
22
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
23
23
|
const app = alepha.inject(TestApp);
|
|
24
24
|
await alepha.start();
|
|
25
25
|
|
|
@@ -62,7 +62,7 @@ describe("ServerSecurityProvider", () => {
|
|
|
62
62
|
group: "read",
|
|
63
63
|
handler: () => "USER",
|
|
64
64
|
});
|
|
65
|
-
|
|
65
|
+
issuer = $issuer({
|
|
66
66
|
secret: "test",
|
|
67
67
|
roles: [
|
|
68
68
|
{
|
|
@@ -77,7 +77,7 @@ describe("ServerSecurityProvider", () => {
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
const alepha = Alepha.create().with(
|
|
80
|
+
const alepha = Alepha.create().with(AlephaServer).with(AlephaSecurity);
|
|
81
81
|
const app = alepha.inject(TestApp);
|
|
82
82
|
await alepha.start();
|
|
83
83
|
|
|
@@ -11,3 +11,8 @@ export * from "./schemas/userAccountInfoSchema.ts";
|
|
|
11
11
|
export const AlephaSecurity = $module({
|
|
12
12
|
name: "alepha.security",
|
|
13
13
|
});
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use `AlephaSecurity` instead. Server security providers are automatically registered when `AlephaServer` is available.
|
|
17
|
+
*/
|
|
18
|
+
export const AlephaServerSecurity = AlephaSecurity;
|
package/src/security/index.ts
CHANGED
|
@@ -1,27 +1,37 @@
|
|
|
1
|
-
import { $module } from "alepha";
|
|
1
|
+
import { $module, type Alepha } from "alepha";
|
|
2
|
+
import { AlephaServer, type FetchOptions } from "alepha/server";
|
|
3
|
+
import type { UserAccountToken } from "./interfaces/UserAccountToken.ts";
|
|
4
|
+
import { $basicAuth } from "./primitives/$basicAuth.ts";
|
|
5
|
+
import { $issuer } from "./primitives/$issuer.ts";
|
|
2
6
|
import { $permission } from "./primitives/$permission.ts";
|
|
3
|
-
import { $realm } from "./primitives/$realm.ts";
|
|
4
7
|
import { $role } from "./primitives/$role.ts";
|
|
5
8
|
import { CryptoProvider } from "./providers/CryptoProvider.ts";
|
|
6
9
|
import { JwtProvider } from "./providers/JwtProvider.ts";
|
|
7
10
|
import { SecurityProvider } from "./providers/SecurityProvider.ts";
|
|
11
|
+
import { ServerBasicAuthProvider } from "./providers/ServerBasicAuthProvider.ts";
|
|
12
|
+
import { ServerSecurityProvider } from "./providers/ServerSecurityProvider.ts";
|
|
8
13
|
import type { UserAccount } from "./schemas/userAccountInfoSchema.ts";
|
|
9
14
|
|
|
10
15
|
export * from "./errors/InvalidCredentialsError.ts";
|
|
11
16
|
export * from "./errors/InvalidPermissionError.ts";
|
|
12
17
|
export * from "./errors/SecurityError.ts";
|
|
13
18
|
export * from "./interfaces/UserAccountToken.ts";
|
|
19
|
+
export * from "./primitives/$basicAuth.ts";
|
|
20
|
+
export * from "./primitives/$issuer.ts";
|
|
14
21
|
export * from "./primitives/$permission.ts";
|
|
15
|
-
export * from "./primitives/$realm.ts";
|
|
16
22
|
export * from "./primitives/$role.ts";
|
|
17
23
|
export * from "./primitives/$serviceAccount.ts";
|
|
18
24
|
export * from "./providers/CryptoProvider.ts";
|
|
19
25
|
export * from "./providers/JwtProvider.ts";
|
|
20
26
|
export * from "./providers/SecurityProvider.ts";
|
|
27
|
+
export * from "./providers/ServerBasicAuthProvider.ts";
|
|
28
|
+
export * from "./providers/ServerSecurityProvider.ts";
|
|
21
29
|
export * from "./schemas/permissionSchema.ts";
|
|
22
30
|
export * from "./schemas/roleSchema.ts";
|
|
23
31
|
export * from "./schemas/userAccountInfoSchema.ts";
|
|
24
32
|
|
|
33
|
+
import type { ServerRouteSecure } from "./providers/ServerSecurityProvider.ts";
|
|
34
|
+
|
|
25
35
|
declare module "alepha" {
|
|
26
36
|
interface Hooks {
|
|
27
37
|
"security:user:created": {
|
|
@@ -29,22 +39,95 @@ declare module "alepha" {
|
|
|
29
39
|
user: UserAccount;
|
|
30
40
|
};
|
|
31
41
|
}
|
|
42
|
+
|
|
43
|
+
interface State {
|
|
44
|
+
/**
|
|
45
|
+
* Real (or fake) user account, used for internal actions.
|
|
46
|
+
*
|
|
47
|
+
* If you define this, you assume that all actions are executed by this user by default.
|
|
48
|
+
* > To force a different user, you need to pass it explicitly in the options.
|
|
49
|
+
*/
|
|
50
|
+
"alepha.server.security.system.user"?: UserAccountToken;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The authenticated user account attached to the server request state.
|
|
54
|
+
*
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
"alepha.server.request.user"?: UserAccount;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare module "alepha/server" {
|
|
62
|
+
interface ServerRequest<TConfig> {
|
|
63
|
+
user?: UserAccountToken; // for all routes, user is maybe present
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface ServerActionRequest<TConfig> {
|
|
67
|
+
user: UserAccountToken; // for actions, user is always present
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface ServerRoute {
|
|
71
|
+
/**
|
|
72
|
+
* If true, the route will be protected by the security provider.
|
|
73
|
+
* All actions are secure by default, but you can disable it for specific actions.
|
|
74
|
+
*/
|
|
75
|
+
secure?: boolean | ServerRouteSecure;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface ClientRequestOptions extends FetchOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Forward user from the previous request.
|
|
81
|
+
* If "system", use system user. @see {ServerSecurityProvider.localSystemUser}
|
|
82
|
+
* If "context", use the user from the current context (e.g. request).
|
|
83
|
+
*
|
|
84
|
+
* @default "system" if provided, else "context" if available.
|
|
85
|
+
*/
|
|
86
|
+
user?: UserAccountToken | "system" | "context";
|
|
87
|
+
}
|
|
32
88
|
}
|
|
33
89
|
|
|
34
90
|
/**
|
|
35
91
|
* Provides comprehensive authentication and authorization capabilities with JWT tokens, role-based access control, and user management.
|
|
36
92
|
*
|
|
37
|
-
* The security module enables building secure applications using primitives like `$
|
|
93
|
+
* The security module enables building secure applications using primitives like `$issuer`, `$role`, and `$permission`
|
|
38
94
|
* on class properties. It offers JWT-based authentication, fine-grained permissions, service accounts, and seamless
|
|
39
95
|
* integration with various authentication providers and user management systems.
|
|
40
96
|
*
|
|
41
|
-
*
|
|
97
|
+
* When used with `AlephaServer`, this module automatically registers `ServerSecurityProvider` and `ServerBasicAuthProvider`
|
|
98
|
+
* to protect HTTP routes and actions with JWT and Basic Auth.
|
|
99
|
+
*
|
|
100
|
+
* @see {@link $issuer}
|
|
42
101
|
* @see {@link $role}
|
|
43
102
|
* @see {@link $permission}
|
|
103
|
+
* @see {@link $basicAuth}
|
|
44
104
|
* @module alepha.security
|
|
45
105
|
*/
|
|
46
106
|
export const AlephaSecurity = $module({
|
|
47
107
|
name: "alepha.security",
|
|
48
|
-
primitives: [$
|
|
49
|
-
services: [
|
|
108
|
+
primitives: [$issuer, $role, $permission, $basicAuth],
|
|
109
|
+
services: [
|
|
110
|
+
SecurityProvider,
|
|
111
|
+
JwtProvider,
|
|
112
|
+
CryptoProvider,
|
|
113
|
+
ServerSecurityProvider,
|
|
114
|
+
ServerBasicAuthProvider,
|
|
115
|
+
],
|
|
116
|
+
register: (alepha: Alepha) => {
|
|
117
|
+
// Always register core security providers
|
|
118
|
+
alepha.with(SecurityProvider);
|
|
119
|
+
alepha.with(JwtProvider);
|
|
120
|
+
alepha.with(CryptoProvider);
|
|
121
|
+
|
|
122
|
+
// Register server security providers only if AlephaServer is available
|
|
123
|
+
if (alepha.has(AlephaServer)) {
|
|
124
|
+
alepha.with(ServerSecurityProvider);
|
|
125
|
+
alepha.with(ServerBasicAuthProvider);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
50
128
|
});
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @deprecated Use `AlephaSecurity` instead. Server security providers are automatically registered when `AlephaServer` is available.
|
|
132
|
+
*/
|
|
133
|
+
export const AlephaServerSecurity = AlephaSecurity;
|
|
@@ -2,9 +2,9 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { Alepha } from "alepha";
|
|
3
3
|
import { DateTimeProvider } from "alepha/datetime";
|
|
4
4
|
import { describe, test } from "vitest";
|
|
5
|
-
import { $
|
|
5
|
+
import { $issuer } from "../index.ts";
|
|
6
6
|
|
|
7
|
-
describe("$
|
|
7
|
+
describe("$issuer", () => {
|
|
8
8
|
const roles = [
|
|
9
9
|
{
|
|
10
10
|
name: "admin",
|
|
@@ -18,7 +18,7 @@ describe("$realm", () => {
|
|
|
18
18
|
|
|
19
19
|
test("should create token (access & refresh)", async ({ expect }) => {
|
|
20
20
|
class App {
|
|
21
|
-
|
|
21
|
+
issuer = $issuer({
|
|
22
22
|
secret: "test",
|
|
23
23
|
roles,
|
|
24
24
|
});
|
|
@@ -37,15 +37,15 @@ describe("$realm", () => {
|
|
|
37
37
|
|
|
38
38
|
const now = dt.pause();
|
|
39
39
|
|
|
40
|
-
const token = await app.
|
|
40
|
+
const token = await app.issuer.createToken(user);
|
|
41
41
|
|
|
42
42
|
expect(token).toEqual({
|
|
43
43
|
access_token: expect.any(String),
|
|
44
|
-
expires_in: app.
|
|
44
|
+
expires_in: app.issuer.accessTokenExpiration.asSeconds(),
|
|
45
45
|
refresh_token: expect.any(String),
|
|
46
46
|
token_type: "Bearer",
|
|
47
47
|
issued_at: now.unix(),
|
|
48
|
-
refresh_token_expires_in: app.
|
|
48
|
+
refresh_token_expires_in: app.issuer.refreshTokenExpiration.asSeconds(),
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
expect(
|
|
@@ -54,9 +54,9 @@ describe("$realm", () => {
|
|
|
54
54
|
),
|
|
55
55
|
).toEqual({
|
|
56
56
|
sub: user.id,
|
|
57
|
-
aud: app.
|
|
57
|
+
aud: app.issuer.name,
|
|
58
58
|
iat: now.unix(),
|
|
59
|
-
exp: now.unix() + app.
|
|
59
|
+
exp: now.unix() + app.issuer.accessTokenExpiration.asSeconds(),
|
|
60
60
|
name: user.name,
|
|
61
61
|
roles: ["admin", "user"],
|
|
62
62
|
sid: expect.any(String),
|
|
@@ -71,9 +71,9 @@ describe("$realm", () => {
|
|
|
71
71
|
),
|
|
72
72
|
).toEqual({
|
|
73
73
|
sub: user.id,
|
|
74
|
-
aud: app.
|
|
74
|
+
aud: app.issuer.name,
|
|
75
75
|
iat: now.unix(),
|
|
76
|
-
exp: now.unix() + app.
|
|
76
|
+
exp: now.unix() + app.issuer.refreshTokenExpiration.asSeconds(),
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
expect(
|
|
@@ -88,7 +88,7 @@ describe("$realm", () => {
|
|
|
88
88
|
typ: "refresh",
|
|
89
89
|
});
|
|
90
90
|
|
|
91
|
-
const newToken = await app.
|
|
91
|
+
const newToken = await app.issuer.createToken(user, token);
|
|
92
92
|
expect(newToken).toEqual({
|
|
93
93
|
access_token: expect.any(String),
|
|
94
94
|
issued_at: now.unix(),
|
|
@@ -13,43 +13,46 @@ import type { Role } from "../schemas/roleSchema.ts";
|
|
|
13
13
|
import type { UserAccount } from "../schemas/userAccountInfoSchema.ts";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
* Create a new
|
|
16
|
+
* Create a new issuer.
|
|
17
|
+
*
|
|
18
|
+
* An issuer is responsible for creating and verifying JWT tokens.
|
|
19
|
+
* It can be internal (with a secret) or external (with a JWKS).
|
|
17
20
|
*/
|
|
18
|
-
export const $
|
|
19
|
-
return createPrimitive(
|
|
21
|
+
export const $issuer = (options: IssuerPrimitiveOptions): IssuerPrimitive => {
|
|
22
|
+
return createPrimitive(IssuerPrimitive, options);
|
|
20
23
|
};
|
|
21
24
|
|
|
22
25
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
23
26
|
|
|
24
|
-
export type
|
|
27
|
+
export type IssuerPrimitiveOptions = {
|
|
25
28
|
/**
|
|
26
|
-
* Define the
|
|
29
|
+
* Define the issuer name.
|
|
27
30
|
* If not provided, it will use the property key.
|
|
28
31
|
*/
|
|
29
32
|
name?: string;
|
|
30
33
|
|
|
31
34
|
/**
|
|
32
|
-
* Short description about the
|
|
35
|
+
* Short description about the issuer.
|
|
33
36
|
*/
|
|
34
37
|
description?: string;
|
|
35
38
|
|
|
36
39
|
/**
|
|
37
|
-
* All roles available in the
|
|
40
|
+
* All roles available in the issuer. Role is a string (role name) or a Role object (embedded role).
|
|
38
41
|
*/
|
|
39
42
|
roles?: Array<string | Role>;
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
45
|
+
* Issuer settings.
|
|
43
46
|
*/
|
|
44
|
-
settings?:
|
|
47
|
+
settings?: IssuerSettings;
|
|
45
48
|
|
|
46
49
|
/**
|
|
47
50
|
* Parse the JWT payload to create a user account info.
|
|
48
51
|
*/
|
|
49
52
|
profile?: (jwtPayload: Record<string, any>) => UserAccount;
|
|
50
|
-
} & (
|
|
53
|
+
} & (IssuerInternal | IssuerExternal);
|
|
51
54
|
|
|
52
|
-
export interface
|
|
55
|
+
export interface IssuerSettings {
|
|
53
56
|
accessToken?: {
|
|
54
57
|
/**
|
|
55
58
|
* Lifetime of the access token.
|
|
@@ -87,14 +90,14 @@ export interface RealmSettings {
|
|
|
87
90
|
onDeleteSession?: (refreshToken: string) => Promise<void>;
|
|
88
91
|
}
|
|
89
92
|
|
|
90
|
-
export type
|
|
93
|
+
export type IssuerInternal = {
|
|
91
94
|
/**
|
|
92
95
|
* Internal secret to sign JWT tokens and verify them.
|
|
93
96
|
*/
|
|
94
97
|
secret: string;
|
|
95
98
|
};
|
|
96
99
|
|
|
97
|
-
export interface
|
|
100
|
+
export interface IssuerExternal {
|
|
98
101
|
/**
|
|
99
102
|
* URL to the JWKS (JSON Web Key Set) to verify JWT tokens from external providers.
|
|
100
103
|
*/
|
|
@@ -103,7 +106,7 @@ export interface RealmExternal {
|
|
|
103
106
|
|
|
104
107
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
105
108
|
|
|
106
|
-
export class
|
|
109
|
+
export class IssuerPrimitive extends Primitive<IssuerPrimitiveOptions> {
|
|
107
110
|
protected readonly securityProvider = $inject(SecurityProvider);
|
|
108
111
|
protected readonly dateTimeProvider = $inject(DateTimeProvider);
|
|
109
112
|
protected readonly jwt = $inject(JwtProvider);
|
|
@@ -148,14 +151,14 @@ export class RealmPrimitive extends Primitive<RealmPrimitiveOptions> {
|
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
/**
|
|
151
|
-
* Get all roles in the
|
|
154
|
+
* Get all roles in the issuer.
|
|
152
155
|
*/
|
|
153
156
|
public getRoles(): Role[] {
|
|
154
157
|
return this.securityProvider.getRoles(this.name);
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
/**
|
|
158
|
-
* Set all roles in the
|
|
161
|
+
* Set all roles in the issuer.
|
|
159
162
|
*/
|
|
160
163
|
public async setRoles(roles: Role[]): Promise<void> {
|
|
161
164
|
await this.securityProvider.updateRealm(this.name, roles);
|
|
@@ -336,7 +339,7 @@ export class RealmPrimitive extends Primitive<RealmPrimitiveOptions> {
|
|
|
336
339
|
}
|
|
337
340
|
}
|
|
338
341
|
|
|
339
|
-
$
|
|
342
|
+
$issuer[KIND] = IssuerPrimitive;
|
|
340
343
|
|
|
341
344
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
342
345
|
|