alepha 0.13.1 → 0.13.2
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 -1
- package/dist/api-files/index.d.ts +28 -91
- package/dist/api-files/index.js +10 -755
- package/dist/api-files/index.js.map +1 -1
- package/dist/api-jobs/index.d.ts +46 -46
- package/dist/api-jobs/index.js +13 -13
- package/dist/api-jobs/index.js.map +1 -1
- package/dist/api-notifications/index.d.ts +129 -146
- package/dist/api-notifications/index.js +17 -39
- package/dist/api-notifications/index.js.map +1 -1
- package/dist/api-parameters/index.d.ts +21 -22
- package/dist/api-parameters/index.js +22 -22
- package/dist/api-parameters/index.js.map +1 -1
- package/dist/api-users/index.d.ts +223 -2000
- package/dist/api-users/index.js +914 -4787
- package/dist/api-users/index.js.map +1 -1
- package/dist/api-verifications/index.d.ts +96 -96
- package/dist/batch/index.d.ts +13 -13
- package/dist/batch/index.js +8 -8
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +14 -14
- package/dist/bucket/index.js +12 -12
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/index.d.ts +11 -11
- package/dist/cache/index.js +9 -9
- package/dist/cache/index.js.map +1 -1
- package/dist/cli/index.d.ts +28 -26
- package/dist/cli/index.js +50 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +19 -19
- package/dist/command/index.js +25 -25
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +218 -218
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +232 -232
- package/dist/core/index.js +218 -218
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +2113 -0
- package/dist/core/index.native.js.map +1 -0
- package/dist/datetime/index.d.ts +9 -9
- package/dist/datetime/index.js +7 -7
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +16 -16
- package/dist/email/index.js +9 -9
- package/dist/email/index.js.map +1 -1
- package/dist/file/index.js +1 -1
- package/dist/file/index.js.map +1 -1
- package/dist/lock/index.d.ts +9 -9
- package/dist/lock/index.js +8 -8
- package/dist/lock/index.js.map +1 -1
- package/dist/lock-redis/index.js +3 -66
- package/dist/lock-redis/index.js.map +1 -1
- package/dist/logger/index.d.ts +5 -5
- package/dist/logger/index.js +8 -8
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/index.browser.js +114 -114
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.d.ts +218 -218
- package/dist/orm/index.js +46 -46
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/index.d.ts +29 -29
- package/dist/queue/index.js +20 -20
- package/dist/queue/index.js.map +1 -1
- package/dist/queue-redis/index.d.ts +2 -2
- package/dist/redis/index.d.ts +10 -10
- package/dist/retry/index.d.ts +19 -19
- package/dist/retry/index.js +7 -7
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +16 -16
- package/dist/scheduler/index.js +9 -9
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +80 -80
- package/dist/security/index.js +32 -32
- package/dist/security/index.js.map +1 -1
- package/dist/server/index.browser.js +1 -1
- package/dist/server/index.browser.js.map +1 -1
- package/dist/server/index.d.ts +101 -101
- package/dist/server/index.js +16 -16
- package/dist/server/index.js.map +1 -1
- package/dist/server-auth/index.browser.js +4 -982
- package/dist/server-auth/index.browser.js.map +1 -1
- package/dist/server-auth/index.d.ts +204 -785
- package/dist/server-auth/index.js +47 -1239
- package/dist/server-auth/index.js.map +1 -1
- package/dist/server-cache/index.d.ts +10 -10
- package/dist/server-cache/index.js +2 -2
- package/dist/server-cache/index.js.map +1 -1
- package/dist/server-compress/index.d.ts +4 -4
- package/dist/server-compress/index.js +1 -1
- package/dist/server-compress/index.js.map +1 -1
- package/dist/server-cookies/index.browser.js +8 -8
- package/dist/server-cookies/index.browser.js.map +1 -1
- package/dist/server-cookies/index.d.ts +17 -17
- package/dist/server-cookies/index.js +10 -10
- package/dist/server-cookies/index.js.map +1 -1
- package/dist/server-cors/index.d.ts +17 -17
- package/dist/server-cors/index.js +9 -9
- package/dist/server-cors/index.js.map +1 -1
- package/dist/server-health/index.d.ts +19 -19
- package/dist/server-helmet/index.d.ts +1 -1
- package/dist/server-links/index.browser.js +12 -12
- package/dist/server-links/index.browser.js.map +1 -1
- package/dist/server-links/index.d.ts +59 -251
- package/dist/server-links/index.js +23 -502
- package/dist/server-links/index.js.map +1 -1
- package/dist/server-metrics/index.d.ts +4 -4
- package/dist/server-multipart/index.d.ts +2 -2
- package/dist/server-proxy/index.d.ts +12 -12
- package/dist/server-proxy/index.js +10 -10
- package/dist/server-proxy/index.js.map +1 -1
- package/dist/server-rate-limit/index.d.ts +22 -22
- package/dist/server-rate-limit/index.js +12 -12
- package/dist/server-rate-limit/index.js.map +1 -1
- package/dist/server-security/index.d.ts +22 -22
- package/dist/server-security/index.js +15 -15
- package/dist/server-security/index.js.map +1 -1
- package/dist/server-static/index.d.ts +14 -14
- package/dist/server-static/index.js +8 -8
- package/dist/server-static/index.js.map +1 -1
- package/dist/server-swagger/index.d.ts +25 -184
- package/dist/server-swagger/index.js +21 -724
- package/dist/server-swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +14 -14
- package/dist/sms/index.js +9 -9
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +11 -11
- package/dist/thread/index.js +17 -17
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/index.d.ts +26 -26
- package/dist/topic/index.js +16 -16
- package/dist/topic/index.js.map +1 -1
- package/dist/topic-redis/index.d.ts +1 -1
- package/dist/vite/index.d.ts +3 -3
- package/dist/vite/index.js +8 -8
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +11 -11
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +58 -58
- package/dist/websocket/index.js +13 -13
- package/dist/websocket/index.js.map +1 -1
- package/package.json +113 -52
- package/src/api-files/services/FileService.ts +5 -7
- package/src/api-jobs/index.ts +1 -1
- package/src/api-jobs/{descriptors → primitives}/$job.ts +8 -8
- package/src/api-jobs/providers/JobProvider.ts +9 -9
- package/src/api-jobs/services/JobService.ts +5 -5
- package/src/api-notifications/index.ts +5 -15
- package/src/api-notifications/{descriptors → primitives}/$notification.ts +10 -10
- package/src/api-notifications/services/NotificationSenderService.ts +3 -3
- package/src/api-parameters/index.ts +1 -1
- package/src/api-parameters/{descriptors → primitives}/$config.ts +7 -12
- package/src/api-users/index.ts +1 -1
- package/src/api-users/{descriptors → primitives}/$userRealm.ts +8 -8
- package/src/api-users/providers/UserRealmProvider.ts +1 -1
- package/src/batch/index.ts +3 -3
- package/src/batch/{descriptors → primitives}/$batch.ts +13 -16
- package/src/bucket/index.ts +8 -8
- package/src/bucket/{descriptors → primitives}/$bucket.ts +8 -8
- package/src/bucket/providers/LocalFileStorageProvider.ts +3 -3
- package/src/cache/index.ts +4 -4
- package/src/cache/{descriptors → primitives}/$cache.ts +15 -15
- package/src/cli/apps/AlephaPackageBuilderCli.ts +24 -2
- package/src/cli/commands/DrizzleCommands.ts +6 -6
- package/src/cli/commands/VerifyCommands.ts +1 -1
- package/src/cli/commands/ViteCommands.ts +6 -1
- package/src/cli/services/ProjectUtils.ts +34 -3
- package/src/command/index.ts +5 -5
- package/src/command/{descriptors → primitives}/$command.ts +9 -12
- package/src/command/providers/CliProvider.ts +10 -10
- package/src/core/Alepha.ts +30 -33
- package/src/core/constants/KIND.ts +1 -1
- package/src/core/constants/OPTIONS.ts +1 -1
- package/src/core/helpers/{descriptor.ts → primitive.ts} +18 -18
- package/src/core/helpers/ref.ts +1 -1
- package/src/core/index.shared.ts +8 -8
- package/src/core/{descriptors → primitives}/$context.ts +5 -5
- package/src/core/{descriptors → primitives}/$hook.ts +4 -4
- package/src/core/{descriptors → primitives}/$inject.ts +2 -2
- package/src/core/{descriptors → primitives}/$module.ts +9 -9
- package/src/core/{descriptors → primitives}/$use.ts +2 -2
- package/src/core/providers/CodecManager.ts +1 -1
- package/src/core/providers/JsonSchemaCodec.ts +1 -1
- package/src/core/providers/StateManager.ts +2 -2
- package/src/datetime/index.ts +3 -3
- package/src/datetime/{descriptors → primitives}/$interval.ts +6 -6
- package/src/email/index.ts +4 -4
- package/src/email/{descriptors → primitives}/$email.ts +8 -8
- package/src/file/index.ts +1 -1
- package/src/lock/index.ts +3 -3
- package/src/lock/{descriptors → primitives}/$lock.ts +10 -10
- package/src/logger/index.ts +8 -8
- package/src/logger/{descriptors → primitives}/$logger.ts +2 -2
- package/src/logger/services/Logger.ts +1 -1
- package/src/orm/constants/PG_SYMBOLS.ts +2 -2
- package/src/orm/index.browser.ts +2 -2
- package/src/orm/index.ts +8 -8
- package/src/orm/{descriptors → primitives}/$entity.ts +11 -11
- package/src/orm/{descriptors → primitives}/$repository.ts +2 -2
- package/src/orm/{descriptors → primitives}/$sequence.ts +8 -8
- package/src/orm/{descriptors → primitives}/$transaction.ts +4 -4
- package/src/orm/providers/PostgresTypeProvider.ts +3 -3
- package/src/orm/providers/RepositoryProvider.ts +4 -4
- package/src/orm/providers/drivers/DatabaseProvider.ts +7 -7
- package/src/orm/services/ModelBuilder.ts +9 -9
- package/src/orm/services/PgRelationManager.ts +2 -2
- package/src/orm/services/PostgresModelBuilder.ts +5 -5
- package/src/orm/services/Repository.ts +7 -7
- package/src/orm/services/SqliteModelBuilder.ts +5 -5
- package/src/queue/index.ts +7 -7
- package/src/queue/{descriptors → primitives}/$consumer.ts +15 -15
- package/src/queue/{descriptors → primitives}/$queue.ts +12 -12
- package/src/queue/providers/WorkerProvider.ts +7 -7
- package/src/retry/index.ts +3 -3
- package/src/retry/{descriptors → primitives}/$retry.ts +14 -14
- package/src/scheduler/index.ts +3 -3
- package/src/scheduler/{descriptors → primitives}/$scheduler.ts +9 -9
- package/src/scheduler/providers/CronProvider.ts +1 -1
- package/src/security/index.ts +9 -9
- package/src/security/{descriptors → primitives}/$permission.ts +7 -7
- package/src/security/{descriptors → primitives}/$realm.ts +6 -12
- package/src/security/{descriptors → primitives}/$role.ts +12 -12
- package/src/security/{descriptors → primitives}/$serviceAccount.ts +8 -8
- package/src/server/index.browser.ts +1 -1
- package/src/server/index.ts +14 -14
- package/src/server/{descriptors → primitives}/$action.ts +13 -13
- package/src/server/{descriptors → primitives}/$route.ts +9 -9
- package/src/server/providers/NodeHttpServerProvider.ts +1 -1
- package/src/server/services/HttpClient.ts +1 -1
- package/src/server-auth/index.browser.ts +1 -1
- package/src/server-auth/index.ts +6 -6
- package/src/server-auth/{descriptors → primitives}/$auth.ts +10 -10
- package/src/server-auth/{descriptors → primitives}/$authCredentials.ts +4 -4
- package/src/server-auth/{descriptors → primitives}/$authGithub.ts +4 -4
- package/src/server-auth/{descriptors → primitives}/$authGoogle.ts +4 -4
- package/src/server-auth/providers/ServerAuthProvider.ts +4 -4
- package/src/server-cache/providers/ServerCacheProvider.ts +7 -7
- package/src/server-compress/providers/ServerCompressProvider.ts +3 -3
- package/src/server-cookies/index.browser.ts +2 -2
- package/src/server-cookies/index.ts +5 -5
- package/src/server-cookies/{descriptors → primitives}/$cookie.browser.ts +12 -12
- package/src/server-cookies/{descriptors → primitives}/$cookie.ts +13 -13
- package/src/server-cookies/providers/ServerCookiesProvider.ts +4 -4
- package/src/server-cookies/services/CookieParser.ts +1 -1
- package/src/server-cors/index.ts +3 -3
- package/src/server-cors/{descriptors → primitives}/$cors.ts +11 -13
- package/src/server-cors/providers/ServerCorsProvider.ts +5 -5
- package/src/server-links/index.browser.ts +5 -5
- package/src/server-links/index.ts +9 -9
- package/src/server-links/{descriptors → primitives}/$remote.ts +11 -11
- package/src/server-links/providers/LinkProvider.ts +7 -7
- package/src/server-links/providers/{RemoteDescriptorProvider.ts → RemotePrimitiveProvider.ts} +6 -6
- package/src/server-links/providers/ServerLinksProvider.ts +3 -3
- package/src/server-proxy/index.ts +3 -3
- package/src/server-proxy/{descriptors → primitives}/$proxy.ts +8 -8
- package/src/server-proxy/providers/ServerProxyProvider.ts +4 -4
- package/src/server-rate-limit/index.ts +6 -6
- package/src/server-rate-limit/{descriptors → primitives}/$rateLimit.ts +13 -13
- package/src/server-rate-limit/providers/ServerRateLimitProvider.ts +5 -5
- package/src/server-security/index.ts +3 -3
- package/src/server-security/{descriptors → primitives}/$basicAuth.ts +13 -13
- package/src/server-security/providers/ServerBasicAuthProvider.ts +5 -5
- package/src/server-security/providers/ServerSecurityProvider.ts +4 -4
- package/src/server-static/index.ts +3 -3
- package/src/server-static/{descriptors → primitives}/$serve.ts +8 -10
- package/src/server-static/providers/ServerStaticProvider.ts +6 -6
- package/src/server-swagger/index.ts +5 -5
- package/src/server-swagger/{descriptors → primitives}/$swagger.ts +9 -9
- package/src/server-swagger/providers/ServerSwaggerProvider.ts +11 -10
- package/src/sms/index.ts +4 -4
- package/src/sms/{descriptors → primitives}/$sms.ts +8 -8
- package/src/thread/index.ts +3 -3
- package/src/thread/{descriptors → primitives}/$thread.ts +13 -13
- package/src/thread/providers/ThreadProvider.ts +7 -9
- package/src/topic/index.ts +5 -5
- package/src/topic/{descriptors → primitives}/$subscriber.ts +14 -14
- package/src/topic/{descriptors → primitives}/$topic.ts +10 -10
- package/src/topic/providers/TopicProvider.ts +4 -4
- package/src/vite/tasks/copyAssets.ts +1 -1
- package/src/vite/tasks/generateSitemap.ts +3 -3
- package/src/vite/tasks/prerenderPages.ts +2 -2
- package/src/vite/tasks/runAlepha.ts +2 -2
- package/src/websocket/index.browser.ts +3 -3
- package/src/websocket/index.shared.ts +2 -2
- package/src/websocket/index.ts +4 -4
- package/src/websocket/interfaces/WebSocketInterfaces.ts +3 -3
- package/src/websocket/{descriptors → primitives}/$channel.ts +10 -10
- package/src/websocket/{descriptors → primitives}/$websocket.ts +8 -8
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +7 -7
- package/src/websocket/providers/WebSocketServerProvider.ts +3 -3
- package/src/websocket/services/WebSocketClient.ts +5 -5
- package/src/api-notifications/providers/MemorySmsProvider.ts +0 -20
- package/src/api-notifications/providers/SmsProvider.ts +0 -8
- /package/src/core/{descriptors → primitives}/$atom.ts +0 -0
- /package/src/core/{descriptors → primitives}/$env.ts +0 -0
- /package/src/server-auth/{descriptors → primitives}/$authApple.ts +0 -0
- /package/src/server-links/{descriptors → primitives}/$client.ts +0 -0
|
@@ -1,314 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { $
|
|
3
|
-
import { $action, $route, AlephaServer,
|
|
4
|
-
import { randomUUID, timingSafeEqual } from "node:crypto";
|
|
1
|
+
import "alepha/server/security";
|
|
2
|
+
import { $env, $hook, $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, t } from "alepha";
|
|
3
|
+
import { $action, $route, AlephaServer, HttpClient, ServerReply, ServerTimingProvider, UnauthorizedError } from "alepha/server";
|
|
5
4
|
import { $logger } from "alepha/logger";
|
|
6
5
|
import { $retry } from "alepha/retry";
|
|
7
|
-
import {
|
|
6
|
+
import { ServerProxyProvider } from "alepha/server/proxy";
|
|
7
|
+
import { SecurityProvider } from "alepha/security";
|
|
8
8
|
|
|
9
|
-
//#region src/server-security/providers/ServerBasicAuthProvider.ts
|
|
10
|
-
var ServerBasicAuthProvider = class {
|
|
11
|
-
alepha = $inject(Alepha);
|
|
12
|
-
log = $logger();
|
|
13
|
-
routerProvider = $inject(ServerRouterProvider);
|
|
14
|
-
realm = "Secure Area";
|
|
15
|
-
/**
|
|
16
|
-
* Registered basic auth descriptors with their configurations
|
|
17
|
-
*/
|
|
18
|
-
registeredAuths = [];
|
|
19
|
-
/**
|
|
20
|
-
* Register a basic auth configuration (called by descriptors)
|
|
21
|
-
*/
|
|
22
|
-
registerAuth(config) {
|
|
23
|
-
this.registeredAuths.push(config);
|
|
24
|
-
}
|
|
25
|
-
onStart = $hook({
|
|
26
|
-
on: "start",
|
|
27
|
-
handler: async () => {
|
|
28
|
-
for (const auth of this.registeredAuths) if (auth.paths) for (const pattern of auth.paths) {
|
|
29
|
-
const matchedRoutes = this.routerProvider.getRoutes(pattern);
|
|
30
|
-
for (const route of matchedRoutes) route.secure = { basic: {
|
|
31
|
-
username: auth.username,
|
|
32
|
-
password: auth.password
|
|
33
|
-
} };
|
|
34
|
-
}
|
|
35
|
-
if (this.registeredAuths.length > 0) this.log.info(`Initialized with ${this.registeredAuths.length} registered basic-auth configurations.`);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
/**
|
|
39
|
-
* Hook into server:onRequest to check basic auth
|
|
40
|
-
*/
|
|
41
|
-
onRequest = $hook({
|
|
42
|
-
on: "server:onRequest",
|
|
43
|
-
handler: async ({ route, request }) => {
|
|
44
|
-
const routeAuth = route.secure;
|
|
45
|
-
if (typeof routeAuth === "object" && "basic" in routeAuth && routeAuth.basic) this.checkAuth(request, routeAuth.basic);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
/**
|
|
49
|
-
* Hook into action:onRequest to check basic auth for actions
|
|
50
|
-
*/
|
|
51
|
-
onActionRequest = $hook({
|
|
52
|
-
on: "action:onRequest",
|
|
53
|
-
handler: async ({ action, request }) => {
|
|
54
|
-
const routeAuth = action.route.secure;
|
|
55
|
-
if (isBasicAuth(routeAuth)) this.checkAuth(request, routeAuth.basic);
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
/**
|
|
59
|
-
* Check basic authentication
|
|
60
|
-
*/
|
|
61
|
-
checkAuth(request, options) {
|
|
62
|
-
const authHeader = request.headers?.authorization;
|
|
63
|
-
if (!authHeader || !authHeader.startsWith("Basic ")) {
|
|
64
|
-
this.sendAuthRequired(request);
|
|
65
|
-
throw new HttpError({
|
|
66
|
-
status: 401,
|
|
67
|
-
message: "Authentication required"
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
const base64Credentials = authHeader.slice(6);
|
|
71
|
-
const credentials = Buffer.from(base64Credentials, "base64").toString("utf-8");
|
|
72
|
-
const colonIndex = credentials.indexOf(":");
|
|
73
|
-
const username = colonIndex !== -1 ? credentials.slice(0, colonIndex) : credentials;
|
|
74
|
-
const password = colonIndex !== -1 ? credentials.slice(colonIndex + 1) : "";
|
|
75
|
-
if (!this.timingSafeCredentialCheck(username, password, options.username, options.password)) {
|
|
76
|
-
this.sendAuthRequired(request);
|
|
77
|
-
this.log.warn(`Failed basic auth attempt for user`, { username });
|
|
78
|
-
throw new HttpError({
|
|
79
|
-
status: 401,
|
|
80
|
-
message: "Invalid credentials"
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Performs a timing-safe comparison of credentials to prevent timing attacks.
|
|
86
|
-
* Always compares both username and password to avoid leaking which one is wrong.
|
|
87
|
-
*/
|
|
88
|
-
timingSafeCredentialCheck(inputUsername, inputPassword, expectedUsername, expectedPassword) {
|
|
89
|
-
const inputUserBuf = Buffer.from(inputUsername, "utf-8");
|
|
90
|
-
const expectedUserBuf = Buffer.from(expectedUsername, "utf-8");
|
|
91
|
-
const inputPassBuf = Buffer.from(inputPassword, "utf-8");
|
|
92
|
-
const expectedPassBuf = Buffer.from(expectedPassword, "utf-8");
|
|
93
|
-
return (this.safeCompare(inputUserBuf, expectedUserBuf) & this.safeCompare(inputPassBuf, expectedPassBuf)) === 1;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Compares two buffers in constant time, handling different lengths safely.
|
|
97
|
-
* Returns 1 if equal, 0 if not equal.
|
|
98
|
-
*/
|
|
99
|
-
safeCompare(input, expected) {
|
|
100
|
-
if (input.length !== expected.length) {
|
|
101
|
-
timingSafeEqual(input, input);
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
return timingSafeEqual(input, expected) ? 1 : 0;
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Send WWW-Authenticate header
|
|
108
|
-
*/
|
|
109
|
-
sendAuthRequired(request) {
|
|
110
|
-
request.reply.setHeader("WWW-Authenticate", `Basic realm="${this.realm}"`);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
const isBasicAuth = (value) => {
|
|
114
|
-
return typeof value === "object" && !!value && "basic" in value && !!value.basic;
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
//#endregion
|
|
118
|
-
//#region src/server-security/descriptors/$basicAuth.ts
|
|
119
|
-
/**
|
|
120
|
-
* Declares HTTP Basic Authentication for server routes.
|
|
121
|
-
* This descriptor provides methods to protect routes with username/password authentication.
|
|
122
|
-
*/
|
|
123
|
-
const $basicAuth = (options) => {
|
|
124
|
-
return createDescriptor(BasicAuthDescriptor, options);
|
|
125
|
-
};
|
|
126
|
-
var BasicAuthDescriptor = class extends Descriptor {
|
|
127
|
-
serverBasicAuthProvider = $inject(ServerBasicAuthProvider);
|
|
128
|
-
get name() {
|
|
129
|
-
return this.options.name ?? `${this.config.propertyKey}`;
|
|
130
|
-
}
|
|
131
|
-
onInit() {
|
|
132
|
-
this.serverBasicAuthProvider.registerAuth(this.options);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Checks basic auth for the given request using this descriptor's configuration.
|
|
136
|
-
*/
|
|
137
|
-
check(request, options) {
|
|
138
|
-
const mergedOptions = {
|
|
139
|
-
...this.options,
|
|
140
|
-
...options
|
|
141
|
-
};
|
|
142
|
-
this.serverBasicAuthProvider.checkAuth(request, mergedOptions);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
$basicAuth[KIND] = BasicAuthDescriptor;
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
//#region src/server-security/providers/ServerSecurityProvider.ts
|
|
149
|
-
var ServerSecurityProvider = class {
|
|
150
|
-
log = $logger();
|
|
151
|
-
securityProvider = $inject(SecurityProvider);
|
|
152
|
-
jwtProvider = $inject(JwtProvider);
|
|
153
|
-
alepha = $inject(Alepha);
|
|
154
|
-
onConfigure = $hook({
|
|
155
|
-
on: "configure",
|
|
156
|
-
handler: async () => {
|
|
157
|
-
for (const action of this.alepha.descriptors($action)) {
|
|
158
|
-
if (action.options.disabled || action.options.secure === false || this.securityProvider.getRealms().length === 0) continue;
|
|
159
|
-
if (typeof action.options.secure !== "object") this.securityProvider.createPermission({
|
|
160
|
-
name: action.name,
|
|
161
|
-
group: action.group,
|
|
162
|
-
method: action.route.method,
|
|
163
|
-
path: action.route.path
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
onActionRequest = $hook({
|
|
169
|
-
on: "action:onRequest",
|
|
170
|
-
handler: async ({ action, request, options }) => {
|
|
171
|
-
if (action.options.secure === false && !options.user) {
|
|
172
|
-
this.log.trace("Skipping security check for route");
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
if (isBasicAuth(action.route.secure)) return;
|
|
176
|
-
const permission = this.securityProvider.getPermissions().find((it) => it.path === action.route.path && it.method === action.route.method);
|
|
177
|
-
try {
|
|
178
|
-
request.user = this.createUserFromLocalFunctionContext(options, permission);
|
|
179
|
-
const route = action.route;
|
|
180
|
-
if (typeof route.secure === "object") this.check(request.user, route.secure);
|
|
181
|
-
this.alepha.state.set("alepha.server.request.user", this.alepha.codec.decode(userAccountInfoSchema, request.user));
|
|
182
|
-
} catch (error) {
|
|
183
|
-
if (action.options.secure || permission) throw error;
|
|
184
|
-
this.log.trace("Skipping security check for action");
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
onRequest = $hook({
|
|
189
|
-
on: "server:onRequest",
|
|
190
|
-
priority: "last",
|
|
191
|
-
handler: async ({ request, route }) => {
|
|
192
|
-
if (route.secure === false) {
|
|
193
|
-
this.log.trace("Skipping security check for route - explicitly disabled");
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (isBasicAuth(route.secure)) return;
|
|
197
|
-
const permission = this.securityProvider.getPermissions().find((it) => it.path === route.path && it.method === route.method);
|
|
198
|
-
if (!request.headers.authorization && !route.secure && !permission) {
|
|
199
|
-
this.log.trace("Skipping security check for route - no authorization header and not secure");
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
try {
|
|
203
|
-
request.user = await this.securityProvider.createUserFromToken(request.headers.authorization, { permission });
|
|
204
|
-
if (typeof route.secure === "object") this.check(request.user, route.secure);
|
|
205
|
-
this.alepha.state.set("alepha.server.request.user", this.alepha.codec.decode(userAccountInfoSchema, request.user));
|
|
206
|
-
this.log.trace("User set from request token", {
|
|
207
|
-
user: request.user,
|
|
208
|
-
permission
|
|
209
|
-
});
|
|
210
|
-
} catch (error) {
|
|
211
|
-
if (route.secure || permission) throw error;
|
|
212
|
-
this.log.trace("Skipping security check for route - error occurred", error);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
check(user, secure) {
|
|
217
|
-
if (secure.realm) {
|
|
218
|
-
if (user.realm !== secure.realm) throw new ForbiddenError(`User must belong to realm '${secure.realm}' to access this route`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Get the user account token for a local action call.
|
|
223
|
-
* There are three possible sources for the user:
|
|
224
|
-
* - `options.user`: the user passed in the options
|
|
225
|
-
* - `"system"`: the system user from the state (you MUST set state `server.security.system.user`)
|
|
226
|
-
* - `"context"`: the user from the request context (you MUST be in an HTTP request context)
|
|
227
|
-
*
|
|
228
|
-
* Priority order: `options.user` > `"system"` > `"context"`.
|
|
229
|
-
*
|
|
230
|
-
* In testing environment, if no user is provided, a test user is created based on the SecurityProvider's roles.
|
|
231
|
-
*/
|
|
232
|
-
createUserFromLocalFunctionContext(options, permission) {
|
|
233
|
-
const fromOptions = typeof options.user === "object" ? options.user : void 0;
|
|
234
|
-
const type = typeof options.user === "string" ? options.user : void 0;
|
|
235
|
-
let user;
|
|
236
|
-
const fromContext = this.alepha.context.get("request")?.user;
|
|
237
|
-
const fromSystem = this.alepha.state.get("alepha.server.security.system.user");
|
|
238
|
-
if (type === "system") user = fromSystem;
|
|
239
|
-
else if (type === "context") user = fromContext;
|
|
240
|
-
else user = fromOptions ?? fromContext ?? fromSystem;
|
|
241
|
-
if (!user) {
|
|
242
|
-
if (this.alepha.isTest() && !("user" in options)) return this.createTestUser();
|
|
243
|
-
throw new UnauthorizedError("User is required for calling this action");
|
|
244
|
-
}
|
|
245
|
-
const roles = user.roles ?? (this.alepha.isTest() ? this.securityProvider.getRoles().map((role) => role.name) : []);
|
|
246
|
-
let ownership;
|
|
247
|
-
if (permission) {
|
|
248
|
-
const result = this.securityProvider.checkPermission(permission, ...roles);
|
|
249
|
-
if (!result.isAuthorized) throw new ForbiddenError(`Permission '${this.securityProvider.permissionToString(permission)}' is required for this route`);
|
|
250
|
-
ownership = result.ownership;
|
|
251
|
-
}
|
|
252
|
-
return {
|
|
253
|
-
...user,
|
|
254
|
-
ownership
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
createTestUser() {
|
|
258
|
-
return {
|
|
259
|
-
id: randomUUID(),
|
|
260
|
-
name: "Test",
|
|
261
|
-
roles: this.securityProvider.getRoles().map((role) => role.name)
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
onClientRequest = $hook({
|
|
265
|
-
on: "client:onRequest",
|
|
266
|
-
handler: async ({ request, options }) => {
|
|
267
|
-
if (!this.alepha.isTest()) return;
|
|
268
|
-
if ("user" in options && options.user === void 0) return;
|
|
269
|
-
request.headers = new Headers(request.headers);
|
|
270
|
-
if (!request.headers.has("authorization")) {
|
|
271
|
-
const test = this.createTestUser();
|
|
272
|
-
const user = typeof options?.user === "object" ? options.user : void 0;
|
|
273
|
-
const sub = user?.id ?? test.id;
|
|
274
|
-
const roles = user?.roles ?? test.roles;
|
|
275
|
-
const token = await this.jwtProvider.create({
|
|
276
|
-
sub,
|
|
277
|
-
roles
|
|
278
|
-
}, user?.realm ?? this.securityProvider.getRealms()[0]?.name);
|
|
279
|
-
request.headers.set("authorization", `Bearer ${token}`);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
//#endregion
|
|
286
|
-
//#region src/server-security/index.ts
|
|
287
|
-
/**
|
|
288
|
-
* Plugin for Alepha Server that provides security features. Based on the Alepha Security module.
|
|
289
|
-
*
|
|
290
|
-
* By default, all $action will be guarded by a permission check.
|
|
291
|
-
*
|
|
292
|
-
* @see {@link ServerSecurityProvider}
|
|
293
|
-
* @module alepha.server.security
|
|
294
|
-
*/
|
|
295
|
-
const AlephaServerSecurity = $module({
|
|
296
|
-
name: "alepha.server.security",
|
|
297
|
-
descriptors: [
|
|
298
|
-
$realm,
|
|
299
|
-
$role,
|
|
300
|
-
$permission,
|
|
301
|
-
$basicAuth
|
|
302
|
-
],
|
|
303
|
-
services: [
|
|
304
|
-
AlephaServer,
|
|
305
|
-
AlephaSecurity,
|
|
306
|
-
ServerSecurityProvider,
|
|
307
|
-
ServerBasicAuthProvider
|
|
308
|
-
]
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
//#endregion
|
|
312
9
|
//#region src/server-links/schemas/apiLinksResponseSchema.ts
|
|
313
10
|
const apiLinkSchema = t.object({
|
|
314
11
|
name: t.text({ description: "Name of the API link, used for identification." }),
|
|
@@ -361,7 +58,7 @@ var LinkProvider = class LinkProvider {
|
|
|
361
58
|
this.serverLinks.push(link);
|
|
362
59
|
}
|
|
363
60
|
get links() {
|
|
364
|
-
const apiLinks = this.alepha.
|
|
61
|
+
const apiLinks = this.alepha.store.get("alepha.server.request.apiLinks")?.links;
|
|
365
62
|
if (apiLinks) {
|
|
366
63
|
if (this.alepha.isBrowser()) return apiLinks;
|
|
367
64
|
const links = [];
|
|
@@ -381,7 +78,7 @@ var LinkProvider = class LinkProvider {
|
|
|
381
78
|
method: "GET",
|
|
382
79
|
schema: { response: apiLinksResponseSchema }
|
|
383
80
|
});
|
|
384
|
-
this.alepha.
|
|
81
|
+
this.alepha.store.set("alepha.server.request.apiLinks", data);
|
|
385
82
|
return data.links;
|
|
386
83
|
}
|
|
387
84
|
/**
|
|
@@ -485,7 +182,7 @@ var LinkProvider = class LinkProvider {
|
|
|
485
182
|
});
|
|
486
183
|
}
|
|
487
184
|
async getLinkByName(name, options = {}) {
|
|
488
|
-
if (this.alepha.isBrowser() && !this.alepha.
|
|
185
|
+
if (this.alepha.isBrowser() && !this.alepha.store.get("alepha.server.request.apiLinks")) await this.fetchLinks();
|
|
489
186
|
const link = this.links.find((a) => a.name === name && (!options.group || a.group === options.group) && (!options.service || options.service === a.service));
|
|
490
187
|
if (!link) {
|
|
491
188
|
const error = new UnauthorizedError(`Action ${name} not found.`);
|
|
@@ -504,7 +201,7 @@ var LinkProvider = class LinkProvider {
|
|
|
504
201
|
};
|
|
505
202
|
|
|
506
203
|
//#endregion
|
|
507
|
-
//#region src/server-links/
|
|
204
|
+
//#region src/server-links/primitives/$client.ts
|
|
508
205
|
/**
|
|
509
206
|
* Create a new client.
|
|
510
207
|
*/
|
|
@@ -514,9 +211,9 @@ const $client = (scope) => {
|
|
|
514
211
|
$client[KIND] = "$client";
|
|
515
212
|
|
|
516
213
|
//#endregion
|
|
517
|
-
//#region src/server-links/
|
|
214
|
+
//#region src/server-links/primitives/$remote.ts
|
|
518
215
|
/**
|
|
519
|
-
* $remote is a
|
|
216
|
+
* $remote is a primitive that allows you to define remote service access.
|
|
520
217
|
*
|
|
521
218
|
* Use it only when you have 2 or more services that need to communicate with each other.
|
|
522
219
|
*
|
|
@@ -525,198 +222,22 @@ $client[KIND] = "$client";
|
|
|
525
222
|
* You can add a service account if you want to use a security layer.
|
|
526
223
|
*/
|
|
527
224
|
const $remote = (options) => {
|
|
528
|
-
return
|
|
225
|
+
return createPrimitive(RemotePrimitive, options);
|
|
529
226
|
};
|
|
530
|
-
var
|
|
227
|
+
var RemotePrimitive = class extends Primitive {
|
|
531
228
|
get name() {
|
|
532
229
|
return this.options.name ?? this.config.propertyKey;
|
|
533
230
|
}
|
|
534
231
|
};
|
|
535
|
-
$remote[KIND] =
|
|
536
|
-
|
|
537
|
-
//#endregion
|
|
538
|
-
//#region src/server-proxy/descriptors/$proxy.ts
|
|
539
|
-
/**
|
|
540
|
-
* Creates a proxy descriptor to forward requests to another server.
|
|
541
|
-
*
|
|
542
|
-
* This descriptor enables you to create reverse proxy functionality, allowing your Alepha server
|
|
543
|
-
* to forward requests to other services while maintaining a unified API surface. It's particularly
|
|
544
|
-
* useful for microservice architectures, API gateways, or when you need to aggregate multiple
|
|
545
|
-
* services behind a single endpoint.
|
|
546
|
-
*
|
|
547
|
-
* **Key Features**
|
|
548
|
-
*
|
|
549
|
-
* - **Path-based routing**: Match specific paths or patterns to proxy
|
|
550
|
-
* - **Dynamic targets**: Support both static and dynamic target resolution
|
|
551
|
-
* - **Request/Response hooks**: Modify requests before forwarding and responses after receiving
|
|
552
|
-
* - **URL rewriting**: Transform URLs before forwarding to the target
|
|
553
|
-
* - **Conditional proxying**: Enable/disable proxies based on environment or conditions
|
|
554
|
-
*
|
|
555
|
-
* @example
|
|
556
|
-
* **Basic proxy setup:**
|
|
557
|
-
* ```ts
|
|
558
|
-
* import { $proxy } from "alepha/server/proxy";
|
|
559
|
-
*
|
|
560
|
-
* class ApiGateway {
|
|
561
|
-
* // Forward all /api/* requests to external service
|
|
562
|
-
* api = $proxy({
|
|
563
|
-
* path: "/api/*",
|
|
564
|
-
* target: "https://api.example.com"
|
|
565
|
-
* });
|
|
566
|
-
* }
|
|
567
|
-
* ```
|
|
568
|
-
*
|
|
569
|
-
* @example
|
|
570
|
-
* **Dynamic target with environment-based routing:**
|
|
571
|
-
* ```ts
|
|
572
|
-
* class ApiGateway {
|
|
573
|
-
* // Route to different environments based on configuration
|
|
574
|
-
* api = $proxy({
|
|
575
|
-
* path: "/api/*",
|
|
576
|
-
* target: () => process.env.NODE_ENV === "production"
|
|
577
|
-
* ? "https://api.prod.example.com"
|
|
578
|
-
* : "https://api.dev.example.com"
|
|
579
|
-
* });
|
|
580
|
-
* }
|
|
581
|
-
* ```
|
|
582
|
-
*
|
|
583
|
-
* @example
|
|
584
|
-
* **Advanced proxy with request/response modification:**
|
|
585
|
-
* ```ts
|
|
586
|
-
* class SecureProxy {
|
|
587
|
-
* secure = $proxy({
|
|
588
|
-
* path: "/secure/*",
|
|
589
|
-
* target: "https://secure-api.example.com",
|
|
590
|
-
* beforeRequest: async (request, proxyRequest) => {
|
|
591
|
-
* // Add authentication headers
|
|
592
|
-
* proxyRequest.headers = {
|
|
593
|
-
* ...proxyRequest.headers,
|
|
594
|
-
* 'Authorization': `Bearer ${await getServiceToken()}`,
|
|
595
|
-
* 'X-Forwarded-For': request.headers['x-forwarded-for'] || request.ip
|
|
596
|
-
* };
|
|
597
|
-
* },
|
|
598
|
-
* afterResponse: async (request, proxyResponse) => {
|
|
599
|
-
* // Log response for monitoring
|
|
600
|
-
* console.log(`Proxied ${request.url} -> ${proxyResponse.status}`);
|
|
601
|
-
* },
|
|
602
|
-
* rewrite: (url) => {
|
|
603
|
-
* // Remove /secure prefix when forwarding
|
|
604
|
-
* url.pathname = url.pathname.replace('/secure', '');
|
|
605
|
-
* }
|
|
606
|
-
* });
|
|
607
|
-
* }
|
|
608
|
-
* ```
|
|
609
|
-
*
|
|
610
|
-
* @example
|
|
611
|
-
* **Conditional proxy based on feature flags:**
|
|
612
|
-
* ```ts
|
|
613
|
-
* class FeatureProxy {
|
|
614
|
-
* newApi = $proxy({
|
|
615
|
-
* path: "/v2/*",
|
|
616
|
-
* target: "https://new-api.example.com",
|
|
617
|
-
* disabled: !process.env.ENABLE_V2_API // Disable if feature flag is off
|
|
618
|
-
* });
|
|
619
|
-
* }
|
|
620
|
-
* ```
|
|
621
|
-
*/
|
|
622
|
-
const $proxy = (options) => {
|
|
623
|
-
return createDescriptor(ProxyDescriptor, options);
|
|
624
|
-
};
|
|
625
|
-
var ProxyDescriptor = class extends Descriptor {};
|
|
626
|
-
$proxy[KIND] = ProxyDescriptor;
|
|
627
|
-
|
|
628
|
-
//#endregion
|
|
629
|
-
//#region src/server-proxy/providers/ServerProxyProvider.ts
|
|
630
|
-
var ServerProxyProvider = class {
|
|
631
|
-
log = $logger();
|
|
632
|
-
routerProvider = $inject(ServerRouterProvider);
|
|
633
|
-
alepha = $inject(Alepha);
|
|
634
|
-
configure = $hook({
|
|
635
|
-
on: "configure",
|
|
636
|
-
handler: () => {
|
|
637
|
-
for (const proxy of this.alepha.descriptors($proxy)) this.createProxy(proxy.options);
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
createProxy(options) {
|
|
641
|
-
if (options.disabled) return;
|
|
642
|
-
const path = options.path;
|
|
643
|
-
const target = typeof options.target === "function" ? options.target() : options.target;
|
|
644
|
-
if (!path.endsWith("/*")) throw new AlephaError("Proxy path should end with '/*'");
|
|
645
|
-
const handler = this.createProxyHandler(target, options);
|
|
646
|
-
for (const method of routeMethods) this.routerProvider.createRoute({
|
|
647
|
-
method,
|
|
648
|
-
path,
|
|
649
|
-
handler
|
|
650
|
-
});
|
|
651
|
-
this.log.info("Proxying", {
|
|
652
|
-
path,
|
|
653
|
-
target
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
createProxyHandler(target, options) {
|
|
657
|
-
return async (request) => {
|
|
658
|
-
const url = new URL(target + request.url.pathname);
|
|
659
|
-
if (request.url.search) url.search = request.url.search;
|
|
660
|
-
options.rewrite?.(url);
|
|
661
|
-
const requestInit = {
|
|
662
|
-
url: url.toString(),
|
|
663
|
-
method: request.method,
|
|
664
|
-
headers: {
|
|
665
|
-
...request.headers,
|
|
666
|
-
"accept-encoding": "identity"
|
|
667
|
-
},
|
|
668
|
-
body: this.getRawRequestBody(request)
|
|
669
|
-
};
|
|
670
|
-
if (requestInit.body) requestInit.duplex = "half";
|
|
671
|
-
if (options.beforeRequest) await options.beforeRequest(request, requestInit);
|
|
672
|
-
this.log.debug("Proxying request", {
|
|
673
|
-
url: url.toString(),
|
|
674
|
-
method: request.method,
|
|
675
|
-
headers: request.headers
|
|
676
|
-
});
|
|
677
|
-
const response = await fetch(requestInit.url, requestInit);
|
|
678
|
-
request.reply.status = response.status;
|
|
679
|
-
request.reply.headers = Object.fromEntries(response.headers.entries());
|
|
680
|
-
request.reply.body = response.body;
|
|
681
|
-
this.log.debug("Received response", {
|
|
682
|
-
status: request.reply.status,
|
|
683
|
-
headers: request.reply.headers
|
|
684
|
-
});
|
|
685
|
-
if (options.afterResponse) await options.afterResponse(request, response);
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
getRawRequestBody(req) {
|
|
689
|
-
const { method } = req;
|
|
690
|
-
if (method === "GET" || method === "HEAD" || method === "OPTIONS") return;
|
|
691
|
-
if (req.raw?.web?.req) return req.raw.web.req.body;
|
|
692
|
-
if (req.raw?.node?.req) {
|
|
693
|
-
const nodeReq = req.raw.node.req;
|
|
694
|
-
return ReadableStream.from(nodeReq);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
};
|
|
698
|
-
|
|
699
|
-
//#endregion
|
|
700
|
-
//#region src/server-proxy/index.ts
|
|
701
|
-
/**
|
|
702
|
-
* Plugin for Alepha that provides a proxy server functionality.
|
|
703
|
-
*
|
|
704
|
-
* @see {@link $proxy}
|
|
705
|
-
* @module alepha.server.proxy
|
|
706
|
-
*/
|
|
707
|
-
const AlephaServerProxy = $module({
|
|
708
|
-
name: "alepha.server.proxy",
|
|
709
|
-
descriptors: [$proxy],
|
|
710
|
-
services: [AlephaServer, ServerProxyProvider]
|
|
711
|
-
});
|
|
232
|
+
$remote[KIND] = RemotePrimitive;
|
|
712
233
|
|
|
713
234
|
//#endregion
|
|
714
|
-
//#region src/server-links/providers/
|
|
235
|
+
//#region src/server-links/providers/RemotePrimitiveProvider.ts
|
|
715
236
|
const envSchema$1 = t.object({ SERVER_API_PREFIX: t.text({
|
|
716
237
|
description: "Prefix for all API routes (e.g. $action).",
|
|
717
238
|
default: "/api"
|
|
718
239
|
}) });
|
|
719
|
-
var
|
|
240
|
+
var RemotePrimitiveProvider = class {
|
|
720
241
|
env = $env(envSchema$1);
|
|
721
242
|
alepha = $inject(Alepha);
|
|
722
243
|
proxyProvider = $inject(ServerProxyProvider);
|
|
@@ -729,7 +250,7 @@ var RemoteDescriptorProvider = class {
|
|
|
729
250
|
configure = $hook({
|
|
730
251
|
on: "configure",
|
|
731
252
|
handler: async () => {
|
|
732
|
-
const remotes = this.alepha.
|
|
253
|
+
const remotes = this.alepha.primitives($remote);
|
|
733
254
|
for (const remote of remotes) await this.registerRemote(remote);
|
|
734
255
|
}
|
|
735
256
|
});
|
|
@@ -825,7 +346,7 @@ var ServerLinksProvider = class {
|
|
|
825
346
|
env = $env(envSchema);
|
|
826
347
|
alepha = $inject(Alepha);
|
|
827
348
|
linkProvider = $inject(LinkProvider);
|
|
828
|
-
remoteProvider = $inject(
|
|
349
|
+
remoteProvider = $inject(RemotePrimitiveProvider);
|
|
829
350
|
serverTimingProvider = $inject(ServerTimingProvider);
|
|
830
351
|
get prefix() {
|
|
831
352
|
return this.env.SERVER_API_PREFIX;
|
|
@@ -833,7 +354,7 @@ var ServerLinksProvider = class {
|
|
|
833
354
|
onRoute = $hook({
|
|
834
355
|
on: "configure",
|
|
835
356
|
handler: () => {
|
|
836
|
-
for (const action of this.alepha.
|
|
357
|
+
for (const action of this.alepha.primitives($action)) this.linkProvider.registerLink({
|
|
837
358
|
name: action.name,
|
|
838
359
|
group: action.group,
|
|
839
360
|
schema: action.options.schema,
|
|
@@ -960,7 +481,7 @@ var ServerLinksProvider = class {
|
|
|
960
481
|
/**
|
|
961
482
|
* Provides server-side link management and remote capabilities for client-server interactions.
|
|
962
483
|
*
|
|
963
|
-
* The server-links module enables declarative link definitions using `$remote` and `$client`
|
|
484
|
+
* The server-links module enables declarative link definitions using `$remote` and `$client` primitives,
|
|
964
485
|
* facilitating seamless API endpoint management and client-server communication. It integrates with server
|
|
965
486
|
* security features to ensure safe and controlled access to resources.
|
|
966
487
|
*
|
|
@@ -970,15 +491,15 @@ var ServerLinksProvider = class {
|
|
|
970
491
|
*/
|
|
971
492
|
const AlephaServerLinks = $module({
|
|
972
493
|
name: "alepha.server.links",
|
|
973
|
-
|
|
494
|
+
primitives: [$remote, $client],
|
|
974
495
|
services: [
|
|
975
496
|
AlephaServer,
|
|
976
497
|
ServerLinksProvider,
|
|
977
|
-
|
|
498
|
+
RemotePrimitiveProvider,
|
|
978
499
|
LinkProvider
|
|
979
500
|
]
|
|
980
501
|
});
|
|
981
502
|
|
|
982
503
|
//#endregion
|
|
983
|
-
export { $client, $remote, AlephaServerLinks, LinkProvider,
|
|
504
|
+
export { $client, $remote, AlephaServerLinks, LinkProvider, RemotePrimitive, RemotePrimitiveProvider, ServerLinksProvider, apiLinkSchema, apiLinksResponseSchema };
|
|
984
505
|
//# sourceMappingURL=index.js.map
|