@tstdl/base 0.93.78 → 0.93.81

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 (39) hide show
  1. package/api/server/gateway.js +1 -1
  2. package/authentication/authentication.api.d.ts +9 -0
  3. package/authentication/authentication.api.js +3 -0
  4. package/authentication/client/authentication.service.d.ts +23 -15
  5. package/authentication/client/authentication.service.js +30 -21
  6. package/authentication/index.d.ts +1 -0
  7. package/authentication/index.js +1 -0
  8. package/authentication/models/authentication-credentials.model.d.ts +2 -2
  9. package/authentication/models/authentication-credentials.model.js +5 -5
  10. package/authentication/models/authentication-session.model.d.ts +2 -2
  11. package/authentication/models/authentication-session.model.js +3 -3
  12. package/authentication/models/subject.model.js +5 -3
  13. package/authentication/models/token-payload-base.model.d.ts +5 -1
  14. package/authentication/models/token-payload-base.model.js +10 -2
  15. package/authentication/models/token.model.d.ts +9 -1
  16. package/authentication/server/authentication-ancillary.service.d.ts +12 -15
  17. package/authentication/server/authentication-ancillary.service.js +3 -0
  18. package/authentication/server/authentication.api-controller.js +5 -5
  19. package/authentication/server/authentication.audit.d.ts +7 -5
  20. package/authentication/server/authentication.service.d.ts +32 -22
  21. package/authentication/server/authentication.service.js +116 -65
  22. package/authentication/server/drizzle/{0001_condemned_pretty_boy.sql → 0000_violet_callisto.sql} +34 -5
  23. package/authentication/server/drizzle/meta/0000_snapshot.json +500 -6
  24. package/authentication/server/drizzle/meta/_journal.json +2 -9
  25. package/authentication/types.d.ts +6 -0
  26. package/authentication/types.js +1 -0
  27. package/document-management/server/drizzle/{0000_ordinary_pretty_boy.sql → 0000_glamorous_lorna_dane.sql} +96 -76
  28. package/document-management/server/drizzle/meta/0000_snapshot.json +360 -142
  29. package/document-management/server/drizzle/meta/_journal.json +2 -16
  30. package/examples/api/authentication.js +3 -2
  31. package/examples/api/custom-authentication.js +11 -9
  32. package/orm/server/drizzle/schema-converter.js +53 -32
  33. package/package.json +1 -1
  34. package/authentication/server/drizzle/0000_calm_warlock.sql +0 -28
  35. package/authentication/server/drizzle/meta/0001_snapshot.json +0 -651
  36. package/document-management/server/drizzle/0001_lyrical_wong.sql +0 -123
  37. package/document-management/server/drizzle/0002_round_warbird.sql +0 -1
  38. package/document-management/server/drizzle/meta/0001_snapshot.json +0 -2728
  39. package/document-management/server/drizzle/meta/0002_snapshot.json +0 -2722
@@ -5,22 +5,8 @@
5
5
  {
6
6
  "idx": 0,
7
7
  "version": "7",
8
- "when": 1750253838549,
9
- "tag": "0000_ordinary_pretty_boy",
10
- "breakpoints": true
11
- },
12
- {
13
- "idx": 1,
14
- "version": "7",
15
- "when": 1764857079867,
16
- "tag": "0001_lyrical_wong",
17
- "breakpoints": true
18
- },
19
- {
20
- "idx": 2,
21
- "version": "7",
22
- "when": 1767824153882,
23
- "tag": "0002_round_warbird",
8
+ "when": 1767826943882,
9
+ "tag": "0000_glamorous_lorna_dane",
24
10
  "breakpoints": true
25
11
  }
26
12
  ]
@@ -17,7 +17,8 @@ import { timeout } from '../../utils/timing.js';
17
17
  import { Agent } from 'undici';
18
18
  async function serverTest() {
19
19
  const authenticationService = await injectAsync(AuthenticationServerService);
20
- await authenticationService.setCredentials('foobar', 'mysuperdupersecret-fvhc54w');
20
+ const subject = await authenticationService.resolveSubject({ subject: 'foobar' });
21
+ await authenticationService.setCredentials(subject, 'mysuperdupersecret-fvhc54w');
21
22
  }
22
23
  async function clientTest() {
23
24
  const authenticationService = inject(AuthenticationClientService);
@@ -25,7 +26,7 @@ async function clientTest() {
25
26
  await timeout(250); // allow server to initialize
26
27
  const passwordCheckResult = await authenticationService.checkSecret('123456');
27
28
  console.log({ 'password check for "123456"': passwordCheckResult });
28
- await authenticationService.login('foobar', 'mysuperdupersecret-fvhc54w');
29
+ await authenticationService.login({ subject: 'foobar' }, 'mysuperdupersecret-fvhc54w');
29
30
  authenticationService.token$.subscribe((token) => console.log({ token }));
30
31
  }
31
32
  async function test() {
@@ -18,7 +18,7 @@ import { AuthenticationAncillaryService, AuthenticationApiController, Authentica
18
18
  import { configureUndiciHttpClientAdapter } from '../../http/client/adapters/undici.adapter.js';
19
19
  import { configureHttpClient } from '../../http/client/module.js';
20
20
  import { configureNodeHttpServer } from '../../http/server/node/module.js';
21
- import { Singleton } from '../../injector/decorators.js';
21
+ import { Singleton } from '../../injector/index.js';
22
22
  import { inject, injectAsync } from '../../injector/inject.js';
23
23
  import { configureLocalMessageBus } from '../../message-bus/local/module.js';
24
24
  import { WebServerModule } from '../../module/modules/index.js';
@@ -65,17 +65,18 @@ __decorate([
65
65
  ], AuthenticationData.prototype, "deviceId", void 0);
66
66
  const CustomAuthenticationApiClient = getAuthenticationApiClient(CustomTokenPaylod, AuthenticationData, emptyObjectSchema);
67
67
  let CustomAuthenticationAncillaryService = class CustomAuthenticationAncillaryService extends AuthenticationAncillaryService {
68
- getTokenPayload(_subject, authenticationData) {
68
+ getTokenPayload(_subject, authenticationData, _context) {
69
69
  return { deviceRegistrationId: `registration:${authenticationData.deviceId}` };
70
70
  }
71
- resolveSubject() {
72
- throw new Error('Method not implemented.');
71
+ async resolveSubjects(data) {
72
+ const subjects = await this.subjectRepository.loadManyByQuery({ id: data.subject });
73
+ return subjects;
73
74
  }
74
- handleInitSecretReset() {
75
+ canImpersonate(_token, _subject, _authenticationData) {
75
76
  throw new Error('Method not implemented.');
76
77
  }
77
- canImpersonate() {
78
- throw new Error('Method not implemented.');
78
+ handleInitSecretReset() {
79
+ // send mail
79
80
  }
80
81
  };
81
82
  CustomAuthenticationAncillaryService = __decorate([
@@ -83,13 +84,14 @@ CustomAuthenticationAncillaryService = __decorate([
83
84
  ], CustomAuthenticationAncillaryService);
84
85
  async function serverTest() {
85
86
  const authenticationService = await injectAsync(AuthenticationServerService);
86
- await authenticationService.setCredentials('foobar', 'supersecret-dupidupudoo9275');
87
+ const subject = await authenticationService.resolveSubject({ subject: 'foobar' });
88
+ await authenticationService.setCredentials(subject, 'supersecret-dupidupudoo9275');
87
89
  }
88
90
  async function clientTest(application) {
89
91
  const authenticationService = inject(AuthenticationClientService);
90
92
  await timeout(1500); // allow server to initialize
91
93
  authenticationService.initialize();
92
- await authenticationService.login('foobar', 'supersecret-dupidupudoo9275');
94
+ await authenticationService.login({ subject: 'foobar' }, 'supersecret-dupidupudoo9275');
93
95
  authenticationService.token$.subscribe((token) => console.log({ token }));
94
96
  application.requestShutdown();
95
97
  }
@@ -33,19 +33,10 @@ export function getColumnDefinitionsMap(table) {
33
33
  return table[columnDefinitionsMapSymbol];
34
34
  }
35
35
  export function _getDrizzleTableFromType(type, fallbackSchemaName) {
36
- const metadata = reflectionRegistry.getMetadata(type);
37
- assertDefined(metadata, `Type ${type.name} does not have reflection metadata.`);
38
- const tableReflectionDatas = [];
39
- for (let currentMetadata = metadata; isNotNullOrUndefined(currentMetadata?.parent); currentMetadata = reflectionRegistry.getMetadata(currentMetadata.parent)) {
40
- const tableReflectionData = currentMetadata.data.tryGet('orm');
41
- if (isDefined(tableReflectionData)) {
42
- tableReflectionDatas.push(tableReflectionData);
43
- }
44
- }
36
+ const tableReflectionDatas = getTableReflectionDatas(type);
45
37
  const mergedTableReflectionData = tableReflectionDatas.reduceRight((merged, data) => ({ ...merged, ...data }), {});
46
- const tableReflectionData = tableReflectionDatas[0];
47
38
  const schema = assertDefinedPass(mergedTableReflectionData.schema ?? fallbackSchemaName, 'Table schema not provided');
48
- const tableName = tableReflectionData?.name ?? getDefaultTableName(type);
39
+ const tableName = getTableName(type);
49
40
  const dbSchema = getDbSchema(schema);
50
41
  const columnDefinitions = getPostgresColumnEntries(type, dbSchema, tableName);
51
42
  const columnDefinitionsMap = new Map(columnDefinitions.map((column) => [column.objectPath.path, column]));
@@ -194,7 +185,7 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
194
185
  const foreignTable = getDrizzleTableFromType(tenantReferenceData.target(), dbSchema.schemaName);
195
186
  const nonTenantColumn = tenantReferenceData.targetColumn ?? 'id';
196
187
  return foreignKey({
197
- name: getForeignKeyName(tableName, [nonTenantColumn]),
188
+ name: getForeignKeyName(tableName, getTableName(tenantReferenceData.target()), [nonTenantColumn]),
198
189
  columns: [getColumn(table, 'tenantId'), getColumn(table, columnDefinition.name)],
199
190
  foreignColumns: [getColumn(foreignTable, 'tenantId'), getColumn(foreignTable, nonTenantColumn)],
200
191
  });
@@ -204,7 +195,7 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
204
195
  return tableReflectionData.foreignKeys?.map((foreignKeyData) => {
205
196
  const foreignTable = getDrizzleTableFromType(foreignKeyData.target(), dbSchema.schemaName);
206
197
  return foreignKey({
207
- name: foreignKeyData.options?.name ?? getForeignKeyName(tableName, foreignKeyData.columns, { naming: foreignKeyData.options?.naming }),
198
+ name: foreignKeyData.options?.name ?? getForeignKeyName(tableName, getTableName(foreignKeyData.target()), foreignKeyData.columns, { naming: foreignKeyData.options?.naming }),
208
199
  columns: foreignKeyData.columns.map((column) => getColumn(table, column)),
209
200
  foreignColumns: foreignKeyData.foreignColumns.map((column) => getColumn(foreignTable, column)),
210
201
  });
@@ -227,6 +218,25 @@ export function _getDrizzleTableFromType(type, fallbackSchemaName) {
227
218
  drizzleSchema[columnDefinitionsMapSymbol] = columnDefinitionsMap;
228
219
  return drizzleSchema;
229
220
  }
221
+ function unwrapSchema(schema) {
222
+ let nullable = false;
223
+ let array = false;
224
+ let currentSchema = schema;
225
+ while (true) {
226
+ if ((currentSchema instanceof NullableSchema) || (currentSchema instanceof OptionalSchema)) {
227
+ nullable = true;
228
+ currentSchema = currentSchema.schema;
229
+ }
230
+ else if (currentSchema instanceof ArraySchema) {
231
+ array = true;
232
+ currentSchema = currentSchema.itemSchema;
233
+ }
234
+ else {
235
+ break;
236
+ }
237
+ }
238
+ return { schema: currentSchema, nullable, array };
239
+ }
230
240
  function getPostgresColumnEntries(type, dbSchema, tableName, path = new JsonPath({ dollar: false }), prefix = '') {
231
241
  const metadata = reflectionRegistry.getMetadata(type);
232
242
  assertDefined(metadata, `Type ${type.name} does not have reflection metadata (path: ${path.toString()}).`);
@@ -269,23 +279,8 @@ function getPostgresColumnEntries(type, dbSchema, tableName, path = new JsonPath
269
279
  return entries;
270
280
  }
271
281
  function getPostgresColumn(tableName, columnName, dbSchema, propertySchema, reflectionData, options, context) {
272
- let nullable = false;
273
- let array = false;
274
- let baseSchema = propertySchema;
275
- while (true) {
276
- if ((baseSchema instanceof NullableSchema) || (baseSchema instanceof OptionalSchema)) {
277
- nullable = true;
278
- baseSchema = baseSchema.schema;
279
- }
280
- else if (baseSchema instanceof ArraySchema) {
281
- array = true;
282
- baseSchema = baseSchema.itemSchema;
283
- }
284
- else {
285
- break;
286
- }
287
- }
288
- let column = getPostgresBaseColumn(columnName, dbSchema, baseSchema, reflectionData, context);
282
+ const { schema, nullable, array } = unwrapSchema(propertySchema);
283
+ let column = getPostgresBaseColumn(columnName, dbSchema, schema, reflectionData, context);
289
284
  if (array) {
290
285
  column = column.array();
291
286
  }
@@ -371,8 +366,34 @@ function getIndexName(tableName, columnsOrBaseName, options) {
371
366
  function getUniqueName(tableName, columnsOrBaseName, options) {
372
367
  return getIdentifier(tableName, columnsOrBaseName, 'unique', options);
373
368
  }
374
- function getForeignKeyName(tableName, columnsOrBaseName, options) {
375
- return getIdentifier(tableName, columnsOrBaseName, 'fkey', options);
369
+ function getForeignKeyName(tableName, foreignTableName, columnsOrBaseName, options) {
370
+ const middle = isString(columnsOrBaseName) ? columnsOrBaseName : getColumnNames(columnsOrBaseName).join('_');
371
+ const identifier = `${getTablePrefix(tableName, options?.naming)}_${middle}_${getTablePrefix(foreignTableName, options?.naming)}_fkey`;
372
+ if (identifier.length > 63) {
373
+ if (options?.naming != 'abbreviated-table') {
374
+ return getForeignKeyName(tableName, foreignTableName, columnsOrBaseName, { naming: 'abbreviated-table' });
375
+ }
376
+ throw new Error(`Identifier "${identifier}" for table "${tableName}" is too long. Maximum length is 63 characters.`);
377
+ }
378
+ console.log(tableName, foreignTableName, columnsOrBaseName, 'Foreign key name:', identifier);
379
+ return identifier;
380
+ }
381
+ function getTableName(type) {
382
+ const tableReflectionDatas = getTableReflectionDatas(type);
383
+ const tableReflectionData = tableReflectionDatas[0];
384
+ return tableReflectionData?.name ?? getDefaultTableName(type);
385
+ }
386
+ function getTableReflectionDatas(type) {
387
+ const metadata = reflectionRegistry.getMetadata(type);
388
+ assertDefined(metadata, `Type ${type.name} does not have reflection metadata.`);
389
+ const tableReflectionDatas = [];
390
+ for (let currentMetadata = metadata; isNotNullOrUndefined(currentMetadata?.parent); currentMetadata = reflectionRegistry.getMetadata(currentMetadata.parent)) {
391
+ const tableReflectionData = currentMetadata.data.tryGet('orm');
392
+ if (isDefined(tableReflectionData)) {
393
+ tableReflectionDatas.push(tableReflectionData);
394
+ }
395
+ }
396
+ return tableReflectionDatas;
376
397
  }
377
398
  function getIdentifier(tableName, columnsOrBaseName, suffix, options) {
378
399
  const middle = isString(columnsOrBaseName) ? columnsOrBaseName : getColumnNames(columnsOrBaseName).join('_');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tstdl/base",
3
- "version": "0.93.78",
3
+ "version": "0.93.81",
4
4
  "author": "Patrick Hein",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,28 +0,0 @@
1
- CREATE TABLE "authentication"."credentials" (
2
- "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
- "subject" text NOT NULL,
4
- "hash_version" integer NOT NULL,
5
- "salt" "bytea" NOT NULL,
6
- "hash" "bytea" NOT NULL,
7
- "revision" integer NOT NULL,
8
- "revision_timestamp" timestamp with time zone NOT NULL,
9
- "create_timestamp" timestamp with time zone NOT NULL,
10
- "delete_timestamp" timestamp with time zone,
11
- "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL,
12
- CONSTRAINT "credentials_subject_unique" UNIQUE("subject")
13
- );
14
- --> statement-breakpoint
15
- CREATE TABLE "authentication"."session" (
16
- "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
17
- "subject" text NOT NULL,
18
- "begin" timestamp with time zone NOT NULL,
19
- "end" timestamp with time zone NOT NULL,
20
- "refresh_token_hash_version" integer NOT NULL,
21
- "refresh_token_salt" "bytea" NOT NULL,
22
- "refresh_token_hash" "bytea" NOT NULL,
23
- "revision" integer NOT NULL,
24
- "revision_timestamp" timestamp with time zone NOT NULL,
25
- "create_timestamp" timestamp with time zone NOT NULL,
26
- "delete_timestamp" timestamp with time zone,
27
- "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL
28
- );