@tstdl/base 0.93.2 → 0.93.4

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.
Files changed (182) hide show
  1. package/ai/ai.service.d.ts +2 -1
  2. package/ai/ai.service.js +11 -3
  3. package/ai/types.d.ts +3 -1
  4. package/api/server/api-request-token.provider.d.ts +5 -3
  5. package/api/server/api-request-token.provider.js +12 -4
  6. package/api/server/gateway.d.ts +1 -9
  7. package/api/server/gateway.js +67 -36
  8. package/api/types.d.ts +5 -1
  9. package/application/application.d.ts +2 -0
  10. package/application/application.js +3 -1
  11. package/application/providers.d.ts +1 -1
  12. package/application/providers.js +1 -1
  13. package/audit/audit.model.d.ts +14 -9
  14. package/audit/audit.model.js +36 -27
  15. package/audit/auditor.d.ts +32 -23
  16. package/audit/auditor.js +84 -21
  17. package/audit/drizzle/{0000_tiny_the_captain.sql → 0000_bored_stick.sql} +5 -4
  18. package/audit/drizzle/meta/0000_snapshot.json +22 -15
  19. package/audit/drizzle/meta/_journal.json +2 -2
  20. package/audit/index.d.ts +3 -1
  21. package/audit/index.js +3 -1
  22. package/audit/module.d.ts +1 -1
  23. package/audit/module.js +1 -2
  24. package/audit/schemas.d.ts +2 -2
  25. package/audit/schemas.js +1 -1
  26. package/audit/types.d.ts +2 -1
  27. package/audit/types.js +2 -1
  28. package/authentication/models/authentication-credentials.model.js +1 -2
  29. package/authentication/models/authentication-session.model.d.ts +2 -2
  30. package/authentication/models/authentication-session.model.js +3 -5
  31. package/authentication/server/authentication-api-request-token.provider.d.ts +2 -2
  32. package/authentication/server/authentication-api-request-token.provider.js +8 -5
  33. package/authentication/server/authentication.api-controller.d.ts +8 -8
  34. package/authentication/server/authentication.api-controller.js +16 -16
  35. package/authentication/server/authentication.audit.d.ts +34 -0
  36. package/authentication/server/authentication.audit.js +1 -0
  37. package/authentication/server/authentication.service.d.ts +19 -10
  38. package/authentication/server/authentication.service.js +158 -43
  39. package/authentication/server/module.d.ts +1 -1
  40. package/authentication/server/schemas.d.ts +2 -3
  41. package/authentication/server/schemas.js +2 -3
  42. package/constants.d.ts +1 -0
  43. package/constants.js +1 -0
  44. package/document-management/api/document-management.api.d.ts +74 -74
  45. package/document-management/models/document-assignment-scope.model.d.ts +1 -2
  46. package/document-management/models/document-assignment-scope.model.js +4 -6
  47. package/document-management/models/document-assignment-task.model.d.ts +1 -2
  48. package/document-management/models/document-assignment-task.model.js +3 -5
  49. package/document-management/models/document-category.model.d.ts +1 -2
  50. package/document-management/models/document-category.model.js +3 -4
  51. package/document-management/models/document-collection-assignment.model.d.ts +1 -2
  52. package/document-management/models/document-collection-assignment.model.js +5 -7
  53. package/document-management/models/document-collection.model.d.ts +1 -2
  54. package/document-management/models/document-collection.model.js +3 -4
  55. package/document-management/models/document-management-table.d.ts +1 -1
  56. package/document-management/models/document-management-table.js +1 -1
  57. package/document-management/models/document-property-value.model.d.ts +1 -2
  58. package/document-management/models/document-property-value.model.js +5 -8
  59. package/document-management/models/document-property.model.d.ts +1 -2
  60. package/document-management/models/document-property.model.js +2 -3
  61. package/document-management/models/document-request-collection-assignment.model.d.ts +1 -2
  62. package/document-management/models/document-request-collection-assignment.model.js +4 -6
  63. package/document-management/models/document-request-template.d.ts +1 -2
  64. package/document-management/models/document-request-template.js +4 -6
  65. package/document-management/models/document-request.model.d.ts +1 -1
  66. package/document-management/models/document-request.model.js +4 -5
  67. package/document-management/models/document-requests-template.d.ts +1 -1
  68. package/document-management/models/document-requests-template.js +2 -3
  69. package/document-management/models/document-tag-assignment.model.d.ts +1 -2
  70. package/document-management/models/document-tag-assignment.model.js +4 -6
  71. package/document-management/models/document-tag.model.d.ts +1 -1
  72. package/document-management/models/document-tag.model.js +2 -3
  73. package/document-management/models/document-type-property.model.d.ts +1 -2
  74. package/document-management/models/document-type-property.model.js +4 -6
  75. package/document-management/models/document-type-validation.model.d.ts +1 -2
  76. package/document-management/models/document-type-validation.model.js +4 -6
  77. package/document-management/models/document-type.model.d.ts +1 -2
  78. package/document-management/models/document-type.model.js +3 -5
  79. package/document-management/models/document-validation-definition.model.d.ts +1 -2
  80. package/document-management/models/document-validation-definition.model.js +3 -4
  81. package/document-management/models/document-validation-execution-related-document.model.d.ts +1 -2
  82. package/document-management/models/document-validation-execution-related-document.model.js +4 -6
  83. package/document-management/models/document-validation-execution.model.d.ts +1 -2
  84. package/document-management/models/document-validation-execution.model.js +8 -9
  85. package/document-management/models/document-workflow.model.d.ts +1 -2
  86. package/document-management/models/document-workflow.model.js +5 -7
  87. package/document-management/models/document.model.d.ts +1 -2
  88. package/document-management/models/document.model.js +5 -7
  89. package/document-management/server/api/document-management.api.js +1 -1
  90. package/document-management/server/module.d.ts +1 -1
  91. package/document-management/server/module.js +1 -1
  92. package/document-management/server/schemas.d.ts +1 -1
  93. package/document-management/server/schemas.js +1 -1
  94. package/document-management/server/services/document-category-type.service.d.ts +2 -2
  95. package/document-management/server/services/document-category-type.service.js +1 -2
  96. package/document-management/server/services/document-collection.service.d.ts +1 -1
  97. package/document-management/server/services/document-collection.service.js +1 -2
  98. package/document-management/server/services/document-management-ai.service.js +3 -3
  99. package/document-management/server/services/document-management.service.js +6 -6
  100. package/document-management/server/services/document-property.service.d.ts +1 -1
  101. package/document-management/server/services/document-property.service.js +1 -2
  102. package/document-management/server/services/document-validation.service.js +2 -2
  103. package/document-management/server/services/document-workflow.service.d.ts +2 -2
  104. package/document-management/server/services/document-workflow.service.js +1 -2
  105. package/document-management/server/services/document.service.d.ts +1 -1
  106. package/document-management/server/services/document.service.js +1 -2
  107. package/document-management/server/services/singleton.js +1 -1
  108. package/document-management/server/validators/ai-validation-executor.d.ts +2 -2
  109. package/document-management/server/validators/ai-validation-executor.js +6 -6
  110. package/document-management/server/validators/single-document-validation-executor.d.ts +2 -1
  111. package/document-management/server/validators/single-document-validation-executor.js +3 -2
  112. package/document-management/service-models/document.service-model.d.ts +62 -62
  113. package/document-management/service-models/document.service-model.js +1 -1
  114. package/document-management/service-models/enriched/enriched-document-management-data.view.js +1 -1
  115. package/document-management/service-models/enriched/enriched-document.view.d.ts +1 -1
  116. package/examples/api/authentication.js +2 -2
  117. package/examples/api/basic-overview.js +2 -2
  118. package/examples/api/custom-authentication.js +2 -2
  119. package/examples/api/streaming.js +2 -2
  120. package/examples/browser/basic.js +2 -2
  121. package/examples/document-management/main.js +4 -2
  122. package/examples/http/client.js +2 -2
  123. package/examples/mail/basic.js +2 -2
  124. package/examples/pdf/basic.js +2 -2
  125. package/examples/template/basic.js +2 -2
  126. package/http/server/http-server-request.d.ts +3 -3
  127. package/key-value-store/postgres/key-value-store.service.js +1 -2
  128. package/key-value-store/postgres/models/key-value.model.d.ts +1 -2
  129. package/key-value-store/postgres/models/key-value.model.js +2 -4
  130. package/key-value-store/postgres/models/schemas.d.ts +1 -1
  131. package/key-value-store/postgres/models/schemas.js +1 -1
  132. package/lock/postgres/lock.js +1 -1
  133. package/lock/postgres/models/lock.model.d.ts +1 -2
  134. package/lock/postgres/models/lock.model.js +3 -5
  135. package/lock/postgres/models/schemas.d.ts +1 -1
  136. package/lock/postgres/models/schemas.js +1 -1
  137. package/lock/postgres/provider.js +1 -2
  138. package/mail/models/mail-log.model.d.ts +1 -1
  139. package/mail/models/mail-log.model.js +4 -5
  140. package/mail/models/schemas.d.ts +1 -1
  141. package/mail/models/schemas.js +1 -1
  142. package/openid-connect/oidc-state.model.d.ts +1 -1
  143. package/openid-connect/oidc-state.model.js +2 -3
  144. package/openid-connect/oidc.service.js +1 -1
  145. package/orm/data-types/bytea.js +1 -1
  146. package/orm/data-types/numeric-date.js +1 -1
  147. package/orm/decorators.d.ts +65 -72
  148. package/orm/decorators.js +42 -40
  149. package/orm/entity.d.ts +1 -1
  150. package/orm/entity.js +13 -13
  151. package/orm/index.d.ts +2 -1
  152. package/orm/index.js +2 -1
  153. package/orm/schemas/json.d.ts +1 -1
  154. package/orm/schemas/json.js +1 -1
  155. package/orm/schemas/numeric-date.d.ts +1 -1
  156. package/orm/schemas/numeric-date.js +1 -1
  157. package/orm/schemas/timestamp.d.ts +1 -1
  158. package/orm/schemas/timestamp.js +1 -1
  159. package/orm/schemas/uuid.d.ts +2 -2
  160. package/orm/schemas/uuid.js +1 -1
  161. package/orm/server/drizzle/index.js +1 -0
  162. package/orm/server/drizzle/schema-converter.d.ts +15 -0
  163. package/orm/server/drizzle/schema-converter.js +300 -0
  164. package/orm/server/repository.d.ts +1 -1
  165. package/orm/server/repository.js +12 -9
  166. package/orm/sqls.d.ts +1 -1
  167. package/orm/sqls.js +1 -1
  168. package/orm/types.d.ts +2 -6
  169. package/orm/types.js +1 -4
  170. package/package.json +12 -10
  171. package/queue/postgres/job.model.d.ts +3 -3
  172. package/queue/postgres/job.model.js +5 -6
  173. package/queue/postgres/queue.js +2 -2
  174. package/queue/postgres/schemas.d.ts +1 -1
  175. package/queue/postgres/schemas.js +1 -1
  176. package/supports.d.ts +1 -0
  177. package/supports.js +2 -1
  178. package/types/types.d.ts +12 -1
  179. package/utils/object/object.d.ts +3 -1
  180. package/utils/object/object.js +7 -1
  181. package/orm/server/drizzle/schema-converter.ts +0 -408
  182. /package/orm/server/drizzle/{index.ts → index.d.ts} +0 -0
@@ -33,8 +33,8 @@ let AuthenticationApiController = class AuthenticationApiController {
33
33
  * @param parameters The parameters for the request.
34
34
  * @returns The token result.
35
35
  */
36
- async login({ parameters }) {
37
- const result = await this.authenticationService.login(parameters.subject, parameters.secret, parameters.data);
36
+ async login({ parameters, getAuditor }) {
37
+ const result = await this.authenticationService.login(parameters.subject, parameters.secret, parameters.data, await getAuditor());
38
38
  return this.getTokenResponse(result);
39
39
  }
40
40
  /**
@@ -43,9 +43,9 @@ let AuthenticationApiController = class AuthenticationApiController {
43
43
  * @param parameters The parameters for the request.
44
44
  * @returns The token result.
45
45
  */
46
- async refresh({ request, parameters }) {
46
+ async refresh({ request, parameters, getAuditor }) {
47
47
  const refreshTokenString = tryGetAuthorizationTokenStringFromRequest(request, 'refreshToken') ?? '';
48
- const result = await this.authenticationService.refresh(refreshTokenString, parameters.data);
48
+ const result = await this.authenticationService.refresh(refreshTokenString, parameters.data, undefined, await getAuditor());
49
49
  return this.getTokenResponse(result);
50
50
  }
51
51
  /**
@@ -54,10 +54,10 @@ let AuthenticationApiController = class AuthenticationApiController {
54
54
  * @param parameters The parameters for the request.
55
55
  * @returns The token result.
56
56
  */
57
- async impersonate({ request, parameters }) {
57
+ async impersonate({ request, parameters, getAuditor }) {
58
58
  const tokenString = tryGetAuthorizationTokenStringFromRequest(request) ?? '';
59
59
  const refreshTokenString = tryGetAuthorizationTokenStringFromRequest(request, 'refreshToken') ?? '';
60
- const impersonatorResult = await this.authenticationService.impersonate(tokenString, refreshTokenString, parameters.subject, parameters.data);
60
+ const impersonatorResult = await this.authenticationService.impersonate(tokenString, refreshTokenString, parameters.subject, parameters.data, await getAuditor());
61
61
  return this.getTokenResponse(impersonatorResult);
62
62
  }
63
63
  /**
@@ -66,9 +66,9 @@ let AuthenticationApiController = class AuthenticationApiController {
66
66
  * @param parameters The parameters for the request.
67
67
  * @returns The token result.
68
68
  */
69
- async unimpersonate({ request, parameters }) {
69
+ async unimpersonate({ request, parameters, getAuditor }) {
70
70
  const impersonatorRefreshTokenString = tryGetAuthorizationTokenStringFromRequest(request, 'impersonatorRefreshToken') ?? '';
71
- const result = await this.authenticationService.refresh(impersonatorRefreshTokenString, parameters.data, { omitImpersonator: true });
71
+ const result = await this.authenticationService.unimpersonate(impersonatorRefreshTokenString, parameters.data, await getAuditor());
72
72
  return this.getTokenResponse(result);
73
73
  }
74
74
  /**
@@ -76,7 +76,7 @@ let AuthenticationApiController = class AuthenticationApiController {
76
76
  * @param request The request context.
77
77
  * @returns 'ok' if the session was ended.
78
78
  */
79
- async endSession({ request }) {
79
+ async endSession({ request, getAuditor }) {
80
80
  let sessionId;
81
81
  try {
82
82
  const tokenString = tryGetAuthorizationTokenStringFromRequest(request) ?? '';
@@ -93,7 +93,7 @@ let AuthenticationApiController = class AuthenticationApiController {
93
93
  throw error;
94
94
  }
95
95
  }
96
- await this.authenticationService.endSession(sessionId);
96
+ await this.authenticationService.endSession(sessionId, await getAuditor());
97
97
  const result = 'ok';
98
98
  return new HttpServerResponse({
99
99
  cookies: {
@@ -106,8 +106,8 @@ let AuthenticationApiController = class AuthenticationApiController {
106
106
  },
107
107
  });
108
108
  }
109
- async changeSecret({ parameters }) {
110
- await this.authenticationService.changeSecret(parameters.subject, parameters.currentSecret, parameters.newSecret);
109
+ async changeSecret({ parameters, getAuditor }) {
110
+ await this.authenticationService.changeSecret(parameters.subject, parameters.currentSecret, parameters.newSecret, await getAuditor());
111
111
  return 'ok';
112
112
  }
113
113
  /**
@@ -115,8 +115,8 @@ let AuthenticationApiController = class AuthenticationApiController {
115
115
  * @param parameters The parameters for the request.
116
116
  * @returns 'ok' if the secret reset was initialized.
117
117
  */
118
- async initSecretReset({ parameters }) {
119
- await this.authenticationService.initSecretReset(parameters.subject, parameters.data);
118
+ async initSecretReset({ parameters, getAuditor }) {
119
+ await this.authenticationService.initSecretReset(parameters.subject, parameters.data, await getAuditor());
120
120
  return 'ok';
121
121
  }
122
122
  /**
@@ -124,8 +124,8 @@ let AuthenticationApiController = class AuthenticationApiController {
124
124
  * @param parameters The parameters for the request.
125
125
  * @returns 'ok' if the secret was reset.
126
126
  */
127
- async resetSecret({ parameters }) {
128
- await this.authenticationService.resetSecret(parameters.token, parameters.newSecret);
127
+ async resetSecret({ parameters, getAuditor }) {
128
+ await this.authenticationService.resetSecret(parameters.token, parameters.newSecret, await getAuditor());
129
129
  return 'ok';
130
130
  }
131
131
  /**
@@ -0,0 +1,34 @@
1
+ export type AuthenticationAuditEvents = {
2
+ 'login-success': {
3
+ sessionId: string;
4
+ };
5
+ 'login-failure': {
6
+ providedSubject: string;
7
+ };
8
+ 'logout': {
9
+ sessionId: string;
10
+ };
11
+ 'refresh-success': {
12
+ sessionId: string;
13
+ };
14
+ 'refresh-failure': {
15
+ reason: string;
16
+ };
17
+ 'impersonate-success': {
18
+ impersonatedSubject: string;
19
+ };
20
+ 'impersonate-failure': {
21
+ impersonatedSubject: string;
22
+ reason: string;
23
+ };
24
+ 'unimpersonate-success': {};
25
+ 'change-secret-success': {};
26
+ 'change-secret-failure': {
27
+ providedSubject: string;
28
+ };
29
+ 'init-secret-reset': {};
30
+ 'reset-secret-success': {};
31
+ 'reset-secret-failure': {
32
+ reason: string;
33
+ };
34
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,4 @@
1
+ import { Auditor } from '../../audit/index.js';
1
2
  import { type AfterResolve, afterResolve } from '../../injector/index.js';
2
3
  import type { BinaryData, Record } from '../../types/index.js';
3
4
  import { type RefreshToken, type SecretCheckResult, type SecretResetToken, type Token } from '../models/index.js';
@@ -190,63 +191,71 @@ export declare class AuthenticationService<AdditionalTokenPayload extends Record
190
191
  * @param subject The subject to log in.
191
192
  * @param secret The secret to log in with.
192
193
  * @param data Additional authentication data.
194
+ * @param auditor Auditor for auditing.
193
195
  * @returns Token
194
196
  */
195
- login(subject: string, secret: string, data: AuthenticationData): Promise<TokenResult<AdditionalTokenPayload>>;
197
+ login(subject: string, secret: string, data: AuthenticationData, auditor: Auditor): Promise<TokenResult<AdditionalTokenPayload>>;
196
198
  /**
197
199
  * Ends a session.
198
200
  * @param sessionId The id of the session to end.
201
+ * @param auditor Auditor for auditing.
199
202
  */
200
- endSession(sessionId: string): Promise<void>;
203
+ endSession(sessionId: string, auditor: Auditor): Promise<void>;
201
204
  /**
202
205
  * Refreshes a token.
203
206
  * @param refreshToken The refresh token to use.
204
207
  * @param authenticationData Additional authentication data.
205
208
  * @param options Options for refreshing the token.
209
+ * @param auditor Auditor for auditing.
206
210
  * @returns The token result.
207
211
  * @throws {InvalidTokenError} If the refresh token is invalid.
208
212
  */
209
- refresh(refreshToken: string, authenticationData: AuthenticationData, { omitImpersonator }?: {
213
+ refresh(refreshToken: string, authenticationData: AuthenticationData, options: {
210
214
  omitImpersonator?: boolean;
211
- }): Promise<TokenResult<AdditionalTokenPayload>>;
215
+ } | undefined, auditor: Auditor): Promise<TokenResult<AdditionalTokenPayload>>;
212
216
  /**
213
217
  * Impersonates a subject.
214
- * @param impersonatorRoken The token of the impersonator.
218
+ * @param impersonatorToken The token of the impersonator.
215
219
  * @param impersonatorRefreshToken The refresh token of the impersonator.
216
220
  * @param subject The subject to impersonate.
217
221
  * @param authenticationData Additional authentication data.
222
+ * @param auditor Auditor for auditing.
218
223
  * @returns The token result.
219
224
  * @throws {ForbiddenError} If impersonation is not allowed.
220
225
  */
221
- impersonate(impersonatorRoken: string, impersonatorRefreshToken: string, subject: string, authenticationData: AuthenticationData): Promise<TokenResult<AdditionalTokenPayload>>;
226
+ impersonate(impersonatorToken: string, impersonatorRefreshToken: string, subject: string, authenticationData: AuthenticationData, auditor: Auditor): Promise<TokenResult<AdditionalTokenPayload>>;
222
227
  /**
223
228
  * Unimpersonates a subject.
224
229
  * @param impersonatorRefreshToken The refresh token of the impersonator.
225
230
  * @param authenticationData Additional authentication data.
231
+ * @param auditor Auditor for auditing.
226
232
  * @returns The token result.
227
233
  */
228
- unimpersonate(impersonatorRefreshToken: string, authenticationData: AuthenticationData): Promise<TokenResult<AdditionalTokenPayload>>;
234
+ unimpersonate(impersonatorRefreshToken: string, authenticationData: AuthenticationData, auditor: Auditor): Promise<TokenResult<AdditionalTokenPayload>>;
229
235
  /**
230
236
  * Initializes a secret reset. This usually involves sending an email for verification.
231
237
  * @param subject The subject to reset the secret for.
232
238
  * @param data Additional data for the secret reset.
239
+ * @param auditor Auditor for auditing.
233
240
  * @throws {NotImplementedError} If no ancillary service is registered.
234
241
  */
235
- initSecretReset(subject: string, data: AdditionalInitSecretResetData): Promise<void>;
242
+ initSecretReset(subject: string, data: AdditionalInitSecretResetData, auditor: Auditor): Promise<void>;
236
243
  /**
237
244
  * Changes a subject's secret.
238
245
  * @param subject The subject to change the secret for.
239
246
  * @param currentSecret The current secret.
240
247
  * @param newSecret The new secret.
248
+ * @param auditor Auditor for auditing.
241
249
  */
242
- changeSecret(subject: string, currentSecret: string, newSecret: string): Promise<void>;
250
+ changeSecret(subject: string, currentSecret: string, newSecret: string, auditor: Auditor): Promise<void>;
243
251
  /**
244
252
  * Resets a secret.
245
253
  * @param tokenString The secret reset token.
246
254
  * @param newSecret The new secret.
255
+ * @param auditor Auditor for auditing.
247
256
  * @throws {InvalidTokenError} If the token is invalid.
248
257
  */
249
- resetSecret(tokenString: string, newSecret: string): Promise<void>;
258
+ resetSecret(tokenString: string, newSecret: string, auditor: Auditor): Promise<void>;
250
259
  /**
251
260
  * Checks a secret against the requirements.
252
261
  * @param secret The secret to check.
@@ -4,16 +4,18 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
+ var AuthenticationService_1;
8
+ import { ActorType, Auditor, AuditOutcome } from '../../audit/index.js';
9
+ import { NIL_UUID } from '../../constants.js';
7
10
  import { ForbiddenError } from '../../errors/forbidden.error.js';
8
11
  import { InvalidCredentialsError } from '../../errors/index.js';
9
12
  import { InvalidTokenError } from '../../errors/invalid-token.error.js';
10
13
  import { NotFoundError } from '../../errors/not-found.error.js';
11
14
  import { NotImplementedError } from '../../errors/not-implemented.error.js';
12
- import { Singleton, afterResolve, inject, provide } from '../../injector/index.js';
15
+ import { afterResolve, inject, provide, Singleton } from '../../injector/index.js';
13
16
  import { KeyValueStore } from '../../key-value-store/key-value.store.js';
14
17
  import { Logger } from '../../logger/logger.js';
15
- import { DatabaseConfig } from '../../orm/server/index.js';
16
- import { EntityRepositoryConfig, injectRepository } from '../../orm/server/repository.js';
18
+ import { DatabaseConfig, EntityRepositoryConfig, injectRepository } from '../../orm/server/index.js';
17
19
  import { Alphabet } from '../../utils/alphabet.js';
18
20
  import { asyncHook } from '../../utils/async-hook/async-hook.js';
19
21
  import { decodeBase64, encodeBase64 } from '../../utils/base64.js';
@@ -78,14 +80,14 @@ const SIGNING_SECRETS_LENGTH = 64;
78
80
  * @template AuthenticationData Type of additional authentication data
79
81
  * @template AdditionalInitSecretResetData Type of additional secret reset data
80
82
  */
81
- let AuthenticationService = class AuthenticationService {
83
+ let AuthenticationService = AuthenticationService_1 = class AuthenticationService {
82
84
  #credentialsRepository = injectRepository(AuthenticationCredentials);
83
85
  #sessionRepository = injectRepository(AuthenticationSession);
84
86
  #authenticationSecretRequirementsValidator = inject(AuthenticationSecretRequirementsValidator);
85
87
  #authenticationAncillaryService = inject(AuthenticationAncillaryService, undefined, { optional: true });
86
88
  #keyValueStore = inject((KeyValueStore), 'authentication');
87
89
  #options = inject(AuthenticationServiceOptions);
88
- #logger = inject(Logger, 'authentication');
90
+ #logger = inject(Logger, 'Authentication');
89
91
  hooks = {
90
92
  beforeLogin: asyncHook(),
91
93
  afterLogin: asyncHook(),
@@ -203,76 +205,146 @@ let AuthenticationService = class AuthenticationService {
203
205
  * @param subject The subject to log in.
204
206
  * @param secret The secret to log in with.
205
207
  * @param data Additional authentication data.
208
+ * @param auditor Auditor for auditing.
206
209
  * @returns Token
207
210
  */
208
- async login(subject, secret, data) {
211
+ async login(subject, secret, data, auditor) {
212
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
209
213
  const authenticationResult = await this.authenticate(subject, secret);
210
214
  if (!authenticationResult.success) {
215
+ const actualSubject = await this.tryResolveSubject(subject) ?? subject;
216
+ await authAuditor.warn('login-failure', {
217
+ targetId: actualSubject,
218
+ targetType: 'User',
219
+ details: { providedSubject: subject },
220
+ });
211
221
  throw new InvalidCredentialsError();
212
222
  }
213
- await this.hooks.afterLogin.trigger({ subject: authenticationResult.subject });
223
+ await this.hooks.beforeLogin.trigger({ subject: authenticationResult.subject });
214
224
  const token = await this.getToken(authenticationResult.subject, data);
215
225
  await this.hooks.afterLogin.trigger({ subject: authenticationResult.subject });
226
+ const sessionId = token.jsonToken.payload.sessionId;
227
+ await authAuditor.info('login-success', {
228
+ actor: authenticationResult.subject,
229
+ actorType: ActorType.User,
230
+ targetId: authenticationResult.subject,
231
+ targetType: 'User',
232
+ network: { sessionId },
233
+ details: { sessionId },
234
+ });
216
235
  return token;
217
236
  }
218
237
  /**
219
238
  * Ends a session.
220
239
  * @param sessionId The id of the session to end.
240
+ * @param auditor Auditor for auditing.
221
241
  */
222
- async endSession(sessionId) {
242
+ async endSession(sessionId, auditor) {
243
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
244
+ const session = await this.#sessionRepository.tryLoad(sessionId);
245
+ if (isUndefined(session)) {
246
+ this.#logger.warn(`Session "${sessionId}" not found for logout.`);
247
+ return;
248
+ }
223
249
  const now = currentTimestamp();
224
250
  await this.#sessionRepository.update(sessionId, { end: now });
251
+ await authAuditor.info('logout', {
252
+ actor: session.subject,
253
+ actorType: ActorType.User,
254
+ targetId: session.subject,
255
+ targetType: 'User',
256
+ details: { sessionId },
257
+ });
225
258
  }
226
259
  /**
227
260
  * Refreshes a token.
228
261
  * @param refreshToken The refresh token to use.
229
262
  * @param authenticationData Additional authentication data.
230
263
  * @param options Options for refreshing the token.
264
+ * @param auditor Auditor for auditing.
231
265
  * @returns The token result.
232
266
  * @throws {InvalidTokenError} If the refresh token is invalid.
233
267
  */
234
- async refresh(refreshToken, authenticationData, { omitImpersonator = false } = {}) {
235
- const validatedRefreshToken = await this.validateRefreshToken(refreshToken);
236
- const sessionId = validatedRefreshToken.payload.sessionId;
237
- const session = await this.#sessionRepository.load(sessionId);
238
- const hash = await this.getHash(validatedRefreshToken.payload.secret, session.refreshTokenSalt);
239
- if (session.end <= currentTimestamp()) {
240
- throw new InvalidTokenError('Session is expired.');
268
+ async refresh(refreshToken, authenticationData, options = {}, auditor) {
269
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
270
+ try {
271
+ const validatedRefreshToken = await this.validateRefreshToken(refreshToken);
272
+ const sessionId = validatedRefreshToken.payload.sessionId;
273
+ const session = await this.#sessionRepository.load(sessionId);
274
+ const hash = await this.getHash(validatedRefreshToken.payload.secret, session.refreshTokenSalt);
275
+ if (session.end <= currentTimestamp()) {
276
+ throw new InvalidTokenError('Session is expired.');
277
+ }
278
+ if (!timingSafeBinaryEquals(hash, session.refreshTokenHash)) {
279
+ throw new InvalidTokenError('Invalid refresh token.');
280
+ }
281
+ const now = currentTimestamp();
282
+ const impersonator = (options.omitImpersonator == true) ? undefined : validatedRefreshToken.payload.impersonator;
283
+ const newEnd = now + this.refreshTokenTimeToLive;
284
+ const tokenPayload = await this.#authenticationAncillaryService?.getTokenPayload(session.subject, authenticationData, { action: GetTokenPayloadContextAction.Refresh });
285
+ const { token, jsonToken } = await this.createToken({ additionalTokenPayload: tokenPayload, subject: session.subject, sessionId, refreshTokenExpiration: newEnd, impersonator, timestamp: now });
286
+ const newRefreshToken = await this.createRefreshToken(validatedRefreshToken.payload.subject, sessionId, newEnd, { impersonator });
287
+ await this.#sessionRepository.update(sessionId, {
288
+ end: newEnd,
289
+ refreshTokenHashVersion: 1,
290
+ refreshTokenSalt: newRefreshToken.salt,
291
+ refreshTokenHash: newRefreshToken.hash,
292
+ });
293
+ await authAuditor.info('refresh-success', {
294
+ actor: session.subject,
295
+ actorType: ActorType.User,
296
+ targetId: session.subject,
297
+ targetType: 'User',
298
+ details: { sessionId },
299
+ });
300
+ return { token, jsonToken, refreshToken: newRefreshToken.token, omitImpersonatorRefreshToken: options.omitImpersonator };
241
301
  }
242
- if (!timingSafeBinaryEquals(hash, session.refreshTokenHash)) {
243
- throw new InvalidTokenError('Invalid refresh token.');
302
+ catch (error) {
303
+ await authAuditor.warn('refresh-failure', {
304
+ targetId: NIL_UUID,
305
+ targetType: 'User',
306
+ details: { reason: error.message },
307
+ });
308
+ throw error;
244
309
  }
245
- const now = currentTimestamp();
246
- const impersonator = omitImpersonator ? undefined : validatedRefreshToken.payload.impersonator;
247
- const newEnd = now + this.refreshTokenTimeToLive;
248
- const tokenPayload = await this.#authenticationAncillaryService?.getTokenPayload(session.subject, authenticationData, { action: GetTokenPayloadContextAction.Refresh });
249
- const { token, jsonToken } = await this.createToken({ additionalTokenPayload: tokenPayload, subject: session.subject, sessionId, refreshTokenExpiration: newEnd, impersonator, timestamp: now });
250
- const newRefreshToken = await this.createRefreshToken(validatedRefreshToken.payload.subject, sessionId, newEnd, { impersonator });
251
- await this.#sessionRepository.update(sessionId, {
252
- end: newEnd,
253
- refreshTokenHashVersion: 1,
254
- refreshTokenSalt: newRefreshToken.salt,
255
- refreshTokenHash: newRefreshToken.hash,
256
- });
257
- return { token, jsonToken, refreshToken: newRefreshToken.token, omitImpersonatorRefreshToken: omitImpersonator };
258
310
  }
259
311
  /**
260
312
  * Impersonates a subject.
261
- * @param impersonatorRoken The token of the impersonator.
313
+ * @param impersonatorToken The token of the impersonator.
262
314
  * @param impersonatorRefreshToken The refresh token of the impersonator.
263
315
  * @param subject The subject to impersonate.
264
316
  * @param authenticationData Additional authentication data.
317
+ * @param auditor Auditor for auditing.
265
318
  * @returns The token result.
266
319
  * @throws {ForbiddenError} If impersonation is not allowed.
267
320
  */
268
- async impersonate(impersonatorRoken, impersonatorRefreshToken, subject, authenticationData) {
269
- const validatedImpersonatorRoken = await this.validateToken(impersonatorRoken);
321
+ async impersonate(impersonatorToken, impersonatorRefreshToken, subject, authenticationData, auditor) {
322
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
323
+ const validatedImpersonatorToken = await this.validateToken(impersonatorToken);
270
324
  const validatedImpersonatorRefreshToken = await this.validateRefreshToken(impersonatorRefreshToken);
271
- const allowed = await this.#authenticationAncillaryService?.canImpersonate(validatedImpersonatorRoken.payload, subject, authenticationData) ?? false;
325
+ const allowed = await this.#authenticationAncillaryService?.canImpersonate(validatedImpersonatorToken.payload, subject, authenticationData) ?? false;
272
326
  if (!allowed) {
327
+ const impersonatedSubject = await this.tryResolveSubject(subject);
328
+ await authAuditor.warn('impersonate-failure', {
329
+ outcome: AuditOutcome.Denied,
330
+ actor: validatedImpersonatorToken.payload.subject,
331
+ actorType: ActorType.User,
332
+ targetId: impersonatedSubject ?? NIL_UUID,
333
+ targetType: 'User',
334
+ details: { impersonatedSubject: subject, reason: 'Impersonation forbidden.' },
335
+ });
273
336
  throw new ForbiddenError('Impersonation forbidden.');
274
337
  }
275
- const tokenResult = await this.getToken(subject, authenticationData, { impersonator: validatedImpersonatorRoken.payload.subject });
338
+ const tokenResult = await this.getToken(subject, authenticationData, { impersonator: validatedImpersonatorToken.payload.subject });
339
+ await authAuditor.info('impersonate-success', {
340
+ actor: validatedImpersonatorToken.payload.subject,
341
+ actorType: ActorType.User,
342
+ impersonator: validatedImpersonatorToken.payload.subject,
343
+ impersonatorType: ActorType.User,
344
+ targetId: tokenResult.jsonToken.payload.subject,
345
+ targetType: 'User',
346
+ details: { impersonatedSubject: subject },
347
+ });
276
348
  return {
277
349
  ...tokenResult,
278
350
  impersonatorRefreshToken,
@@ -283,21 +355,32 @@ let AuthenticationService = class AuthenticationService {
283
355
  * Unimpersonates a subject.
284
356
  * @param impersonatorRefreshToken The refresh token of the impersonator.
285
357
  * @param authenticationData Additional authentication data.
358
+ * @param auditor Auditor for auditing.
286
359
  * @returns The token result.
287
360
  */
288
- async unimpersonate(impersonatorRefreshToken, authenticationData) {
289
- return await this.refresh(impersonatorRefreshToken, authenticationData, { omitImpersonator: true });
361
+ async unimpersonate(impersonatorRefreshToken, authenticationData, auditor) {
362
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
363
+ const tokenResult = await this.refresh(impersonatorRefreshToken, authenticationData, { omitImpersonator: true }, auditor);
364
+ await authAuditor.info('unimpersonate-success', {
365
+ actor: tokenResult.jsonToken.payload.subject,
366
+ actorType: ActorType.User,
367
+ targetId: tokenResult.jsonToken.payload.subject,
368
+ targetType: 'User',
369
+ });
370
+ return tokenResult;
290
371
  }
291
372
  /**
292
373
  * Initializes a secret reset. This usually involves sending an email for verification.
293
374
  * @param subject The subject to reset the secret for.
294
375
  * @param data Additional data for the secret reset.
376
+ * @param auditor Auditor for auditing.
295
377
  * @throws {NotImplementedError} If no ancillary service is registered.
296
378
  */
297
- async initSecretReset(subject, data) {
379
+ async initSecretReset(subject, data, auditor) {
298
380
  if (isUndefined(this.#authenticationAncillaryService)) {
299
381
  throw new NotImplementedError('No ancillary service registered.');
300
382
  }
383
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
301
384
  const actualSubject = await this.tryResolveSubject(subject);
302
385
  if (isUndefined(actualSubject)) {
303
386
  this.#logger.warn(`Subject "${subject}" not found for secret reset.`);
@@ -315,31 +398,63 @@ let AuthenticationService = class AuthenticationService {
315
398
  ...data,
316
399
  };
317
400
  await this.#authenticationAncillaryService.handleInitSecretReset(initSecretResetData);
401
+ await authAuditor.info('init-secret-reset', {
402
+ targetId: actualSubject,
403
+ targetType: 'User',
404
+ });
318
405
  }
319
406
  /**
320
407
  * Changes a subject's secret.
321
408
  * @param subject The subject to change the secret for.
322
409
  * @param currentSecret The current secret.
323
410
  * @param newSecret The new secret.
411
+ * @param auditor Auditor for auditing.
324
412
  */
325
- async changeSecret(subject, currentSecret, newSecret) {
413
+ async changeSecret(subject, currentSecret, newSecret, auditor) {
414
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
326
415
  const authenticationResult = await this.authenticate(subject, currentSecret);
327
416
  if (!authenticationResult.success) {
417
+ const resolvedSubject = await this.tryResolveSubject(subject);
418
+ await authAuditor.warn('change-secret-failure', {
419
+ targetId: resolvedSubject ?? NIL_UUID,
420
+ targetType: 'User',
421
+ details: { providedSubject: subject },
422
+ });
328
423
  throw new InvalidCredentialsError();
329
424
  }
330
425
  await this.hooks.beforeChangeSecret.trigger({ subject });
331
426
  await this.setCredentials(subject, newSecret);
332
427
  await this.hooks.afterChangeSecret.trigger({ subject });
428
+ await authAuditor.info('change-secret-success', {
429
+ targetId: authenticationResult.subject,
430
+ targetType: 'User',
431
+ });
333
432
  }
334
433
  /**
335
434
  * Resets a secret.
336
435
  * @param tokenString The secret reset token.
337
436
  * @param newSecret The new secret.
437
+ * @param auditor Auditor for auditing.
338
438
  * @throws {InvalidTokenError} If the token is invalid.
339
439
  */
340
- async resetSecret(tokenString, newSecret) {
341
- const token = await this.validateSecretResetToken(tokenString);
342
- await this.setCredentials(token.payload.subject, newSecret);
440
+ async resetSecret(tokenString, newSecret, auditor) {
441
+ const authAuditor = auditor.fork(AuthenticationService_1.name);
442
+ try {
443
+ const token = await this.validateSecretResetToken(tokenString);
444
+ await this.setCredentials(token.payload.subject, newSecret);
445
+ await authAuditor.info('reset-secret-success', {
446
+ targetId: token.payload.subject,
447
+ targetType: 'User',
448
+ });
449
+ }
450
+ catch (error) {
451
+ await authAuditor.warn('reset-secret-failure', {
452
+ targetId: NIL_UUID,
453
+ targetType: 'User',
454
+ details: { reason: error.message },
455
+ });
456
+ throw error;
457
+ }
343
458
  }
344
459
  /**
345
460
  * Checks a secret against the requirements.
@@ -511,7 +626,7 @@ let AuthenticationService = class AuthenticationService {
511
626
  return new Uint8Array(hash);
512
627
  }
513
628
  };
514
- AuthenticationService = __decorate([
629
+ AuthenticationService = AuthenticationService_1 = __decorate([
515
630
  Singleton({
516
631
  providers: [
517
632
  provide(EntityRepositoryConfig, { useValue: { schema: 'authentication' } }),
@@ -1,6 +1,6 @@
1
1
  import type { Provider } from '../../injector/provider.js';
2
2
  import type { InjectionToken } from '../../injector/token.js';
3
- import type { DatabaseConfig } from '../../orm/server/module.js';
3
+ import { type DatabaseConfig } from '../../orm/server/index.js';
4
4
  import { AuthenticationAncillaryService } from './authentication-ancillary.service.js';
5
5
  import { AuthenticationService, AuthenticationServiceOptions } from './authentication.service.js';
6
6
  /**
@@ -1,5 +1,4 @@
1
- import { AuthenticationCredentials } from '../models/authentication-credentials.model.js';
2
- import { AuthenticationSession } from '../models/authentication-session.model.js';
3
- export declare const authenticationSchema: import("../../orm/server/database-schema.js").DatabaseSchema<"authentication">;
1
+ import { AuthenticationCredentials, AuthenticationSession } from '../models/index.js';
2
+ export declare const authenticationSchema: import("../../orm/server/index.js").DatabaseSchema<"authentication">;
4
3
  export declare const authenticationCredentials: import("../../orm/server/types.js").PgTableFromType<typeof AuthenticationCredentials, "authentication">;
5
4
  export declare const authenticationSession: import("../../orm/server/types.js").PgTableFromType<typeof AuthenticationSession, "authentication">;
@@ -1,6 +1,5 @@
1
- import { databaseSchema } from '../../orm/server/database-schema.js';
2
- import { AuthenticationCredentials } from '../models/authentication-credentials.model.js';
3
- import { AuthenticationSession } from '../models/authentication-session.model.js';
1
+ import { databaseSchema } from '../../orm/server/index.js';
2
+ import { AuthenticationCredentials, AuthenticationSession } from '../models/index.js';
4
3
  export const authenticationSchema = databaseSchema('authentication');
5
4
  export const authenticationCredentials = authenticationSchema.getTable(AuthenticationCredentials);
6
5
  export const authenticationSession = authenticationSchema.getTable(AuthenticationSession);
package/constants.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const NIL_UUID = "00000000-0000-0000-0000-000000000000";
package/constants.js ADDED
@@ -0,0 +1 @@
1
+ export const NIL_UUID = '00000000-0000-0000-0000-000000000000';