itlab-internal-services 2.16.5 → 2.16.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.
Files changed (47) hide show
  1. package/dist/classes/document/index.d.ts +1 -0
  2. package/dist/classes/document/index.js +3 -1
  3. package/dist/classes/document/likeable-document.class.d.ts +3 -1
  4. package/dist/classes/document/likeable-document.class.js +5 -1
  5. package/dist/classes/document/timestamps-document.class.d.ts +200 -0
  6. package/dist/classes/document/timestamps-document.class.js +27 -0
  7. package/dist/classes/document/viewable-document.class.d.ts +3 -1
  8. package/dist/classes/document/viewable-document.class.js +5 -1
  9. package/dist/classes/entity-map.class.d.ts +21 -0
  10. package/dist/classes/entity-map.class.js +28 -0
  11. package/dist/classes/fetch-options/base-options.class.d.ts +2 -0
  12. package/dist/classes/fetch-options/base-options.class.js +17 -0
  13. package/dist/classes/fetch-options/comments-options.class.d.ts +8 -0
  14. package/dist/classes/fetch-options/comments-options.class.js +14 -0
  15. package/dist/classes/fetch-options/content-options.class.d.ts +8 -1
  16. package/dist/classes/fetch-options/content-options.class.js +14 -0
  17. package/dist/classes/fetch-options/drafted-options.class.d.ts +7 -2
  18. package/dist/classes/fetch-options/drafted-options.class.js +12 -1
  19. package/dist/classes/fetch-options/index.d.ts +7 -6
  20. package/dist/classes/fetch-options/index.js +21 -13
  21. package/dist/classes/fetch-options/liked-by-options.class.d.ts +7 -0
  22. package/dist/classes/fetch-options/liked-by-options.class.js +24 -0
  23. package/dist/classes/fetch-options/timestamps-options.class.d.ts +12 -0
  24. package/dist/classes/fetch-options/timestamps-options.class.js +40 -0
  25. package/dist/classes/fetch-options/viewed-by-options.class.d.ts +10 -2
  26. package/dist/classes/fetch-options/viewed-by-options.class.js +32 -1
  27. package/dist/classes/index.d.ts +1 -0
  28. package/dist/classes/index.js +3 -1
  29. package/dist/classes/task-manager.class.d.ts +0 -38
  30. package/dist/classes/task-manager.class.js +0 -58
  31. package/dist/decorators/authenticated-account.decorator.d.ts +1 -1
  32. package/dist/index.d.ts +0 -1
  33. package/dist/index.js +0 -1
  34. package/dist/modules/services/providers/accounts.service.d.ts +15 -0
  35. package/dist/modules/services/providers/accounts.service.js +33 -0
  36. package/dist/modules/services/providers/mail/dtos/event-cancel-mail.dto.d.ts +4 -0
  37. package/dist/pipes/restricted-fields.pipe.d.ts +1 -24
  38. package/dist/pipes/restricted-fields.pipe.js +23 -21
  39. package/dist/types/has-timestamps.type.d.ts +4 -0
  40. package/dist/types/has-timestamps.type.js +2 -0
  41. package/dist/types/index.d.ts +1 -0
  42. package/dist/types/index.js +1 -0
  43. package/package.json +1 -1
  44. package/dist/interceptors/attribute-sanitizer.interceptor.d.ts +0 -68
  45. package/dist/interceptors/attribute-sanitizer.interceptor.js +0 -154
  46. package/dist/interceptors/index.d.ts +0 -1
  47. package/dist/interceptors/index.js +0 -17
@@ -10,6 +10,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.LikedByOptions = LikedByOptions;
13
+ exports.populateLikedBy = populateLikedBy;
13
14
  const swagger_1 = require("@nestjs/swagger");
14
15
  const class_validator_1 = require("class-validator");
15
16
  const transform_1 = require("../../transform");
@@ -22,5 +23,28 @@ function LikedByOptions(Base) {
22
23
  (0, class_validator_1.IsOptional)(),
23
24
  __metadata("design:type", Boolean)
24
25
  ], LikedByOptions.prototype, "includeLikedBy", void 0);
26
+ __decorate([
27
+ (0, swagger_1.ApiPropertyOptional)({}),
28
+ (0, transform_1.BooleanTransform)(),
29
+ (0, class_validator_1.IsOptional)(),
30
+ __metadata("design:type", Boolean)
31
+ ], LikedByOptions.prototype, "includeLikedByIds", void 0);
25
32
  return LikedByOptions;
26
33
  }
34
+ async function populateLikedBy(options, items, accountsService) {
35
+ if (options.includeLikedBy) {
36
+ const userMap = await accountsService.getUserMap(items.map((item) => item._likedBy));
37
+ items.forEach((item) => {
38
+ item.likedBy = userMap.getMultiple(item._likedBy);
39
+ });
40
+ }
41
+ items.forEach((item) => {
42
+ item.likes = Math.max(item._likedBy.length, item.likes); // TODO: Tmp Fix
43
+ if (!options.includeLikedBy)
44
+ item.likedBy = undefined;
45
+ if (!options.includeLikedByIds)
46
+ item._likedBy = undefined;
47
+ if (!(options.includeLikedBy || options.includeLikedByIds))
48
+ item.likes = undefined;
49
+ });
50
+ }
@@ -0,0 +1,12 @@
1
+ import { HasTimestamps } from '../../types';
2
+ export declare function TimestampsOptions<TBase extends new (...args: any[]) => any>(Base: TBase, options: {
3
+ requiredPermissions: string[];
4
+ }): {
5
+ new (...args: any[]): {
6
+ [x: string]: any;
7
+ includeTimestamps?: boolean;
8
+ };
9
+ } & TBase;
10
+ export declare function populateTimestamps<TOptions extends {
11
+ includeTimestamps?: boolean;
12
+ }, TItems extends HasTimestamps>(options: TOptions, items: TItems[], additionalKeys?: (keyof TItems)[]): void;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TimestampsOptions = TimestampsOptions;
13
+ exports.populateTimestamps = populateTimestamps;
14
+ const swagger_1 = require("@nestjs/swagger");
15
+ const class_validator_1 = require("class-validator");
16
+ const pipes_1 = require("../../pipes");
17
+ const transform_1 = require("../../transform");
18
+ function TimestampsOptions(Base, options) {
19
+ class TimestampsOptions extends Base {
20
+ }
21
+ __decorate([
22
+ (0, swagger_1.ApiPropertyOptional)({}),
23
+ (0, transform_1.BooleanTransform)(),
24
+ (0, class_validator_1.IsOptional)(),
25
+ (0, pipes_1.Restricted)(options.requiredPermissions),
26
+ __metadata("design:type", Boolean)
27
+ ], TimestampsOptions.prototype, "includeTimestamps", void 0);
28
+ return TimestampsOptions;
29
+ }
30
+ function populateTimestamps(options, items, additionalKeys = []) {
31
+ if (!options.includeTimestamps) {
32
+ items.forEach((item) => {
33
+ item.createdAt = undefined;
34
+ item.updatedAt = undefined;
35
+ additionalKeys.forEach((key) => {
36
+ item[key] = undefined;
37
+ });
38
+ });
39
+ }
40
+ }
@@ -1,9 +1,17 @@
1
- export declare function ViewedByOptions<TBase extends new (...args: any[]) => any>(Base: TBase, options?: {
2
- requiredPermissions?: string[];
1
+ import { AccountsService } from '../../modules';
2
+ import { IsViewable } from '../../types';
3
+ export declare function ViewedByOptions<TBase extends new (...args: any[]) => any>(Base: TBase, options: {
4
+ requiredPermissions: string[];
3
5
  }): {
4
6
  new (...args: any[]): {
5
7
  [x: string]: any;
6
8
  includeViewedBy?: boolean;
9
+ includeViewedByIds?: boolean;
7
10
  viewedBy?: string;
8
11
  };
9
12
  } & TBase;
13
+ export declare function populateViewedBy(options: {
14
+ includeViewedBy?: boolean;
15
+ includeViewedByIds?: boolean;
16
+ viewedBy?: string;
17
+ }, items: IsViewable[], accountsService: AccountsService): Promise<void>;
@@ -10,8 +10,10 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ViewedByOptions = ViewedByOptions;
13
+ exports.populateViewedBy = populateViewedBy;
13
14
  const swagger_1 = require("@nestjs/swagger");
14
15
  const class_validator_1 = require("class-validator");
16
+ const rxjs_1 = require("rxjs");
15
17
  const pipes_1 = require("../../pipes");
16
18
  const transform_1 = require("../../transform");
17
19
  function ViewedByOptions(Base, options) {
@@ -21,8 +23,37 @@ function ViewedByOptions(Base, options) {
21
23
  (0, swagger_1.ApiPropertyOptional)({}),
22
24
  (0, transform_1.BooleanTransform)(),
23
25
  (0, class_validator_1.IsOptional)(),
24
- (0, pipes_1.Restricted)(options === null || options === void 0 ? void 0 : options.requiredPermissions),
26
+ (0, pipes_1.Restricted)(options.requiredPermissions),
25
27
  __metadata("design:type", Boolean)
26
28
  ], ViewedByOptions.prototype, "includeViewedBy", void 0);
29
+ __decorate([
30
+ (0, swagger_1.ApiPropertyOptional)({}),
31
+ (0, transform_1.BooleanTransform)(),
32
+ (0, class_validator_1.IsOptional)(),
33
+ (0, pipes_1.Restricted)(options.requiredPermissions),
34
+ __metadata("design:type", Boolean)
35
+ ], ViewedByOptions.prototype, "includeViewedByIds", void 0);
27
36
  return ViewedByOptions;
28
37
  }
38
+ async function populateViewedBy(options, items, accountsService) {
39
+ if (options.viewedBy) {
40
+ items.forEach((item) => {
41
+ item.addView(options.viewedBy).then(rxjs_1.noop);
42
+ });
43
+ }
44
+ if (options.includeViewedBy) {
45
+ const userMap = await accountsService.getUserMap(items.map((item) => item._viewedBy));
46
+ items.forEach((item) => {
47
+ item.viewedBy = userMap.getMultiple(item._viewedBy);
48
+ });
49
+ }
50
+ items.forEach((item) => {
51
+ item.views = Math.max(item._viewedBy.length, item.views); // TODO: Tmp Fix
52
+ if (!options.includeViewedBy)
53
+ item.viewedBy = undefined;
54
+ if (!options.includeViewedByIds)
55
+ item._viewedBy = undefined;
56
+ if (!(options.includeViewedBy || options.includeViewedByIds))
57
+ item.views = undefined;
58
+ });
59
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './document';
2
2
  export * from './fetch-options';
3
3
  export { DocumentMerger } from './document-merger.class';
4
+ export { EntityMap } from './entity-map.class';
4
5
  export { ReportCategory } from './report-category.class';
5
6
  export { TaskManager } from './task-manager.class';
@@ -14,11 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.TaskManager = exports.ReportCategory = exports.DocumentMerger = void 0;
17
+ exports.TaskManager = exports.ReportCategory = exports.EntityMap = exports.DocumentMerger = void 0;
18
18
  __exportStar(require("./document"), exports);
19
19
  __exportStar(require("./fetch-options"), exports);
20
20
  var document_merger_class_1 = require("./document-merger.class");
21
21
  Object.defineProperty(exports, "DocumentMerger", { enumerable: true, get: function () { return document_merger_class_1.DocumentMerger; } });
22
+ var entity_map_class_1 = require("./entity-map.class");
23
+ Object.defineProperty(exports, "EntityMap", { enumerable: true, get: function () { return entity_map_class_1.EntityMap; } });
22
24
  var report_category_class_1 = require("./report-category.class");
23
25
  Object.defineProperty(exports, "ReportCategory", { enumerable: true, get: function () { return report_category_class_1.ReportCategory; } });
24
26
  var task_manager_class_1 = require("./task-manager.class");
@@ -1,5 +1,3 @@
1
- import { Account, User } from '../models';
2
- import { AccountsService } from '../modules';
3
1
  /**
4
2
  * TaskManager is a utility class that collects asynchronous tasks
5
3
  * and executes them in parallel.
@@ -17,22 +15,6 @@ import { AccountsService } from '../modules';
17
15
  */
18
16
  export declare class TaskManager {
19
17
  private tasks;
20
- /**
21
- * Fetches all users for the given ID groups and returns a mapping.
22
- * Ensures each user is fetched only once.
23
- * @param userIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
24
- * @param accountsService Service responsible for fetching users
25
- * @returns Map of userId -> user
26
- */
27
- static fetchAndMapUsers(userIdGroups: string[][], accountsService: AccountsService): Promise<FetchMap<User>>;
28
- /**
29
- * Fetches all users for the given ID groups and returns a mapping.
30
- * Ensures each user is fetched only once.
31
- * @param accountIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
32
- * @param accountsService Service responsible for fetching users
33
- * @returns Map of userId -> user
34
- */
35
- static fetchAndMapAccounts(accountIdGroups: string[][], accountsService: AccountsService): Promise<FetchMap<Account>>;
36
18
  /**
37
19
  * Adds a new asynchronous task to the queue.
38
20
  *
@@ -53,23 +35,3 @@ export declare class TaskManager {
53
35
  */
54
36
  clear(): void;
55
37
  }
56
- declare class FetchMap<T extends User | Account> {
57
- private readonly map;
58
- constructor(items?: T[]);
59
- /**
60
- * Maps a single ID to an user/account object using a user/account Map.
61
- * @param id ID of user/account to map
62
- * @param map Map of id -> user/account object
63
- * @returns user/account object
64
- */
65
- get(id: string): T;
66
- /**
67
- * Maps an array of IDs to user/account objects using a user/account Map.
68
- * Filters out any IDs that don’t have a corresponding entity.
69
- * @param ids Array of user/account IDs to map
70
- * @param map Map of id -> user/account object
71
- * @returns Array of user/account objects
72
- */
73
- getMultiple(ids: string[]): T[];
74
- }
75
- export {};
@@ -20,40 +20,6 @@ class TaskManager {
20
20
  constructor() {
21
21
  this.tasks = [];
22
22
  }
23
- /**
24
- * Fetches all users for the given ID groups and returns a mapping.
25
- * Ensures each user is fetched only once.
26
- * @param userIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
27
- * @param accountsService Service responsible for fetching users
28
- * @returns Map of userId -> user
29
- */
30
- static async fetchAndMapUsers(userIdGroups, accountsService) {
31
- // Collect all unique user IDs across all groups
32
- const uniqueUserIds = new Set(userIdGroups.flat());
33
- if (uniqueUserIds.size === 0)
34
- return new FetchMap();
35
- // Fetch all users once
36
- const userCollection = await accountsService.getUserCollection(Array.from(uniqueUserIds));
37
- // Build a map for quick lookup
38
- return new FetchMap(userCollection);
39
- }
40
- /**
41
- * Fetches all users for the given ID groups and returns a mapping.
42
- * Ensures each user is fetched only once.
43
- * @param accountIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
44
- * @param accountsService Service responsible for fetching users
45
- * @returns Map of userId -> user
46
- */
47
- static async fetchAndMapAccounts(accountIdGroups, accountsService) {
48
- // Collect all unique user IDs across all groups
49
- const uniqueAccountIds = new Set(accountIdGroups.flat());
50
- if (uniqueAccountIds.size === 0)
51
- return new FetchMap();
52
- // Fetch all users once
53
- const accountCollection = await accountsService.getAccountCollection(Array.from(uniqueAccountIds));
54
- // Build a map for quick lookup
55
- return new FetchMap(accountCollection);
56
- }
57
23
  /**
58
24
  * Adds a new asynchronous task to the queue.
59
25
  *
@@ -81,27 +47,3 @@ class TaskManager {
81
47
  }
82
48
  }
83
49
  exports.TaskManager = TaskManager;
84
- class FetchMap {
85
- constructor(items = []) {
86
- this.map = new Map(items.map((item) => [item.id, item]));
87
- }
88
- /**
89
- * Maps a single ID to an user/account object using a user/account Map.
90
- * @param id ID of user/account to map
91
- * @param map Map of id -> user/account object
92
- * @returns user/account object
93
- */
94
- get(id) {
95
- return this.map.get(id);
96
- }
97
- /**
98
- * Maps an array of IDs to user/account objects using a user/account Map.
99
- * Filters out any IDs that don’t have a corresponding entity.
100
- * @param ids Array of user/account IDs to map
101
- * @param map Map of id -> user/account object
102
- * @returns Array of user/account objects
103
- */
104
- getMultiple(ids) {
105
- return ids.map((id) => this.map.get(id)).filter(Boolean);
106
- }
107
- }
@@ -14,4 +14,4 @@ import { Account } from '../models';
14
14
  * @param {ExecutionContext} executionContext - The context of the current request.
15
15
  * @returns {Account[keyof Account] | Account} The requested account attribute or full account object.
16
16
  */
17
- export declare const AuthenticatedAccount: (...dataOrPipes: (keyof Account | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>>)[]) => ParameterDecorator;
17
+ export declare const AuthenticatedAccount: (...dataOrPipes: (import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | keyof Account)[]) => ParameterDecorator;
package/dist/index.d.ts CHANGED
@@ -3,7 +3,6 @@ export * from './controllers';
3
3
  export * from './decorators';
4
4
  export * from './exceptions';
5
5
  export * from './functions';
6
- export * from './interceptors';
7
6
  export * from './middleware';
8
7
  export * from './models';
9
8
  export * from './modules';
package/dist/index.js CHANGED
@@ -20,7 +20,6 @@ __exportStar(require("./controllers"), exports);
20
20
  __exportStar(require("./decorators"), exports);
21
21
  __exportStar(require("./exceptions"), exports);
22
22
  __exportStar(require("./functions"), exports);
23
- __exportStar(require("./interceptors"), exports);
24
23
  __exportStar(require("./middleware"), exports);
25
24
  __exportStar(require("./models"), exports);
26
25
  __exportStar(require("./modules"), exports);
@@ -1,4 +1,5 @@
1
1
  import { ConfigService } from '@nestjs/config';
2
+ import { EntityMap } from '../../../classes';
2
3
  import { Account, User } from '../../../models';
3
4
  import { AuthenticationModuleOptions } from '../../authentication';
4
5
  import { BaseHttpService } from '../base-http.service';
@@ -35,6 +36,13 @@ export declare class AccountsService extends BaseHttpService {
35
36
  * @returns {Promise<Account[]>} Resolves to an array of account objects (empty if none found).
36
37
  */
37
38
  getAccountCollection(accountIds: string[]): Promise<Account[]>;
39
+ /**
40
+ * Fetches all accounts for the given ID groups and returns a mapping.
41
+ * Ensures each account is fetched only once.
42
+ * @param accountIdGroups Array of arrays of account IDs (e.g., authors, likedBy, viewedBy)
43
+ * @returns Map of accountId -> Account
44
+ */
45
+ getAccountMap(accountIdGroups: string[][]): Promise<EntityMap<Account>>;
38
46
  /**
39
47
  * Retrieves a single user entry derived from an account.
40
48
  *
@@ -49,4 +57,11 @@ export declare class AccountsService extends BaseHttpService {
49
57
  * @returns {Promise<User[]>} Resolves to a list of users (empty array if none found).
50
58
  */
51
59
  getUserCollection(userIds: string[]): Promise<User[]>;
60
+ /**
61
+ * Fetches all users for the given ID groups and returns a mapping.
62
+ * Ensures each user is fetched only once.
63
+ * @param userIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
64
+ * @returns Map of userId -> user
65
+ */
66
+ getUserMap(userIdGroups: string[][]): Promise<EntityMap<User>>;
52
67
  }
@@ -16,6 +16,7 @@ exports.AccountsService = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const config_1 = require("@nestjs/config");
18
18
  const itlab_functions_1 = require("itlab-functions");
19
+ const classes_1 = require("../../../classes");
19
20
  const authentication_1 = require("../../authentication");
20
21
  const base_http_service_1 = require("../base-http.service");
21
22
  const base_urls_1 = require("../base-urls");
@@ -65,6 +66,22 @@ let AccountsService = class AccountsService extends base_http_service_1.BaseHttp
65
66
  });
66
67
  return (await Promise.all(chunkedAccounts)).flat();
67
68
  }
69
+ /**
70
+ * Fetches all accounts for the given ID groups and returns a mapping.
71
+ * Ensures each account is fetched only once.
72
+ * @param accountIdGroups Array of arrays of account IDs (e.g., authors, likedBy, viewedBy)
73
+ * @returns Map of accountId -> Account
74
+ */
75
+ async getAccountMap(accountIdGroups) {
76
+ // Collect all unique account IDs across all groups
77
+ const uniqueAccountIds = new Set(accountIdGroups.flat());
78
+ if (uniqueAccountIds.size === 0)
79
+ return new classes_1.EntityMap();
80
+ // Fetch all accounts once
81
+ const accountCollection = await this.getAccountCollection(Array.from(uniqueAccountIds));
82
+ // Build a map for quick lookup
83
+ return new classes_1.EntityMap(accountCollection);
84
+ }
68
85
  /**
69
86
  * Retrieves a single user entry derived from an account.
70
87
  *
@@ -89,6 +106,22 @@ let AccountsService = class AccountsService extends base_http_service_1.BaseHttp
89
106
  });
90
107
  return (await Promise.all(chunkedUsers)).flat();
91
108
  }
109
+ /**
110
+ * Fetches all users for the given ID groups and returns a mapping.
111
+ * Ensures each user is fetched only once.
112
+ * @param userIdGroups Array of arrays of user IDs (e.g., authors, likedBy, viewedBy)
113
+ * @returns Map of userId -> user
114
+ */
115
+ async getUserMap(userIdGroups) {
116
+ // Collect all unique user IDs across all groups
117
+ const uniqueUserIds = new Set(userIdGroups.flat());
118
+ if (uniqueUserIds.size === 0)
119
+ return new classes_1.EntityMap();
120
+ // Fetch all users once
121
+ const userCollection = await this.getUserCollection(Array.from(uniqueUserIds));
122
+ // Build a map for quick lookup
123
+ return new classes_1.EntityMap(userCollection);
124
+ }
92
125
  };
93
126
  exports.AccountsService = AccountsService;
94
127
  exports.AccountsService = AccountsService = __decorate([
@@ -4,6 +4,10 @@ import { MailRecipient } from '../models';
4
4
  */
5
5
  export type EventCancelMailDto = {
6
6
  recipient: MailRecipient;
7
+ /**
8
+ * Mode of participation (e.g., in person, online).
9
+ */
10
+ participation?: string;
7
11
  /**
8
12
  * Title of the event that has been cancelled.
9
13
  * @example "Meetup"
@@ -1,8 +1,3 @@
1
- import { ArgumentMetadata, PipeTransform } from '@nestjs/common';
2
- import { Reflector } from '@nestjs/core';
3
- import { Request } from 'express';
4
- import { Account } from '../models';
5
- import { AuthenticationModuleOptions } from '../modules';
6
1
  /**
7
2
  * @Restricted Decorator
8
3
  *
@@ -14,22 +9,4 @@ import { AuthenticationModuleOptions } from '../modules';
14
9
  * @param {...string[]} perms - One or more permissions required to retain this field.
15
10
  */
16
11
  export declare function Restricted(perms?: string | string[]): PropertyDecorator;
17
- /**
18
- * RestrictedFieldsPipe
19
- *
20
- * Global pipe that inspects incoming DTOs for properties decorated with `@Restricted`.
21
- * If the current request's account lacks the required permissions,
22
- * the corresponding properties are stripped from the DTO.
23
- *
24
- * This ensures that sensitive fields are never accidentally
25
- * processed further down the request lifecycle.
26
- */
27
- export declare class RestrictedFieldsPipe implements PipeTransform {
28
- private readonly request;
29
- private readonly authenticationOptions;
30
- private readonly reflector;
31
- constructor(request: Request & {
32
- account?: Account;
33
- }, authenticationOptions: AuthenticationModuleOptions, reflector: Reflector);
34
- transform(value: unknown, metadata: ArgumentMetadata): any;
35
- }
12
+ export declare function UseRestricted(): ClassDecorator;
@@ -12,8 +12,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.RestrictedFieldsPipe = void 0;
16
15
  exports.Restricted = Restricted;
16
+ exports.UseRestricted = UseRestricted;
17
17
  const common_1 = require("@nestjs/common");
18
18
  const core_1 = require("@nestjs/core");
19
19
  const class_validator_1 = require("class-validator");
@@ -21,23 +21,6 @@ const itlab_functions_1 = require("itlab-functions");
21
21
  const modules_1 = require("../modules");
22
22
  const service_auth_guard_1 = require("../modules/authentication/guards/service-auth.guard");
23
23
  const RESTRICTED_METADATA_KEY = Symbol('itlab-restricted-metadata');
24
- /**
25
- * @Restricted Decorator
26
- *
27
- * Marks a DTO property as restricted to specific permissions.
28
- * When a request passes through the global `RestrictedFieldsPipe`,
29
- * these properties will be removed if the requesting account does not
30
- * have all required permissions.
31
- *
32
- * @param {...string[]} perms - One or more permissions required to retain this field.
33
- */
34
- function Restricted(perms) {
35
- return (target, propertyKey) => {
36
- // Store metadata without touching the property descriptor
37
- const existingMetadata = Reflect.getMetadata(RESTRICTED_METADATA_KEY, target) || {};
38
- Reflect.defineMetadata(RESTRICTED_METADATA_KEY, Object.assign(Object.assign({}, existingMetadata), { [propertyKey.toString()]: [perms !== null && perms !== void 0 ? perms : []].flat() }), target);
39
- };
40
- }
41
24
  /**
42
25
  * RestrictedFieldsPipe
43
26
  *
@@ -70,16 +53,35 @@ let RestrictedFieldsPipe = class RestrictedFieldsPipe {
70
53
  return value;
71
54
  for (const [propertyKey, requiredPerms] of Object.entries(restrictions)) {
72
55
  if (requiredPerms.length && !(0, itlab_functions_1.hasSomePermission)(requiredPerms, grantedPerms)) {
73
- delete value[propertyKey];
56
+ value[propertyKey] = undefined;
74
57
  }
75
58
  }
76
59
  return value;
77
60
  }
78
61
  };
79
- exports.RestrictedFieldsPipe = RestrictedFieldsPipe;
80
- exports.RestrictedFieldsPipe = RestrictedFieldsPipe = __decorate([
62
+ RestrictedFieldsPipe = __decorate([
81
63
  (0, common_1.Injectable)({ scope: common_1.Scope.REQUEST }),
82
64
  __param(0, (0, common_1.Inject)(core_1.REQUEST)),
83
65
  __param(1, (0, modules_1.InjectAuthenticationOptions)()),
84
66
  __metadata("design:paramtypes", [Object, Object, core_1.Reflector])
85
67
  ], RestrictedFieldsPipe);
68
+ /**
69
+ * @Restricted Decorator
70
+ *
71
+ * Marks a DTO property as restricted to specific permissions.
72
+ * When a request passes through the global `RestrictedFieldsPipe`,
73
+ * these properties will be removed if the requesting account does not
74
+ * have all required permissions.
75
+ *
76
+ * @param {...string[]} perms - One or more permissions required to retain this field.
77
+ */
78
+ function Restricted(perms) {
79
+ return (target, propertyKey) => {
80
+ // Store metadata without touching the property descriptor
81
+ const existingMetadata = Reflect.getMetadata(RESTRICTED_METADATA_KEY, target) || {};
82
+ Reflect.defineMetadata(RESTRICTED_METADATA_KEY, Object.assign(Object.assign({}, existingMetadata), { [propertyKey.toString()]: [perms !== null && perms !== void 0 ? perms : []].flat() }), target);
83
+ };
84
+ }
85
+ function UseRestricted() {
86
+ return (0, common_1.applyDecorators)((0, common_1.UsePipes)(RestrictedFieldsPipe));
87
+ }
@@ -0,0 +1,4 @@
1
+ export type HasTimestamps = {
2
+ createdAt: Date;
3
+ updatedAt: Date;
4
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,4 @@
1
1
  export * from './duplicable-model.type';
2
+ export * from './has-timestamps.type';
2
3
  export * from './likeable.type';
3
4
  export * from './viewable.type';
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./duplicable-model.type"), exports);
18
+ __exportStar(require("./has-timestamps.type"), exports);
18
19
  __exportStar(require("./likeable.type"), exports);
19
20
  __exportStar(require("./viewable.type"), exports);
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "Timo Scheuermann",
5
5
  "email": "timo.scheuermann@sv-informatik.de"
6
6
  },
7
- "version": "2.16.5",
7
+ "version": "2.16.7",
8
8
  "type": "commonjs",
9
9
  "files": [
10
10
  "dist"
@@ -1,68 +0,0 @@
1
- import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
2
- import { Observable } from 'rxjs';
3
- /**
4
- * AttributeSanitizerInterceptor
5
- *
6
- * This interceptor removes specified attributes from response objects.
7
- * It works with plain objects, arrays, sets, maps and also with Mongoose
8
- * documents by normalizing them to plain objects before sanitization.
9
- *
10
- * This is especially useful for removing sensitive fields (e.g., passwords,
11
- * tokens, SSNs) consistently across deeply nested response structures.
12
- */
13
- export declare class AttributeSanitizerInterceptor implements NestInterceptor {
14
- private readonly keys;
15
- private readonly mongooseToObjectOptions;
16
- /**
17
- * @param keys - One or more property names to remove from every object.
18
- * @param mongooseToObjectOptions - Options forwarded to Mongoose `.toObject()`
19
- * when normalizing documents.
20
- */
21
- constructor(keys: string | string[], mongooseToObjectOptions?: Record<string, unknown>);
22
- /**
23
- * Intercepts the response and removes the targeted attributes.
24
- *
25
- * @param _context - Execution context (unused here).
26
- * @param next - Next handler in the pipeline.
27
- * @returns Sanitized response data.
28
- */
29
- intercept(_context: ExecutionContext, next: CallHandler): Observable<unknown>;
30
- /**
31
- * Recursively removes targeted keys from objects, arrays, and nested structures.
32
- *
33
- * @param value - Any response value.
34
- * @returns A sanitized value without the targeted attributes.
35
- */
36
- private sanitizeRecursively;
37
- /**
38
- * Converts a Mongoose document to a plain object if needed.
39
- *
40
- * @param value - Possible Mongoose document.
41
- * @returns A plain object if conversion is possible, otherwise the value itself.
42
- */
43
- private normalizeIfMongooseDocument;
44
- /**
45
- * Checks whether a value is a plain object (and not a class instance, Date, etc.).
46
- *
47
- * @param value - Any value.
48
- * @returns True if the value is a plain object.
49
- */
50
- private isPlainObject;
51
- /**
52
- * Converts the user-provided keys into a Set for O(1) lookup.
53
- *
54
- * @param keys - String or array of strings.
55
- * @returns A Set of keys.
56
- */
57
- private ensureKeySet;
58
- }
59
- /**
60
- * @UseAttributeSanitizer
61
- *
62
- * Convenience decorator that applies the AttributeSanitizerInterceptor
63
- * to a route or controller.
64
- *
65
- * @param keys - One or more keys to remove from all response objects.
66
- * @param mongooseToObjectOptions - Options for Mongoose `.toObject()` normalization.
67
- */
68
- export declare function UseAttributeSanitizer(keys: string | string[], mongooseToObjectOptions?: Record<string, unknown>): MethodDecorator & ClassDecorator;