@flusys/nestjs-shared 3.0.0-rc → 3.0.1

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/README.md +851 -275
  2. package/cjs/classes/api-controller.class.js +4 -4
  3. package/cjs/constants/permissions.js +34 -11
  4. package/cjs/decorators/require-permission.decorator.js +7 -3
  5. package/cjs/enums/index.js +20 -0
  6. package/cjs/enums/notification-type.enum.js +17 -0
  7. package/cjs/enums/participant-status.enum.js +17 -0
  8. package/cjs/enums/recurrence-type.enum.js +18 -0
  9. package/cjs/exceptions/permission.exception.js +2 -2
  10. package/cjs/guards/permission.guard.js +66 -65
  11. package/cjs/index.js +1 -0
  12. package/cjs/interfaces/event-manager-adapter.interface.js +11 -0
  13. package/cjs/interfaces/index.js +2 -0
  14. package/cjs/interfaces/notification-adapter.interface.js +11 -0
  15. package/cjs/interfaces/permission.interface.js +1 -1
  16. package/cjs/utils/html-sanitizer.util.js +9 -9
  17. package/cjs/utils/request.util.js +2 -1
  18. package/classes/api-controller.class.d.ts +3 -3
  19. package/constants/permissions.d.ts +36 -0
  20. package/decorators/require-permission.decorator.d.ts +3 -2
  21. package/enums/index.d.ts +3 -0
  22. package/enums/notification-type.enum.d.ts +6 -0
  23. package/enums/participant-status.enum.d.ts +6 -0
  24. package/enums/recurrence-type.enum.d.ts +7 -0
  25. package/exceptions/permission.exception.d.ts +1 -1
  26. package/fesm/classes/api-controller.class.js +5 -5
  27. package/fesm/constants/permissions.js +28 -14
  28. package/fesm/decorators/require-permission.decorator.js +18 -65
  29. package/fesm/enums/index.js +3 -0
  30. package/fesm/enums/notification-type.enum.js +7 -0
  31. package/fesm/enums/participant-status.enum.js +7 -0
  32. package/fesm/enums/recurrence-type.enum.js +8 -0
  33. package/fesm/exceptions/permission.exception.js +2 -2
  34. package/fesm/guards/permission.guard.js +66 -65
  35. package/fesm/index.js +1 -0
  36. package/fesm/interfaces/event-manager-adapter.interface.js +1 -0
  37. package/fesm/interfaces/index.js +2 -0
  38. package/fesm/interfaces/notification-adapter.interface.js +1 -0
  39. package/fesm/interfaces/permission.interface.js +1 -3
  40. package/fesm/utils/request.util.js +2 -1
  41. package/guards/permission.guard.d.ts +2 -4
  42. package/index.d.ts +1 -0
  43. package/interfaces/event-manager-adapter.interface.d.ts +43 -0
  44. package/interfaces/index.d.ts +2 -0
  45. package/interfaces/notification-adapter.interface.d.ts +22 -0
  46. package/interfaces/permission.interface.d.ts +13 -8
  47. package/package.json +7 -2
@@ -72,11 +72,11 @@ function _ts_param(paramIndex, decorator) {
72
72
  // Apply PermissionGuard to check permissions from cache
73
73
  decorators.push((0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard));
74
74
  decorators.push((0, _swagger.ApiBearerAuth)());
75
- // Check for complex nested condition first
76
- if (security.condition) {
77
- decorators.push((0, _decorators.RequirePermissionCondition)(security.condition));
75
+ // Check for complex logic first
76
+ if (security.logic) {
77
+ decorators.push((0, _decorators.RequirePermissionLogic)(security.logic));
78
78
  } else if (security.permissions && security.permissions.length > 0) {
79
- if (security.operator === 'or') {
79
+ if (security.operator === 'OR') {
80
80
  decorators.push((0, _decorators.RequireAnyPermission)(...security.permissions));
81
81
  } else {
82
82
  // AND is default and most secure
@@ -1,13 +1,4 @@
1
- /**
2
- * Centralized Permission Codes
3
- *
4
- * Single source of truth for all permission codes used across the application.
5
- * Use these constants instead of hardcoded strings to prevent typos and enable easy refactoring.
6
- *
7
- * Naming Convention: <entity>.<action>
8
- * - entity: The resource being accessed (e.g., user, role, company)
9
- * - action: The operation being performed (create, read, update, delete, assign)
10
- */ // ==================== AUTH MODULE ====================
1
+ // ==================== AUTH MODULE ====================
11
2
  "use strict";
12
3
  Object.defineProperty(exports, "__esModule", {
13
4
  value: true
@@ -37,6 +28,12 @@ _export(exports, {
37
28
  get EMAIL_TEMPLATE_PERMISSIONS () {
38
29
  return EMAIL_TEMPLATE_PERMISSIONS;
39
30
  },
31
+ get EVENT_PARTICIPANT_PERMISSIONS () {
32
+ return EVENT_PARTICIPANT_PERMISSIONS;
33
+ },
34
+ get EVENT_PERMISSIONS () {
35
+ return EVENT_PERMISSIONS;
36
+ },
40
37
  get FILE_PERMISSIONS () {
41
38
  return FILE_PERMISSIONS;
42
39
  },
@@ -49,6 +46,9 @@ _export(exports, {
49
46
  get FORM_RESULT_PERMISSIONS () {
50
47
  return FORM_RESULT_PERMISSIONS;
51
48
  },
49
+ get NOTIFICATION_PERMISSIONS () {
50
+ return NOTIFICATION_PERMISSIONS;
51
+ },
52
52
  get PERMISSIONS () {
53
53
  return PERMISSIONS;
54
54
  },
@@ -159,6 +159,24 @@ const FORM_RESULT_PERMISSIONS = {
159
159
  UPDATE: 'form-result.update',
160
160
  DELETE: 'form-result.delete'
161
161
  };
162
+ const EVENT_PERMISSIONS = {
163
+ CREATE: 'event.create',
164
+ READ: 'event.read',
165
+ UPDATE: 'event.update',
166
+ DELETE: 'event.delete'
167
+ };
168
+ const EVENT_PARTICIPANT_PERMISSIONS = {
169
+ CREATE: 'event-participant.create',
170
+ READ: 'event-participant.read',
171
+ UPDATE: 'event-participant.update',
172
+ DELETE: 'event-participant.delete'
173
+ };
174
+ const NOTIFICATION_PERMISSIONS = {
175
+ CREATE: 'notification.create',
176
+ READ: 'notification.read',
177
+ UPDATE: 'notification.update',
178
+ DELETE: 'notification.delete'
179
+ };
162
180
  const PERMISSIONS = {
163
181
  // Auth
164
182
  USER: USER_PERMISSIONS,
@@ -180,5 +198,10 @@ const PERMISSIONS = {
180
198
  EMAIL_TEMPLATE: EMAIL_TEMPLATE_PERMISSIONS,
181
199
  // Form Builder
182
200
  FORM: FORM_PERMISSIONS,
183
- FORM_RESULT: FORM_RESULT_PERMISSIONS
201
+ FORM_RESULT: FORM_RESULT_PERMISSIONS,
202
+ // Event Manager
203
+ EVENT: EVENT_PERMISSIONS,
204
+ EVENT_PARTICIPANT: EVENT_PARTICIPANT_PERMISSIONS,
205
+ // Notification
206
+ NOTIFICATION: NOTIFICATION_PERMISSIONS
184
207
  };
@@ -17,16 +17,20 @@ _export(exports, {
17
17
  },
18
18
  get RequirePermissionCondition () {
19
19
  return RequirePermissionCondition;
20
+ },
21
+ get RequirePermissionLogic () {
22
+ return RequirePermissionLogic;
20
23
  }
21
24
  });
22
25
  const _common = require("@nestjs/common");
23
26
  const _constants = require("../constants");
24
27
  const RequirePermission = (...permissions)=>(0, _common.SetMetadata)(_constants.PERMISSIONS_KEY, {
25
28
  permissions,
26
- operator: 'and'
29
+ operator: 'AND'
27
30
  });
28
31
  const RequireAnyPermission = (...permissions)=>(0, _common.SetMetadata)(_constants.PERMISSIONS_KEY, {
29
32
  permissions,
30
- operator: 'or'
33
+ operator: 'OR'
31
34
  });
32
- const RequirePermissionCondition = (condition)=>(0, _common.SetMetadata)(_constants.PERMISSIONS_KEY, condition);
35
+ const RequirePermissionLogic = (logic)=>(0, _common.SetMetadata)(_constants.PERMISSIONS_KEY, logic);
36
+ const RequirePermissionCondition = RequirePermissionLogic;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ _export_star(require("./notification-type.enum"), exports);
6
+ _export_star(require("./participant-status.enum"), exports);
7
+ _export_star(require("./recurrence-type.enum"), exports);
8
+ function _export_star(from, to) {
9
+ Object.keys(from).forEach(function(k) {
10
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
11
+ Object.defineProperty(to, k, {
12
+ enumerable: true,
13
+ get: function() {
14
+ return from[k];
15
+ }
16
+ });
17
+ }
18
+ });
19
+ return from;
20
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "NotificationType", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return NotificationType;
9
+ }
10
+ });
11
+ var NotificationType = /*#__PURE__*/ function(NotificationType) {
12
+ NotificationType["INFO"] = "info";
13
+ NotificationType["WARNING"] = "warning";
14
+ NotificationType["SUCCESS"] = "success";
15
+ NotificationType["ERROR"] = "error";
16
+ return NotificationType;
17
+ }({});
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ParticipantStatus", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ParticipantStatus;
9
+ }
10
+ });
11
+ var ParticipantStatus = /*#__PURE__*/ function(ParticipantStatus) {
12
+ ParticipantStatus["PENDING"] = "pending";
13
+ ParticipantStatus["ACCEPTED"] = "accepted";
14
+ ParticipantStatus["DECLINED"] = "declined";
15
+ ParticipantStatus["TENTATIVE"] = "tentative";
16
+ return ParticipantStatus;
17
+ }({});
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "RecurrenceType", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return RecurrenceType;
9
+ }
10
+ });
11
+ var RecurrenceType = /*#__PURE__*/ function(RecurrenceType) {
12
+ RecurrenceType["NONE"] = "none";
13
+ RecurrenceType["DAILY"] = "daily";
14
+ RecurrenceType["WEEKLY"] = "weekly";
15
+ RecurrenceType["BIWEEKLY"] = "biweekly";
16
+ RecurrenceType["MONTHLY"] = "monthly";
17
+ return RecurrenceType;
18
+ }({});
@@ -30,8 +30,8 @@ let PermissionSystemUnavailableException = class PermissionSystemUnavailableExce
30
30
  }
31
31
  };
32
32
  let InsufficientPermissionsException = class InsufficientPermissionsException extends _common.ForbiddenException {
33
- constructor(missingPermissions, operator = 'and'){
34
- const message = operator === 'or' ? `Requires at least one of: ${missingPermissions.join(', ')}` : `Missing required permissions: ${missingPermissions.join(', ')}`;
33
+ constructor(missingPermissions, operator = 'AND'){
34
+ const message = operator === 'OR' ? `Requires at least one of: ${missingPermissions.join(', ')}` : `Missing required permissions: ${missingPermissions.join(', ')}`;
35
35
  super({
36
36
  success: false,
37
37
  message,
@@ -55,8 +55,6 @@ let PermissionGuard = class PermissionGuard {
55
55
  context.getClass()
56
56
  ]);
57
57
  if (!permissionConfig) return true;
58
- const { permissions: requiredPermissions, operator } = this.normalizePermissionConfig(permissionConfig);
59
- if (!requiredPermissions || requiredPermissions.length === 0) return true;
60
58
  const request = context.switchToHttp().getRequest();
61
59
  const user = request.user;
62
60
  if (!user) throw new _common.UnauthorizedException('Authentication required');
@@ -69,90 +67,93 @@ let PermissionGuard = class PermissionGuard {
69
67
  this.logger.warn(`No permissions found (userId: ${user.id})`, 'PermissionGuard');
70
68
  throw new _permissionexception.NoPermissionsFoundException();
71
69
  }
72
- if (this.isNestedCondition(permissionConfig)) {
73
- const result = this.evaluateCondition(permissionConfig, userPermissions);
74
- if (!result.passed) {
75
- this.logger.warn(`Permission denied (userId: ${user.id})`, 'PermissionGuard');
76
- throw new _permissionexception.InsufficientPermissionsException(result.missingPermissions, result.operator);
77
- }
78
- } else {
79
- this.validateSimplePermissions(requiredPermissions, userPermissions, operator);
70
+ const logicNode = this.normalizeToLogicNode(permissionConfig);
71
+ if (!logicNode) return true;
72
+ const result = this.evaluateLogicNode(logicNode, userPermissions);
73
+ if (!result.passed) {
74
+ this.logger.warn(`Permission denied (userId: ${user.id})`, 'PermissionGuard');
75
+ throw new _permissionexception.InsufficientPermissionsException(result.missingPermissions, result.operator);
80
76
  }
81
77
  return true;
82
78
  }
83
- normalizePermissionConfig(config) {
84
- if (Array.isArray(config)) return {
85
- permissions: config,
86
- operator: 'and'
87
- };
88
- return {
89
- permissions: config.permissions || [],
90
- operator: config.operator || 'and'
91
- };
92
- }
93
- validateSimplePermissions(requiredPermissions, userPermissions, operator) {
94
- if (operator === 'or') {
95
- const hasAny = requiredPermissions.some((p)=>this.hasPermission(userPermissions, p));
96
- if (!hasAny) throw new _permissionexception.InsufficientPermissionsException(requiredPermissions, 'or');
97
- } else {
98
- const hasAll = requiredPermissions.every((p)=>this.hasPermission(userPermissions, p));
99
- if (!hasAll) {
100
- const missing = requiredPermissions.filter((p)=>!this.hasPermission(userPermissions, p));
101
- throw new _permissionexception.InsufficientPermissionsException(missing, 'and');
102
- }
79
+ normalizeToLogicNode(config) {
80
+ // string - single permission
81
+ if (typeof config === 'string') {
82
+ return config ? {
83
+ type: 'action',
84
+ actionId: config
85
+ } : null;
103
86
  }
87
+ // string[] - treat as AND of multiple permissions
88
+ if (Array.isArray(config)) {
89
+ if (config.length === 0) return null;
90
+ if (config.length === 1) return {
91
+ type: 'action',
92
+ actionId: config[0]
93
+ };
94
+ return {
95
+ type: 'group',
96
+ operator: 'AND',
97
+ children: config.map((p)=>({
98
+ type: 'action',
99
+ actionId: p
100
+ }))
101
+ };
102
+ }
103
+ // SimplePermissionConfig - { permissions: string[], operator: 'AND'|'OR' }
104
+ if ('permissions' in config && Array.isArray(config.permissions)) {
105
+ const simple = config;
106
+ if (simple.permissions.length === 0) return null;
107
+ if (simple.permissions.length === 1) return {
108
+ type: 'action',
109
+ actionId: simple.permissions[0]
110
+ };
111
+ return {
112
+ type: 'group',
113
+ operator: simple.operator || 'AND',
114
+ children: simple.permissions.map((p)=>({
115
+ type: 'action',
116
+ actionId: p
117
+ }))
118
+ };
119
+ }
120
+ // ILogicNode
121
+ return config;
104
122
  }
105
- isNestedCondition(config) {
106
- if (Array.isArray(config)) return false;
107
- return 'children' in config && Array.isArray(config.children) && config.children.length > 0;
108
- }
109
- evaluateCondition(condition, userPermissions) {
110
- const { permissions = [], operator, children = [] } = condition;
111
- // SECURITY: Fail-closed - deny access when no permissions configured (empty condition)
112
- if (permissions.length === 0 && children.length === 0) {
123
+ evaluateLogicNode(node, userPermissions) {
124
+ if (node.type === 'action') {
125
+ const passed = this.hasPermission(userPermissions, node.actionId);
126
+ return {
127
+ passed,
128
+ missingPermissions: passed ? [] : [
129
+ node.actionId
130
+ ],
131
+ operator: 'AND'
132
+ };
133
+ }
134
+ // Group node
135
+ const { operator, children } = node;
136
+ // SECURITY: Fail-closed - deny access when no children configured
137
+ if (!children || children.length === 0) {
113
138
  return {
114
139
  passed: false,
115
- message: 'No permissions configured - access denied by default',
116
140
  missingPermissions: [],
117
141
  operator
118
142
  };
119
143
  }
120
144
  const results = [];
121
- const failureDetails = [];
122
145
  const missingPermissions = [];
123
- if (permissions.length > 0) {
124
- if (operator === 'or') {
125
- const hasAny = permissions.some((p)=>this.hasPermission(userPermissions, p));
126
- results.push(hasAny);
127
- if (!hasAny) {
128
- failureDetails.push(`needs one of: [${permissions.join(', ')}]`);
129
- missingPermissions.push(...permissions);
130
- }
131
- } else {
132
- const hasAll = permissions.every((p)=>this.hasPermission(userPermissions, p));
133
- results.push(hasAll);
134
- if (!hasAll) {
135
- const missing = permissions.filter((p)=>!this.hasPermission(userPermissions, p));
136
- failureDetails.push(`missing: [${missing.join(', ')}]`);
137
- missingPermissions.push(...missing);
138
- }
139
- }
140
- }
141
146
  for (const child of children){
142
- const childResult = this.evaluateCondition(child, userPermissions);
147
+ const childResult = this.evaluateLogicNode(child, userPermissions);
143
148
  results.push(childResult.passed);
144
149
  if (!childResult.passed) {
145
- failureDetails.push(`(${childResult.message})`);
146
150
  missingPermissions.push(...childResult.missingPermissions);
147
151
  }
148
152
  }
149
- // Evaluate based on operator - empty results already handled above
150
- const passed = operator === 'or' ? results.some((r)=>r) : results.every((r)=>r);
151
- const message = passed ? 'OK' : `Denied: ${failureDetails.join(` ${operator.toUpperCase()} `)}`;
153
+ const passed = operator === 'OR' ? results.some((r)=>r) : results.every((r)=>r);
152
154
  return {
153
155
  passed,
154
- message,
155
- missingPermissions,
156
+ missingPermissions: passed ? [] : missingPermissions,
156
157
  operator
157
158
  };
158
159
  }
package/cjs/index.js CHANGED
@@ -7,6 +7,7 @@ _export_star(require("./constants"), exports);
7
7
  _export_star(require("./decorators"), exports);
8
8
  _export_star(require("./dtos"), exports);
9
9
  _export_star(require("./entities"), exports);
10
+ _export_star(require("./enums"), exports);
10
11
  _export_star(require("./exceptions"), exports);
11
12
  _export_star(require("./guards"), exports);
12
13
  _export_star(require("./interceptors"), exports);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "EVENT_MANAGER_ADAPTER", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return EVENT_MANAGER_ADAPTER;
9
+ }
10
+ });
11
+ const EVENT_MANAGER_ADAPTER = 'EVENT_MANAGER_ADAPTER';
@@ -4,10 +4,12 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  _export_star(require("./api.interface"), exports);
6
6
  _export_star(require("./datasource.interface"), exports);
7
+ _export_star(require("./event-manager-adapter.interface"), exports);
7
8
  _export_star(require("./identity.interface"), exports);
8
9
  _export_star(require("./logged-user-info.interface"), exports);
9
10
  _export_star(require("./logger.interface"), exports);
10
11
  _export_star(require("./module-config.interface"), exports);
12
+ _export_star(require("./notification-adapter.interface"), exports);
11
13
  _export_star(require("./permission.interface"), exports);
12
14
  function _export_star(from, to) {
13
15
  Object.keys(from).forEach(function(k) {
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "NOTIFICATION_ADAPTER", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return NOTIFICATION_ADAPTER;
9
+ }
10
+ });
11
+ const NOTIFICATION_ADAPTER = 'NOTIFICATION_ADAPTER';
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ /** Action node - checks a single permission/action code */ "use strict";
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
@@ -1,11 +1,4 @@
1
- /**
2
- * HTML Sanitizer Utilities
3
- *
4
- * Provides functions for escaping HTML content to prevent XSS attacks.
5
- * Use these utilities when interpolating user-provided variables into HTML content.
6
- */ /**
7
- * HTML entity mapping for escaping special characters
8
- */ "use strict";
1
+ "use strict";
9
2
  Object.defineProperty(exports, "__esModule", {
10
3
  value: true
11
4
  });
@@ -23,7 +16,14 @@ _export(exports, {
23
16
  return escapeHtmlVariables;
24
17
  }
25
18
  });
26
- const HTML_ESCAPE_MAP = {
19
+ /**
20
+ * HTML Sanitizer Utilities
21
+ *
22
+ * Provides functions for escaping HTML content to prevent XSS attacks.
23
+ * Use these utilities when interpolating user-provided variables into HTML content.
24
+ */ /**
25
+ * HTML entity mapping for escaping special characters
26
+ */ const HTML_ESCAPE_MAP = {
27
27
  '&': '&amp;',
28
28
  '<': '&lt;',
29
29
  '>': '&gt;',
@@ -19,6 +19,7 @@ _export(exports, {
19
19
  return parseDurationToMs;
20
20
  }
21
21
  });
22
+ const _config = require("@flusys/nestjs-core/config");
22
23
  const _constants = require("../constants");
23
24
  /** Time unit multipliers in milliseconds */ const TIME_UNIT_MS = {
24
25
  s: 1000,
@@ -45,7 +46,7 @@ function isBrowserRequest(req) {
45
46
  function buildCookieOptions(req) {
46
47
  const hostname = req.hostname || '';
47
48
  const origin = req.headers.origin || '';
48
- const isProduction = process.env.NODE_ENV === 'production';
49
+ const isProduction = _config.envConfig.isProduction();
49
50
  const forwardedProto = req.headers['x-forwarded-proto'];
50
51
  const isHttps = isProduction || forwardedProto === 'https' || origin.startsWith('https://') || req.secure;
51
52
  let domain;
@@ -1,14 +1,14 @@
1
1
  import { BulkResponseDto, DeleteDto, FilterAndPaginationDto, GetByIdBodyDto, ListResponseDto, MessageResponseDto, SingleResponseDto } from '../dtos';
2
2
  import { Identity } from '../entities';
3
- import { ILoggedUserInfo, IService, PermissionCondition, PermissionOperator } from '../interfaces';
3
+ import { ILoggedUserInfo, IPermissionLogic, IService } from '../interfaces';
4
4
  import { Type } from '@nestjs/common';
5
5
  export type ApiEndpoint = 'insert' | 'insertMany' | 'getById' | 'getAll' | 'update' | 'updateMany' | 'delete';
6
6
  export type SecurityLevel = 'public' | 'jwt' | 'permission';
7
7
  export interface EndpointSecurity {
8
8
  level: SecurityLevel;
9
9
  permissions?: string[];
10
- operator?: PermissionOperator;
11
- condition?: PermissionCondition;
10
+ operator?: 'AND' | 'OR';
11
+ logic?: IPermissionLogic;
12
12
  }
13
13
  export type ApiSecurityConfig = {
14
14
  [K in ApiEndpoint]?: EndpointSecurity | SecurityLevel;
@@ -86,6 +86,24 @@ export declare const FORM_RESULT_PERMISSIONS: {
86
86
  readonly UPDATE: "form-result.update";
87
87
  readonly DELETE: "form-result.delete";
88
88
  };
89
+ export declare const EVENT_PERMISSIONS: {
90
+ readonly CREATE: "event.create";
91
+ readonly READ: "event.read";
92
+ readonly UPDATE: "event.update";
93
+ readonly DELETE: "event.delete";
94
+ };
95
+ export declare const EVENT_PARTICIPANT_PERMISSIONS: {
96
+ readonly CREATE: "event-participant.create";
97
+ readonly READ: "event-participant.read";
98
+ readonly UPDATE: "event-participant.update";
99
+ readonly DELETE: "event-participant.delete";
100
+ };
101
+ export declare const NOTIFICATION_PERMISSIONS: {
102
+ readonly CREATE: "notification.create";
103
+ readonly READ: "notification.read";
104
+ readonly UPDATE: "notification.update";
105
+ readonly DELETE: "notification.delete";
106
+ };
89
107
  export declare const PERMISSIONS: {
90
108
  readonly USER: {
91
109
  readonly CREATE: "user.create";
@@ -175,5 +193,23 @@ export declare const PERMISSIONS: {
175
193
  readonly UPDATE: "form-result.update";
176
194
  readonly DELETE: "form-result.delete";
177
195
  };
196
+ readonly EVENT: {
197
+ readonly CREATE: "event.create";
198
+ readonly READ: "event.read";
199
+ readonly UPDATE: "event.update";
200
+ readonly DELETE: "event.delete";
201
+ };
202
+ readonly EVENT_PARTICIPANT: {
203
+ readonly CREATE: "event-participant.create";
204
+ readonly READ: "event-participant.read";
205
+ readonly UPDATE: "event-participant.update";
206
+ readonly DELETE: "event-participant.delete";
207
+ };
208
+ readonly NOTIFICATION: {
209
+ readonly CREATE: "notification.create";
210
+ readonly READ: "notification.read";
211
+ readonly UPDATE: "notification.update";
212
+ readonly DELETE: "notification.delete";
213
+ };
178
214
  };
179
215
  export type PermissionCode = (typeof PERMISSIONS)[keyof typeof PERMISSIONS][keyof (typeof PERMISSIONS)[keyof typeof PERMISSIONS]];
@@ -1,4 +1,5 @@
1
- import { PermissionCondition } from '../interfaces/permission.interface';
1
+ import { IPermissionLogic } from '../interfaces/permission.interface';
2
2
  export declare const RequirePermission: (...permissions: string[]) => import("@nestjs/common").CustomDecorator<string>;
3
3
  export declare const RequireAnyPermission: (...permissions: string[]) => import("@nestjs/common").CustomDecorator<string>;
4
- export declare const RequirePermissionCondition: (condition: PermissionCondition) => import("@nestjs/common").CustomDecorator<string>;
4
+ export declare const RequirePermissionLogic: (logic: IPermissionLogic) => import("@nestjs/common").CustomDecorator<string>;
5
+ export declare const RequirePermissionCondition: (logic: IPermissionLogic) => import("@nestjs/common").CustomDecorator<string>;
@@ -0,0 +1,3 @@
1
+ export * from './notification-type.enum';
2
+ export * from './participant-status.enum';
3
+ export * from './recurrence-type.enum';
@@ -0,0 +1,6 @@
1
+ export declare enum NotificationType {
2
+ INFO = "info",
3
+ WARNING = "warning",
4
+ SUCCESS = "success",
5
+ ERROR = "error"
6
+ }
@@ -0,0 +1,6 @@
1
+ export declare enum ParticipantStatus {
2
+ PENDING = "pending",
3
+ ACCEPTED = "accepted",
4
+ DECLINED = "declined",
5
+ TENTATIVE = "tentative"
6
+ }
@@ -0,0 +1,7 @@
1
+ export declare enum RecurrenceType {
2
+ NONE = "none",
3
+ DAILY = "daily",
4
+ WEEKLY = "weekly",
5
+ BIWEEKLY = "biweekly",
6
+ MONTHLY = "monthly"
7
+ }
@@ -3,7 +3,7 @@ export declare class PermissionSystemUnavailableException extends InternalServer
3
3
  constructor(message?: string);
4
4
  }
5
5
  export declare class InsufficientPermissionsException extends ForbiddenException {
6
- constructor(missingPermissions: string[], operator?: 'and' | 'or');
6
+ constructor(missingPermissions: string[], operator?: 'AND' | 'OR');
7
7
  }
8
8
  export declare class NoPermissionsFoundException extends ForbiddenException {
9
9
  constructor();
@@ -25,7 +25,7 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { CurrentUser, Public, RequirePermission, RequireAnyPermission, RequirePermissionCondition } from '../decorators';
28
+ import { CurrentUser, Public, RequirePermission, RequireAnyPermission, RequirePermissionLogic } from '../decorators';
29
29
  import { DeleteDto, FilterAndPaginationDto, GetByIdBodyDto } from '../dtos';
30
30
  import { JwtAuthGuard, PermissionGuard } from '../guards';
31
31
  import { IdempotencyInterceptor, SetCreatedByOnBody, SetDeletedByOnBody, SetUpdateByOnBody, Slug } from '../interceptors';
@@ -62,11 +62,11 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
62
62
  // Apply PermissionGuard to check permissions from cache
63
63
  decorators.push(UseGuards(JwtAuthGuard, PermissionGuard));
64
64
  decorators.push(ApiBearerAuth());
65
- // Check for complex nested condition first
66
- if (security.condition) {
67
- decorators.push(RequirePermissionCondition(security.condition));
65
+ // Check for complex logic first
66
+ if (security.logic) {
67
+ decorators.push(RequirePermissionLogic(security.logic));
68
68
  } else if (security.permissions && security.permissions.length > 0) {
69
- if (security.operator === 'or') {
69
+ if (security.operator === 'OR') {
70
70
  decorators.push(RequireAnyPermission(...security.permissions));
71
71
  } else {
72
72
  // AND is default and most secure