identity-admin 1.26.3 → 1.26.5

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.
@@ -27,6 +27,7 @@ const ResponseUtils_1 = __importDefault(require("../utils/ResponseUtils"));
27
27
  const StringUtils_1 = __importDefault(require("../utils/StringUtils"));
28
28
  const Repository_1 = __importDefault(require("../repositories/Repository"));
29
29
  const ResourceUtils_1 = require("../utils/ResourceUtils");
30
+ const UserActionsLog_1 = __importDefault(require("../models/userActionsLog/UserActionsLog"));
30
31
  let ActionController = class ActionController {
31
32
  constructor(resources) {
32
33
  this.resources = resources;
@@ -57,7 +58,18 @@ let ActionController = class ActionController {
57
58
  for (var i = 0; i < extraActions.length; i++) {
58
59
  const extraAction = extraActions[i];
59
60
  if (extraAction.key === actionKey) {
61
+ const oldRecord = yield repository.findById(record._id);
60
62
  response = yield extraAction.handler(req, res, data);
63
+ const newRecord = yield repository.findById(record._id);
64
+ const userActionsLog = new UserActionsLog_1.default({
65
+ action: actionKey,
66
+ modelName,
67
+ userId: req.user._id,
68
+ dataBefore: JSON.stringify(oldRecord),
69
+ dataAfter: JSON.stringify(newRecord),
70
+ resourceId: record._id,
71
+ });
72
+ yield userActionsLog.save();
61
73
  break;
62
74
  }
63
75
  }
@@ -38,6 +38,8 @@ const ActionsGenerator_1 = __importDefault(require("../helpers/ActionsGenerator"
38
38
  const helpers_1 = require("../types/helpers");
39
39
  const PopulationHelper_1 = require("../helpers/PopulationHelper");
40
40
  const ReportsGenerator_1 = __importDefault(require("../helpers/ReportsGenerator"));
41
+ const IUserActionsLog_1 = require("../models/userActionsLog/IUserActionsLog");
42
+ const UserActionsLog_1 = __importDefault(require("../models/userActionsLog/UserActionsLog"));
41
43
  let DashboardController = DashboardController_1 = class DashboardController {
42
44
  constructor(resource, repository, resources, modelConfigurations) {
43
45
  this.resource = resource;
@@ -231,7 +233,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
231
233
  });
232
234
  }
233
235
  create(req, res) {
234
- var _a, _b, _c, _d;
236
+ var _a, _b, _c, _d, _e, _f;
235
237
  return __awaiter(this, void 0, void 0, function* () {
236
238
  if (!this.validateRequest(req, res)) {
237
239
  return;
@@ -283,6 +285,17 @@ let DashboardController = DashboardController_1 = class DashboardController {
283
285
  if (!record.isValid() || !record.document) {
284
286
  return ResponseUtils_1.default.unprocessable(res, 'Invalid Data', record.getErrors());
285
287
  }
288
+ if ((_e = resource.properties) === null || _e === void 0 ? void 0 : _e.enableLog) {
289
+ const newRecord = yield repository.findById(record.getDocument()._id);
290
+ const userActionsLog = new UserActionsLog_1.default({
291
+ action: IUserActionsLog_1.UserActions.CREATE,
292
+ modelName: (_f = resource === null || resource === void 0 ? void 0 : resource.properties) === null || _f === void 0 ? void 0 : _f.modelName,
293
+ userId: req.user._id,
294
+ dataAfter: JSON.stringify(newRecord),
295
+ resourceId: newRecord === null || newRecord === void 0 ? void 0 : newRecord._id,
296
+ });
297
+ yield userActionsLog.save();
298
+ }
286
299
  if (crudOperations && crudOperations.create && crudOperations.create.after) {
287
300
  record = yield crudOperations.create.after(req, record, currentUser, recordParams);
288
301
  }
@@ -292,7 +305,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
292
305
  });
293
306
  }
294
307
  update(req, res) {
295
- var _a, _b, _c, _d, _e;
308
+ var _a, _b, _c, _d, _e, _f, _g;
296
309
  return __awaiter(this, void 0, void 0, function* () {
297
310
  if (!this.validateRequest(req, res)) {
298
311
  return;
@@ -348,6 +361,18 @@ let DashboardController = DashboardController_1 = class DashboardController {
348
361
  // if (resource.properties.modelName === ModelNames.Settings) {
349
362
  // await AppSettings.run()
350
363
  // }
364
+ if ((_f = resource.properties) === null || _f === void 0 ? void 0 : _f.enableLog) {
365
+ const newRecord = yield repository.findById(record._id);
366
+ const userActionsLog = new UserActionsLog_1.default({
367
+ action: IUserActionsLog_1.UserActions.EDIT,
368
+ modelName: (_g = resource === null || resource === void 0 ? void 0 : resource.properties) === null || _g === void 0 ? void 0 : _g.modelName,
369
+ userId: req.user._id,
370
+ dataBefore: JSON.stringify(record),
371
+ dataAfter: JSON.stringify(newRecord),
372
+ resourceId: record._id,
373
+ });
374
+ yield userActionsLog.save();
375
+ }
351
376
  if (crudOperations && crudOperations.update && crudOperations.update.after) {
352
377
  recordSaveResult = yield crudOperations.update.after(req, recordSaveResult, recordParams, currentUser);
353
378
  }
@@ -534,7 +559,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
534
559
  });
535
560
  }
536
561
  delete(req, res) {
537
- var _a, _b, _c, _d;
562
+ var _a, _b, _c, _d, _e, _f;
538
563
  return __awaiter(this, void 0, void 0, function* () {
539
564
  if (!this.validateRequest(req, res)) {
540
565
  return;
@@ -563,6 +588,16 @@ let DashboardController = DashboardController_1 = class DashboardController {
563
588
  if (!record) {
564
589
  return ResponseUtils_1.default.send(res, 404, 'record Not Found');
565
590
  }
591
+ if ((_e = resource.properties) === null || _e === void 0 ? void 0 : _e.enableLog) {
592
+ const userActionsLog = new UserActionsLog_1.default({
593
+ action: IUserActionsLog_1.UserActions.DELETE,
594
+ modelName: (_f = resource === null || resource === void 0 ? void 0 : resource.properties) === null || _f === void 0 ? void 0 : _f.modelName,
595
+ userId: req.user._id,
596
+ dataBefore: JSON.stringify(record),
597
+ resourceId: record._id,
598
+ });
599
+ yield userActionsLog.save();
600
+ }
566
601
  yield repository.remove({ _id: record._id });
567
602
  return ResponseUtils_1.default.send(res, 200, 'OK');
568
603
  });
@@ -38,7 +38,7 @@ const SetupParent = {
38
38
  };
39
39
  class ResourceGenerator {
40
40
  static generate(resource, currentUser, configurations, modelConfigurations, permissions) {
41
- var _a, _b, _c, _d, _e, _f, _g;
41
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
42
42
  const SetupParent = {
43
43
  name: "Setup",
44
44
  icon: "PermDataSetting",
@@ -161,7 +161,7 @@ class ResourceGenerator {
161
161
  ? (_d = (_c = resource.properties.filters) === null || _c === void 0 ? void 0 : _c.scopes) === null || _d === void 0 ? void 0 : _d.auto.options
162
162
  : (_g = (_f = (_e = resource.properties.filters) === null || _e === void 0 ? void 0 : _e.scopes) === null || _f === void 0 ? void 0 : _f.manual) === null || _g === void 0 ? void 0 : _g.options;
163
163
  modifiedResource.properties.filters.scopes.options =
164
- ResourceHelper_1.default.setScopeFilterOptions(modelName, options);
164
+ ResourceHelper_1.default.setScopeFilterOptions(modelName, options, ((_j = (_h = resource.properties.filters) === null || _h === void 0 ? void 0 : _h.scopes) === null || _j === void 0 ? void 0 : _j.showAll) === undefined ? true : (_l = (_k = resource.properties.filters) === null || _k === void 0 ? void 0 : _k.scopes) === null || _l === void 0 ? void 0 : _l.showAll);
165
165
  }
166
166
  const actions = ActionsGenerator_1.default.generateActions(actionsCheck, resource, currentUser, modelConfiguration);
167
167
  modifiedResource.properties.actions = actions;
@@ -9,7 +9,7 @@ export default class ResourcesHelper {
9
9
  static prepareFilterProperties(properties: string[], schema: any): string[];
10
10
  static checkResourceTranslation(resource: IResourceFile, key: string): string | undefined;
11
11
  static checkActionTranslation(resource: IResourceFile, action: string): string | undefined;
12
- static setScopeFilterOptions(modelName: string, options: string[]): any;
12
+ static setScopeFilterOptions(modelName: string, options: string[], showAll: boolean): any;
13
13
  static getFilters(filters: any): {
14
14
  scopes: {};
15
15
  searchBar: {};
@@ -151,12 +151,14 @@ class ResourcesHelper {
151
151
  translation = (0, i18n_1.__)({ phrase: resource.properties.actionsTranslations[action], locale: i18n_1.default.getLocale() });
152
152
  return translation;
153
153
  }
154
- static setScopeFilterOptions(modelName, options) {
154
+ static setScopeFilterOptions(modelName, options, showAll) {
155
155
  var arrayOfOptions = [];
156
- arrayOfOptions.push({
157
- key: 'all',
158
- value: (0, i18n_1.__)({ phrase: 'ALL', locale: i18n_1.default.getLocale() }),
159
- });
156
+ if (showAll) {
157
+ arrayOfOptions.push({
158
+ key: 'all',
159
+ value: (0, i18n_1.__)({ phrase: 'ALL', locale: i18n_1.default.getLocale() }),
160
+ });
161
+ }
160
162
  options.forEach((key) => {
161
163
  const optionObject = {
162
164
  key,
@@ -0,0 +1,2 @@
1
+ export declare function renderDiff(diff: any): string | null;
2
+ export declare function isRelevant(diff: any): boolean;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRelevant = exports.renderDiff = void 0;
4
+ function renderDiff(diff) {
5
+ var _a;
6
+ const path = (_a = diff.path) === null || _a === void 0 ? void 0 : _a.join('.');
7
+ const oldValue = formatValue(diff.lhs);
8
+ const newValue = formatValue(diff.rhs);
9
+ switch (diff.kind) {
10
+ case 'N':
11
+ return `${path}: Added - ${newValue}`;
12
+ case 'D':
13
+ return `${path}: Removed - ${oldValue}`;
14
+ case 'E':
15
+ return `${path}: Modified - ${oldValue} => ${newValue}`;
16
+ case 'A':
17
+ return renderArrayChange(diff, path);
18
+ default:
19
+ return null;
20
+ }
21
+ }
22
+ exports.renderDiff = renderDiff;
23
+ function formatValue(value) {
24
+ if (typeof value === 'object') {
25
+ return JSON.stringify(value);
26
+ }
27
+ if (typeof value === 'boolean') {
28
+ return `${value}`;
29
+ }
30
+ return value;
31
+ }
32
+ function renderArrayChange(diff, path) {
33
+ const { index, item } = diff;
34
+ const { kind, rhs, lhs } = item;
35
+ const changeText = kind === 'N' ? 'Added' : 'Removed';
36
+ const value = formatValue(kind === 'N' ? rhs : lhs);
37
+ if (typeof index !== 'undefined') {
38
+ return `${path}[${index}]: ${changeText} - ${value}`;
39
+ }
40
+ else {
41
+ return `${path}: Array Change - ${changeText} ${value}`;
42
+ }
43
+ }
44
+ function isRelevant(diff) {
45
+ var _a;
46
+ const lastElement = (_a = diff.path) === null || _a === void 0 ? void 0 : _a.slice(-1)[0];
47
+ return !['__v', 'createdAt', 'updatedAt', '_id', 'id'].includes(lastElement);
48
+ }
49
+ exports.isRelevant = isRelevant;
@@ -4,4 +4,5 @@ export default class ModelNames {
4
4
  static Permission: string;
5
5
  static PermissionGroup: string;
6
6
  static AdminPermission: string;
7
+ static UserActionsLog: string;
7
8
  }
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  class ModelNames {
4
4
  }
5
5
  exports.default = ModelNames;
6
- ModelNames.User = 'IdentityUser';
6
+ ModelNames.User = 'User';
7
7
  ModelNames.RequestLog = 'RequestLog';
8
8
  ModelNames.Permission = 'Permission';
9
9
  ModelNames.PermissionGroup = 'PermissionGroup';
10
10
  ModelNames.AdminPermission = 'AdminPermission';
11
+ ModelNames.UserActionsLog = 'UserActionsLog';
@@ -0,0 +1,24 @@
1
+ import { Document, Model, Types } from 'mongoose';
2
+ export declare enum UserActions {
3
+ CREATE = "create",
4
+ EDIT = "edit",
5
+ DELETE = "delete"
6
+ }
7
+ export interface IUserActionsLogProps {
8
+ _id?: Types.ObjectId;
9
+ userId: Types.ObjectId;
10
+ action: string;
11
+ modelName: string;
12
+ dataBefore?: string;
13
+ dataAfter?: string;
14
+ resourceId?: Types.ObjectId;
15
+ changes?: string;
16
+ user?: any;
17
+ }
18
+ export interface IUserActionsLogDocument extends IUserActionsLogProps, Document {
19
+ _id: Types.ObjectId;
20
+ createdAt: Date;
21
+ updatedAt: Date;
22
+ }
23
+ export default interface IUserActionsLogModel extends Model<IUserActionsLogDocument> {
24
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserActions = void 0;
4
+ var UserActions;
5
+ (function (UserActions) {
6
+ UserActions["CREATE"] = "create";
7
+ UserActions["EDIT"] = "edit";
8
+ UserActions["DELETE"] = "delete";
9
+ })(UserActions = exports.UserActions || (exports.UserActions = {}));
@@ -0,0 +1,3 @@
1
+ import IUserActionsLogModel from "./IUserActionsLog";
2
+ declare const UserActionsLog: IUserActionsLogModel;
3
+ export default UserActionsLog;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mongoose_1 = require("mongoose");
7
+ const ModelNames_1 = __importDefault(require("../ModelNames"));
8
+ const deep_diff_1 = require("deep-diff");
9
+ const UserActionsLogHelper_1 = require("../../helpers/UserActionsLog/UserActionsLogHelper");
10
+ const UserActionsLogSchema = new mongoose_1.Schema({
11
+ userId: {
12
+ type: mongoose_1.Schema.Types.ObjectId,
13
+ required: true,
14
+ },
15
+ action: {
16
+ type: String,
17
+ required: true,
18
+ },
19
+ modelName: {
20
+ type: String,
21
+ required: true,
22
+ },
23
+ dataBefore: {
24
+ type: String,
25
+ },
26
+ dataAfter: {
27
+ type: String,
28
+ },
29
+ resourceId: {
30
+ type: mongoose_1.Schema.Types.ObjectId,
31
+ refPath: 'modelName'
32
+ }
33
+ }, { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } });
34
+ UserActionsLogSchema.virtual('changes').get(function () {
35
+ const deepDiff_changes = (0, deep_diff_1.diff)(this.dataBefore ? JSON.parse(this.dataBefore) : undefined, this.dataAfter ? JSON.parse(this.dataAfter) : undefined);
36
+ let changes = '';
37
+ deepDiff_changes === null || deepDiff_changes === void 0 ? void 0 : deepDiff_changes.forEach((diff) => (changes += (0, UserActionsLogHelper_1.isRelevant)(diff) ? `${(0, UserActionsLogHelper_1.renderDiff)(diff)}\n` : ''));
38
+ return changes;
39
+ });
40
+ const UserActionsLog = (0, mongoose_1.model)(ModelNames_1.default.UserActionsLog, UserActionsLogSchema);
41
+ exports.default = UserActionsLog;
@@ -3,7 +3,7 @@ import { Document, Model } from 'mongoose';
3
3
  import { IRequest } from '../middlewares/isAuth';
4
4
  import { IRepository, PageInfo, PaginateParams } from '../repositories/Repository';
5
5
  import SaveResult from '../repositories/SaveResult';
6
- import { ActionNames, ActionTypes, FieldTypes, FileTypes, HandlerStrategy, NeighborTypes, Virtuals } from './helpers';
6
+ import { ActionNames, ActionTypes, FieldTypes, FileTypes, HandlerStrategy, ImageOptimizingCategories, NeighborTypes, Virtuals } from './helpers';
7
7
  declare type orderTypes = 'asc' | 'desc';
8
8
  declare type VirtualFieldTypes = 'password' | 'ref' | 'Array';
9
9
  declare type Severity = 'success' | 'info' | 'warning' | 'error';
@@ -186,6 +186,11 @@ interface IFilters {
186
186
  * @default false
187
187
  */
188
188
  isAccessible: boolean;
189
+ /**
190
+ * Show All tab
191
+ * @default true
192
+ */
193
+ showAll?: boolean;
189
194
  /**
190
195
  * Automatic scope that filters by the specified key with one of the given options
191
196
  * This filter works automatically by mentioning the key as saved in the database along with the values that this key can has.
@@ -282,6 +287,11 @@ export interface IFieldValue {
282
287
  * Can be used only if this field is a reference to the Image collection
283
288
  */
284
289
  mediaUploader?: boolean;
290
+ /**
291
+ * Used only if this field is of type image. It specifies what is the optimizing level of an image before upload
292
+ * @default NORMAL
293
+ */
294
+ imageOptimizingCategory?: ImageOptimizingCategories;
285
295
  /**
286
296
  * Specify the type of the file to be uploaded. Only required if the media uploader is true.
287
297
  * @default image
@@ -517,6 +527,11 @@ export interface IResourceFile {
517
527
  * @default true
518
528
  */
519
529
  isVisible?: (currentUser: Document) => Promise<boolean>;
530
+ /**
531
+ * The property that controls the ability of logging changes of this resource.
532
+ * @default false
533
+ */
534
+ enableLog?: (currentUser: Document) => Promise<boolean>;
520
535
  /**
521
536
  * The default order
522
537
  * @default asc
@@ -59,3 +59,7 @@ export declare enum NeighborTypes {
59
59
  NEXT = "NEXT",
60
60
  PREVIOUS = "PREVIOUS"
61
61
  }
62
+ export declare enum ImageOptimizingCategories {
63
+ NORMAL = "NORMAL",
64
+ BANNERS = "BANNERS"
65
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NeighborTypes = exports.HandlerStrategy = exports.FileTypes = exports.FieldTypes = exports.ActionTypes = exports.ActionNames = exports.Virtuals = void 0;
3
+ exports.ImageOptimizingCategories = exports.NeighborTypes = exports.HandlerStrategy = exports.FileTypes = exports.FieldTypes = exports.ActionTypes = exports.ActionNames = exports.Virtuals = void 0;
4
4
  var Virtuals;
5
5
  (function (Virtuals) {
6
6
  Virtuals["SHOW"] = "SHOW";
@@ -69,3 +69,8 @@ var NeighborTypes;
69
69
  NeighborTypes["NEXT"] = "NEXT";
70
70
  NeighborTypes["PREVIOUS"] = "PREVIOUS";
71
71
  })(NeighborTypes = exports.NeighborTypes || (exports.NeighborTypes = {}));
72
+ var ImageOptimizingCategories;
73
+ (function (ImageOptimizingCategories) {
74
+ ImageOptimizingCategories["NORMAL"] = "NORMAL";
75
+ ImageOptimizingCategories["BANNERS"] = "BANNERS";
76
+ })(ImageOptimizingCategories = exports.ImageOptimizingCategories || (exports.ImageOptimizingCategories = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "identity-admin",
3
- "version": "1.26.3",
3
+ "version": "1.26.5",
4
4
  "description": "",
5
5
  "main": "lib/Dashboard.js",
6
6
  "types": "lib/Dashbord.d.ts",
@@ -42,10 +42,12 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@react-pdf/renderer": "^3.1.14",
45
+ "@types/deep-diff": "^1.0.5",
45
46
  "@types/express-session": "^1.17.5",
46
47
  "bcryptjs": "^2.4.3",
47
48
  "connect-mongo": "^4.6.0",
48
49
  "cookie-parser": "^1.4.6",
50
+ "deep-diff": "^1.0.2",
49
51
  "express-session": "^1.17.3",
50
52
  "lodash": "^4.17.21",
51
53
  "memory-cache": "^0.2.0",