enterprise-logging-system 1.0.0
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/README.md +16 -0
- package/dist/__tests__/exports.test.d.ts +2 -0
- package/dist/__tests__/exports.test.d.ts.map +1 -0
- package/dist/__tests__/exports.test.js +48 -0
- package/dist/__tests__/exports.test.js.map +1 -0
- package/dist/backend/config/database.d.ts +11 -0
- package/dist/backend/config/database.d.ts.map +1 -0
- package/dist/backend/config/database.js +65 -0
- package/dist/backend/config/database.js.map +1 -0
- package/dist/backend/config/logging.config.d.ts +28 -0
- package/dist/backend/config/logging.config.d.ts.map +1 -0
- package/dist/backend/config/logging.config.js +36 -0
- package/dist/backend/config/logging.config.js.map +1 -0
- package/dist/backend/controllers/LogController.d.ts +18 -0
- package/dist/backend/controllers/LogController.d.ts.map +1 -0
- package/dist/backend/controllers/LogController.js +159 -0
- package/dist/backend/controllers/LogController.js.map +1 -0
- package/dist/backend/index.d.ts +8 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +24 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/middleware/loggingMiddleware.d.ts +8 -0
- package/dist/backend/middleware/loggingMiddleware.d.ts.map +1 -0
- package/dist/backend/middleware/loggingMiddleware.js +112 -0
- package/dist/backend/middleware/loggingMiddleware.js.map +1 -0
- package/dist/backend/models/AccessLog.d.ts +73 -0
- package/dist/backend/models/AccessLog.d.ts.map +1 -0
- package/dist/backend/models/AccessLog.js +10 -0
- package/dist/backend/models/AccessLog.js.map +1 -0
- package/dist/backend/models/ChangeLog.d.ts +81 -0
- package/dist/backend/models/ChangeLog.d.ts.map +1 -0
- package/dist/backend/models/ChangeLog.js +11 -0
- package/dist/backend/models/ChangeLog.js.map +1 -0
- package/dist/backend/models/ExportLog.d.ts +64 -0
- package/dist/backend/models/ExportLog.d.ts.map +1 -0
- package/dist/backend/models/ExportLog.js +10 -0
- package/dist/backend/models/ExportLog.js.map +1 -0
- package/dist/backend/models/SessionLog.d.ts +94 -0
- package/dist/backend/models/SessionLog.d.ts.map +1 -0
- package/dist/backend/models/SessionLog.js +11 -0
- package/dist/backend/models/SessionLog.js.map +1 -0
- package/dist/backend/models/index.d.ts +5 -0
- package/dist/backend/models/index.d.ts.map +1 -0
- package/dist/backend/models/index.js +21 -0
- package/dist/backend/models/index.js.map +1 -0
- package/dist/backend/repositories/AccessLogRepository.d.ts +14 -0
- package/dist/backend/repositories/AccessLogRepository.d.ts.map +1 -0
- package/dist/backend/repositories/AccessLogRepository.js +60 -0
- package/dist/backend/repositories/AccessLogRepository.js.map +1 -0
- package/dist/backend/repositories/BaseRepository.d.ts +28 -0
- package/dist/backend/repositories/BaseRepository.d.ts.map +1 -0
- package/dist/backend/repositories/BaseRepository.js +112 -0
- package/dist/backend/repositories/BaseRepository.js.map +1 -0
- package/dist/backend/repositories/ChangeLogRepository.d.ts +12 -0
- package/dist/backend/repositories/ChangeLogRepository.d.ts.map +1 -0
- package/dist/backend/repositories/ChangeLogRepository.js +47 -0
- package/dist/backend/repositories/ChangeLogRepository.js.map +1 -0
- package/dist/backend/repositories/ExportLogRepository.d.ts +11 -0
- package/dist/backend/repositories/ExportLogRepository.d.ts.map +1 -0
- package/dist/backend/repositories/ExportLogRepository.js +45 -0
- package/dist/backend/repositories/ExportLogRepository.js.map +1 -0
- package/dist/backend/repositories/SessionLogRepository.d.ts +20 -0
- package/dist/backend/repositories/SessionLogRepository.d.ts.map +1 -0
- package/dist/backend/repositories/SessionLogRepository.js +171 -0
- package/dist/backend/repositories/SessionLogRepository.js.map +1 -0
- package/dist/backend/repositories/index.d.ts +6 -0
- package/dist/backend/repositories/index.d.ts.map +1 -0
- package/dist/backend/repositories/index.js +22 -0
- package/dist/backend/repositories/index.js.map +1 -0
- package/dist/backend/services/LoggingService.d.ts +110 -0
- package/dist/backend/services/LoggingService.d.ts.map +1 -0
- package/dist/backend/services/LoggingService.js +97 -0
- package/dist/backend/services/LoggingService.js.map +1 -0
- package/dist/backend/utils/Logger.d.ts +8 -0
- package/dist/backend/utils/Logger.d.ts.map +1 -0
- package/dist/backend/utils/Logger.js +23 -0
- package/dist/backend/utils/Logger.js.map +1 -0
- package/dist/examples/queries.d.ts +29 -0
- package/dist/examples/queries.d.ts.map +1 -0
- package/dist/examples/queries.js +151 -0
- package/dist/examples/queries.js.map +1 -0
- package/dist/frontend/activity-monitor/ActivityMonitor.d.ts +45 -0
- package/dist/frontend/activity-monitor/ActivityMonitor.d.ts.map +1 -0
- package/dist/frontend/activity-monitor/ActivityMonitor.js +159 -0
- package/dist/frontend/activity-monitor/ActivityMonitor.js.map +1 -0
- package/dist/frontend/idle-tracker/IdleTracker.d.ts +34 -0
- package/dist/frontend/idle-tracker/IdleTracker.d.ts.map +1 -0
- package/dist/frontend/idle-tracker/IdleTracker.js +56 -0
- package/dist/frontend/idle-tracker/IdleTracker.js.map +1 -0
- package/dist/frontend/index.d.ts +3 -0
- package/dist/frontend/index.d.ts.map +1 -0
- package/dist/frontend/index.js +19 -0
- package/dist/frontend/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/shared/types/index.d.ts +41 -0
- package/dist/shared/types/index.d.ts.map +1 -0
- package/dist/shared/types/index.js +3 -0
- package/dist/shared/types/index.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Enterprise Logging System
|
|
2
|
+
|
|
3
|
+
A comprehensive logging system with idle time tracking, compatible with both MongoDB and Amazon DocumentDB.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Access Logs**: Page views, user actions, system information
|
|
8
|
+
- **Session Logs**: With accurate idle time tracking and configurable thresholds
|
|
9
|
+
- **Change Logs**: Field-level auditing with old/new value comparison
|
|
10
|
+
- **Export Logs**: Complete export history tracking
|
|
11
|
+
- **DocumentDB Compatible**: Same code runs on MongoDB and DocumentDB
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @enterprise-logging/system
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/exports.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const pkg = __importStar(require("../index"));
|
|
37
|
+
describe('package exports', () => {
|
|
38
|
+
it('exports expected symbols', () => {
|
|
39
|
+
expect(pkg).toBeTruthy();
|
|
40
|
+
// Backend
|
|
41
|
+
expect(typeof pkg.setupLoggingSystem).toBe('function');
|
|
42
|
+
expect(typeof pkg.LoggingService).toBe('function');
|
|
43
|
+
// Frontend (should be importable; not instantiating in Node test env)
|
|
44
|
+
expect(typeof pkg.ActivityMonitor).toBe('function');
|
|
45
|
+
expect(typeof pkg.IdleTracker).toBe('function');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=exports.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports.test.js","sourceRoot":"","sources":["../../src/__tests__/exports.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,8CAAgC;AAEhC,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;QAEzB,UAAU;QACV,MAAM,CAAC,OAAQ,GAAW,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,MAAM,CAAC,OAAQ,GAAW,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE5D,sEAAsE;QACtE,MAAM,CAAC,OAAQ,GAAW,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAQ,GAAW,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Db } from 'mongodb';
|
|
2
|
+
export declare class DatabaseClient {
|
|
3
|
+
private client;
|
|
4
|
+
private db;
|
|
5
|
+
private logger;
|
|
6
|
+
constructor();
|
|
7
|
+
connect(): Promise<Db>;
|
|
8
|
+
disconnect(): Promise<void>;
|
|
9
|
+
getDatabase(): Db;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=database.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/backend/config/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,EAAE,EAA2B,MAAM,SAAS,CAAC;AAGnE,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,MAAM,CAAS;;IAMjB,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC;IA4CtB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAOjC,WAAW,IAAI,EAAE;CAMlB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseClient = void 0;
|
|
4
|
+
const mongodb_1 = require("mongodb");
|
|
5
|
+
const Logger_1 = require("../utils/Logger");
|
|
6
|
+
class DatabaseClient {
|
|
7
|
+
client = null;
|
|
8
|
+
db = null;
|
|
9
|
+
logger;
|
|
10
|
+
constructor() {
|
|
11
|
+
this.logger = new Logger_1.Logger('DatabaseClient');
|
|
12
|
+
}
|
|
13
|
+
async connect() {
|
|
14
|
+
const uri = process.env.MONGO_URI || 'mongodb://localhost:27017';
|
|
15
|
+
const dbName = process.env.MONGO_DB_NAME || 'enterprise_logs';
|
|
16
|
+
try {
|
|
17
|
+
const writeConcernEnv = process.env.MONGO_WRITE_CONCERN;
|
|
18
|
+
const w = writeConcernEnv === undefined
|
|
19
|
+
? undefined
|
|
20
|
+
: writeConcernEnv === 'majority'
|
|
21
|
+
? 'majority'
|
|
22
|
+
: Number.isFinite(Number(writeConcernEnv))
|
|
23
|
+
? Number(writeConcernEnv)
|
|
24
|
+
: undefined;
|
|
25
|
+
const options = {
|
|
26
|
+
maxPoolSize: parseInt(process.env.MONGO_POOL_SIZE || '10'),
|
|
27
|
+
minPoolSize: parseInt(process.env.MONGO_MIN_POOL_SIZE || '2'),
|
|
28
|
+
tls: process.env.MONGO_TLS === 'true' ? true : false,
|
|
29
|
+
tlsCAFile: process.env.MONGO_TLS_CA_FILE,
|
|
30
|
+
tlsAllowInvalidCertificates: process.env.MONGO_TLS_ALLOW_INVALID === 'true',
|
|
31
|
+
retryWrites: process.env.MONGO_RETRY_WRITES === 'true',
|
|
32
|
+
...(w !== undefined ? { w } : {})
|
|
33
|
+
};
|
|
34
|
+
// Clean options (remove undefined values)
|
|
35
|
+
Object.keys(options).forEach(key => {
|
|
36
|
+
if (options[key] === undefined) {
|
|
37
|
+
delete options[key];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
this.client = new mongodb_1.MongoClient(uri, options);
|
|
41
|
+
await this.client.connect();
|
|
42
|
+
this.db = this.client.db(dbName);
|
|
43
|
+
this.logger.info(`Connected to database: ${dbName}`);
|
|
44
|
+
return this.db;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
this.logger.error('Failed to connect to database:', error);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async disconnect() {
|
|
52
|
+
if (this.client) {
|
|
53
|
+
await this.client.close();
|
|
54
|
+
this.logger.info('Disconnected from database');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
getDatabase() {
|
|
58
|
+
if (!this.db) {
|
|
59
|
+
throw new Error('Database not connected');
|
|
60
|
+
}
|
|
61
|
+
return this.db;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.DatabaseClient = DatabaseClient;
|
|
65
|
+
//# sourceMappingURL=database.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/backend/config/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const loggingConfig: {
|
|
2
|
+
database: {
|
|
3
|
+
uri: string;
|
|
4
|
+
dbName: string;
|
|
5
|
+
poolSize: number;
|
|
6
|
+
tls: boolean;
|
|
7
|
+
tlsCAFile: string;
|
|
8
|
+
retryWrites: boolean;
|
|
9
|
+
};
|
|
10
|
+
idleTracking: {
|
|
11
|
+
threshold: number;
|
|
12
|
+
heartbeatInterval: number;
|
|
13
|
+
batchSize: number;
|
|
14
|
+
batchInterval: number;
|
|
15
|
+
};
|
|
16
|
+
retention: {
|
|
17
|
+
accessLogs: number;
|
|
18
|
+
sessionLogs: number;
|
|
19
|
+
changeLogs: number;
|
|
20
|
+
exportLogs: number;
|
|
21
|
+
};
|
|
22
|
+
api: {
|
|
23
|
+
port: number;
|
|
24
|
+
basePath: string;
|
|
25
|
+
corsOrigin: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=logging.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.config.d.ts","sourceRoot":"","sources":["../../../src/backend/config/logging.config.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCzB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loggingConfig = void 0;
|
|
4
|
+
// config/logging.config.ts
|
|
5
|
+
exports.loggingConfig = {
|
|
6
|
+
// Database configuration
|
|
7
|
+
database: {
|
|
8
|
+
uri: process.env.MONGO_URI || 'mongodb://localhost:27017',
|
|
9
|
+
dbName: process.env.MONGO_DB_NAME || 'enterprise_logs',
|
|
10
|
+
poolSize: parseInt(process.env.MONGO_POOL_SIZE || '10'),
|
|
11
|
+
tls: process.env.MONGO_TLS === 'true',
|
|
12
|
+
tlsCAFile: process.env.MONGO_TLS_CA_FILE,
|
|
13
|
+
retryWrites: process.env.MONGO_RETRY_WRITES === 'true'
|
|
14
|
+
},
|
|
15
|
+
// Idle tracking
|
|
16
|
+
idleTracking: {
|
|
17
|
+
threshold: parseInt(process.env.IDLE_THRESHOLD || '300000'), // 5 minutes
|
|
18
|
+
heartbeatInterval: parseInt(process.env.HEARTBEAT_INTERVAL || '30000'), // 30 seconds
|
|
19
|
+
batchSize: parseInt(process.env.ACTIVITY_BATCH_SIZE || '10'),
|
|
20
|
+
batchInterval: parseInt(process.env.BATCH_INTERVAL || '5000') // 5 seconds
|
|
21
|
+
},
|
|
22
|
+
// Log retention
|
|
23
|
+
retention: {
|
|
24
|
+
accessLogs: parseInt(process.env.ACCESS_LOG_RETENTION || '30'), // days
|
|
25
|
+
sessionLogs: parseInt(process.env.SESSION_LOG_RETENTION || '30'),
|
|
26
|
+
changeLogs: parseInt(process.env.CHANGE_LOG_RETENTION || '90'),
|
|
27
|
+
exportLogs: parseInt(process.env.EXPORT_LOG_RETENTION || '90')
|
|
28
|
+
},
|
|
29
|
+
// API configuration
|
|
30
|
+
api: {
|
|
31
|
+
port: parseInt(process.env.LOGGING_API_PORT || '3001'),
|
|
32
|
+
basePath: process.env.LOGGING_API_BASE_PATH || '/api/logs',
|
|
33
|
+
corsOrigin: process.env.CORS_ORIGIN || '*'
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=logging.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logging.config.js","sourceRoot":"","sources":["../../../src/backend/config/logging.config.ts"],"names":[],"mappings":";;;AAAA,2BAA2B;AACd,QAAA,aAAa,GAAG;IAC3B,yBAAyB;IACzB,QAAQ,EAAE;QACR,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,2BAA2B;QACzD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,iBAAiB;QACtD,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC;QACvD,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM;QACrC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM;KACvD;IAED,gBAAgB;IAChB,YAAY,EAAE;QACZ,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,QAAQ,CAAC,EAAE,YAAY;QACzE,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,EAAE,aAAa;QACrF,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC;QAC5D,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC,YAAY;KAC3E;IAED,gBAAgB;IAChB,SAAS,EAAE;QACT,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC,EAAE,OAAO;QACvE,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,IAAI,CAAC;QAChE,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC;QAC9D,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,CAAC;KAC/D;IAED,oBAAoB;IACpB,GAAG,EAAE;QACH,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC;QACtD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,WAAW;QAC1D,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG;KAC3C;CACF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
import { LoggingService } from '../services/LoggingService';
|
|
3
|
+
export declare class LogController {
|
|
4
|
+
private loggingService;
|
|
5
|
+
constructor(loggingService: LoggingService);
|
|
6
|
+
logPageView(req: Request, res: Response): Promise<void>;
|
|
7
|
+
logAction(req: Request, res: Response): Promise<void>;
|
|
8
|
+
startSession(req: Request, res: Response): Promise<void>;
|
|
9
|
+
endSession(req: Request, res: Response): Promise<void>;
|
|
10
|
+
recordHeartbeat(req: Request, res: Response): Promise<void>;
|
|
11
|
+
recordActivity(req: Request, res: Response): Promise<void>;
|
|
12
|
+
getUserTimeline(req: Request, res: Response): Promise<void>;
|
|
13
|
+
getSessionDetails(req: Request, res: Response): Promise<void>;
|
|
14
|
+
getEntityHistory(req: Request, res: Response): Promise<void>;
|
|
15
|
+
getExportHistory(req: Request, res: Response): Promise<void>;
|
|
16
|
+
batchActivities(req: Request, res: Response): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=LogController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogController.d.ts","sourceRoot":"","sources":["../../../src/backend/controllers/LogController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,qBAAa,aAAa;IACZ,OAAO,CAAC,cAAc;gBAAd,cAAc,EAAE,cAAc;IAG5C,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvD,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAWrD,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxD,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAWtD,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAU3D,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1D,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3D,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7D,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5D,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAY5D,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAqClE"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LogController = void 0;
|
|
4
|
+
class LogController {
|
|
5
|
+
loggingService;
|
|
6
|
+
constructor(loggingService) {
|
|
7
|
+
this.loggingService = loggingService;
|
|
8
|
+
}
|
|
9
|
+
// Access Log endpoints
|
|
10
|
+
async logPageView(req, res) {
|
|
11
|
+
try {
|
|
12
|
+
const data = req.body;
|
|
13
|
+
const result = await this.loggingService.logPageView(data);
|
|
14
|
+
res.json({ success: true, data: result });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
res.status(500).json({ success: false, error: error.message });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async logAction(req, res) {
|
|
21
|
+
try {
|
|
22
|
+
const data = req.body;
|
|
23
|
+
const result = await this.loggingService.logAction(data);
|
|
24
|
+
res.json({ success: true, data: result });
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
res.status(500).json({ success: false, error: error.message });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Session endpoints
|
|
31
|
+
async startSession(req, res) {
|
|
32
|
+
try {
|
|
33
|
+
const data = req.body;
|
|
34
|
+
const result = await this.loggingService.startSession(data);
|
|
35
|
+
res.json({ success: true, data: result });
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
res.status(500).json({ success: false, error: error.message });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async endSession(req, res) {
|
|
42
|
+
try {
|
|
43
|
+
const { sessionId } = req.params;
|
|
44
|
+
const { reason } = req.body;
|
|
45
|
+
const result = await this.loggingService.endSession(sessionId, reason);
|
|
46
|
+
res.json({ success: true, data: result });
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
res.status(500).json({ success: false, error: error.message });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async recordHeartbeat(req, res) {
|
|
53
|
+
try {
|
|
54
|
+
const { sessionId } = req.body;
|
|
55
|
+
const result = await this.loggingService.recordHeartbeat(sessionId);
|
|
56
|
+
res.json({ success: true, data: result });
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
res.status(500).json({ success: false, error: error.message });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async recordActivity(req, res) {
|
|
63
|
+
try {
|
|
64
|
+
const { sessionId } = req.body;
|
|
65
|
+
const result = await this.loggingService.recordActivity(sessionId);
|
|
66
|
+
res.json({ success: true, data: result });
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
res.status(500).json({ success: false, error: error.message });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Query endpoints
|
|
73
|
+
async getUserTimeline(req, res) {
|
|
74
|
+
try {
|
|
75
|
+
const { userId } = req.params;
|
|
76
|
+
const { startDate, endDate } = req.query;
|
|
77
|
+
const dateRange = {
|
|
78
|
+
startDate: new Date(startDate),
|
|
79
|
+
endDate: new Date(endDate)
|
|
80
|
+
};
|
|
81
|
+
const result = await this.loggingService.getUserTimeline(userId, dateRange);
|
|
82
|
+
res.json({ success: true, data: result });
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
res.status(500).json({ success: false, error: error.message });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async getSessionDetails(req, res) {
|
|
89
|
+
try {
|
|
90
|
+
const { sessionId } = req.params;
|
|
91
|
+
const result = await this.loggingService.getSessionDetails(sessionId);
|
|
92
|
+
res.json({ success: true, data: result });
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
res.status(500).json({ success: false, error: error.message });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async getEntityHistory(req, res) {
|
|
99
|
+
try {
|
|
100
|
+
const { entityType, entityId } = req.params;
|
|
101
|
+
const result = await this.loggingService.getEntityHistory(entityType, entityId);
|
|
102
|
+
res.json({ success: true, data: result });
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
res.status(500).json({ success: false, error: error.message });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async getExportHistory(req, res) {
|
|
109
|
+
try {
|
|
110
|
+
const { userId } = req.params;
|
|
111
|
+
const { exportType } = req.query;
|
|
112
|
+
const result = await this.loggingService.getExportHistory(userId, exportType);
|
|
113
|
+
res.json({ success: true, data: result });
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
res.status(500).json({ success: false, error: error.message });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Batch endpoints for frontend
|
|
120
|
+
async batchActivities(req, res) {
|
|
121
|
+
try {
|
|
122
|
+
const { sessionId, userId, events } = req.body;
|
|
123
|
+
// Process batch of events
|
|
124
|
+
const results = [];
|
|
125
|
+
for (const event of events) {
|
|
126
|
+
if (event.type === 'PAGE_VIEW') {
|
|
127
|
+
const result = await this.loggingService.logPageView({
|
|
128
|
+
tenantId: req.headers['x-tenant-id'],
|
|
129
|
+
userId,
|
|
130
|
+
userRole: req.headers['x-user-role'] || 'user',
|
|
131
|
+
sessionId,
|
|
132
|
+
ipAddress: req.ip || '',
|
|
133
|
+
userAgent: req.headers['user-agent'] || '',
|
|
134
|
+
...event.data
|
|
135
|
+
});
|
|
136
|
+
results.push(result);
|
|
137
|
+
}
|
|
138
|
+
else if (event.type === 'ACTION') {
|
|
139
|
+
const result = await this.loggingService.logAction({
|
|
140
|
+
tenantId: req.headers['x-tenant-id'],
|
|
141
|
+
userId,
|
|
142
|
+
userRole: req.headers['x-user-role'] || 'user',
|
|
143
|
+
sessionId,
|
|
144
|
+
ipAddress: req.ip || '',
|
|
145
|
+
userAgent: req.headers['user-agent'] || '',
|
|
146
|
+
...event.data
|
|
147
|
+
});
|
|
148
|
+
results.push(result);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
res.json({ success: true, data: results });
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
res.status(500).json({ success: false, error: error.message });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.LogController = LogController;
|
|
159
|
+
//# sourceMappingURL=LogController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogController.js","sourceRoot":"","sources":["../../../src/backend/controllers/LogController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './services/LoggingService';
|
|
2
|
+
export * from './controllers/LogController';
|
|
3
|
+
export * from './middleware/loggingMiddleware';
|
|
4
|
+
export * from './repositories';
|
|
5
|
+
export * from './models';
|
|
6
|
+
export * from './config/database';
|
|
7
|
+
export * from './config/logging.config';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./services/LoggingService"), exports);
|
|
18
|
+
__exportStar(require("./controllers/LogController"), exports);
|
|
19
|
+
__exportStar(require("./middleware/loggingMiddleware"), exports);
|
|
20
|
+
__exportStar(require("./repositories"), exports);
|
|
21
|
+
__exportStar(require("./models"), exports);
|
|
22
|
+
__exportStar(require("./config/database"), exports);
|
|
23
|
+
__exportStar(require("./config/logging.config"), exports);
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/backend/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C;AAC1C,8DAA4C;AAC5C,iEAA+C;AAC/C,iDAA+B;AAC/B,2CAAyB;AACzB,oDAAkC;AAClC,0DAAwC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { LoggingService } from '../services/LoggingService';
|
|
3
|
+
export declare function createLoggingMiddleware(loggingService: LoggingService): {
|
|
4
|
+
apiLogger: (req: Request, res: Response, next: NextFunction) => void;
|
|
5
|
+
sessionTracker: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
6
|
+
changeLogger: (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=loggingMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggingMiddleware.d.ts","sourceRoot":"","sources":["../../../src/backend/middleware/loggingMiddleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,cAAc;qBAGjD,OAAO,OAAO,QAAQ,QAAQ,YAAY;0BAoC/B,OAAO,OAAO,QAAQ,QAAQ,YAAY;wBA0B5C,OAAO,OAAO,QAAQ,QAAQ,YAAY;EAoDvE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createLoggingMiddleware = createLoggingMiddleware;
|
|
4
|
+
function createLoggingMiddleware(loggingService) {
|
|
5
|
+
return {
|
|
6
|
+
// Log all API requests
|
|
7
|
+
apiLogger: (req, res, next) => {
|
|
8
|
+
const startTime = Date.now();
|
|
9
|
+
res.on('finish', async () => {
|
|
10
|
+
try {
|
|
11
|
+
const duration = Date.now() - startTime;
|
|
12
|
+
await loggingService.logAction({
|
|
13
|
+
tenantId: req.headers['x-tenant-id'],
|
|
14
|
+
userId: req.headers['x-user-id'] || 'anonymous',
|
|
15
|
+
userRole: req.headers['x-user-role'] || 'guest',
|
|
16
|
+
sessionId: req.headers['x-session-id'] || '',
|
|
17
|
+
ipAddress: req.ip || '',
|
|
18
|
+
userAgent: req.headers['user-agent'] || '',
|
|
19
|
+
activityType: 'API_CALL',
|
|
20
|
+
activityName: `${req.method} ${req.path}`,
|
|
21
|
+
actionType: 'HTTP_REQUEST',
|
|
22
|
+
actionTarget: req.path,
|
|
23
|
+
actionData: {
|
|
24
|
+
method: req.method,
|
|
25
|
+
path: req.path,
|
|
26
|
+
statusCode: res.statusCode,
|
|
27
|
+
duration,
|
|
28
|
+
query: req.query,
|
|
29
|
+
params: req.params
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error('Failed to log API request:', error);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
next();
|
|
38
|
+
},
|
|
39
|
+
// Auto-start session for authenticated requests
|
|
40
|
+
sessionTracker: async (req, res, next) => {
|
|
41
|
+
const sessionId = req.headers['x-session-id'];
|
|
42
|
+
const userId = req.headers['x-user-id'];
|
|
43
|
+
if (userId && sessionId && !req.headers['x-session-logged']) {
|
|
44
|
+
try {
|
|
45
|
+
await loggingService.startSession({
|
|
46
|
+
tenantId: req.headers['x-tenant-id'],
|
|
47
|
+
userId,
|
|
48
|
+
userRole: req.headers['x-user-role'] || 'user',
|
|
49
|
+
sessionId,
|
|
50
|
+
ipAddress: req.ip || '',
|
|
51
|
+
userAgent: req.headers['user-agent'] || ''
|
|
52
|
+
});
|
|
53
|
+
// Mark as logged to prevent duplicate session starts
|
|
54
|
+
req.headers['x-session-logged'] = 'true';
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('Failed to start session:', error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
next();
|
|
61
|
+
},
|
|
62
|
+
// Track changes in request body
|
|
63
|
+
changeLogger: async (req, res, next) => {
|
|
64
|
+
const originalSend = res.send;
|
|
65
|
+
res.send = function (body) {
|
|
66
|
+
// Only log successful POST, PUT, PATCH, DELETE requests
|
|
67
|
+
if ([200, 201].includes(res.statusCode) &&
|
|
68
|
+
['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
|
|
69
|
+
// Parse the response to get entity information
|
|
70
|
+
try {
|
|
71
|
+
const response = typeof body === 'string' ? JSON.parse(body) : body;
|
|
72
|
+
if (response.data?.id || response.data?._id) {
|
|
73
|
+
// Extract entity info from request
|
|
74
|
+
const entityMatch = req.path.match(/\/([^\/]+)\/?$/);
|
|
75
|
+
const entityType = entityMatch ? entityMatch[1] : 'unknown';
|
|
76
|
+
// In a real implementation, you would compare old vs new values
|
|
77
|
+
// This is a simplified version
|
|
78
|
+
setTimeout(async () => {
|
|
79
|
+
try {
|
|
80
|
+
await loggingService.logChange({
|
|
81
|
+
tenantId: req.headers['x-tenant-id'],
|
|
82
|
+
userId: req.headers['x-user-id'] || 'system',
|
|
83
|
+
userRole: req.headers['x-user-role'] || 'system',
|
|
84
|
+
sessionId: req.headers['x-session-id'] || '',
|
|
85
|
+
ipAddress: req.ip || '',
|
|
86
|
+
userAgent: req.headers['user-agent'] || '',
|
|
87
|
+
entityType,
|
|
88
|
+
entityId: response.data.id || response.data._id,
|
|
89
|
+
type: req.method === 'POST' ? 'CREATE' :
|
|
90
|
+
req.method === 'DELETE' ? 'DELETE' : 'UPDATE',
|
|
91
|
+
changes: [], // In real impl, populate with field changes
|
|
92
|
+
status: 'SUCCESS',
|
|
93
|
+
reason: req.headers['x-change-reason']
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error('Failed to log change:', error);
|
|
98
|
+
}
|
|
99
|
+
}, 0);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error('Failed to parse response for change logging:', error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return originalSend.call(this, body);
|
|
107
|
+
};
|
|
108
|
+
next();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=loggingMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loggingMiddleware.js","sourceRoot":"","sources":["../../../src/backend/middleware/loggingMiddleware.ts"],"names":[],"mappings":"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"}
|