alepha 0.15.3 → 0.15.5
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 +26 -11
- package/dist/api/audits/index.d.ts +335 -335
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +11 -3
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +3 -3
- package/dist/api/files/index.js +4 -3
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +198 -155
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/jobs/index.js +103 -5
- package/dist/api/jobs/index.js.map +1 -1
- package/dist/api/keys/index.d.ts +198 -198
- package/dist/api/keys/index.d.ts.map +1 -1
- package/dist/api/keys/index.js +3 -3
- package/dist/api/keys/index.js.map +1 -1
- package/dist/api/notifications/index.browser.js +1 -0
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +3 -3
- package/dist/api/notifications/index.js +4 -3
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +263 -263
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/parameters/index.js +41 -30
- package/dist/api/parameters/index.js.map +1 -1
- package/dist/api/users/index.d.ts +383 -77
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +284 -72
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +131 -131
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/api/verifications/index.js +3 -3
- package/dist/api/verifications/index.js.map +1 -1
- package/dist/batch/index.d.ts +3 -3
- package/dist/batch/index.js +3 -3
- package/dist/batch/index.js.map +1 -1
- package/dist/bucket/index.d.ts +3 -3
- package/dist/bucket/index.js +6 -6
- package/dist/bucket/index.js.map +1 -1
- package/dist/cache/core/index.d.ts +3 -3
- package/dist/cache/core/index.js +3 -3
- package/dist/cache/core/index.js.map +1 -1
- package/dist/cli/index.d.ts +5612 -20
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +122 -91
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +11 -4
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +8 -6
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +4 -8
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +3 -3
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +3 -3
- package/dist/datetime/index.js +3 -3
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +16 -16
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +10562 -10
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +3 -3
- package/dist/fake/index.js +3 -3
- package/dist/fake/index.js.map +1 -1
- package/dist/lock/core/index.d.ts +9 -4
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/core/index.js +12 -4
- package/dist/lock/core/index.js.map +1 -1
- package/dist/logger/index.d.ts +3 -3
- package/dist/logger/index.js +6 -3
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +3 -3
- package/dist/mcp/index.js +3 -3
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.d.ts +12 -12
- package/dist/orm/index.js +4 -4
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +3 -3
- package/dist/queue/core/index.js +3 -3
- package/dist/queue/core/index.js.map +1 -1
- package/dist/react/auth/index.browser.js +2 -1
- package/dist/react/auth/index.browser.js.map +1 -1
- package/dist/react/auth/index.d.ts +3 -3
- package/dist/react/auth/index.js +5 -4
- package/dist/react/auth/index.js.map +1 -1
- package/dist/react/core/index.d.ts +6 -6
- package/dist/react/core/index.js +3 -3
- package/dist/react/core/index.js.map +1 -1
- package/dist/react/form/index.d.ts +3 -3
- package/dist/react/form/index.js +3 -3
- package/dist/react/form/index.js.map +1 -1
- package/dist/react/head/index.d.ts +3 -3
- package/dist/react/head/index.js +3 -3
- package/dist/react/head/index.js.map +1 -1
- package/dist/react/i18n/index.d.ts +3 -3
- package/dist/react/i18n/index.js +3 -3
- package/dist/react/i18n/index.js.map +1 -1
- package/dist/react/intro/index.css +337 -0
- package/dist/react/intro/index.css.map +1 -0
- package/dist/react/intro/index.d.ts +10 -0
- package/dist/react/intro/index.d.ts.map +1 -0
- package/dist/react/intro/index.js +222 -0
- package/dist/react/intro/index.js.map +1 -0
- package/dist/react/router/index.browser.js +2 -2
- package/dist/react/router/index.browser.js.map +1 -1
- package/dist/react/router/index.d.ts +11 -1
- package/dist/react/router/index.d.ts.map +1 -1
- package/dist/react/router/index.js +21 -11
- package/dist/react/router/index.js.map +1 -1
- package/dist/redis/index.d.ts +22 -22
- package/dist/redis/index.js +3 -3
- package/dist/redis/index.js.map +1 -1
- package/dist/retry/index.d.ts +3 -3
- package/dist/retry/index.js +3 -3
- package/dist/retry/index.js.map +1 -1
- package/dist/scheduler/index.d.ts +16 -4
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +45 -7
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +3 -3
- package/dist/security/index.js +5 -5
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +3 -3
- package/dist/server/auth/index.js +3 -3
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +3 -3
- package/dist/server/cache/index.js +3 -3
- 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/compress/index.js +4 -3
- package/dist/server/compress/index.js.map +1 -1
- package/dist/server/cookies/index.d.ts +3 -3
- package/dist/server/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.d.ts +14 -25
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +13 -29
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +3 -3
- package/dist/server/cors/index.js +3 -3
- package/dist/server/cors/index.js.map +1 -1
- package/dist/server/health/index.d.ts +20 -20
- package/dist/server/health/index.js +3 -3
- package/dist/server/health/index.js.map +1 -1
- package/dist/server/helmet/index.d.ts +3 -3
- package/dist/server/helmet/index.js +3 -3
- package/dist/server/helmet/index.js.map +1 -1
- package/dist/server/links/index.d.ts +42 -42
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +4 -4
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +3 -3
- package/dist/server/metrics/index.js +3 -3
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts +3 -3
- package/dist/server/multipart/index.js +3 -3
- package/dist/server/multipart/index.js.map +1 -1
- package/dist/server/proxy/index.d.ts +3 -3
- package/dist/server/proxy/index.js +3 -3
- package/dist/server/proxy/index.js.map +1 -1
- package/dist/server/rate-limit/index.d.ts +3 -3
- package/dist/server/rate-limit/index.js +3 -3
- package/dist/server/rate-limit/index.js.map +1 -1
- package/dist/server/static/index.d.ts +3 -3
- package/dist/server/static/index.js +6 -6
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +3 -3
- package/dist/server/swagger/index.js +6 -6
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +3 -3
- package/dist/sms/index.js +6 -6
- package/dist/sms/index.js.map +1 -1
- package/dist/system/index.d.ts +3 -3
- package/dist/system/index.js +3 -3
- package/dist/system/index.js.map +1 -1
- package/dist/thread/index.d.ts +3 -3
- package/dist/thread/index.js +3 -3
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts +3 -3
- package/dist/topic/core/index.js +3 -3
- package/dist/topic/core/index.js.map +1 -1
- package/dist/vite/index.d.ts +6286 -4
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +28 -2
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.d.ts +37 -37
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +3 -3
- package/dist/websocket/index.js.map +1 -1
- package/package.json +12 -4
- package/src/api/audits/controllers/AdminAuditController.ts +8 -0
- package/src/api/audits/index.ts +3 -3
- package/src/api/files/controllers/AdminFileStatsController.ts +1 -0
- package/src/api/files/index.ts +3 -3
- package/src/api/jobs/controllers/AdminJobController.ts +18 -2
- package/src/api/jobs/index.ts +4 -3
- package/src/api/jobs/services/JobAudits.spec.ts +89 -0
- package/src/api/jobs/services/JobAudits.ts +101 -0
- package/src/api/keys/index.ts +3 -3
- package/src/api/notifications/controllers/AdminNotificationController.ts +1 -0
- package/src/api/notifications/index.ts +3 -3
- package/src/api/parameters/controllers/AdminConfigController.ts +10 -0
- package/src/api/parameters/index.ts +5 -3
- package/src/api/users/__tests__/ApiKeys-integration.spec.ts +1 -1
- package/src/api/users/__tests__/ApiKeys.spec.ts +1 -1
- package/src/api/users/__tests__/EmailVerification.spec.ts +16 -1
- package/src/api/users/__tests__/PasswordReset.spec.ts +11 -0
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +10 -0
- package/src/api/users/controllers/AdminIdentityController.ts +3 -0
- package/src/api/users/controllers/AdminSessionController.ts +3 -0
- package/src/api/users/controllers/AdminUserController.ts +5 -0
- package/src/api/users/index.ts +8 -9
- package/src/api/users/primitives/$realm.ts +117 -19
- package/src/api/users/providers/RealmProvider.ts +15 -7
- package/src/api/users/services/CredentialService.spec.ts +11 -0
- package/src/api/users/services/CredentialService.ts +47 -24
- package/src/api/users/services/IdentityService.ts +12 -4
- package/src/api/users/services/RegistrationService.spec.ts +11 -0
- package/src/api/users/services/RegistrationService.ts +33 -12
- package/src/api/users/services/SessionService.ts +83 -12
- package/src/api/users/services/UserAudits.ts +47 -0
- package/src/api/users/services/UserFiles.ts +19 -0
- package/src/api/users/services/UserJobs.spec.ts +107 -0
- package/src/api/users/services/UserJobs.ts +62 -0
- package/src/api/users/services/UserParameters.ts +23 -0
- package/src/api/users/services/UserService.ts +34 -17
- package/src/api/verifications/index.ts +3 -3
- package/src/batch/index.ts +3 -3
- package/src/bucket/index.ts +3 -3
- package/src/cache/core/index.ts +3 -3
- package/src/cli/commands/build.ts +1 -0
- package/src/cli/commands/db.ts +9 -0
- package/src/cli/commands/init.spec.ts +2 -17
- package/src/cli/commands/init.ts +37 -1
- package/src/cli/providers/ViteDevServerProvider.ts +36 -2
- package/src/cli/services/AlephaCliUtils.ts +17 -0
- package/src/cli/services/PackageManagerUtils.ts +15 -1
- package/src/cli/services/ProjectScaffolder.ts +8 -13
- package/src/cli/templates/agentMd.ts +2 -25
- package/src/cli/templates/apiAppSecurityTs.ts +37 -2
- package/src/cli/templates/mainCss.ts +2 -32
- package/src/cli/templates/webAppRouterTs.ts +5 -5
- package/src/cli/templates/webHomeComponentTsx.ts +10 -0
- package/src/command/helpers/Runner.ts +14 -1
- package/src/command/index.ts +3 -3
- package/src/core/helpers/primitive.ts +0 -5
- package/src/core/index.ts +3 -3
- package/src/datetime/index.ts +3 -3
- package/src/email/index.ts +3 -3
- package/src/email/index.workerd.ts +36 -0
- package/src/email/providers/LocalEmailProvider.ts +2 -2
- package/src/email/providers/WorkermailerEmailProvider.ts +221 -0
- package/src/fake/index.ts +3 -3
- package/src/lock/core/index.ts +3 -3
- package/src/lock/core/primitives/$lock.ts +13 -1
- package/src/logger/index.ts +3 -3
- package/src/logger/providers/PrettyFormatterProvider.ts +7 -0
- package/src/mcp/index.ts +3 -3
- package/src/orm/index.ts +3 -3
- package/src/orm/providers/drivers/NodeSqliteProvider.ts +1 -1
- package/src/queue/core/index.ts +3 -3
- package/src/react/auth/index.ts +3 -3
- package/src/react/auth/services/ReactAuth.ts +3 -1
- package/src/react/core/index.ts +3 -3
- package/src/react/form/index.ts +3 -3
- package/src/react/head/index.ts +3 -3
- package/src/react/i18n/index.ts +3 -3
- package/src/react/intro/components/GettingStarted.css +334 -0
- package/src/react/intro/components/GettingStarted.tsx +276 -0
- package/src/react/intro/index.ts +1 -0
- package/src/react/router/atoms/ssrManifestAtom.ts +7 -0
- package/src/react/router/index.browser.ts +2 -0
- package/src/react/router/index.ts +2 -0
- package/src/react/router/providers/ReactServerProvider.ts +14 -4
- package/src/react/router/providers/SSRManifestProvider.ts +7 -0
- package/src/redis/index.ts +3 -3
- package/src/retry/index.ts +3 -3
- package/src/router/index.ts +3 -3
- package/src/scheduler/index.ts +3 -3
- package/src/scheduler/index.workerd.ts +43 -0
- package/src/scheduler/providers/CronProvider.ts +53 -6
- package/src/scheduler/providers/WorkerdCronProvider.ts +102 -0
- package/src/security/index.ts +3 -3
- package/src/security/providers/JwtProvider.ts +2 -2
- package/src/server/auth/index.ts +3 -3
- package/src/server/cache/index.ts +3 -3
- package/src/server/compress/index.ts +3 -3
- package/src/server/compress/providers/ServerCompressProvider.ts +6 -0
- package/src/server/cookies/index.ts +3 -3
- package/src/server/core/index.ts +3 -3
- package/src/server/core/primitives/$action.spec.ts +3 -2
- package/src/server/core/primitives/$action.ts +6 -2
- package/src/server/core/providers/NodeHttpServerProvider.ts +2 -15
- package/src/server/core/providers/ServerProvider.ts +4 -2
- package/src/server/core/providers/ServerRouterProvider.ts +5 -27
- package/src/server/cors/index.ts +3 -3
- package/src/server/health/index.ts +3 -3
- package/src/server/helmet/index.ts +3 -3
- package/src/server/links/index.ts +3 -3
- package/src/server/links/providers/ServerLinksProvider.spec.ts +332 -0
- package/src/server/links/providers/ServerLinksProvider.ts +1 -1
- package/src/server/metrics/index.ts +3 -3
- package/src/server/multipart/index.ts +3 -3
- package/src/server/proxy/index.ts +3 -3
- package/src/server/rate-limit/index.ts +3 -3
- package/src/server/static/index.ts +3 -3
- package/src/server/swagger/index.ts +3 -3
- package/src/sms/index.ts +3 -3
- package/src/system/index.ts +3 -3
- package/src/thread/index.ts +3 -3
- package/src/topic/core/index.ts +3 -3
- package/src/vite/tasks/generateCloudflare.ts +38 -2
- package/src/websocket/index.ts +3 -3
- package/src/cli/templates/webHelloComponentTsx.ts +0 -30
- /package/src/api/users/{notifications → services}/UserNotifications.ts +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Alepha } from "alepha";
|
|
2
|
+
import { AlephaApiAudits, AuditService } from "alepha/api/audits";
|
|
3
|
+
import { AlephaOrm } from "alepha/orm";
|
|
4
|
+
import { describe, test } from "vitest";
|
|
5
|
+
import { JobAudits } from "./JobAudits.ts";
|
|
6
|
+
|
|
7
|
+
describe("JobAudits", () => {
|
|
8
|
+
test("should log trigger event", async ({ expect }) => {
|
|
9
|
+
const alepha = Alepha.create().with(AlephaOrm).with(AlephaApiAudits);
|
|
10
|
+
|
|
11
|
+
const jobAudits = alepha.inject(JobAudits);
|
|
12
|
+
const auditService = alepha.inject(AuditService);
|
|
13
|
+
await alepha.start();
|
|
14
|
+
|
|
15
|
+
// Log a trigger event
|
|
16
|
+
await jobAudits.logTrigger("my-test-job");
|
|
17
|
+
|
|
18
|
+
// Verify audit was recorded
|
|
19
|
+
const audits = await auditService.find({ type: "job", action: "trigger" });
|
|
20
|
+
|
|
21
|
+
expect(audits.content).toHaveLength(1);
|
|
22
|
+
expect(audits.content[0].type).toBe("job");
|
|
23
|
+
expect(audits.content[0].action).toBe("trigger");
|
|
24
|
+
expect(audits.content[0].resourceType).toBe("job");
|
|
25
|
+
expect(audits.content[0].resourceId).toBe("my-test-job");
|
|
26
|
+
expect(audits.content[0].description).toBe(
|
|
27
|
+
"Manually triggered job: my-test-job",
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("should log pause event", async ({ expect }) => {
|
|
32
|
+
const alepha = Alepha.create().with(AlephaOrm).with(AlephaApiAudits);
|
|
33
|
+
|
|
34
|
+
const jobAudits = alepha.inject(JobAudits);
|
|
35
|
+
const auditService = alepha.inject(AuditService);
|
|
36
|
+
await alepha.start();
|
|
37
|
+
|
|
38
|
+
await jobAudits.logPause("daily-cleanup");
|
|
39
|
+
|
|
40
|
+
const audits = await auditService.find({ type: "job", action: "pause" });
|
|
41
|
+
|
|
42
|
+
expect(audits.content).toHaveLength(1);
|
|
43
|
+
expect(audits.content[0].resourceId).toBe("daily-cleanup");
|
|
44
|
+
expect(audits.content[0].description).toBe("Paused job: daily-cleanup");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("should log schedule change with cron metadata", async ({ expect }) => {
|
|
48
|
+
const alepha = Alepha.create().with(AlephaOrm).with(AlephaApiAudits);
|
|
49
|
+
|
|
50
|
+
const jobAudits = alepha.inject(JobAudits);
|
|
51
|
+
const auditService = alepha.inject(AuditService);
|
|
52
|
+
await alepha.start();
|
|
53
|
+
|
|
54
|
+
await jobAudits.logScheduleChange("backup-job", {
|
|
55
|
+
oldCron: "0 0 * * *",
|
|
56
|
+
newCron: "0 3 * * *",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const audits = await auditService.find({
|
|
60
|
+
type: "job",
|
|
61
|
+
action: "schedule_change",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expect(audits.content).toHaveLength(1);
|
|
65
|
+
expect(audits.content[0].resourceId).toBe("backup-job");
|
|
66
|
+
expect(audits.content[0].metadata).toEqual({
|
|
67
|
+
oldCron: "0 0 * * *",
|
|
68
|
+
newCron: "0 3 * * *",
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("should register job audit type", async ({ expect }) => {
|
|
73
|
+
const alepha = Alepha.create().with(AlephaOrm).with(AlephaApiAudits);
|
|
74
|
+
|
|
75
|
+
alepha.inject(JobAudits);
|
|
76
|
+
const auditService = alepha.inject(AuditService);
|
|
77
|
+
await alepha.start();
|
|
78
|
+
|
|
79
|
+
const types = auditService.getRegisteredTypes();
|
|
80
|
+
const jobType = types.find((t) => t.type === "job");
|
|
81
|
+
|
|
82
|
+
expect(jobType).toBeDefined();
|
|
83
|
+
expect(jobType?.actions).toContain("trigger");
|
|
84
|
+
expect(jobType?.actions).toContain("pause");
|
|
85
|
+
expect(jobType?.actions).toContain("resume");
|
|
86
|
+
expect(jobType?.actions).toContain("cancel");
|
|
87
|
+
expect(jobType?.actions).toContain("schedule_change");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { $audit, type AuditLogOptions } from "alepha/api/audits";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Job-specific audit service.
|
|
5
|
+
*
|
|
6
|
+
* Provides type-safe audit logging for job-related events.
|
|
7
|
+
* This service is lazy-loaded when the audits feature is enabled.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const jobAudits = alepha.inject(JobAudits);
|
|
12
|
+
* await jobAudits.logTrigger("my-job", { description: "Manually triggered" });
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export class JobAudits {
|
|
16
|
+
protected readonly audit = $audit({
|
|
17
|
+
type: "job",
|
|
18
|
+
description: "Background job execution events",
|
|
19
|
+
actions: ["trigger", "pause", "resume", "cancel", "schedule_change"],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Log a manual job trigger event.
|
|
24
|
+
*/
|
|
25
|
+
public async logTrigger(
|
|
26
|
+
jobName: string,
|
|
27
|
+
options: Omit<AuditLogOptions, "resourceType" | "resourceId"> = {},
|
|
28
|
+
) {
|
|
29
|
+
await this.audit.log("trigger", {
|
|
30
|
+
...options,
|
|
31
|
+
resourceType: "job",
|
|
32
|
+
resourceId: jobName,
|
|
33
|
+
description: options.description ?? `Manually triggered job: ${jobName}`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Log a job pause event.
|
|
39
|
+
*/
|
|
40
|
+
public async logPause(
|
|
41
|
+
jobName: string,
|
|
42
|
+
options: Omit<AuditLogOptions, "resourceType" | "resourceId"> = {},
|
|
43
|
+
) {
|
|
44
|
+
await this.audit.log("pause", {
|
|
45
|
+
...options,
|
|
46
|
+
resourceType: "job",
|
|
47
|
+
resourceId: jobName,
|
|
48
|
+
description: options.description ?? `Paused job: ${jobName}`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Log a job resume event.
|
|
54
|
+
*/
|
|
55
|
+
public async logResume(
|
|
56
|
+
jobName: string,
|
|
57
|
+
options: Omit<AuditLogOptions, "resourceType" | "resourceId"> = {},
|
|
58
|
+
) {
|
|
59
|
+
await this.audit.log("resume", {
|
|
60
|
+
...options,
|
|
61
|
+
resourceType: "job",
|
|
62
|
+
resourceId: jobName,
|
|
63
|
+
description: options.description ?? `Resumed job: ${jobName}`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Log a job cancellation event.
|
|
69
|
+
*/
|
|
70
|
+
public async logCancel(
|
|
71
|
+
jobName: string,
|
|
72
|
+
options: Omit<AuditLogOptions, "resourceType" | "resourceId"> = {},
|
|
73
|
+
) {
|
|
74
|
+
await this.audit.log("cancel", {
|
|
75
|
+
...options,
|
|
76
|
+
resourceType: "job",
|
|
77
|
+
resourceId: jobName,
|
|
78
|
+
description: options.description ?? `Cancelled job: ${jobName}`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Log a job schedule change event.
|
|
84
|
+
*/
|
|
85
|
+
public async logScheduleChange(
|
|
86
|
+
jobName: string,
|
|
87
|
+
options: Omit<AuditLogOptions, "resourceType" | "resourceId"> & {
|
|
88
|
+
oldCron?: string;
|
|
89
|
+
newCron?: string;
|
|
90
|
+
} = {},
|
|
91
|
+
) {
|
|
92
|
+
const { oldCron, newCron, ...rest } = options;
|
|
93
|
+
await this.audit.log("schedule_change", {
|
|
94
|
+
...rest,
|
|
95
|
+
resourceType: "job",
|
|
96
|
+
resourceId: jobName,
|
|
97
|
+
description: rest.description ?? `Changed schedule for job: ${jobName}`,
|
|
98
|
+
metadata: { oldCron, newCron, ...rest.metadata },
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
package/src/api/keys/index.ts
CHANGED
|
@@ -16,9 +16,9 @@ export * from "./schemas/revokeApiKeyResponseSchema.ts";
|
|
|
16
16
|
export * from "./services/ApiKeyService.ts";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* |
|
|
20
|
-
*
|
|
21
|
-
* |
|
|
19
|
+
* | Stability | Since | Runtime |
|
|
20
|
+
* |-----------|-------|---------|
|
|
21
|
+
* | 3 - stable | 0.11.0 | node, bun, workerd|
|
|
22
22
|
*
|
|
23
23
|
* API key management module for programmatic access.
|
|
24
24
|
*
|
|
@@ -15,6 +15,7 @@ export class AdminNotificationController {
|
|
|
15
15
|
public readonly findNotifications = $action({
|
|
16
16
|
path: this.url,
|
|
17
17
|
group: this.group,
|
|
18
|
+
secure: true,
|
|
18
19
|
description: "Find notifications with pagination and filtering",
|
|
19
20
|
schema: {
|
|
20
21
|
query: notificationQuerySchema,
|
|
@@ -25,9 +25,9 @@ export * from "./services/NotificationService.ts";
|
|
|
25
25
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* |
|
|
29
|
-
*
|
|
30
|
-
* |
|
|
28
|
+
* | Stability | Since | Runtime |
|
|
29
|
+
* |-----------|-------|---------|
|
|
30
|
+
* | 3 - stable | 0.10.0 | node, bun, workerd|
|
|
31
31
|
*
|
|
32
32
|
* User notification management.
|
|
33
33
|
*
|
|
@@ -41,6 +41,7 @@ export class AdminConfigController {
|
|
|
41
41
|
*/
|
|
42
42
|
getConfigTree = $action({
|
|
43
43
|
group: this.group,
|
|
44
|
+
secure: true,
|
|
44
45
|
description:
|
|
45
46
|
"Get tree structure of all configuration names for navigation.",
|
|
46
47
|
path: "/configs/tree",
|
|
@@ -58,6 +59,7 @@ export class AdminConfigController {
|
|
|
58
59
|
*/
|
|
59
60
|
listConfigNames = $action({
|
|
60
61
|
group: this.group,
|
|
62
|
+
secure: true,
|
|
61
63
|
description: "List all unique configuration names.",
|
|
62
64
|
path: "/configs",
|
|
63
65
|
method: "GET",
|
|
@@ -75,6 +77,7 @@ export class AdminConfigController {
|
|
|
75
77
|
*/
|
|
76
78
|
getByStatus = $action({
|
|
77
79
|
group: this.group,
|
|
80
|
+
secure: true,
|
|
78
81
|
description: "Get all configurations with a specific status.",
|
|
79
82
|
path: "/configs/status/:status",
|
|
80
83
|
method: "GET",
|
|
@@ -95,6 +98,7 @@ export class AdminConfigController {
|
|
|
95
98
|
*/
|
|
96
99
|
getHistory = $action({
|
|
97
100
|
group: this.group,
|
|
101
|
+
secure: true,
|
|
98
102
|
description: "Get all versions of a specific configuration.",
|
|
99
103
|
path: "/configs/:name/history",
|
|
100
104
|
method: "GET",
|
|
@@ -115,6 +119,7 @@ export class AdminConfigController {
|
|
|
115
119
|
*/
|
|
116
120
|
getCurrent = $action({
|
|
117
121
|
group: this.group,
|
|
122
|
+
secure: true,
|
|
118
123
|
description: "Get current and next scheduled values for a configuration.",
|
|
119
124
|
path: "/configs/:name",
|
|
120
125
|
method: "GET",
|
|
@@ -139,6 +144,7 @@ export class AdminConfigController {
|
|
|
139
144
|
*/
|
|
140
145
|
getVersion = $action({
|
|
141
146
|
group: this.group,
|
|
147
|
+
secure: true,
|
|
142
148
|
description: "Get a specific version of a configuration.",
|
|
143
149
|
path: "/configs/:name/versions/:version",
|
|
144
150
|
method: "GET",
|
|
@@ -157,6 +163,7 @@ export class AdminConfigController {
|
|
|
157
163
|
*/
|
|
158
164
|
createVersion = $action({
|
|
159
165
|
group: this.group,
|
|
166
|
+
secure: true,
|
|
160
167
|
description:
|
|
161
168
|
"Create a new version of a configuration (immediate or scheduled).",
|
|
162
169
|
path: "/configs/:name",
|
|
@@ -184,6 +191,7 @@ export class AdminConfigController {
|
|
|
184
191
|
*/
|
|
185
192
|
rollback = $action({
|
|
186
193
|
group: this.group,
|
|
194
|
+
secure: true,
|
|
187
195
|
description:
|
|
188
196
|
"Rollback a configuration to a previous version (creates new version with old content).",
|
|
189
197
|
path: "/configs/:name/rollback",
|
|
@@ -207,6 +215,7 @@ export class AdminConfigController {
|
|
|
207
215
|
*/
|
|
208
216
|
activateNow = $action({
|
|
209
217
|
group: this.group,
|
|
218
|
+
secure: true,
|
|
210
219
|
description: "Activate a future/next configuration version immediately.",
|
|
211
220
|
path: "/configs/:name/activate",
|
|
212
221
|
method: "POST",
|
|
@@ -248,6 +257,7 @@ export class AdminConfigController {
|
|
|
248
257
|
*/
|
|
249
258
|
checkScheduled = $action({
|
|
250
259
|
group: this.group,
|
|
260
|
+
secure: true,
|
|
251
261
|
description:
|
|
252
262
|
"Manually trigger activation check for all scheduled configurations.",
|
|
253
263
|
path: "/configs/activate-scheduled",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { $module } from "alepha";
|
|
2
2
|
import { AdminConfigController } from "./controllers/AdminConfigController.ts";
|
|
3
|
+
import { $config } from "./primitives/$config.ts";
|
|
3
4
|
import { ConfigActivationScheduler } from "./schedulers/ConfigActivationScheduler.ts";
|
|
4
5
|
import { ConfigStore } from "./services/ConfigStore.ts";
|
|
5
6
|
|
|
@@ -19,9 +20,9 @@ export * from "./services/ConfigStore.ts";
|
|
|
19
20
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
|
-
* |
|
|
23
|
-
*
|
|
24
|
-
* |
|
|
23
|
+
* | Stability | Since | Runtime |
|
|
24
|
+
* |-----------|-------|---------|
|
|
25
|
+
* | 3 - stable | 0.9.0 | node, bun, workerd|
|
|
25
26
|
*
|
|
26
27
|
* Application configuration management.
|
|
27
28
|
*
|
|
@@ -35,5 +36,6 @@ export * from "./services/ConfigStore.ts";
|
|
|
35
36
|
*/
|
|
36
37
|
export const AlephaApiParameters = $module({
|
|
37
38
|
name: "alepha.api.parameters",
|
|
39
|
+
primitives: [$config],
|
|
38
40
|
services: [ConfigStore, AdminConfigController, ConfigActivationScheduler],
|
|
39
41
|
});
|
|
@@ -5,7 +5,13 @@ import { AlephaEmail, MemoryEmailProvider } from "alepha/email";
|
|
|
5
5
|
import { AlephaSecurity } from "alepha/security";
|
|
6
6
|
import { BadRequestError } from "alepha/server";
|
|
7
7
|
import { describe, it } from "vitest";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
AlephaApiUsers,
|
|
10
|
+
RealmProvider,
|
|
11
|
+
UserController,
|
|
12
|
+
UserNotifications,
|
|
13
|
+
UserService,
|
|
14
|
+
} from "../index.ts";
|
|
9
15
|
|
|
10
16
|
const setup = async () => {
|
|
11
17
|
const alepha = Alepha.create({
|
|
@@ -16,9 +22,18 @@ const setup = async () => {
|
|
|
16
22
|
alepha.with(AlephaEmail);
|
|
17
23
|
alepha.with(AlephaApiVerification);
|
|
18
24
|
alepha.with(AlephaApiUsers);
|
|
25
|
+
alepha.with(UserNotifications);
|
|
19
26
|
|
|
20
27
|
await alepha.start();
|
|
21
28
|
|
|
29
|
+
// Enable notifications for the default realm
|
|
30
|
+
const realmProvider = alepha.inject(RealmProvider);
|
|
31
|
+
realmProvider.register("default", {
|
|
32
|
+
features: {
|
|
33
|
+
notifications: true,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
22
37
|
const emailProvider = alepha.inject(MemoryEmailProvider);
|
|
23
38
|
emailProvider.records = [];
|
|
24
39
|
|
|
@@ -8,8 +8,10 @@ import { describe, it } from "vitest";
|
|
|
8
8
|
import {
|
|
9
9
|
AlephaApiUsers,
|
|
10
10
|
CredentialService,
|
|
11
|
+
RealmProvider,
|
|
11
12
|
SessionService,
|
|
12
13
|
UserController,
|
|
14
|
+
UserNotifications,
|
|
13
15
|
} from "../index.ts";
|
|
14
16
|
|
|
15
17
|
const setup = async () => {
|
|
@@ -21,9 +23,18 @@ const setup = async () => {
|
|
|
21
23
|
alepha.with(AlephaEmail);
|
|
22
24
|
alepha.with(AlephaApiVerification);
|
|
23
25
|
alepha.with(AlephaApiUsers);
|
|
26
|
+
alepha.with(UserNotifications);
|
|
24
27
|
|
|
25
28
|
await alepha.start();
|
|
26
29
|
|
|
30
|
+
// Enable notifications for the default realm
|
|
31
|
+
const realmProvider = alepha.inject(RealmProvider);
|
|
32
|
+
realmProvider.register("default", {
|
|
33
|
+
features: {
|
|
34
|
+
notifications: true,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
27
38
|
const emailProvider = alepha.inject(MemoryEmailProvider);
|
|
28
39
|
emailProvider.records = [];
|
|
29
40
|
|
|
@@ -62,6 +62,14 @@ export const realmAuthSettingsAtom = $atom({
|
|
|
62
62
|
resetPasswordAllowed: t.boolean({
|
|
63
63
|
description: "Enable forgot password functionality",
|
|
64
64
|
}),
|
|
65
|
+
adminEmails: t.array(t.email(), {
|
|
66
|
+
description:
|
|
67
|
+
"List of email addresses that are automatically promoted to admin role on login",
|
|
68
|
+
}),
|
|
69
|
+
adminUsernames: t.array(t.text(), {
|
|
70
|
+
description:
|
|
71
|
+
"List of usernames that are automatically promoted to admin role on login",
|
|
72
|
+
}),
|
|
65
73
|
passwordPolicy: t.object({
|
|
66
74
|
minLength: t.integer({
|
|
67
75
|
description: "Minimum password length",
|
|
@@ -97,6 +105,8 @@ export const realmAuthSettingsAtom = $atom({
|
|
|
97
105
|
resetPasswordAllowed: false,
|
|
98
106
|
firstNameLastNameEnabled: false,
|
|
99
107
|
firstNameLastNameRequired: false,
|
|
108
|
+
adminEmails: [],
|
|
109
|
+
adminUsernames: [],
|
|
100
110
|
// TODO: not implemented yet
|
|
101
111
|
passwordPolicy: {
|
|
102
112
|
minLength: 8,
|
|
@@ -15,6 +15,7 @@ export class AdminIdentityController {
|
|
|
15
15
|
public readonly findIdentities = $action({
|
|
16
16
|
path: this.url,
|
|
17
17
|
group: this.group,
|
|
18
|
+
secure: true,
|
|
18
19
|
description: "Find identities with pagination and filtering",
|
|
19
20
|
schema: {
|
|
20
21
|
query: t.extend(identityQuerySchema, {
|
|
@@ -34,6 +35,7 @@ export class AdminIdentityController {
|
|
|
34
35
|
public readonly getIdentity = $action({
|
|
35
36
|
path: `${this.url}/:id`,
|
|
36
37
|
group: this.group,
|
|
38
|
+
secure: true,
|
|
37
39
|
description: "Get an identity by ID",
|
|
38
40
|
schema: {
|
|
39
41
|
params: t.object({
|
|
@@ -55,6 +57,7 @@ export class AdminIdentityController {
|
|
|
55
57
|
method: "DELETE",
|
|
56
58
|
path: `${this.url}/:id`,
|
|
57
59
|
group: this.group,
|
|
60
|
+
secure: true,
|
|
58
61
|
description: "Delete an identity",
|
|
59
62
|
schema: {
|
|
60
63
|
params: t.object({
|
|
@@ -15,6 +15,7 @@ export class AdminSessionController {
|
|
|
15
15
|
public readonly findSessions = $action({
|
|
16
16
|
path: this.url,
|
|
17
17
|
group: this.group,
|
|
18
|
+
secure: true,
|
|
18
19
|
description: "Find sessions with pagination and filtering",
|
|
19
20
|
schema: {
|
|
20
21
|
query: t.extend(sessionQuerySchema, {
|
|
@@ -34,6 +35,7 @@ export class AdminSessionController {
|
|
|
34
35
|
public readonly getSession = $action({
|
|
35
36
|
path: `${this.url}/:id`,
|
|
36
37
|
group: this.group,
|
|
38
|
+
secure: true,
|
|
37
39
|
description: "Get a session by ID",
|
|
38
40
|
schema: {
|
|
39
41
|
params: t.object({
|
|
@@ -55,6 +57,7 @@ export class AdminSessionController {
|
|
|
55
57
|
method: "DELETE",
|
|
56
58
|
path: `${this.url}/:id`,
|
|
57
59
|
group: this.group,
|
|
60
|
+
secure: true,
|
|
58
61
|
description: "Delete a session",
|
|
59
62
|
schema: {
|
|
60
63
|
params: t.object({
|
|
@@ -17,6 +17,7 @@ export class AdminUserController {
|
|
|
17
17
|
public readonly findUsers = $action({
|
|
18
18
|
path: this.url,
|
|
19
19
|
group: this.group,
|
|
20
|
+
secure: true,
|
|
20
21
|
description: "Find users with pagination and filtering",
|
|
21
22
|
schema: {
|
|
22
23
|
query: t.extend(userQuerySchema, {
|
|
@@ -36,6 +37,7 @@ export class AdminUserController {
|
|
|
36
37
|
public readonly getUser = $action({
|
|
37
38
|
path: `${this.url}/:id`,
|
|
38
39
|
group: this.group,
|
|
40
|
+
secure: true,
|
|
39
41
|
description: "Get a user by ID",
|
|
40
42
|
schema: {
|
|
41
43
|
params: t.object({
|
|
@@ -57,6 +59,7 @@ export class AdminUserController {
|
|
|
57
59
|
method: "POST",
|
|
58
60
|
path: this.url,
|
|
59
61
|
group: this.group,
|
|
62
|
+
secure: true,
|
|
60
63
|
description: "Create a new user",
|
|
61
64
|
schema: {
|
|
62
65
|
query: t.object({
|
|
@@ -76,6 +79,7 @@ export class AdminUserController {
|
|
|
76
79
|
method: "PATCH",
|
|
77
80
|
path: `${this.url}/:id`,
|
|
78
81
|
group: this.group,
|
|
82
|
+
secure: true,
|
|
79
83
|
description: "Update a user",
|
|
80
84
|
schema: {
|
|
81
85
|
params: t.object({
|
|
@@ -98,6 +102,7 @@ export class AdminUserController {
|
|
|
98
102
|
method: "DELETE",
|
|
99
103
|
path: `${this.url}/:id`,
|
|
100
104
|
group: this.group,
|
|
105
|
+
secure: true,
|
|
101
106
|
description: "Delete a user",
|
|
102
107
|
schema: {
|
|
103
108
|
params: t.object({
|
package/src/api/users/index.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { $module } from "alepha";
|
|
2
|
-
import { AlephaApiNotifications } from "alepha/api/notifications";
|
|
3
|
-
import { AlephaApiVerification } from "alepha/api/verifications";
|
|
4
2
|
import { AlephaEmail } from "alepha/email";
|
|
5
3
|
import { AlephaServerCompress } from "alepha/server/compress";
|
|
6
4
|
import { AlephaServerHelmet } from "alepha/server/helmet";
|
|
@@ -9,7 +7,6 @@ import { AdminSessionController } from "./controllers/AdminSessionController.ts"
|
|
|
9
7
|
import { AdminUserController } from "./controllers/AdminUserController.ts";
|
|
10
8
|
import { RealmController } from "./controllers/RealmController.ts";
|
|
11
9
|
import { UserController } from "./controllers/UserController.ts";
|
|
12
|
-
import { UserNotifications } from "./notifications/UserNotifications.ts";
|
|
13
10
|
import { RealmProvider } from "./providers/RealmProvider.ts";
|
|
14
11
|
import { CredentialService } from "./services/CredentialService.ts";
|
|
15
12
|
import { IdentityService } from "./services/IdentityService.ts";
|
|
@@ -52,14 +49,19 @@ export * from "./services/IdentityService.ts";
|
|
|
52
49
|
export * from "./services/RegistrationService.ts";
|
|
53
50
|
export * from "./services/SessionCrudService.ts";
|
|
54
51
|
export * from "./services/SessionService.ts";
|
|
52
|
+
export * from "./services/UserAudits.ts";
|
|
53
|
+
export * from "./services/UserFiles.ts";
|
|
54
|
+
export * from "./services/UserJobs.ts";
|
|
55
|
+
export * from "./services/UserNotifications.ts";
|
|
56
|
+
export * from "./services/UserParameters.ts";
|
|
55
57
|
export * from "./services/UserService.ts";
|
|
56
58
|
|
|
57
59
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
|
-
* |
|
|
61
|
-
*
|
|
62
|
-
* |
|
|
62
|
+
* | Stability | Since | Runtime |
|
|
63
|
+
* |-----------|-------|---------|
|
|
64
|
+
* | 3 - stable | 0.5.0 | node, bun, workerd|
|
|
63
65
|
*
|
|
64
66
|
* Complete user management with multi-realm support for multi-tenant applications.
|
|
65
67
|
*
|
|
@@ -78,8 +80,6 @@ export * from "./services/UserService.ts";
|
|
|
78
80
|
export const AlephaApiUsers = $module({
|
|
79
81
|
name: "alepha.api.users",
|
|
80
82
|
services: [
|
|
81
|
-
AlephaApiVerification,
|
|
82
|
-
AlephaApiNotifications,
|
|
83
83
|
AlephaServerHelmet,
|
|
84
84
|
AlephaServerCompress,
|
|
85
85
|
AlephaEmail,
|
|
@@ -95,6 +95,5 @@ export const AlephaApiUsers = $module({
|
|
|
95
95
|
AdminSessionController,
|
|
96
96
|
AdminIdentityController,
|
|
97
97
|
RealmController,
|
|
98
|
-
UserNotifications,
|
|
99
98
|
],
|
|
100
99
|
});
|