@autofleet/shtinker 1.2.0-beta.5 → 1.2.1-beta
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.
- package/dist/audit-logger.js +14 -37
- package/dist/index.d.ts +4 -1
- package/dist/index.js +15 -15
- package/dist/types.d.ts +5 -0
- package/dist/types.js +6 -1
- package/package.json +3 -3
- package/src/const.ts +1 -0
- package/src/index.ts +14 -6
- package/src/types.ts +7 -0
package/dist/audit-logger.js
CHANGED
|
@@ -13,10 +13,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const zehut_1 = require("@autofleet/zehut");
|
|
16
|
-
const lodash_1 = require("lodash");
|
|
17
16
|
const const_1 = require("./const");
|
|
18
17
|
const logger_1 = __importDefault(require("./logger"));
|
|
19
|
-
const CUSTOM_FIELDS_PROPERTY = 'customFields';
|
|
20
18
|
const getAuditContext = () => {
|
|
21
19
|
var _a;
|
|
22
20
|
const currentTrace = (0, zehut_1.getCurrentPayload)();
|
|
@@ -36,41 +34,17 @@ const isEmpty = (field) => {
|
|
|
36
34
|
return false;
|
|
37
35
|
};
|
|
38
36
|
const filterOutEmptyFields = (fields, instance) => fields.filter((field) => !isEmpty(instance.get(field)) || !isEmpty(instance.previous(field)));
|
|
39
|
-
const
|
|
37
|
+
const getChangedFields = (instance, options) => {
|
|
40
38
|
// When bulk updating in sequelize using the "returning" option, the instance.changed() stops working.
|
|
41
|
-
// It's a known
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const filteredChangedFields = filterOutEmptyFields(changedFields.filter((field) => field !== CUSTOM_FIELDS_PROPERTY), instance);
|
|
45
|
-
return filteredChangedFields.map((property) => ({
|
|
46
|
-
property,
|
|
47
|
-
previousValue: instance.previous(property),
|
|
48
|
-
newValue: instance.get(property),
|
|
49
|
-
}));
|
|
50
|
-
};
|
|
51
|
-
const getChangedCustomFieldsRows = (instance) => {
|
|
52
|
-
const customFieldsChanged = instance.changed().includes(CUSTOM_FIELDS_PROPERTY);
|
|
53
|
-
if (!customFieldsChanged) {
|
|
54
|
-
return [];
|
|
55
|
-
}
|
|
56
|
-
const customFields = instance.get(CUSTOM_FIELDS_PROPERTY);
|
|
57
|
-
const previousCustomFields = instance.previous(CUSTOM_FIELDS_PROPERTY);
|
|
58
|
-
const changedCustomFields = Object.keys(customFields).filter((field) => {
|
|
59
|
-
const newValue = customFields === null || customFields === void 0 ? void 0 : customFields[field];
|
|
60
|
-
const oldValue = previousCustomFields === null || previousCustomFields === void 0 ? void 0 : previousCustomFields[field];
|
|
61
|
-
return (!isEmpty(newValue) || !isEmpty(oldValue)) && !(0, lodash_1.isEqual)(newValue, oldValue);
|
|
62
|
-
});
|
|
63
|
-
return changedCustomFields.map((changedCustomField) => ({
|
|
64
|
-
property: `customFields.${changedCustomField}`,
|
|
65
|
-
previousValue: previousCustomFields === null || previousCustomFields === void 0 ? void 0 : previousCustomFields[changedCustomField],
|
|
66
|
-
newValue: customFields === null || customFields === void 0 ? void 0 : customFields[changedCustomField],
|
|
67
|
-
}));
|
|
39
|
+
// It's a known issut with sequelize.
|
|
40
|
+
const changedProperties = options.returning ? options.fields : instance.changed();
|
|
41
|
+
return filterOutEmptyFields(changedProperties, instance);
|
|
68
42
|
};
|
|
69
43
|
class AuditLogger {
|
|
70
44
|
constructor(options) {
|
|
71
45
|
this.rabbit = options.rabbit;
|
|
72
46
|
this.sequelize = options.sequelize;
|
|
73
|
-
this.logger = options.logger
|
|
47
|
+
this.logger = options.logger;
|
|
74
48
|
}
|
|
75
49
|
registerHooks() {
|
|
76
50
|
Object.entries(this.sequelize.models).forEach(([modelName, modelType]) => {
|
|
@@ -78,18 +52,21 @@ class AuditLogger {
|
|
|
78
52
|
try {
|
|
79
53
|
const auditContext = getAuditContext();
|
|
80
54
|
if (auditContext) {
|
|
81
|
-
const
|
|
82
|
-
const changedCustomFieldsRows = getChangedCustomFieldsRows(instance);
|
|
55
|
+
const changedProperties = getChangedFields(instance, options);
|
|
83
56
|
const payload = {
|
|
84
57
|
entityType: modelName,
|
|
85
58
|
entityId: instance.id,
|
|
86
|
-
rows:
|
|
59
|
+
rows: changedProperties.map((property) => ({
|
|
60
|
+
property,
|
|
61
|
+
previousValue: instance.previous(property),
|
|
62
|
+
newValue: instance.get(property),
|
|
63
|
+
})),
|
|
87
64
|
};
|
|
88
65
|
this.sendAuditLogRows(payload);
|
|
89
66
|
}
|
|
90
67
|
}
|
|
91
68
|
catch (error) {
|
|
92
|
-
|
|
69
|
+
logger_1.default.error('Failed to send audit log rows', error);
|
|
93
70
|
}
|
|
94
71
|
}));
|
|
95
72
|
});
|
|
@@ -100,7 +77,7 @@ class AuditLogger {
|
|
|
100
77
|
yield this.rabbit.sendToQueue(const_1.AUDIT_LOG_CONTEXT_QUEUE, context);
|
|
101
78
|
}
|
|
102
79
|
catch (err) {
|
|
103
|
-
|
|
80
|
+
logger_1.default.error('Failed to send audit log context', err);
|
|
104
81
|
}
|
|
105
82
|
});
|
|
106
83
|
}
|
|
@@ -110,7 +87,7 @@ class AuditLogger {
|
|
|
110
87
|
yield this.rabbit.sendToQueue(const_1.AUDIT_LOG_ROWS_QUEUE, payload);
|
|
111
88
|
}
|
|
112
89
|
catch (err) {
|
|
113
|
-
|
|
90
|
+
logger_1.default.error('Failed to send audit log rows', err);
|
|
114
91
|
}
|
|
115
92
|
});
|
|
116
93
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ import AuditLogger from './audit-logger';
|
|
|
2
2
|
import { AuditLoggerOptions } from './types';
|
|
3
3
|
export declare const enableAuditing: (options: AuditLoggerOptions) => void;
|
|
4
4
|
export declare const setAuditContext: (entityType: string, action: string) => (req: any, res: any, next: any) => Promise<any>;
|
|
5
|
-
export declare const setRabbitAuditContext: (entityType: string, action: string) => (endpoint: string
|
|
5
|
+
export declare const setRabbitAuditContext: (entityType: string, action: string) => (endpoint: string, { userId, automationId }: {
|
|
6
|
+
userId: any;
|
|
7
|
+
automationId: any;
|
|
8
|
+
}) => Promise<any>;
|
|
6
9
|
export * from './types';
|
|
7
10
|
export * from './const';
|
|
8
11
|
export default AuditLogger;
|
package/dist/index.js
CHANGED
|
@@ -29,32 +29,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.setRabbitAuditContext = exports.setAuditContext = exports.enableAuditing = void 0;
|
|
30
30
|
const zehut_1 = require("@autofleet/zehut");
|
|
31
31
|
const audit_logger_1 = __importDefault(require("./audit-logger"));
|
|
32
|
+
const types_1 = require("./types");
|
|
32
33
|
const const_1 = require("./const");
|
|
33
34
|
const audit_api_1 = __importDefault(require("./audit-api"));
|
|
34
35
|
const logger_1 = __importDefault(require("./logger"));
|
|
35
36
|
let auditLogger;
|
|
36
37
|
const enableAuditing = (options) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
auditLogger.registerHooks();
|
|
41
|
-
}
|
|
38
|
+
auditLogger = new audit_logger_1.default(options);
|
|
39
|
+
(0, audit_api_1.default)(options);
|
|
40
|
+
auditLogger.registerHooks();
|
|
42
41
|
};
|
|
43
42
|
exports.enableAuditing = enableAuditing;
|
|
44
43
|
const setAuditContext = (entityType, action) => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
44
|
try {
|
|
46
|
-
if (process.env.DISABLE_AUDIT_LOGS === 'true') {
|
|
47
|
-
return next();
|
|
48
|
-
}
|
|
49
45
|
const currentTrace = (0, zehut_1.getCurrentPayload)();
|
|
50
46
|
if (currentTrace && currentTrace.context && currentTrace.context.get) {
|
|
51
47
|
const user = currentTrace.context.get(const_1.USER_CONTEXT_KEY);
|
|
48
|
+
const { performedBy, actionOrigin } = (user === null || user === void 0 ? void 0 : user.id)
|
|
49
|
+
? { performedBy: user.id, actionOrigin: types_1.ActionOrigin.USER }
|
|
50
|
+
: { performedBy: req.headers['x-af-automation-id'], actionOrigin: types_1.ActionOrigin.AUTOMATION };
|
|
52
51
|
const auditLogContext = {
|
|
53
52
|
entityType,
|
|
54
53
|
action,
|
|
55
54
|
endpoint: req.url,
|
|
56
55
|
method: req.method,
|
|
57
|
-
performedBy
|
|
56
|
+
performedBy,
|
|
57
|
+
actionOrigin,
|
|
58
58
|
};
|
|
59
59
|
currentTrace.context.set(const_1.AUDIT_LOG_CONTEXT_KEY, auditLogContext);
|
|
60
60
|
yield auditLogger.sendAuditLogContext(auditLogContext);
|
|
@@ -66,20 +66,20 @@ const setAuditContext = (entityType, action) => (req, res, next) => __awaiter(vo
|
|
|
66
66
|
return next();
|
|
67
67
|
});
|
|
68
68
|
exports.setAuditContext = setAuditContext;
|
|
69
|
-
const setRabbitAuditContext = (entityType, action) => (endpoint) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
const setRabbitAuditContext = (entityType, action) => (endpoint, { userId, automationId }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
70
70
|
var _a;
|
|
71
|
-
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
71
|
+
console.log({ automationId });
|
|
74
72
|
const currentTrace = (0, zehut_1.getCurrentPayload)();
|
|
73
|
+
const user = currentTrace.context.get(const_1.USER_CONTEXT_KEY);
|
|
74
|
+
const contextAutomationId = currentTrace.context.get('x-af-automation-id');
|
|
75
75
|
if ((_a = currentTrace === null || currentTrace === void 0 ? void 0 : currentTrace.context) === null || _a === void 0 ? void 0 : _a.get) {
|
|
76
|
-
const user = currentTrace.context.get(const_1.USER_CONTEXT_KEY);
|
|
77
76
|
const auditLogContext = {
|
|
78
77
|
entityType,
|
|
79
78
|
action,
|
|
80
79
|
endpoint,
|
|
81
80
|
method: 'rabbit',
|
|
82
|
-
performedBy: user === null || user === void 0 ? void 0 : user.id,
|
|
81
|
+
performedBy: (user === null || user === void 0 ? void 0 : user.id) || contextAutomationId,
|
|
82
|
+
actionOrigin: userId ? types_1.ActionOrigin.USER : types_1.ActionOrigin.AUTOMATION,
|
|
83
83
|
};
|
|
84
84
|
currentTrace.context.set(const_1.AUDIT_LOG_CONTEXT_KEY, auditLogContext);
|
|
85
85
|
yield auditLogger.sendAuditLogContext(auditLogContext);
|
package/dist/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export interface AuditLogContext {
|
|
|
11
11
|
performedBy: string;
|
|
12
12
|
endpoint: string;
|
|
13
13
|
method: string;
|
|
14
|
+
actionOrigin?: string;
|
|
14
15
|
}
|
|
15
16
|
export interface AuditLogRow {
|
|
16
17
|
property: string;
|
|
@@ -46,3 +47,7 @@ export declare enum EntityType {
|
|
|
46
47
|
DRIVER = "Driver",
|
|
47
48
|
PRICE_CALCULATION = "PriceCalculation"
|
|
48
49
|
}
|
|
50
|
+
export declare enum ActionOrigin {
|
|
51
|
+
USER = "user",
|
|
52
|
+
AUTOMATION = "automation"
|
|
53
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EntityType = exports.Action = void 0;
|
|
3
|
+
exports.ActionOrigin = exports.EntityType = exports.Action = void 0;
|
|
4
4
|
var Action;
|
|
5
5
|
(function (Action) {
|
|
6
6
|
Action["CREATE"] = "create";
|
|
@@ -27,3 +27,8 @@ var EntityType;
|
|
|
27
27
|
EntityType["DRIVER"] = "Driver";
|
|
28
28
|
EntityType["PRICE_CALCULATION"] = "PriceCalculation";
|
|
29
29
|
})(EntityType = exports.EntityType || (exports.EntityType = {}));
|
|
30
|
+
var ActionOrigin;
|
|
31
|
+
(function (ActionOrigin) {
|
|
32
|
+
ActionOrigin["USER"] = "user";
|
|
33
|
+
ActionOrigin["AUTOMATION"] = "automation";
|
|
34
|
+
})(ActionOrigin = exports.ActionOrigin || (exports.ActionOrigin = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/shtinker",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1-beta",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@autofleet/errors": "^1.2.2",
|
|
16
16
|
"@autofleet/logger": "^4.0.6",
|
|
17
17
|
"@autofleet/network": "^1.4.7",
|
|
18
|
-
"@autofleet/rabbit": "^3.2.
|
|
18
|
+
"@autofleet/rabbit": "^3.2.22",
|
|
19
19
|
"lodash": "^4.17.21",
|
|
20
20
|
"sequelize-typescript": "^2.1.5"
|
|
21
21
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"typescript": "^4.9.5"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@autofleet/zehut": "^3.x
|
|
38
|
+
"@autofleet/zehut": "^3.x"
|
|
39
39
|
},
|
|
40
40
|
"author": "Autofleet",
|
|
41
41
|
"license": "ISC"
|
package/src/const.ts
CHANGED
|
@@ -2,3 +2,4 @@ export const AUDIT_LOG_CONTEXT_QUEUE = 'audit-log-context';
|
|
|
2
2
|
export const AUDIT_LOG_ROWS_QUEUE = 'audit-log-rows';
|
|
3
3
|
export const AUDIT_LOG_CONTEXT_KEY = 'auditLogContext';
|
|
4
4
|
export const USER_CONTEXT_KEY = 'userObject';
|
|
5
|
+
export const AUTOMATION_ID_HEADER = 'x-af-automation-id';
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getCurrentPayload as getCurrentTrace } from '@autofleet/zehut';
|
|
2
2
|
import AuditLogger from './audit-logger';
|
|
3
|
-
import { AuditLogContext, AuditLoggerOptions } from './types';
|
|
4
|
-
import { AUDIT_LOG_CONTEXT_KEY, USER_CONTEXT_KEY } from './const';
|
|
3
|
+
import { ActionOrigin, AuditLogContext, AuditLoggerOptions } from './types';
|
|
4
|
+
import { AUDIT_LOG_CONTEXT_KEY, AUTOMATION_ID_HEADER, USER_CONTEXT_KEY } from './const';
|
|
5
5
|
import addAuditApi from './audit-api';
|
|
6
6
|
import logger from './logger';
|
|
7
7
|
|
|
@@ -23,15 +23,20 @@ export const setAuditContext = (
|
|
|
23
23
|
if (process.env.DISABLE_AUDIT_LOGS === 'true') {
|
|
24
24
|
return next();
|
|
25
25
|
}
|
|
26
|
+
logger.info('shtinker automation context', { contextData: req.headers[AUTOMATION_ID_HEADER] });
|
|
26
27
|
const currentTrace = getCurrentTrace();
|
|
27
28
|
if (currentTrace && currentTrace.context && currentTrace.context.get) {
|
|
28
29
|
const user = currentTrace.context.get(USER_CONTEXT_KEY);
|
|
30
|
+
const { performedBy, actionOrigin } = user?.id
|
|
31
|
+
? { performedBy: user.id, actionOrigin: ActionOrigin.USER }
|
|
32
|
+
: { performedBy: req.headers[AUTOMATION_ID_HEADER] ?? null, actionOrigin: req.headers[AUTOMATION_ID_HEADER] ? ActionOrigin.AUTOMATION : null };
|
|
29
33
|
const auditLogContext: AuditLogContext = {
|
|
30
34
|
entityType,
|
|
31
35
|
action,
|
|
32
36
|
endpoint: req.url,
|
|
33
37
|
method: req.method,
|
|
34
|
-
performedBy
|
|
38
|
+
performedBy,
|
|
39
|
+
actionOrigin,
|
|
35
40
|
};
|
|
36
41
|
currentTrace.context.set(AUDIT_LOG_CONTEXT_KEY, auditLogContext);
|
|
37
42
|
await auditLogger.sendAuditLogContext(auditLogContext);
|
|
@@ -45,19 +50,22 @@ export const setAuditContext = (
|
|
|
45
50
|
export const setRabbitAuditContext = (
|
|
46
51
|
entityType: string,
|
|
47
52
|
action: string,
|
|
48
|
-
) => async (endpoint: string): Promise<any> => {
|
|
53
|
+
) => async (endpoint: string, { userId, automationId }:{ userId:string; automationId:string; }): Promise<any> => {
|
|
49
54
|
if (process.env.DISABLE_AUDIT_LOGS === 'true') {
|
|
50
55
|
return;
|
|
51
56
|
}
|
|
52
57
|
const currentTrace = getCurrentTrace();
|
|
53
58
|
if (currentTrace?.context?.get) {
|
|
54
|
-
const
|
|
59
|
+
const { performedBy, actionOrigin } = userId
|
|
60
|
+
? { performedBy: userId, actionOrigin: ActionOrigin.USER }
|
|
61
|
+
: { performedBy: automationId ?? null, actionOrigin: automationId ? ActionOrigin.AUTOMATION : null };
|
|
55
62
|
const auditLogContext: AuditLogContext = {
|
|
56
63
|
entityType,
|
|
57
64
|
action,
|
|
58
65
|
endpoint,
|
|
59
66
|
method: 'rabbit',
|
|
60
|
-
performedBy
|
|
67
|
+
performedBy,
|
|
68
|
+
actionOrigin,
|
|
61
69
|
};
|
|
62
70
|
currentTrace.context.set(AUDIT_LOG_CONTEXT_KEY, auditLogContext);
|
|
63
71
|
await auditLogger.sendAuditLogContext(auditLogContext);
|
package/src/types.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface AuditLogContext {
|
|
|
14
14
|
performedBy: string;
|
|
15
15
|
endpoint: string;
|
|
16
16
|
method: string;
|
|
17
|
+
actionOrigin?: string;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export interface AuditLogRow {
|
|
@@ -45,6 +46,7 @@ export enum Action {
|
|
|
45
46
|
UPSERT = 'upsert',
|
|
46
47
|
JOIN = 'join',
|
|
47
48
|
MOVE = 'move',
|
|
49
|
+
REOPTIMIZATION = 'reoptimization',
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
export enum EntityType {
|
|
@@ -53,3 +55,8 @@ export enum EntityType {
|
|
|
53
55
|
DRIVER = 'Driver',
|
|
54
56
|
PRICE_CALCULATION = 'PriceCalculation',
|
|
55
57
|
}
|
|
58
|
+
|
|
59
|
+
export const enum ActionOrigin {
|
|
60
|
+
USER = 'user',
|
|
61
|
+
AUTOMATION = 'automation',
|
|
62
|
+
}
|