@carlonicora/nestjs-neo4jsonapi 4.13.0 → 4.15.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/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +1 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +22 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +5 -0
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/enums/queue.id.d.ts +1 -0
- package/dist/config/enums/queue.id.d.ts.map +1 -1
- package/dist/config/enums/queue.id.js +1 -0
- package/dist/config/enums/queue.id.js.map +1 -1
- package/dist/config/interfaces/base.config.interface.d.ts +2 -0
- package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.analytics.interface.d.ts +13 -0
- package/dist/config/interfaces/config.analytics.interface.d.ts.map +1 -0
- package/dist/config/interfaces/config.analytics.interface.js +3 -0
- package/dist/config/interfaces/config.analytics.interface.js.map +1 -0
- package/dist/config/interfaces/index.d.ts +1 -0
- package/dist/config/interfaces/index.d.ts.map +1 -1
- package/dist/config/interfaces/index.js +1 -0
- package/dist/config/interfaces/index.js.map +1 -1
- package/dist/foundations/analytics/analytics.module.d.ts +39 -0
- package/dist/foundations/analytics/analytics.module.d.ts.map +1 -0
- package/dist/foundations/analytics/analytics.module.js +122 -0
- package/dist/foundations/analytics/analytics.module.js.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts +32 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js +197 -0
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.controller.d.ts +29 -0
- package/dist/foundations/analytics/controllers/analytics.controller.d.ts.map +1 -0
- package/dist/foundations/analytics/controllers/analytics.controller.js +85 -0
- package/dist/foundations/analytics/controllers/analytics.controller.js.map +1 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts +13 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.d.ts.map +1 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.js +61 -0
- package/dist/foundations/analytics/cron/analytics-retention.cron.js.map +1 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts +21 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.d.ts.map +1 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.js +105 -0
- package/dist/foundations/analytics/dtos/analytics-event.post.dto.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.d.ts +17 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.js +18 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-breakdown.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts +30 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.js +28 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-daily-summary.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.d.ts +8 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.js +15 -0
- package/dist/foundations/analytics/entities/analytics-event.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.d.ts +39 -0
- package/dist/foundations/analytics/entities/analytics-page-view.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.js +38 -0
- package/dist/foundations/analytics/entities/analytics-page-view.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-page-view.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.d.ts +52 -0
- package/dist/foundations/analytics/entities/analytics-session.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.js +47 -0
- package/dist/foundations/analytics/entities/analytics-session.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-session.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.d.ts +24 -0
- package/dist/foundations/analytics/entities/analytics-summary.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.js +20 -0
- package/dist/foundations/analytics/entities/analytics-summary.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-summary.meta.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.d.ts +20 -0
- package/dist/foundations/analytics/entities/analytics-timeline.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.js +18 -0
- package/dist/foundations/analytics/entities/analytics-timeline.js.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts +3 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.d.ts.map +1 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.js +10 -0
- package/dist/foundations/analytics/entities/analytics-timeline.meta.js.map +1 -0
- package/dist/foundations/analytics/index.d.ts +27 -0
- package/dist/foundations/analytics/index.d.ts.map +1 -0
- package/dist/foundations/analytics/index.js +54 -0
- package/dist/foundations/analytics/index.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts +80 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.js +28 -0
- package/dist/foundations/analytics/interfaces/analytics.config.interface.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts +30 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.js +3 -0
- package/dist/foundations/analytics/interfaces/analytics.page-view.input.js.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts +30 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.d.ts.map +1 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js +3 -0
- package/dist/foundations/analytics/interfaces/analytics.resolved-page-view.js.map +1 -0
- package/dist/foundations/analytics/processors/analytics.processor.d.ts +33 -0
- package/dist/foundations/analytics/processors/analytics.processor.d.ts.map +1 -0
- package/dist/foundations/analytics/processors/analytics.processor.js +126 -0
- package/dist/foundations/analytics/processors/analytics.processor.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts +38 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js +142 -0
- package/dist/foundations/analytics/repositories/analytics-daily-summary.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts +30 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.js +62 -0
- package/dist/foundations/analytics/repositories/analytics-page-view.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts +87 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.js +261 -0
- package/dist/foundations/analytics/repositories/analytics-session.repository.js.map +1 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts +145 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.d.ts.map +1 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.js +490 -0
- package/dist/foundations/analytics/repositories/analytics.admin.repository.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.admin.service.d.ts +74 -0
- package/dist/foundations/analytics/services/analytics.admin.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.admin.service.js +126 -0
- package/dist/foundations/analytics/services/analytics.admin.service.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.service.d.ts +31 -0
- package/dist/foundations/analytics/services/analytics.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.service.js +57 -0
- package/dist/foundations/analytics/services/analytics.service.js.map +1 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts +34 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.d.ts.map +1 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.js +93 -0
- package/dist/foundations/analytics/services/analytics.visitor-id.service.js.map +1 -0
- package/dist/foundations/foundations.modules.d.ts +3 -0
- package/dist/foundations/foundations.modules.d.ts.map +1 -1
- package/dist/foundations/foundations.modules.js +3 -1
- package/dist/foundations/foundations.modules.js.map +1 -1
- package/dist/foundations/index.d.ts +1 -0
- package/dist/foundations/index.d.ts.map +1 -1
- package/dist/foundations/index.js +1 -0
- package/dist/foundations/index.js.map +1 -1
- package/dist/foundations/s3/services/s3.service.d.ts +1 -0
- package/dist/foundations/s3/services/s3.service.d.ts.map +1 -1
- package/dist/foundations/s3/services/s3.service.js +10 -3
- package/dist/foundations/s3/services/s3.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AnalyticsAdminService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
18
|
+
const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
|
|
19
|
+
const jsonapi_paginator_1 = require("../../../core/jsonapi/serialisers/jsonapi.paginator");
|
|
20
|
+
const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
|
|
21
|
+
const analytics_breakdown_1 = require("../entities/analytics-breakdown");
|
|
22
|
+
const analytics_page_view_1 = require("../entities/analytics-page-view");
|
|
23
|
+
const analytics_session_1 = require("../entities/analytics-session");
|
|
24
|
+
const analytics_summary_1 = require("../entities/analytics-summary");
|
|
25
|
+
const analytics_timeline_1 = require("../entities/analytics-timeline");
|
|
26
|
+
const analytics_config_interface_1 = require("../interfaces/analytics.config.interface");
|
|
27
|
+
const analytics_page_view_repository_1 = require("../repositories/analytics-page-view.repository");
|
|
28
|
+
const analytics_session_repository_1 = require("../repositories/analytics-session.repository");
|
|
29
|
+
const analytics_admin_repository_1 = require("../repositories/analytics.admin.repository");
|
|
30
|
+
/**
|
|
31
|
+
* Serialises the platform-wide web analytics reports as JSON:API documents.
|
|
32
|
+
*
|
|
33
|
+
* Extends AbstractService over the AnalyticsSession descriptor and its
|
|
34
|
+
* repository, mirroring TokenUsageAdminService: the inherited CRUD is not
|
|
35
|
+
* reachable from any route on AnalyticsAdminController, but keeps the base
|
|
36
|
+
* class coherent. Summary, timeline and breakdown serialise with the
|
|
37
|
+
* AGGREGATE descriptors' models, because their rows are rollups, not nodes.
|
|
38
|
+
*
|
|
39
|
+
* JSON:API documents are built exclusively by the framework — nothing here
|
|
40
|
+
* hand-assembles a { data: { type, attributes } } object.
|
|
41
|
+
*/
|
|
42
|
+
let AnalyticsAdminService = class AnalyticsAdminService extends abstract_service_1.AbstractService {
|
|
43
|
+
constructor(jsonApiService, analyticsSessionRepository, clsService, analyticsAdminRepository, analyticsPageViewRepository, config) {
|
|
44
|
+
super(jsonApiService, analyticsSessionRepository, clsService, analytics_session_1.AnalyticsSessionDescriptor.model);
|
|
45
|
+
this.analyticsSessionRepository = analyticsSessionRepository;
|
|
46
|
+
this.analyticsAdminRepository = analyticsAdminRepository;
|
|
47
|
+
this.analyticsPageViewRepository = analyticsPageViewRepository;
|
|
48
|
+
this.config = config;
|
|
49
|
+
this.descriptor = analytics_session_1.AnalyticsSessionDescriptor;
|
|
50
|
+
}
|
|
51
|
+
async getSummary(params) {
|
|
52
|
+
const rows = await this.analyticsAdminRepository.findSummary({
|
|
53
|
+
from: params.from,
|
|
54
|
+
to: params.to,
|
|
55
|
+
section: params.section,
|
|
56
|
+
retentionCutoff: this.retentionCutoff(),
|
|
57
|
+
});
|
|
58
|
+
return this.jsonApiService.buildList(analytics_summary_1.AnalyticsSummaryDescriptor.model, rows);
|
|
59
|
+
}
|
|
60
|
+
async getTimeline(params) {
|
|
61
|
+
const rows = await this.analyticsAdminRepository.findTimeline({
|
|
62
|
+
from: params.from,
|
|
63
|
+
to: params.to,
|
|
64
|
+
section: params.section,
|
|
65
|
+
granularity: params.granularity,
|
|
66
|
+
retentionCutoff: this.retentionCutoff(),
|
|
67
|
+
});
|
|
68
|
+
return this.jsonApiService.buildList(analytics_timeline_1.AnalyticsTimelineDescriptor.model, rows);
|
|
69
|
+
}
|
|
70
|
+
async getBreakdown(params) {
|
|
71
|
+
const rows = await this.analyticsAdminRepository.findBreakdown({
|
|
72
|
+
from: params.from,
|
|
73
|
+
to: params.to,
|
|
74
|
+
section: params.section,
|
|
75
|
+
dimension: params.dimension,
|
|
76
|
+
limit: params.limit,
|
|
77
|
+
retentionCutoff: this.retentionCutoff(),
|
|
78
|
+
});
|
|
79
|
+
return this.jsonApiService.buildList(analytics_breakdown_1.AnalyticsBreakdownDescriptor.model, rows);
|
|
80
|
+
}
|
|
81
|
+
async getSessions(params) {
|
|
82
|
+
const paginator = new jsonapi_paginator_1.JsonApiPaginator(params.query);
|
|
83
|
+
const rows = await this.analyticsSessionRepository.findForAdmin({
|
|
84
|
+
cursor: paginator.generateCursor(),
|
|
85
|
+
from: params.from,
|
|
86
|
+
to: params.to,
|
|
87
|
+
section: params.section,
|
|
88
|
+
visitorId: params.visitorId,
|
|
89
|
+
userId: params.userId,
|
|
90
|
+
});
|
|
91
|
+
return this.jsonApiService.buildList(analytics_session_1.AnalyticsSessionDescriptor.model, rows, paginator);
|
|
92
|
+
}
|
|
93
|
+
async getSessionPageViews(params) {
|
|
94
|
+
// Throws NotFoundException for an unknown session, so a missing session is
|
|
95
|
+
// a 404 rather than an empty list.
|
|
96
|
+
await this.analyticsSessionRepository.findById({ id: params.sessionId });
|
|
97
|
+
const rows = await this.analyticsPageViewRepository.findBySession({ sessionId: params.sessionId });
|
|
98
|
+
return this.jsonApiService.buildList(analytics_page_view_1.AnalyticsPageViewDescriptor.model, rows);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* ISO date (YYYY-MM-DD, UTC) `retentionMonths` before today. Raw events older
|
|
102
|
+
* than this are gone (rolled up into daily summaries), so it is the boundary
|
|
103
|
+
* between the two sources the aggregate queries read. Shared with the cron.
|
|
104
|
+
* The day is clamped to the target month's length (31 March − 1 month → 28/29 February).
|
|
105
|
+
*/
|
|
106
|
+
retentionCutoff() {
|
|
107
|
+
const today = new Date();
|
|
108
|
+
const totalMonths = today.getUTCFullYear() * 12 + today.getUTCMonth() - this.config.retentionMonths;
|
|
109
|
+
const year = Math.floor(totalMonths / 12);
|
|
110
|
+
const month = totalMonths - year * 12;
|
|
111
|
+
const lastDayOfMonth = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
|
|
112
|
+
const day = Math.min(today.getUTCDate(), lastDayOfMonth);
|
|
113
|
+
return new Date(Date.UTC(year, month, day)).toISOString().slice(0, 10);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.AnalyticsAdminService = AnalyticsAdminService;
|
|
117
|
+
exports.AnalyticsAdminService = AnalyticsAdminService = __decorate([
|
|
118
|
+
(0, common_1.Injectable)(),
|
|
119
|
+
__param(5, (0, common_1.Inject)(analytics_config_interface_1.ANALYTICS_CONFIG)),
|
|
120
|
+
__metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
|
|
121
|
+
analytics_session_repository_1.AnalyticsSessionRepository,
|
|
122
|
+
nestjs_cls_1.ClsService,
|
|
123
|
+
analytics_admin_repository_1.AnalyticsAdminRepository,
|
|
124
|
+
analytics_page_view_repository_1.AnalyticsPageViewRepository, Object])
|
|
125
|
+
], AnalyticsAdminService);
|
|
126
|
+
//# sourceMappingURL=analytics.admin.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.admin.service.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/services/analytics.admin.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,2CAAwC;AACxC,oFAAgF;AAChF,2FAAuF;AACvF,qFAAiF;AACjF,yEAA+E;AAC/E,yEAA8E;AAC9E,qEAA6F;AAC7F,qEAA2E;AAC3E,uEAA6E;AAC7E,yFAAmG;AACnG,mGAA6F;AAC7F,+FAA0F;AAC1F,2FAAuH;AAEvH;;;;;;;;;;;GAWG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,kCAG1C;IAGC,YACE,cAA8B,EACX,0BAAsD,EACzE,UAAsB,EACH,wBAAkD,EAClD,2BAAwD,EACjD,MAAwD;QAElF,KAAK,CAAC,cAAc,EAAE,0BAA0B,EAAE,UAAU,EAAE,8CAA0B,CAAC,KAAK,CAAC,CAAC;QAN7E,+BAA0B,GAA1B,0BAA0B,CAA4B;QAEtD,6BAAwB,GAAxB,wBAAwB,CAA0B;QAClD,gCAA2B,GAA3B,2BAA2B,CAA6B;QAChC,WAAM,GAAN,MAAM,CAAiC;QARjE,eAAU,GAAG,8CAA0B,CAAC;IAW3D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAsD;QACrE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,WAAW,CAAC;YAC3D,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE;SACxC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,8CAA0B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAgF;QAChG,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC;YAC5D,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE;SACxC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,gDAA2B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,MAMlB;QACC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,aAAa,CAAC;YAC7D,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE;SACxC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,kDAA4B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAOjB;QACC,MAAM,SAAS,GAAG,IAAI,oCAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAErD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,YAAY,CAAC;YAC9D,MAAM,EAAE,SAAS,CAAC,cAAc,EAAE;YAClC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,8CAA0B,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAC1F,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,MAA6B;QACrD,2EAA2E;QAC3E,mCAAmC;QACnC,MAAM,IAAI,CAAC,0BAA0B,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAEzE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,2BAA2B,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAEnG,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,iDAA2B,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChF,CAAC;IAED;;;;;OAKG;IACH,eAAe;QACb,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACpG,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,cAAc,CAAC,CAAC;QAEzD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzE,CAAC;CACF,CAAA;AA3GY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAaR,WAAA,IAAA,eAAM,EAAC,6CAAgB,CAAC,CAAA;qCALT,gCAAc;QACiB,yDAA0B;QAC7D,uBAAU;QACuB,qDAAwB;QACrB,4DAA2B;GAXlE,qBAAqB,CA2GjC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Queue } from "bullmq";
|
|
2
|
+
import { ClsService } from "nestjs-cls";
|
|
3
|
+
import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
|
|
4
|
+
import { AppLoggingService } from "../../../core/logging/services/logging.service";
|
|
5
|
+
import { AbstractService } from "../../../core/neo4j/abstracts/abstract.service";
|
|
6
|
+
import { AnalyticsSession, AnalyticsSessionDescriptor } from "../entities/analytics-session";
|
|
7
|
+
import { AnalyticsModuleConfig } from "../interfaces/analytics.config.interface";
|
|
8
|
+
import { AnalyticsPageViewInput } from "../interfaces/analytics.page-view.input";
|
|
9
|
+
import { AnalyticsSessionRepository } from "../repositories/analytics-session.repository";
|
|
10
|
+
export declare class AnalyticsService extends AbstractService<AnalyticsSession, typeof AnalyticsSessionDescriptor.relationships> {
|
|
11
|
+
private readonly queue;
|
|
12
|
+
private readonly logger;
|
|
13
|
+
protected readonly descriptor: import("../../..").EntityDescriptor<AnalyticsSession, {
|
|
14
|
+
user: {
|
|
15
|
+
model: import("../../..").DataMeta;
|
|
16
|
+
direction: "out";
|
|
17
|
+
relationship: string;
|
|
18
|
+
cardinality: "one";
|
|
19
|
+
required: false;
|
|
20
|
+
dtoKey: string;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
private readonly jobName;
|
|
24
|
+
constructor(jsonApiService: JsonApiService, analyticsSessionRepository: AnalyticsSessionRepository, clsService: ClsService, queue: Queue, logger: AppLoggingService, config: Required<AnalyticsModuleConfig>);
|
|
25
|
+
/**
|
|
26
|
+
* Enqueue a page view for async write. Never throws — analytics must not
|
|
27
|
+
* break the caller's request path.
|
|
28
|
+
*/
|
|
29
|
+
track(input: AnalyticsPageViewInput): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=analytics.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/services/analytics.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC7F,OAAO,EAAqC,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACpH,OAAO,EAAE,sBAAsB,EAAE,MAAM,yCAAyC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,8CAA8C,CAAC;AAE1F,qBACa,gBAAiB,SAAQ,eAAe,CACnD,gBAAgB,EAChB,OAAO,0BAA0B,CAAC,aAAa,CAChD;IAQ4B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM;IARzB,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;;OAA8B;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAG/B,cAAc,EAAE,cAAc,EAC9B,0BAA0B,EAAE,0BAA0B,EACtD,UAAU,EAAE,UAAU,EACoB,KAAK,EAAE,KAAK,EACrC,MAAM,EAAE,iBAAiB,EAChB,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC;IAMnE;;;OAGG;IACG,KAAK,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAO1D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AnalyticsService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const bullmq_1 = require("bullmq");
|
|
18
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
19
|
+
const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
|
|
20
|
+
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
21
|
+
const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
|
|
22
|
+
const analytics_session_1 = require("../entities/analytics-session");
|
|
23
|
+
const analytics_config_interface_1 = require("../interfaces/analytics.config.interface");
|
|
24
|
+
const analytics_session_repository_1 = require("../repositories/analytics-session.repository");
|
|
25
|
+
let AnalyticsService = class AnalyticsService extends abstract_service_1.AbstractService {
|
|
26
|
+
constructor(jsonApiService, analyticsSessionRepository, clsService, queue, logger, config) {
|
|
27
|
+
super(jsonApiService, analyticsSessionRepository, clsService, analytics_session_1.AnalyticsSessionDescriptor.model);
|
|
28
|
+
this.queue = queue;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
this.descriptor = analytics_session_1.AnalyticsSessionDescriptor;
|
|
31
|
+
this.jobName = config.jobName;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Enqueue a page view for async write. Never throws — analytics must not
|
|
35
|
+
* break the caller's request path.
|
|
36
|
+
*/
|
|
37
|
+
async track(input) {
|
|
38
|
+
try {
|
|
39
|
+
await this.queue.add(this.jobName, input);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
this.logger.error(`AnalyticsService.track enqueue failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.AnalyticsService = AnalyticsService;
|
|
47
|
+
exports.AnalyticsService = AnalyticsService = __decorate([
|
|
48
|
+
(0, common_1.Injectable)(),
|
|
49
|
+
__param(3, (0, common_1.Inject)(analytics_config_interface_1.ANALYTICS_QUEUE)),
|
|
50
|
+
__param(5, (0, common_1.Inject)(analytics_config_interface_1.ANALYTICS_CONFIG)),
|
|
51
|
+
__metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
|
|
52
|
+
analytics_session_repository_1.AnalyticsSessionRepository,
|
|
53
|
+
nestjs_cls_1.ClsService,
|
|
54
|
+
bullmq_1.Queue,
|
|
55
|
+
logging_service_1.AppLoggingService, Object])
|
|
56
|
+
], AnalyticsService);
|
|
57
|
+
//# sourceMappingURL=analytics.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.service.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/services/analytics.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,mCAA+B;AAC/B,2CAAwC;AACxC,oFAAgF;AAChF,oFAAmF;AACnF,qFAAiF;AACjF,qEAA6F;AAC7F,yFAAoH;AAEpH,+FAA0F;AAGnF,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,kCAGrC;IAIC,YACE,cAA8B,EAC9B,0BAAsD,EACtD,UAAsB,EACG,KAA6B,EACrC,MAAyB,EAChB,MAAuC;QAEjE,KAAK,CAAC,cAAc,EAAE,0BAA0B,EAAE,UAAU,EAAE,8CAA0B,CAAC,KAAK,CAAC,CAAC;QAJtD,UAAK,GAAL,KAAK,CAAO;QACrC,WAAM,GAAN,MAAM,CAAmB;QARzB,eAAU,GAAG,8CAA0B,CAAC;QAYzD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK,CAAC,KAA6B;QACvC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClH,CAAC;IACH,CAAC;CACF,CAAA;AA9BY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;IAYR,WAAA,IAAA,eAAM,EAAC,4CAAe,CAAC,CAAA;IAEvB,WAAA,IAAA,eAAM,EAAC,6CAAgB,CAAC,CAAA;qCALT,gCAAc;QACF,yDAA0B;QAC1C,uBAAU;QAC2B,cAAK;QAC7B,mCAAiB;GAZjC,gBAAgB,CA8B5B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AppLoggingService } from "../../../core/logging/services/logging.service";
|
|
2
|
+
import { RedisClientStorageService } from "../../../core/redis/services/redis.client.storage.service";
|
|
3
|
+
export declare const DAILY_HASH_PREFIX = "d:";
|
|
4
|
+
export declare const COOKIE_ID_PREFIX = "c:";
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the visitor id an analytics event is attributed to.
|
|
7
|
+
*
|
|
8
|
+
* With consent the browser sends the `analytics_visitor` cookie id, used as
|
|
9
|
+
* `c:<uuid>`. Without consent the id is `d:` + sha256(daily salt + IP + user
|
|
10
|
+
* agent). The salt lives in Redis for 48 hours with set-if-absent semantics, so
|
|
11
|
+
* every worker shares one salt per day and no salt outlives its usefulness.
|
|
12
|
+
* IP and user agent are only hashed or classified here; they are never returned
|
|
13
|
+
* and never stored.
|
|
14
|
+
*/
|
|
15
|
+
export declare class AnalyticsVisitorIdService {
|
|
16
|
+
private readonly redis;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
private readonly localSalts;
|
|
19
|
+
private readonly warnedDays;
|
|
20
|
+
constructor(redis: RedisClientStorageService, logger: AppLoggingService);
|
|
21
|
+
isBot(userAgent: string): boolean;
|
|
22
|
+
deviceType(userAgent: string): "desktop" | "mobile" | "tablet";
|
|
23
|
+
resolve(input: {
|
|
24
|
+
visitorId?: string;
|
|
25
|
+
clientIp: string;
|
|
26
|
+
userAgent: string;
|
|
27
|
+
receivedAt: string;
|
|
28
|
+
}): Promise<{
|
|
29
|
+
visitorId: string;
|
|
30
|
+
consented: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
dailySalt(day: string): Promise<string>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=analytics.visitor-id.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.visitor-id.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/analytics/services/analytics.visitor-id.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,yBAAyB,EAAE,MAAM,2DAA2D,CAAC;AAEtG,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAWrC;;;;;;;;;GASG;AACH,qBACa,yBAAyB;IAKlC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;gBAG7B,KAAK,EAAE,yBAAyB,EAChC,MAAM,EAAE,iBAAiB;IAG5C,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIjC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ;IAOxD,OAAO,CAAC,KAAK,EAAE;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAWhD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA0B9C"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var AnalyticsVisitorIdService_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AnalyticsVisitorIdService = exports.COOKIE_ID_PREFIX = exports.DAILY_HASH_PREFIX = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const crypto_1 = require("crypto");
|
|
16
|
+
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
17
|
+
const redis_client_storage_service_1 = require("../../../core/redis/services/redis.client.storage.service");
|
|
18
|
+
exports.DAILY_HASH_PREFIX = "d:";
|
|
19
|
+
exports.COOKIE_ID_PREFIX = "c:";
|
|
20
|
+
/** 48 hours: long enough to cover a day in any worker, too short to re-derive yesterday's ids later. */
|
|
21
|
+
const SALT_TTL_SECONDS = 172800;
|
|
22
|
+
const SALT_KEY_PREFIX = "analytics:salt:";
|
|
23
|
+
const BOT_PATTERN = /bot|crawler|spider|curl|wget|python-requests|headlesschrome|facebookexternalhit|slackbot|twitterbot|linkedinbot|ahrefs|semrush|bingpreview/i;
|
|
24
|
+
const TABLET_PATTERN = /ipad|tablet|kindle|silk/i;
|
|
25
|
+
const MOBILE_PATTERN = /mobi|iphone|android.*mobile|windows phone/i;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves the visitor id an analytics event is attributed to.
|
|
28
|
+
*
|
|
29
|
+
* With consent the browser sends the `analytics_visitor` cookie id, used as
|
|
30
|
+
* `c:<uuid>`. Without consent the id is `d:` + sha256(daily salt + IP + user
|
|
31
|
+
* agent). The salt lives in Redis for 48 hours with set-if-absent semantics, so
|
|
32
|
+
* every worker shares one salt per day and no salt outlives its usefulness.
|
|
33
|
+
* IP and user agent are only hashed or classified here; they are never returned
|
|
34
|
+
* and never stored.
|
|
35
|
+
*/
|
|
36
|
+
let AnalyticsVisitorIdService = AnalyticsVisitorIdService_1 = class AnalyticsVisitorIdService {
|
|
37
|
+
constructor(redis, logger) {
|
|
38
|
+
this.redis = redis;
|
|
39
|
+
this.logger = logger;
|
|
40
|
+
this.localSalts = new Map();
|
|
41
|
+
this.warnedDays = new Set();
|
|
42
|
+
}
|
|
43
|
+
isBot(userAgent) {
|
|
44
|
+
return BOT_PATTERN.test(userAgent ?? "");
|
|
45
|
+
}
|
|
46
|
+
deviceType(userAgent) {
|
|
47
|
+
const ua = userAgent ?? "";
|
|
48
|
+
if (TABLET_PATTERN.test(ua))
|
|
49
|
+
return "tablet";
|
|
50
|
+
if (MOBILE_PATTERN.test(ua))
|
|
51
|
+
return "mobile";
|
|
52
|
+
return "desktop";
|
|
53
|
+
}
|
|
54
|
+
async resolve(input) {
|
|
55
|
+
if (input.visitorId)
|
|
56
|
+
return { visitorId: `${exports.COOKIE_ID_PREFIX}${input.visitorId}`, consented: true };
|
|
57
|
+
const salt = await this.dailySalt(input.receivedAt.slice(0, 10));
|
|
58
|
+
const hash = (0, crypto_1.createHash)("sha256")
|
|
59
|
+
.update(salt + input.clientIp + input.userAgent)
|
|
60
|
+
.digest("hex");
|
|
61
|
+
return { visitorId: `${exports.DAILY_HASH_PREFIX}${hash}`, consented: false };
|
|
62
|
+
}
|
|
63
|
+
async dailySalt(day) {
|
|
64
|
+
const key = `${SALT_KEY_PREFIX}${day}`;
|
|
65
|
+
try {
|
|
66
|
+
const client = this.redis.getRedisClient();
|
|
67
|
+
await client.set(key, (0, crypto_1.randomBytes)(32).toString("hex"), "EX", SALT_TTL_SECONDS, "NX");
|
|
68
|
+
const salt = await client.get(key);
|
|
69
|
+
if (!salt)
|
|
70
|
+
throw new Error(`salt ${key} missing after SET NX`);
|
|
71
|
+
return salt;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (!this.warnedDays.has(day)) {
|
|
75
|
+
this.warnedDays.add(day);
|
|
76
|
+
this.logger.warn(`Redis unavailable for ${key}, using a process-local salt: ${error?.message ?? error}`, AnalyticsVisitorIdService_1.name);
|
|
77
|
+
}
|
|
78
|
+
let salt = this.localSalts.get(day);
|
|
79
|
+
if (!salt) {
|
|
80
|
+
salt = (0, crypto_1.randomBytes)(32).toString("hex");
|
|
81
|
+
this.localSalts.set(day, salt);
|
|
82
|
+
}
|
|
83
|
+
return salt;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.AnalyticsVisitorIdService = AnalyticsVisitorIdService;
|
|
88
|
+
exports.AnalyticsVisitorIdService = AnalyticsVisitorIdService = AnalyticsVisitorIdService_1 = __decorate([
|
|
89
|
+
(0, common_1.Injectable)(),
|
|
90
|
+
__metadata("design:paramtypes", [redis_client_storage_service_1.RedisClientStorageService,
|
|
91
|
+
logging_service_1.AppLoggingService])
|
|
92
|
+
], AnalyticsVisitorIdService);
|
|
93
|
+
//# sourceMappingURL=analytics.visitor-id.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.visitor-id.service.js","sourceRoot":"","sources":["../../../../src/foundations/analytics/services/analytics.visitor-id.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DynamicModule, Type } from "@nestjs/common";
|
|
2
|
+
import { AnalyticsModuleConfig } from "./analytics/interfaces/analytics.config.interface";
|
|
2
3
|
import { ContentExtensionConfig } from "./content/interfaces/content.extension.interface";
|
|
3
4
|
import { ReferralModuleConfig } from "./referral/interfaces/referral.config.interface";
|
|
4
5
|
import { HandbookModuleConfig } from "./handbook/interfaces/handbook.config.interface";
|
|
@@ -18,6 +19,8 @@ export interface FoundationsModuleConfig {
|
|
|
18
19
|
handbook?: HandbookModuleConfig;
|
|
19
20
|
/** Optional configuration for the how-to feature module (opt-in public routes) */
|
|
20
21
|
howTo?: HowToModuleConfig;
|
|
22
|
+
/** Optional override for the analytics feature module (normally switched on by `ANALYTICS_ENABLED=true`) */
|
|
23
|
+
analytics?: AnalyticsModuleConfig;
|
|
21
24
|
/**
|
|
22
25
|
* Foundation module classes to exclude from registration.
|
|
23
26
|
* Default [] keeps all modules registered (neural-erp behavior unchanged).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundations.modules.d.ts","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"foundations.modules.d.ts","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAU,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mDAAmD,CAAC;AAS1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAC;AAE1F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAIvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AAwBhF,OAAO,EAAE,wBAAwB,EAAE,MAAM,2DAA2D,CAAC;AAGrG;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,kEAAkE;IAClE,YAAY,CAAC,EAAE,wBAAwB,CAAC;IACxC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,kFAAkF;IAClF,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,4GAA4G;IAC5G,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;CACvB;AAwDD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,iBAAiB;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,uBAAuB,GAAG,aAAa;CAuBhE"}
|
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.FoundationsModule = void 0;
|
|
11
11
|
const common_1 = require("@nestjs/common");
|
|
12
12
|
const ai_connection_module_1 = require("./ai-connection/ai-connection.module");
|
|
13
|
+
const analytics_module_1 = require("./analytics/analytics.module");
|
|
13
14
|
const assistant_module_1 = require("./assistant/assistant.module");
|
|
14
15
|
const atomicfact_module_1 = require("./atomicfact/atomicfact.module");
|
|
15
16
|
const audit_module_1 = require("./audit/audit.module");
|
|
@@ -49,7 +50,7 @@ const user_activity_module_1 = require("./user-activity/user-activity.module");
|
|
|
49
50
|
const waitlist_module_1 = require("./waitlist/waitlist.module");
|
|
50
51
|
/**
|
|
51
52
|
* All static foundation modules. The dynamic ones (ContentModule,
|
|
52
|
-
* UserActivityModule, ReferralModule, HandbookModule, HowToModule) are
|
|
53
|
+
* UserActivityModule, ReferralModule, HandbookModule, HowToModule, AnalyticsModule) are
|
|
53
54
|
* assembled inside forRoot().
|
|
54
55
|
*
|
|
55
56
|
* HowToModule is dynamic solely so an app can reach
|
|
@@ -147,6 +148,7 @@ let FoundationsModule = FoundationsModule_1 = class FoundationsModule {
|
|
|
147
148
|
{ classRef: referral_module_1.ReferralModule, factory: () => referral_module_1.ReferralModule.forRoot(config?.referral) },
|
|
148
149
|
{ classRef: handbook_module_1.HandbookModule, factory: () => handbook_module_1.HandbookModule.forRoot(config?.handbook) },
|
|
149
150
|
{ classRef: how_to_module_1.HowToModule, factory: () => how_to_module_1.HowToModule.forRoot(config?.howTo) },
|
|
151
|
+
{ classRef: analytics_module_1.AnalyticsModule, factory: () => analytics_module_1.AnalyticsModule.forRoot(config?.analytics) },
|
|
150
152
|
].filter((entry) => !excluded.has(entry.classRef));
|
|
151
153
|
return {
|
|
152
154
|
module: FoundationsModule_1,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foundations.modules.js","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA6D;AAC7D,+EAA0E;AAC1E,mEAA+D;AAC/D,sEAAkE;AAClE,uDAAmD;AACnD,oDAAgD;AAChD,uDAAmD;AACnD,6DAAyD;AACzD,6DAAyD;AACzD,6DAAyD;AAEzD,gEAA4D;AAE5D,4EAAuE;AACvE,6DAAyD;AACzD,gEAA4D;AAE5D,0DAAqD;AAErD,sEAAkE;AAClE,sEAAkE;AAClE,0DAAsD;AACtD,4EAAwE;AACxE,uDAAmD;AACnD,oDAAgD;AAChD,mEAA+D;AAC/D,oDAAgD;AAChD,8CAA0C;AAC1C,qFAAgF;AAChF,kFAA6E;AAC7E,iDAAmD;AACnD,qDAAuD;AACvD,mEAAoE;AACpE,+DAAiE;AACjE,4EAAuE;AACvE,kFAA6E;AAC7E,0DAAsD;AACtD,4EAAuE;AACvE,sEAAkE;AAClE,sEAAiE;AACjE,oDAAgD;AAChD,+EAA0E;AAE1E,gEAA4D;
|
|
1
|
+
{"version":3,"file":"foundations.modules.js","sourceRoot":"","sources":["../../src/foundations/foundations.modules.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC"}
|
|
@@ -53,6 +53,7 @@ __exportStar(require("./tokenusage"), exports);
|
|
|
53
53
|
__exportStar(require("./two-factor"), exports);
|
|
54
54
|
__exportStar(require("./user"), exports);
|
|
55
55
|
__exportStar(require("./user-activity"), exports);
|
|
56
|
+
__exportStar(require("./analytics"), exports);
|
|
56
57
|
__exportStar(require("./waitlist"), exports);
|
|
57
58
|
__exportStar(require("./rbac"), exports);
|
|
58
59
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,sFAAsF;AACtF,wDAAsC;AAEtC,iFAAiF;AACjF,kDAAgC;AAChC,8CAA4B;AAC5B,qDAAmC;AACnC,sDAAoC;AACpC,+CAA6B;AAC7B,0CAAwB;AACxB,yCAAuB;AACvB,0CAAwB;AACxB,4CAA0B;AAC1B,4CAA0B;AAC1B,8CAA4B;AAC5B,4CAA0B;AAC1B,4CAA0B;AAC1B,iDAA+B;AAC/B,4CAA0B;AAC1B,gDAA8B;AAC9B,6CAA2B;AAC3B,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,2CAAyB;AACzB,iDAA+B;AAC/B,0CAAwB;AACxB,yCAAuB;AACvB,6CAA2B;AAC3B,8CAA4B;AAC5B,yCAAuB;AACvB,uCAAqB;AACrB,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,yCAAuB;AACvB,kDAAgC;AAChC,6CAA2B;AAC3B,yCAAuB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/foundations/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,sFAAsF;AACtF,wDAAsC;AAEtC,iFAAiF;AACjF,kDAAgC;AAChC,8CAA4B;AAC5B,qDAAmC;AACnC,sDAAoC;AACpC,+CAA6B;AAC7B,0CAAwB;AACxB,yCAAuB;AACvB,0CAAwB;AACxB,4CAA0B;AAC1B,4CAA0B;AAC1B,8CAA4B;AAC5B,4CAA0B;AAC1B,4CAA0B;AAC1B,iDAA+B;AAC/B,4CAA0B;AAC1B,gDAA8B;AAC9B,6CAA2B;AAC3B,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,2CAAyB;AACzB,iDAA+B;AAC/B,0CAAwB;AACxB,yCAAuB;AACvB,6CAA2B;AAC3B,8CAA4B;AAC5B,yCAAuB;AACvB,uCAAqB;AACrB,2CAAyB;AACzB,+CAA6B;AAC7B,+CAA6B;AAC7B,yCAAuB;AACvB,kDAAgC;AAChC,8CAA4B;AAC5B,6CAA2B;AAC3B,yCAAuB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"s3.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/s3/services/s3.service.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAUlC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAqB,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yDAAyD,CAAC;AAC/F,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAGnF,qBACa,SAAS;
|
|
1
|
+
{"version":3,"file":"s3.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/s3/services/s3.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
+
var S3Service_1;
|
|
11
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
13
|
exports.S3Service = void 0;
|
|
13
14
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
@@ -21,7 +22,7 @@ const nestjs_cls_1 = require("nestjs-cls");
|
|
|
21
22
|
const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
|
|
22
23
|
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
23
24
|
const s3_model_1 = require("../../s3/entities/s3.model");
|
|
24
|
-
let S3Service = class S3Service {
|
|
25
|
+
let S3Service = S3Service_1 = class S3Service {
|
|
25
26
|
constructor(builder, clsService, configService, logger) {
|
|
26
27
|
this.builder = builder;
|
|
27
28
|
this.clsService = clsService;
|
|
@@ -276,8 +277,13 @@ let S3Service = class S3Service {
|
|
|
276
277
|
? { ResponseContentDisposition: this._contentDispositionAttachment(params.filename) }
|
|
277
278
|
: {}),
|
|
278
279
|
});
|
|
280
|
+
// Sign against the start of the current window so the same key yields the same URL
|
|
281
|
+
// for the whole window and browser/image caches can hit. The window is added to the
|
|
282
|
+
// expiry so the URL stays valid for at least the requested ttl from now.
|
|
283
|
+
const windowMs = S3Service_1.SIGNING_WINDOW_SECONDS * 1000;
|
|
279
284
|
const signedUrl = await (0, s3_request_presigner_1.getSignedUrl)(this.s3Client, command, {
|
|
280
|
-
|
|
285
|
+
signingDate: new Date(Math.floor(Date.now() / windowMs) * windowMs),
|
|
286
|
+
expiresIn: (params.ttl ?? 3600) + S3Service_1.SIGNING_WINDOW_SECONDS,
|
|
281
287
|
});
|
|
282
288
|
return signedUrl;
|
|
283
289
|
}
|
|
@@ -852,7 +858,8 @@ let S3Service = class S3Service {
|
|
|
852
858
|
}
|
|
853
859
|
};
|
|
854
860
|
exports.S3Service = S3Service;
|
|
855
|
-
|
|
861
|
+
S3Service.SIGNING_WINDOW_SECONDS = 3600;
|
|
862
|
+
exports.S3Service = S3Service = S3Service_1 = __decorate([
|
|
856
863
|
(0, common_1.Injectable)(),
|
|
857
864
|
__metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
|
|
858
865
|
nestjs_cls_1.ClsService,
|