alepha 0.13.5 → 0.13.7
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/dist/api-audits/index.browser.js +116 -0
- package/dist/api-audits/index.browser.js.map +1 -0
- package/dist/api-audits/index.d.ts +1194 -0
- package/dist/api-audits/index.js +674 -0
- package/dist/api-audits/index.js.map +1 -0
- package/dist/api-notifications/index.d.ts +147 -147
- package/dist/api-parameters/index.browser.js +36 -5
- package/dist/api-parameters/index.browser.js.map +1 -1
- package/dist/api-parameters/index.d.ts +711 -33
- package/dist/api-parameters/index.js +831 -17
- package/dist/api-parameters/index.js.map +1 -1
- package/dist/api-users/index.d.ts +16 -3
- package/dist/api-users/index.js +699 -19
- package/dist/api-users/index.js.map +1 -1
- package/dist/api-verifications/index.js +2 -1
- package/dist/api-verifications/index.js.map +1 -1
- package/dist/bin/index.js +1 -0
- package/dist/bin/index.js.map +1 -1
- package/dist/cli/index.d.ts +85 -31
- package/dist/cli/index.js +205 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +67 -6
- package/dist/command/index.js +30 -3
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +241 -61
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +170 -90
- package/dist/core/index.js +264 -67
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +248 -65
- package/dist/core/index.native.js.map +1 -1
- package/dist/email/index.js +15 -10554
- package/dist/email/index.js.map +1 -1
- package/dist/logger/index.d.ts +4 -4
- package/dist/logger/index.js +77 -72
- package/dist/logger/index.js.map +1 -1
- package/dist/orm/index.d.ts +5 -1
- package/dist/orm/index.js +24 -7
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/index.d.ts +4 -4
- package/dist/redis/index.d.ts +10 -10
- package/dist/security/index.d.ts +28 -28
- package/dist/server/index.d.ts +10 -1
- package/dist/server/index.js +20 -6
- package/dist/server/index.js.map +1 -1
- package/dist/server-auth/index.d.ts +163 -152
- package/dist/server-auth/index.js +40 -10
- package/dist/server-auth/index.js.map +1 -1
- package/dist/server-cookies/index.js +5 -1
- package/dist/server-cookies/index.js.map +1 -1
- package/dist/server-links/index.d.ts +33 -33
- package/dist/server-security/index.d.ts +9 -9
- package/dist/thread/index.js +2 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/vite/index.d.ts +2 -2
- package/dist/vite/index.js +102 -45
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +3 -3
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +7 -7
- package/dist/websocket/index.js +4 -4
- package/dist/websocket/index.js.map +1 -1
- package/package.json +14 -9
- package/src/api-audits/controllers/AuditController.ts +186 -0
- package/src/api-audits/entities/audits.ts +132 -0
- package/src/api-audits/index.browser.ts +18 -0
- package/src/api-audits/index.ts +58 -0
- package/src/api-audits/primitives/$audit.ts +159 -0
- package/src/api-audits/schemas/auditQuerySchema.ts +23 -0
- package/src/api-audits/schemas/auditResourceSchema.ts +9 -0
- package/src/api-audits/schemas/createAuditSchema.ts +27 -0
- package/src/api-audits/services/AuditService.ts +412 -0
- package/src/api-parameters/controllers/ConfigController.ts +324 -0
- package/src/api-parameters/entities/parameters.ts +93 -10
- package/src/api-parameters/index.ts +43 -4
- package/src/api-parameters/primitives/$config.ts +291 -19
- package/src/api-parameters/schedulers/ConfigActivationScheduler.ts +30 -0
- package/src/api-parameters/services/ConfigStore.ts +491 -0
- package/src/api-users/atoms/realmAuthSettingsAtom.ts +19 -0
- package/src/api-users/controllers/UserRealmController.ts +0 -2
- package/src/api-users/index.ts +2 -0
- package/src/api-users/primitives/$userRealm.ts +18 -3
- package/src/api-users/providers/UserRealmProvider.ts +6 -3
- package/src/api-users/services/RegistrationService.ts +2 -1
- package/src/api-users/services/SessionService.ts +4 -0
- package/src/api-users/services/UserService.ts +3 -0
- package/src/api-verifications/index.ts +7 -1
- package/src/bin/index.ts +1 -0
- package/src/cli/assets/biomeJson.ts +1 -1
- package/src/cli/assets/dummySpecTs.ts +7 -0
- package/src/cli/assets/editorconfig.ts +13 -0
- package/src/cli/assets/mainTs.ts +14 -0
- package/src/cli/commands/BiomeCommands.ts +2 -0
- package/src/cli/commands/CoreCommands.ts +28 -9
- package/src/cli/commands/VerifyCommands.ts +2 -1
- package/src/cli/commands/ViteCommands.ts +8 -9
- package/src/cli/services/AlephaCliUtils.ts +214 -23
- package/src/command/helpers/Asker.ts +0 -1
- package/src/command/primitives/$command.ts +67 -0
- package/src/command/providers/CliProvider.ts +39 -8
- package/src/core/Alepha.ts +40 -30
- package/src/core/helpers/jsonSchemaToTypeBox.ts +307 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +30 -3
- package/src/core/providers/EventManager.ts +1 -1
- package/src/core/providers/StateManager.ts +23 -12
- package/src/core/providers/TypeProvider.ts +26 -34
- package/src/logger/index.ts +8 -6
- package/src/logger/primitives/$logger.ts +1 -1
- package/src/logger/providers/{SimpleFormatterProvider.ts → PrettyFormatterProvider.ts} +10 -1
- package/src/orm/index.ts +6 -0
- package/src/orm/services/PgRelationManager.ts +2 -2
- package/src/orm/services/PostgresModelBuilder.ts +11 -7
- package/src/orm/services/Repository.ts +16 -7
- package/src/orm/services/SqliteModelBuilder.ts +10 -0
- package/src/server/index.ts +6 -0
- package/src/server/primitives/$action.ts +10 -1
- package/src/server/providers/ServerBodyParserProvider.ts +11 -5
- package/src/server/providers/ServerRouterProvider.ts +13 -7
- package/src/server-auth/primitives/$auth.ts +7 -0
- package/src/server-auth/providers/ServerAuthProvider.ts +51 -8
- package/src/server-cookies/index.ts +2 -1
- package/src/thread/primitives/$thread.ts +2 -2
- package/src/vite/index.ts +0 -2
- package/src/vite/tasks/buildServer.ts +3 -4
- package/src/vite/tasks/generateCloudflare.ts +35 -19
- package/src/vite/tasks/generateDocker.ts +18 -4
- package/src/vite/tasks/generateSitemap.ts +5 -7
- package/src/vite/tasks/generateVercel.ts +76 -41
- package/src/vite/tasks/runAlepha.ts +16 -1
- package/src/websocket/providers/NodeWebSocketServerProvider.ts +3 -11
- package/src/websocket/services/WebSocketClient.ts +3 -3
- package/dist/cli/dist-BlfFtOk2.js +0 -2770
- package/dist/cli/dist-BlfFtOk2.js.map +0 -1
- package/src/api-parameters/controllers/ParameterController.ts +0 -45
- package/src/api-parameters/services/ParameterStore.ts +0 -23
package/dist/api-users/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $atom, $context, $hook, $inject, $module, Alepha, AlephaError, t } from "alepha";
|
|
1
|
+
import { $atom, $context, $hook, $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive, t } from "alepha";
|
|
2
2
|
import { $notification, AlephaApiNotifications } from "alepha/api/notifications";
|
|
3
3
|
import { AlephaApiVerification } from "alepha/api/verifications";
|
|
4
4
|
import { AlephaEmail } from "alepha/email";
|
|
@@ -15,6 +15,7 @@ import { $client } from "alepha/server/links";
|
|
|
15
15
|
import { $authCredentials, $authGithub, $authGoogle, ServerAuthProvider, authenticationProviderSchema } from "alepha/server/auth";
|
|
16
16
|
import { FileSystemProvider } from "alepha/file";
|
|
17
17
|
import { AlephaApiFiles } from "alepha/api/files";
|
|
18
|
+
import { AlephaApiJobs } from "alepha/api/jobs";
|
|
18
19
|
|
|
19
20
|
//#region ../../src/api-users/schemas/identityQuerySchema.ts
|
|
20
21
|
const identityQuerySchema = t.extend(pageQuerySchema, {
|
|
@@ -160,10 +161,12 @@ var UserRealmProvider = class {
|
|
|
160
161
|
*/
|
|
161
162
|
getRealm(userRealmName = DEFAULT_USER_REALM_NAME$1) {
|
|
162
163
|
let realm = this.realms.get(userRealmName);
|
|
163
|
-
if (!realm)
|
|
164
|
-
this.
|
|
165
|
-
realm =
|
|
166
|
-
|
|
164
|
+
if (!realm) {
|
|
165
|
+
const firstRealm = Array.from(this.realms.values())[0];
|
|
166
|
+
if (userRealmName === DEFAULT_USER_REALM_NAME$1 && firstRealm) realm = firstRealm;
|
|
167
|
+
else if (this.alepha.isTest()) realm = this.register(userRealmName);
|
|
168
|
+
else throw new AlephaError(`Missing user realm '${userRealmName}', please declare $userRealm in your application.`);
|
|
169
|
+
}
|
|
167
170
|
return realm;
|
|
168
171
|
}
|
|
169
172
|
identityRepository(userRealmName = DEFAULT_USER_REALM_NAME$1) {
|
|
@@ -990,6 +993,7 @@ var RegistrationService = class {
|
|
|
990
993
|
}, userRealmName);
|
|
991
994
|
await this.intentCache.invalidate(body.intentId);
|
|
992
995
|
const user = await userRepository.create({
|
|
996
|
+
realm: userRealmName,
|
|
993
997
|
username: intent.data.username,
|
|
994
998
|
email: intent.data.email,
|
|
995
999
|
phoneNumber: intent.data.phoneNumber,
|
|
@@ -1056,10 +1060,7 @@ var RegistrationService = class {
|
|
|
1056
1060
|
});
|
|
1057
1061
|
this.log.debug("Email verification code sent", { email });
|
|
1058
1062
|
} catch (error) {
|
|
1059
|
-
this.log.warn("Failed to send email verification code",
|
|
1060
|
-
email,
|
|
1061
|
-
error
|
|
1062
|
-
});
|
|
1063
|
+
this.log.warn("Failed to send email verification code", error);
|
|
1063
1064
|
}
|
|
1064
1065
|
}
|
|
1065
1066
|
/**
|
|
@@ -1290,6 +1291,7 @@ var UserService = class {
|
|
|
1290
1291
|
email: data.email,
|
|
1291
1292
|
userRealmName
|
|
1292
1293
|
});
|
|
1294
|
+
const realm = this.userRealmProvider.getRealm(userRealmName);
|
|
1293
1295
|
if (data.username) {
|
|
1294
1296
|
if (await this.users(userRealmName).findOne({ where: { username: { eq: data.username } } }).catch(() => void 0)) {
|
|
1295
1297
|
this.log.debug("Username already taken", { username: data.username });
|
|
@@ -1310,7 +1312,8 @@ var UserService = class {
|
|
|
1310
1312
|
}
|
|
1311
1313
|
const user = await this.users(userRealmName).create({
|
|
1312
1314
|
...data,
|
|
1313
|
-
roles: data.roles ?? ["user"]
|
|
1315
|
+
roles: data.roles ?? ["user"],
|
|
1316
|
+
realm: realm.name
|
|
1314
1317
|
});
|
|
1315
1318
|
this.log.info("User created", {
|
|
1316
1319
|
userId: user.id,
|
|
@@ -1656,6 +1659,9 @@ var UserController = class {
|
|
|
1656
1659
|
const realmAuthSettingsAtom = $atom({
|
|
1657
1660
|
name: "alepha.api.users.realmAuthSettings",
|
|
1658
1661
|
schema: t.object({
|
|
1662
|
+
displayName: t.optional(t.string({ description: "Display name shown on auth pages (e.g., 'Customer Portal')" })),
|
|
1663
|
+
description: t.optional(t.string({ description: "Description shown on auth pages" })),
|
|
1664
|
+
logoUrl: t.optional(t.string({ description: "Logo URL for auth pages" })),
|
|
1659
1665
|
registrationAllowed: t.boolean({ description: "Enable user self-registration" }),
|
|
1660
1666
|
emailEnabled: t.boolean({ description: "Enable email address as a login/registration credential" }),
|
|
1661
1667
|
emailRequired: t.boolean({ description: "Require email address for user accounts" }),
|
|
@@ -1721,7 +1727,6 @@ var UserRealmController = class {
|
|
|
1721
1727
|
url = "/realms";
|
|
1722
1728
|
userRealmProvider = $inject(UserRealmProvider);
|
|
1723
1729
|
serverAuthProvider = $inject(ServerAuthProvider);
|
|
1724
|
-
cryptoProvider = $inject(CryptoProvider);
|
|
1725
1730
|
/**
|
|
1726
1731
|
* Get realm configuration settings.
|
|
1727
1732
|
* This endpoint is not exposed in the API documentation.
|
|
@@ -1808,7 +1813,8 @@ var SessionService = class {
|
|
|
1808
1813
|
else {
|
|
1809
1814
|
this.log.warn("Invalid login identifier format", {
|
|
1810
1815
|
provider,
|
|
1811
|
-
username
|
|
1816
|
+
username,
|
|
1817
|
+
realm: name
|
|
1812
1818
|
});
|
|
1813
1819
|
throw new InvalidCredentialsError();
|
|
1814
1820
|
}
|
|
@@ -1816,7 +1822,8 @@ var SessionService = class {
|
|
|
1816
1822
|
if (!user) {
|
|
1817
1823
|
this.log.warn("User not found during login attempt", {
|
|
1818
1824
|
provider,
|
|
1819
|
-
username
|
|
1825
|
+
username,
|
|
1826
|
+
realm: name
|
|
1820
1827
|
});
|
|
1821
1828
|
throw new InvalidCredentialsError();
|
|
1822
1829
|
}
|
|
@@ -1829,14 +1836,16 @@ var SessionService = class {
|
|
|
1829
1836
|
this.log.error("Identity has no password configured", {
|
|
1830
1837
|
provider,
|
|
1831
1838
|
username,
|
|
1832
|
-
identityId: identity.id
|
|
1839
|
+
identityId: identity.id,
|
|
1840
|
+
realm: name
|
|
1833
1841
|
});
|
|
1834
1842
|
throw new InvalidCredentialsError();
|
|
1835
1843
|
}
|
|
1836
1844
|
if (!await this.cryptoProvider.verifyPassword(password, storedPassword)) {
|
|
1837
1845
|
this.log.warn("Invalid password during login attempt", {
|
|
1838
1846
|
provider,
|
|
1839
|
-
username
|
|
1847
|
+
username,
|
|
1848
|
+
realm: name
|
|
1840
1849
|
});
|
|
1841
1850
|
throw new InvalidCredentialsError();
|
|
1842
1851
|
}
|
|
@@ -1985,6 +1994,673 @@ var SessionService = class {
|
|
|
1985
1994
|
}
|
|
1986
1995
|
};
|
|
1987
1996
|
|
|
1997
|
+
//#endregion
|
|
1998
|
+
//#region ../../src/api-audits/entities/audits.ts
|
|
1999
|
+
/**
|
|
2000
|
+
* Audit severity levels for categorizing events.
|
|
2001
|
+
*/
|
|
2002
|
+
const auditSeveritySchema = t.enum([
|
|
2003
|
+
"info",
|
|
2004
|
+
"warning",
|
|
2005
|
+
"critical"
|
|
2006
|
+
], {
|
|
2007
|
+
default: "info",
|
|
2008
|
+
description: "Severity level of the audit event"
|
|
2009
|
+
});
|
|
2010
|
+
/**
|
|
2011
|
+
* Audit log entity for tracking important system events.
|
|
2012
|
+
*
|
|
2013
|
+
* Stores comprehensive audit information including:
|
|
2014
|
+
* - Who performed the action (userId, userRealm)
|
|
2015
|
+
* - What happened (type, action, resource)
|
|
2016
|
+
* - When it happened (createdAt)
|
|
2017
|
+
* - Context and details (metadata, ipAddress, userAgent)
|
|
2018
|
+
*/
|
|
2019
|
+
const audits = $entity({
|
|
2020
|
+
name: "audits",
|
|
2021
|
+
schema: t.object({
|
|
2022
|
+
id: pg.primaryKey(t.bigint()),
|
|
2023
|
+
createdAt: pg.createdAt(),
|
|
2024
|
+
type: t.text({ description: "Audit event type (e.g., auth, user, payment, system)" }),
|
|
2025
|
+
action: t.text({ description: "Specific action performed (e.g., login, create, update)" }),
|
|
2026
|
+
severity: pg.default(auditSeveritySchema, "info"),
|
|
2027
|
+
userId: t.optional(t.uuid()),
|
|
2028
|
+
userRealm: t.optional(t.text()),
|
|
2029
|
+
userEmail: t.optional(t.email()),
|
|
2030
|
+
resourceType: t.optional(t.text()),
|
|
2031
|
+
resourceId: t.optional(t.text()),
|
|
2032
|
+
description: t.optional(t.text()),
|
|
2033
|
+
metadata: t.optional(t.json()),
|
|
2034
|
+
ipAddress: t.optional(t.text()),
|
|
2035
|
+
userAgent: t.optional(t.text()),
|
|
2036
|
+
sessionId: t.optional(t.uuid()),
|
|
2037
|
+
requestId: t.optional(t.text()),
|
|
2038
|
+
success: pg.default(t.boolean(), true),
|
|
2039
|
+
errorMessage: t.optional(t.text())
|
|
2040
|
+
}),
|
|
2041
|
+
indexes: [
|
|
2042
|
+
"createdAt",
|
|
2043
|
+
"type",
|
|
2044
|
+
"action",
|
|
2045
|
+
"userId",
|
|
2046
|
+
"userRealm",
|
|
2047
|
+
"resourceType",
|
|
2048
|
+
"resourceId",
|
|
2049
|
+
"severity",
|
|
2050
|
+
{ columns: ["type", "action"] },
|
|
2051
|
+
{ columns: ["userId", "createdAt"] },
|
|
2052
|
+
{ columns: ["userRealm", "createdAt"] }
|
|
2053
|
+
]
|
|
2054
|
+
});
|
|
2055
|
+
const auditEntitySchema = audits.schema;
|
|
2056
|
+
const auditEntityInsertSchema = audits.insertSchema;
|
|
2057
|
+
|
|
2058
|
+
//#endregion
|
|
2059
|
+
//#region ../../src/api-audits/schemas/auditQuerySchema.ts
|
|
2060
|
+
/**
|
|
2061
|
+
* Query schema for searching and filtering audit logs.
|
|
2062
|
+
*/
|
|
2063
|
+
const auditQuerySchema = t.extend(pageQuerySchema, {
|
|
2064
|
+
type: t.optional(t.text({ description: "Filter by audit type" })),
|
|
2065
|
+
action: t.optional(t.text({ description: "Filter by action" })),
|
|
2066
|
+
severity: t.optional(auditSeveritySchema),
|
|
2067
|
+
userId: t.optional(t.uuid({ description: "Filter by user ID" })),
|
|
2068
|
+
userRealm: t.optional(t.text({ description: "Filter by user realm" })),
|
|
2069
|
+
resourceType: t.optional(t.text({ description: "Filter by resource type" })),
|
|
2070
|
+
resourceId: t.optional(t.text({ description: "Filter by resource ID" })),
|
|
2071
|
+
success: t.optional(t.boolean({ description: "Filter by success status" })),
|
|
2072
|
+
from: t.optional(t.datetime({ description: "Start date filter" })),
|
|
2073
|
+
to: t.optional(t.datetime({ description: "End date filter" })),
|
|
2074
|
+
search: t.optional(t.text({ description: "Search in description" }))
|
|
2075
|
+
});
|
|
2076
|
+
|
|
2077
|
+
//#endregion
|
|
2078
|
+
//#region ../../src/api-audits/schemas/auditResourceSchema.ts
|
|
2079
|
+
/**
|
|
2080
|
+
* Resource schema for audit log responses.
|
|
2081
|
+
*/
|
|
2082
|
+
const auditResourceSchema = audits.schema;
|
|
2083
|
+
|
|
2084
|
+
//#endregion
|
|
2085
|
+
//#region ../../src/api-audits/schemas/createAuditSchema.ts
|
|
2086
|
+
/**
|
|
2087
|
+
* Schema for creating a new audit log entry.
|
|
2088
|
+
*/
|
|
2089
|
+
const createAuditSchema = t.object({
|
|
2090
|
+
type: t.text({ description: "Audit event type" }),
|
|
2091
|
+
action: t.text({ description: "Specific action performed" }),
|
|
2092
|
+
severity: t.optional(auditSeveritySchema),
|
|
2093
|
+
userId: t.optional(t.uuid()),
|
|
2094
|
+
userRealm: t.optional(t.text()),
|
|
2095
|
+
userEmail: t.optional(t.email()),
|
|
2096
|
+
resourceType: t.optional(t.text()),
|
|
2097
|
+
resourceId: t.optional(t.text()),
|
|
2098
|
+
description: t.optional(t.text()),
|
|
2099
|
+
metadata: t.optional(t.json()),
|
|
2100
|
+
ipAddress: t.optional(t.text()),
|
|
2101
|
+
userAgent: t.optional(t.text()),
|
|
2102
|
+
sessionId: t.optional(t.uuid()),
|
|
2103
|
+
requestId: t.optional(t.text()),
|
|
2104
|
+
success: t.optional(t.boolean()),
|
|
2105
|
+
errorMessage: t.optional(t.text())
|
|
2106
|
+
});
|
|
2107
|
+
|
|
2108
|
+
//#endregion
|
|
2109
|
+
//#region ../../src/api-audits/services/AuditService.ts
|
|
2110
|
+
/**
|
|
2111
|
+
* Service for managing audit logs.
|
|
2112
|
+
*
|
|
2113
|
+
* Provides methods for:
|
|
2114
|
+
* - Creating audit entries
|
|
2115
|
+
* - Querying audit history
|
|
2116
|
+
* - Aggregating audit statistics
|
|
2117
|
+
* - Managing registered audit types
|
|
2118
|
+
*/
|
|
2119
|
+
var AuditService = class {
|
|
2120
|
+
alepha = $inject(Alepha);
|
|
2121
|
+
log = $logger();
|
|
2122
|
+
repo = $repository(audits);
|
|
2123
|
+
/**
|
|
2124
|
+
* Registry of audit types and their allowed actions.
|
|
2125
|
+
*/
|
|
2126
|
+
auditTypes = /* @__PURE__ */ new Map();
|
|
2127
|
+
/**
|
|
2128
|
+
* Register an audit type with its allowed actions.
|
|
2129
|
+
*/
|
|
2130
|
+
registerType(definition) {
|
|
2131
|
+
this.auditTypes.set(definition.type, definition);
|
|
2132
|
+
this.log.debug("Audit type registered", {
|
|
2133
|
+
type: definition.type,
|
|
2134
|
+
actions: definition.actions
|
|
2135
|
+
});
|
|
2136
|
+
}
|
|
2137
|
+
/**
|
|
2138
|
+
* Get all registered audit types.
|
|
2139
|
+
*/
|
|
2140
|
+
getRegisteredTypes() {
|
|
2141
|
+
return Array.from(this.auditTypes.values());
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Get current request context if available.
|
|
2145
|
+
*/
|
|
2146
|
+
getRequestContext() {
|
|
2147
|
+
return this.alepha.context.get("request");
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Create a new audit log entry.
|
|
2151
|
+
* Automatically populates ipAddress, userAgent, and requestId from the current request context.
|
|
2152
|
+
*/
|
|
2153
|
+
async create(data) {
|
|
2154
|
+
const request = this.getRequestContext();
|
|
2155
|
+
const contextData = {};
|
|
2156
|
+
if (request) {
|
|
2157
|
+
if (!data.ipAddress && request.ip) contextData.ipAddress = request.ip;
|
|
2158
|
+
if (!data.userAgent && request.headers["user-agent"]) contextData.userAgent = request.headers["user-agent"];
|
|
2159
|
+
if (!data.requestId && request.requestId) contextData.requestId = request.requestId;
|
|
2160
|
+
if (!data.sessionId && request.metadata?.sessionId) contextData.sessionId = request.metadata.sessionId;
|
|
2161
|
+
const user = request.user;
|
|
2162
|
+
if (user) {
|
|
2163
|
+
if (!data.userId && user.id) contextData.userId = user.id;
|
|
2164
|
+
if (!data.userEmail && user.email) contextData.userEmail = user.email;
|
|
2165
|
+
if (!data.userRealm && user.realm) contextData.userRealm = user.realm;
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
this.log.trace("Creating audit entry", {
|
|
2169
|
+
type: data.type,
|
|
2170
|
+
action: data.action,
|
|
2171
|
+
userId: data.userId ?? contextData.userId
|
|
2172
|
+
});
|
|
2173
|
+
const entry = await this.repo.create({
|
|
2174
|
+
...contextData,
|
|
2175
|
+
...data,
|
|
2176
|
+
severity: data.severity ?? "info",
|
|
2177
|
+
success: data.success ?? true
|
|
2178
|
+
});
|
|
2179
|
+
this.log.debug("Audit entry created", {
|
|
2180
|
+
id: entry.id,
|
|
2181
|
+
type: data.type,
|
|
2182
|
+
action: data.action
|
|
2183
|
+
});
|
|
2184
|
+
return entry;
|
|
2185
|
+
}
|
|
2186
|
+
/**
|
|
2187
|
+
* Record an audit event (convenience method).
|
|
2188
|
+
*/
|
|
2189
|
+
async record(type, action, options = {}) {
|
|
2190
|
+
return this.create({
|
|
2191
|
+
type,
|
|
2192
|
+
action,
|
|
2193
|
+
...options
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
/**
|
|
2197
|
+
* Record an authentication event.
|
|
2198
|
+
*/
|
|
2199
|
+
async recordAuth(action, options = {}) {
|
|
2200
|
+
return this.create({
|
|
2201
|
+
type: "auth",
|
|
2202
|
+
action,
|
|
2203
|
+
severity: action === "login_failed" ? "warning" : "info",
|
|
2204
|
+
...options
|
|
2205
|
+
});
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Record a user management event.
|
|
2209
|
+
*/
|
|
2210
|
+
async recordUser(action, options = {}) {
|
|
2211
|
+
return this.create({
|
|
2212
|
+
type: "user",
|
|
2213
|
+
action,
|
|
2214
|
+
resourceType: "user",
|
|
2215
|
+
...options
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
/**
|
|
2219
|
+
* Record a data access event.
|
|
2220
|
+
*/
|
|
2221
|
+
async recordAccess(action, options = {}) {
|
|
2222
|
+
return this.create({
|
|
2223
|
+
type: "access",
|
|
2224
|
+
action,
|
|
2225
|
+
...options
|
|
2226
|
+
});
|
|
2227
|
+
}
|
|
2228
|
+
/**
|
|
2229
|
+
* Record a security event.
|
|
2230
|
+
*/
|
|
2231
|
+
async recordSecurity(action, options = {}) {
|
|
2232
|
+
return this.create({
|
|
2233
|
+
type: "security",
|
|
2234
|
+
action,
|
|
2235
|
+
severity: "warning",
|
|
2236
|
+
...options
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
/**
|
|
2240
|
+
* Record a system event.
|
|
2241
|
+
*/
|
|
2242
|
+
async recordSystem(action, options = {}) {
|
|
2243
|
+
return this.create({
|
|
2244
|
+
type: "system",
|
|
2245
|
+
action,
|
|
2246
|
+
severity: action === "error" ? "critical" : "info",
|
|
2247
|
+
...options
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
/**
|
|
2251
|
+
* Find audit entries with filtering and pagination.
|
|
2252
|
+
*/
|
|
2253
|
+
async find(query = {}) {
|
|
2254
|
+
this.log.trace("Finding audit entries", { query });
|
|
2255
|
+
query.sort ??= "-createdAt";
|
|
2256
|
+
const where = this.repo.createQueryWhere();
|
|
2257
|
+
if (query.type) where.type = { eq: query.type };
|
|
2258
|
+
if (query.action) where.action = { eq: query.action };
|
|
2259
|
+
if (query.severity) where.severity = { eq: query.severity };
|
|
2260
|
+
if (query.userId) where.userId = { eq: query.userId };
|
|
2261
|
+
if (query.userRealm) where.userRealm = { eq: query.userRealm };
|
|
2262
|
+
if (query.resourceType) where.resourceType = { eq: query.resourceType };
|
|
2263
|
+
if (query.resourceId) where.resourceId = { eq: query.resourceId };
|
|
2264
|
+
if (query.success !== void 0) where.success = { eq: query.success };
|
|
2265
|
+
if (query.from) where.createdAt = {
|
|
2266
|
+
...where.createdAt,
|
|
2267
|
+
gte: query.from
|
|
2268
|
+
};
|
|
2269
|
+
if (query.to) where.createdAt = {
|
|
2270
|
+
...where.createdAt,
|
|
2271
|
+
lte: query.to
|
|
2272
|
+
};
|
|
2273
|
+
if (query.search) where.description = { like: `%${query.search}%` };
|
|
2274
|
+
const result = await this.repo.paginate(query, { where }, { count: true });
|
|
2275
|
+
this.log.debug("Audit entries found", {
|
|
2276
|
+
count: result.content.length,
|
|
2277
|
+
total: result.page.totalElements
|
|
2278
|
+
});
|
|
2279
|
+
return result;
|
|
2280
|
+
}
|
|
2281
|
+
/**
|
|
2282
|
+
* Get audit entry by ID.
|
|
2283
|
+
*/
|
|
2284
|
+
async getById(id) {
|
|
2285
|
+
return this.repo.findById(id);
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* Get audit entries for a specific user.
|
|
2289
|
+
*/
|
|
2290
|
+
async findByUser(userId, query = {}) {
|
|
2291
|
+
return this.find({
|
|
2292
|
+
...query,
|
|
2293
|
+
userId
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* Get audit entries for a specific resource.
|
|
2298
|
+
*/
|
|
2299
|
+
async findByResource(resourceType, resourceId, query = {}) {
|
|
2300
|
+
return this.find({
|
|
2301
|
+
...query,
|
|
2302
|
+
resourceType,
|
|
2303
|
+
resourceId
|
|
2304
|
+
});
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2307
|
+
* Get audit statistics for a time period.
|
|
2308
|
+
*/
|
|
2309
|
+
async getStats(options = {}) {
|
|
2310
|
+
this.log.trace("Getting audit stats", options);
|
|
2311
|
+
const where = this.repo.createQueryWhere();
|
|
2312
|
+
if (options.from) where.createdAt = { gte: options.from.toISOString() };
|
|
2313
|
+
if (options.to) where.createdAt = {
|
|
2314
|
+
...where.createdAt,
|
|
2315
|
+
lte: options.to.toISOString()
|
|
2316
|
+
};
|
|
2317
|
+
if (options.userRealm) where.userRealm = { eq: options.userRealm };
|
|
2318
|
+
const all = await this.repo.findMany({ where });
|
|
2319
|
+
const stats = {
|
|
2320
|
+
total: all.length,
|
|
2321
|
+
byType: {},
|
|
2322
|
+
bySeverity: {
|
|
2323
|
+
info: 0,
|
|
2324
|
+
warning: 0,
|
|
2325
|
+
critical: 0
|
|
2326
|
+
},
|
|
2327
|
+
successRate: 0,
|
|
2328
|
+
recentFailures: []
|
|
2329
|
+
};
|
|
2330
|
+
let successCount = 0;
|
|
2331
|
+
for (const entry of all) {
|
|
2332
|
+
stats.byType[entry.type] = (stats.byType[entry.type] || 0) + 1;
|
|
2333
|
+
const severity = entry.severity;
|
|
2334
|
+
stats.bySeverity[severity]++;
|
|
2335
|
+
if (entry.success) successCount++;
|
|
2336
|
+
}
|
|
2337
|
+
stats.successRate = stats.total > 0 ? successCount / stats.total : 1;
|
|
2338
|
+
stats.recentFailures = all.filter((e) => !e.success).sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, 10);
|
|
2339
|
+
return stats;
|
|
2340
|
+
}
|
|
2341
|
+
/**
|
|
2342
|
+
* Delete old audit entries (for retention policy).
|
|
2343
|
+
*/
|
|
2344
|
+
async deleteOlderThan(date) {
|
|
2345
|
+
this.log.info("Deleting old audit entries", { olderThan: date });
|
|
2346
|
+
const old = await this.repo.findMany({ where: { createdAt: { lt: date.toISOString() } } });
|
|
2347
|
+
for (const entry of old) await this.repo.deleteById(entry.id);
|
|
2348
|
+
this.log.info("Old audit entries deleted", { count: old.length });
|
|
2349
|
+
return old.length;
|
|
2350
|
+
}
|
|
2351
|
+
};
|
|
2352
|
+
|
|
2353
|
+
//#endregion
|
|
2354
|
+
//#region ../../src/api-audits/controllers/AuditController.ts
|
|
2355
|
+
/**
|
|
2356
|
+
* REST API controller for audit log management.
|
|
2357
|
+
*
|
|
2358
|
+
* Provides endpoints for:
|
|
2359
|
+
* - Querying audit logs with filtering
|
|
2360
|
+
* - Creating audit entries
|
|
2361
|
+
* - Getting audit statistics
|
|
2362
|
+
* - Viewing registered audit types
|
|
2363
|
+
*/
|
|
2364
|
+
var AuditController = class {
|
|
2365
|
+
url = "/audits";
|
|
2366
|
+
group = "audits";
|
|
2367
|
+
auditService = $inject(AuditService);
|
|
2368
|
+
/**
|
|
2369
|
+
* Find audit entries with filtering and pagination.
|
|
2370
|
+
*/
|
|
2371
|
+
findAudits = $action({
|
|
2372
|
+
path: this.url,
|
|
2373
|
+
group: this.group,
|
|
2374
|
+
description: "Find audit entries with filtering and pagination",
|
|
2375
|
+
schema: {
|
|
2376
|
+
query: auditQuerySchema,
|
|
2377
|
+
response: pg.page(auditResourceSchema)
|
|
2378
|
+
},
|
|
2379
|
+
handler: ({ query }) => this.auditService.find(query)
|
|
2380
|
+
});
|
|
2381
|
+
/**
|
|
2382
|
+
* Get a single audit entry by ID.
|
|
2383
|
+
*/
|
|
2384
|
+
getAudit = $action({
|
|
2385
|
+
path: `${this.url}/:id`,
|
|
2386
|
+
group: this.group,
|
|
2387
|
+
description: "Get a single audit entry by ID",
|
|
2388
|
+
schema: {
|
|
2389
|
+
params: t.object({ id: t.text() }),
|
|
2390
|
+
response: auditResourceSchema
|
|
2391
|
+
},
|
|
2392
|
+
handler: ({ params }) => this.auditService.getById(params.id)
|
|
2393
|
+
});
|
|
2394
|
+
/**
|
|
2395
|
+
* Create a new audit entry.
|
|
2396
|
+
*/
|
|
2397
|
+
createAudit = $action({
|
|
2398
|
+
method: "POST",
|
|
2399
|
+
path: this.url,
|
|
2400
|
+
group: this.group,
|
|
2401
|
+
description: "Create a new audit entry",
|
|
2402
|
+
schema: {
|
|
2403
|
+
body: createAuditSchema,
|
|
2404
|
+
response: auditResourceSchema
|
|
2405
|
+
},
|
|
2406
|
+
handler: ({ body }) => this.auditService.create(body)
|
|
2407
|
+
});
|
|
2408
|
+
/**
|
|
2409
|
+
* Get audit entries for a specific user.
|
|
2410
|
+
*/
|
|
2411
|
+
findByUser = $action({
|
|
2412
|
+
path: `${this.url}/user/:userId`,
|
|
2413
|
+
group: this.group,
|
|
2414
|
+
description: "Get audit entries for a specific user",
|
|
2415
|
+
schema: {
|
|
2416
|
+
params: t.object({ userId: t.uuid() }),
|
|
2417
|
+
query: t.omit(auditQuerySchema, ["userId"]),
|
|
2418
|
+
response: pg.page(auditResourceSchema)
|
|
2419
|
+
},
|
|
2420
|
+
handler: ({ params, query }) => this.auditService.findByUser(params.userId, query)
|
|
2421
|
+
});
|
|
2422
|
+
/**
|
|
2423
|
+
* Get audit entries for a specific resource.
|
|
2424
|
+
*/
|
|
2425
|
+
findByResource = $action({
|
|
2426
|
+
path: `${this.url}/resource/:resourceType/:resourceId`,
|
|
2427
|
+
group: this.group,
|
|
2428
|
+
description: "Get audit entries for a specific resource",
|
|
2429
|
+
schema: {
|
|
2430
|
+
params: t.object({
|
|
2431
|
+
resourceType: t.text(),
|
|
2432
|
+
resourceId: t.text()
|
|
2433
|
+
}),
|
|
2434
|
+
query: t.omit(auditQuerySchema, ["resourceType", "resourceId"]),
|
|
2435
|
+
response: pg.page(auditResourceSchema)
|
|
2436
|
+
},
|
|
2437
|
+
handler: ({ params, query }) => this.auditService.findByResource(params.resourceType, params.resourceId, query)
|
|
2438
|
+
});
|
|
2439
|
+
/**
|
|
2440
|
+
* Get audit statistics.
|
|
2441
|
+
*/
|
|
2442
|
+
getStats = $action({
|
|
2443
|
+
path: `${this.url}/stats`,
|
|
2444
|
+
group: this.group,
|
|
2445
|
+
description: "Get audit statistics for a time period",
|
|
2446
|
+
schema: {
|
|
2447
|
+
query: t.object({
|
|
2448
|
+
from: t.optional(t.datetime()),
|
|
2449
|
+
to: t.optional(t.datetime()),
|
|
2450
|
+
userRealm: t.optional(t.text())
|
|
2451
|
+
}),
|
|
2452
|
+
response: t.object({
|
|
2453
|
+
total: t.integer(),
|
|
2454
|
+
byType: t.record(t.text(), t.integer()),
|
|
2455
|
+
bySeverity: t.object({
|
|
2456
|
+
info: t.integer(),
|
|
2457
|
+
warning: t.integer(),
|
|
2458
|
+
critical: t.integer()
|
|
2459
|
+
}),
|
|
2460
|
+
successRate: t.number(),
|
|
2461
|
+
recentFailures: t.array(auditResourceSchema)
|
|
2462
|
+
})
|
|
2463
|
+
},
|
|
2464
|
+
handler: ({ query }) => this.auditService.getStats({
|
|
2465
|
+
from: query.from ? new Date(query.from) : void 0,
|
|
2466
|
+
to: query.to ? new Date(query.to) : void 0,
|
|
2467
|
+
userRealm: query.userRealm
|
|
2468
|
+
})
|
|
2469
|
+
});
|
|
2470
|
+
/**
|
|
2471
|
+
* Get registered audit types.
|
|
2472
|
+
*/
|
|
2473
|
+
getTypes = $action({
|
|
2474
|
+
path: `${this.url}/types`,
|
|
2475
|
+
group: this.group,
|
|
2476
|
+
description: "Get all registered audit types",
|
|
2477
|
+
schema: { response: t.array(t.object({
|
|
2478
|
+
type: t.text(),
|
|
2479
|
+
description: t.optional(t.text()),
|
|
2480
|
+
actions: t.array(t.text())
|
|
2481
|
+
})) },
|
|
2482
|
+
handler: () => this.auditService.getRegisteredTypes()
|
|
2483
|
+
});
|
|
2484
|
+
/**
|
|
2485
|
+
* Get distinct values for filters.
|
|
2486
|
+
*/
|
|
2487
|
+
getFilterOptions = $action({
|
|
2488
|
+
path: `${this.url}/filters`,
|
|
2489
|
+
group: this.group,
|
|
2490
|
+
description: "Get distinct values for audit filters",
|
|
2491
|
+
schema: { response: t.object({
|
|
2492
|
+
types: t.array(t.text()),
|
|
2493
|
+
actions: t.array(t.text()),
|
|
2494
|
+
resourceTypes: t.array(t.text()),
|
|
2495
|
+
userRealms: t.array(t.text())
|
|
2496
|
+
}) },
|
|
2497
|
+
handler: async () => {
|
|
2498
|
+
const types = this.auditService.getRegisteredTypes();
|
|
2499
|
+
return {
|
|
2500
|
+
types: types.map((t$1) => t$1.type),
|
|
2501
|
+
actions: types.flatMap((t$1) => t$1.actions),
|
|
2502
|
+
resourceTypes: [
|
|
2503
|
+
"user",
|
|
2504
|
+
"session",
|
|
2505
|
+
"file",
|
|
2506
|
+
"order",
|
|
2507
|
+
"payment"
|
|
2508
|
+
],
|
|
2509
|
+
userRealms: ["default"]
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
});
|
|
2513
|
+
};
|
|
2514
|
+
|
|
2515
|
+
//#endregion
|
|
2516
|
+
//#region ../../src/api-audits/primitives/$audit.ts
|
|
2517
|
+
/**
|
|
2518
|
+
* Audit type primitive for registering domain-specific audit events.
|
|
2519
|
+
*
|
|
2520
|
+
* Provides a type-safe way to define and log audit events within a specific domain.
|
|
2521
|
+
*
|
|
2522
|
+
* @example
|
|
2523
|
+
* ```ts
|
|
2524
|
+
* class PaymentAudits {
|
|
2525
|
+
* audit = $audit({
|
|
2526
|
+
* type: "payment",
|
|
2527
|
+
* description: "Payment-related audit events",
|
|
2528
|
+
* actions: ["create", "refund", "cancel", "dispute"],
|
|
2529
|
+
* });
|
|
2530
|
+
*
|
|
2531
|
+
* async logPaymentCreated(paymentId: string, userId: string, amount: number) {
|
|
2532
|
+
* await this.audit.log("create", {
|
|
2533
|
+
* userId,
|
|
2534
|
+
* resourceType: "payment",
|
|
2535
|
+
* resourceId: paymentId,
|
|
2536
|
+
* description: `Payment of ${amount} created`,
|
|
2537
|
+
* metadata: { amount },
|
|
2538
|
+
* });
|
|
2539
|
+
* }
|
|
2540
|
+
* }
|
|
2541
|
+
* ```
|
|
2542
|
+
*/
|
|
2543
|
+
var AuditPrimitive = class extends Primitive {
|
|
2544
|
+
auditService = $inject(AuditService);
|
|
2545
|
+
/**
|
|
2546
|
+
* The audit type identifier.
|
|
2547
|
+
*/
|
|
2548
|
+
get type() {
|
|
2549
|
+
return this.options.type;
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* The audit type description.
|
|
2553
|
+
*/
|
|
2554
|
+
get description() {
|
|
2555
|
+
return this.options.description;
|
|
2556
|
+
}
|
|
2557
|
+
/**
|
|
2558
|
+
* The allowed actions for this audit type.
|
|
2559
|
+
*/
|
|
2560
|
+
get actions() {
|
|
2561
|
+
return this.options.actions;
|
|
2562
|
+
}
|
|
2563
|
+
/**
|
|
2564
|
+
* Log an audit event for this type.
|
|
2565
|
+
*/
|
|
2566
|
+
async log(action, options = {}) {
|
|
2567
|
+
await this.auditService.record(this.options.type, action, options);
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Log a successful audit event.
|
|
2571
|
+
*/
|
|
2572
|
+
async logSuccess(action, options = {}) {
|
|
2573
|
+
await this.log(action, {
|
|
2574
|
+
...options,
|
|
2575
|
+
success: true
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* Log a failed audit event.
|
|
2580
|
+
*/
|
|
2581
|
+
async logFailure(action, errorMessage, options = {}) {
|
|
2582
|
+
await this.log(action, {
|
|
2583
|
+
...options,
|
|
2584
|
+
success: false,
|
|
2585
|
+
errorMessage
|
|
2586
|
+
});
|
|
2587
|
+
}
|
|
2588
|
+
/**
|
|
2589
|
+
* Called during initialization to register this audit type.
|
|
2590
|
+
*/
|
|
2591
|
+
onInit() {
|
|
2592
|
+
const definition = {
|
|
2593
|
+
type: this.options.type,
|
|
2594
|
+
description: this.options.description,
|
|
2595
|
+
actions: this.options.actions
|
|
2596
|
+
};
|
|
2597
|
+
this.auditService.registerType(definition);
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2600
|
+
/**
|
|
2601
|
+
* Create an audit type primitive.
|
|
2602
|
+
*
|
|
2603
|
+
* @example
|
|
2604
|
+
* ```ts
|
|
2605
|
+
* class OrderAudits {
|
|
2606
|
+
* audit = $audit({
|
|
2607
|
+
* type: "order",
|
|
2608
|
+
* description: "Order management events",
|
|
2609
|
+
* actions: ["create", "update", "cancel", "fulfill", "ship"],
|
|
2610
|
+
* });
|
|
2611
|
+
* }
|
|
2612
|
+
* ```
|
|
2613
|
+
*/
|
|
2614
|
+
const $audit = (options) => {
|
|
2615
|
+
return createPrimitive(AuditPrimitive, options);
|
|
2616
|
+
};
|
|
2617
|
+
$audit[KIND] = AuditPrimitive;
|
|
2618
|
+
|
|
2619
|
+
//#endregion
|
|
2620
|
+
//#region ../../src/api-audits/index.ts
|
|
2621
|
+
/**
|
|
2622
|
+
* Provides audit logging API endpoints for Alepha applications.
|
|
2623
|
+
*
|
|
2624
|
+
* This module includes:
|
|
2625
|
+
* - Audit log CRUD operations
|
|
2626
|
+
* - Filtering and searching audit events
|
|
2627
|
+
* - Audit statistics and analytics
|
|
2628
|
+
* - `$audit` primitive for domain-specific audit types
|
|
2629
|
+
*
|
|
2630
|
+
* @module alepha.api.audits
|
|
2631
|
+
*
|
|
2632
|
+
* @example
|
|
2633
|
+
* ```ts
|
|
2634
|
+
* // In your app module
|
|
2635
|
+
* import { AlephaApiAudits } from "alepha/api/audits";
|
|
2636
|
+
*
|
|
2637
|
+
* const App = $module({
|
|
2638
|
+
* name: "app",
|
|
2639
|
+
* services: [AlephaApiAudits, ...],
|
|
2640
|
+
* });
|
|
2641
|
+
*
|
|
2642
|
+
* // Create domain-specific audit types
|
|
2643
|
+
* class PaymentAudits {
|
|
2644
|
+
* audit = $audit({
|
|
2645
|
+
* type: "payment",
|
|
2646
|
+
* actions: ["create", "refund", "cancel"],
|
|
2647
|
+
* });
|
|
2648
|
+
*
|
|
2649
|
+
* async onPaymentCreated(paymentId: string, userId: string) {
|
|
2650
|
+
* await this.audit.log("create", {
|
|
2651
|
+
* userId,
|
|
2652
|
+
* resourceType: "payment",
|
|
2653
|
+
* resourceId: paymentId,
|
|
2654
|
+
* });
|
|
2655
|
+
* }
|
|
2656
|
+
* }
|
|
2657
|
+
* ```
|
|
2658
|
+
*/
|
|
2659
|
+
const AlephaApiAudits = $module({
|
|
2660
|
+
name: "alepha.api.audits",
|
|
2661
|
+
services: [AuditService, AuditController]
|
|
2662
|
+
});
|
|
2663
|
+
|
|
1988
2664
|
//#endregion
|
|
1989
2665
|
//#region ../../src/api-users/primitives/$userRealm.ts
|
|
1990
2666
|
/**
|
|
@@ -2007,8 +2683,9 @@ const $userRealm = (options = {}) => {
|
|
|
2007
2683
|
const userRealmProvider = alepha.inject(UserRealmProvider);
|
|
2008
2684
|
const name = options.realm?.name ?? DEFAULT_USER_REALM_NAME;
|
|
2009
2685
|
const userRealm = userRealmProvider.register(name, options);
|
|
2010
|
-
if (options.modules?.audits)
|
|
2686
|
+
if (options.modules?.audits) alepha.with(AlephaApiAudits);
|
|
2011
2687
|
if (options.modules?.files) alepha.with(AlephaApiFiles);
|
|
2688
|
+
if (options.modules?.jobs) alepha.with(AlephaApiJobs);
|
|
2012
2689
|
const realm = $realm({
|
|
2013
2690
|
...options.realm,
|
|
2014
2691
|
name,
|
|
@@ -2040,10 +2717,12 @@ const $userRealm = (options = {}) => {
|
|
|
2040
2717
|
}
|
|
2041
2718
|
});
|
|
2042
2719
|
realm.link = (name$1) => {
|
|
2043
|
-
return (ctx) => sessionService.link(name$1, ctx.user);
|
|
2720
|
+
return (ctx) => sessionService.link(name$1, ctx.user, realm.name);
|
|
2044
2721
|
};
|
|
2045
2722
|
realm.login = (name$1) => {
|
|
2046
|
-
return (credentials) =>
|
|
2723
|
+
return (credentials) => {
|
|
2724
|
+
return sessionService.login(name$1, credentials.username, credentials.password, realm.name);
|
|
2725
|
+
};
|
|
2047
2726
|
};
|
|
2048
2727
|
const identities$1 = options.identities ?? { credentials: true };
|
|
2049
2728
|
if (identities$1) {
|
|
@@ -2140,7 +2819,8 @@ const AlephaApiUsers = $module({
|
|
|
2140
2819
|
UserController,
|
|
2141
2820
|
SessionController,
|
|
2142
2821
|
IdentityController,
|
|
2143
|
-
UserRealmController
|
|
2822
|
+
UserRealmController,
|
|
2823
|
+
UserNotifications
|
|
2144
2824
|
]
|
|
2145
2825
|
});
|
|
2146
2826
|
|