@serve.zone/dcrouter 18.9.3 → 18.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.js +5 -4
- package/dist_ts/db/documents/classes.authentication-event.doc.d.ts +0 -1
- package/dist_ts/db/documents/classes.authentication-event.doc.js +176 -259
- package/dist_ts/db/documents/classes.email-traffic-bucket.doc.js +110 -188
- package/dist_ts/dns/manager.dns-authority.d.ts +5 -0
- package/dist_ts/dns/manager.dns-authority.js +97 -53
- package/dist_ts/dns/manager.dns.js +23 -5
- package/dist_ts/email/classes.email-domain.manager.js +14 -3
- package/dist_ts/email/classes.email-settings.manager.js +26 -6
- package/dist_ts/email/classes.mail-dns-sync.js +43 -11
- package/dist_ts/monitoring/classes.metricscache.d.ts +28 -19
- package/dist_ts/monitoring/classes.metricscache.js +133 -62
- package/dist_ts/monitoring/classes.metricsmanager.js +7 -5
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +46 -9
- package/dist_ts/security/classes.authentication-event-manager.d.ts +5 -1
- package/dist_ts/security/classes.authentication-event-manager.js +32 -22
- package/dist_ts/vpn/classes.vpn-manager.js +34 -2
- package/dist_ts_migrations/index.d.ts +4 -1
- package/dist_ts_migrations/index.js +18 -3
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/package.json +7 -6
- package/readme.hints.md +84 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +4 -3
- package/ts/db/documents/classes.authentication-event.doc.ts +64 -87
- package/ts/db/documents/classes.email-traffic-bucket.doc.ts +10 -9
- package/ts/dns/manager.dns-authority.ts +92 -54
- package/ts/dns/manager.dns.ts +20 -4
- package/ts/email/classes.email-domain.manager.ts +12 -2
- package/ts/email/classes.email-settings.manager.ts +23 -5
- package/ts/email/classes.mail-dns-sync.ts +45 -10
- package/ts/monitoring/classes.metricscache.ts +133 -79
- package/ts/monitoring/classes.metricsmanager.ts +6 -4
- package/ts/plugins.ts +2 -0
- package/ts/remoteingress/classes.remoteingress-manager.ts +42 -8
- package/ts/security/classes.authentication-event-manager.ts +31 -20
- package/ts/vpn/classes.vpn-manager.ts +32 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -1,273 +1,190 @@
|
|
|
1
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
-
var _, done = false;
|
|
7
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
-
var context = {};
|
|
9
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
-
if (kind === "accessor") {
|
|
14
|
-
if (result === void 0) continue;
|
|
15
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
-
}
|
|
20
|
-
else if (_ = accept(result)) {
|
|
21
|
-
if (kind === "field") initializers.unshift(_);
|
|
22
|
-
else descriptor[key] = _;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
-
done = true;
|
|
27
|
-
};
|
|
28
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
-
var useValue = arguments.length > 2;
|
|
30
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
-
}
|
|
33
|
-
return useValue ? value : void 0;
|
|
34
|
-
};
|
|
35
1
|
import * as plugins from '../../plugins.js';
|
|
36
2
|
import { DcRouterDb } from '../classes.dcrouter-db.js';
|
|
37
3
|
const DB_OPERATION_TIMEOUT_MS = 5_000;
|
|
38
4
|
const getDb = () => DcRouterDb.getInstance().getDb();
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
__esDecorate(null, null, _resolvedAuthSource_decorators, { kind: "field", name: "resolvedAuthSource", static: false, private: false, access: { has: obj => "resolvedAuthSource" in obj, get: obj => obj.resolvedAuthSource, set: (obj, value) => { obj.resolvedAuthSource = value; } }, metadata: _metadata }, _resolvedAuthSource_initializers, _resolvedAuthSource_extraInitializers);
|
|
88
|
-
__esDecorate(null, null, _failureReason_decorators, { kind: "field", name: "failureReason", static: false, private: false, access: { has: obj => "failureReason" in obj, get: obj => obj.failureReason, set: (obj, value) => { obj.failureReason = value; } }, metadata: _metadata }, _failureReason_initializers, _failureReason_extraInitializers);
|
|
89
|
-
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
90
|
-
AuthenticationEventDoc = _classThis = _classDescriptor.value;
|
|
91
|
-
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
92
|
-
__runInitializers(_classThis, _classExtraInitializers);
|
|
5
|
+
export class AuthenticationEventDoc extends plugins.smartdata.SmartDataDbDoc {
|
|
6
|
+
id;
|
|
7
|
+
timestamp;
|
|
8
|
+
username;
|
|
9
|
+
userId;
|
|
10
|
+
success;
|
|
11
|
+
requestedAuthSource;
|
|
12
|
+
resolvedAuthSource;
|
|
13
|
+
failureReason;
|
|
14
|
+
constructor() {
|
|
15
|
+
super();
|
|
16
|
+
}
|
|
17
|
+
toApiObject() {
|
|
18
|
+
return {
|
|
19
|
+
id: this.id,
|
|
20
|
+
timestamp: this.timestamp,
|
|
21
|
+
username: this.username,
|
|
22
|
+
success: this.success,
|
|
23
|
+
requestedAuthSource: this.requestedAuthSource,
|
|
24
|
+
...(this.userId ? { userId: this.userId } : {}),
|
|
25
|
+
...(this.resolvedAuthSource ? { resolvedAuthSource: this.resolvedAuthSource } : {}),
|
|
26
|
+
...(this.failureReason ? { failureReason: this.failureReason } : {}),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
static toPersistedFields(eventArg) {
|
|
30
|
+
return {
|
|
31
|
+
id: eventArg.id,
|
|
32
|
+
timestamp: eventArg.timestamp,
|
|
33
|
+
username: eventArg.username,
|
|
34
|
+
success: eventArg.success,
|
|
35
|
+
requestedAuthSource: eventArg.requestedAuthSource,
|
|
36
|
+
...(eventArg.userId !== undefined ? { userId: eventArg.userId } : {}),
|
|
37
|
+
...(eventArg.resolvedAuthSource !== undefined
|
|
38
|
+
? { resolvedAuthSource: eventArg.resolvedAuthSource }
|
|
39
|
+
: {}),
|
|
40
|
+
...(eventArg.failureReason !== undefined ? { failureReason: eventArg.failureReason } : {}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
static validateEvent(eventArg) {
|
|
44
|
+
if (typeof eventArg.id !== 'string'
|
|
45
|
+
|| !eventArg.id.trim()
|
|
46
|
+
|| !Number.isSafeInteger(eventArg.timestamp)
|
|
47
|
+
|| eventArg.timestamp < 0
|
|
48
|
+
|| typeof eventArg.username !== 'string'
|
|
49
|
+
|| !eventArg.username.trim()
|
|
50
|
+
|| typeof eventArg.success !== 'boolean'
|
|
51
|
+
|| !['auto', 'local', 'idp.global'].includes(eventArg.requestedAuthSource)) {
|
|
52
|
+
throw new Error('Invalid authentication event');
|
|
93
53
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
userId = (__runInitializers(this, _username_extraInitializers), __runInitializers(this, _userId_initializers, void 0));
|
|
98
|
-
success = (__runInitializers(this, _userId_extraInitializers), __runInitializers(this, _success_initializers, void 0));
|
|
99
|
-
requestedAuthSource = (__runInitializers(this, _success_extraInitializers), __runInitializers(this, _requestedAuthSource_initializers, void 0));
|
|
100
|
-
resolvedAuthSource = (__runInitializers(this, _requestedAuthSource_extraInitializers), __runInitializers(this, _resolvedAuthSource_initializers, void 0));
|
|
101
|
-
failureReason = (__runInitializers(this, _resolvedAuthSource_extraInitializers), __runInitializers(this, _failureReason_initializers, void 0));
|
|
102
|
-
constructor() {
|
|
103
|
-
super();
|
|
104
|
-
__runInitializers(this, _failureReason_extraInitializers);
|
|
54
|
+
if (eventArg.userId !== undefined
|
|
55
|
+
&& (typeof eventArg.userId !== 'string' || !eventArg.userId.trim())) {
|
|
56
|
+
throw new Error('Invalid authentication event user ID');
|
|
105
57
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
username: this.username,
|
|
111
|
-
success: this.success,
|
|
112
|
-
requestedAuthSource: this.requestedAuthSource,
|
|
113
|
-
...(this.userId ? { userId: this.userId } : {}),
|
|
114
|
-
...(this.resolvedAuthSource ? { resolvedAuthSource: this.resolvedAuthSource } : {}),
|
|
115
|
-
...(this.failureReason ? { failureReason: this.failureReason } : {}),
|
|
116
|
-
};
|
|
58
|
+
if (eventArg.resolvedAuthSource !== undefined
|
|
59
|
+
&& eventArg.resolvedAuthSource !== 'local'
|
|
60
|
+
&& eventArg.resolvedAuthSource !== 'idp.global') {
|
|
61
|
+
throw new Error('Invalid resolved authentication source');
|
|
117
62
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
63
|
+
if (eventArg.failureReason !== undefined
|
|
64
|
+
&& ![
|
|
65
|
+
'invalidCredentials',
|
|
66
|
+
'serviceUnavailable',
|
|
67
|
+
'identityIssuanceFailed',
|
|
68
|
+
'internalError',
|
|
69
|
+
].includes(eventArg.failureReason)) {
|
|
70
|
+
throw new Error('Invalid authentication failure reason');
|
|
125
71
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
id: eventArg.id,
|
|
129
|
-
timestamp: eventArg.timestamp,
|
|
130
|
-
username: eventArg.username,
|
|
131
|
-
success: eventArg.success,
|
|
132
|
-
requestedAuthSource: eventArg.requestedAuthSource,
|
|
133
|
-
...(eventArg.userId !== undefined ? { userId: eventArg.userId } : {}),
|
|
134
|
-
...(eventArg.resolvedAuthSource !== undefined
|
|
135
|
-
? { resolvedAuthSource: eventArg.resolvedAuthSource }
|
|
136
|
-
: {}),
|
|
137
|
-
...(eventArg.failureReason !== undefined ? { failureReason: eventArg.failureReason } : {}),
|
|
138
|
-
};
|
|
72
|
+
if (eventArg.success && eventArg.failureReason) {
|
|
73
|
+
throw new Error('Successful authentication events cannot carry a failure reason');
|
|
139
74
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|| !eventArg.id.trim()
|
|
143
|
-
|| !Number.isSafeInteger(eventArg.timestamp)
|
|
144
|
-
|| eventArg.timestamp < 0
|
|
145
|
-
|| typeof eventArg.username !== 'string'
|
|
146
|
-
|| !eventArg.username.trim()
|
|
147
|
-
|| typeof eventArg.success !== 'boolean'
|
|
148
|
-
|| !['auto', 'local', 'idp.global'].includes(eventArg.requestedAuthSource)) {
|
|
149
|
-
throw new Error('Invalid authentication event');
|
|
150
|
-
}
|
|
151
|
-
if (eventArg.userId !== undefined
|
|
152
|
-
&& (typeof eventArg.userId !== 'string' || !eventArg.userId.trim())) {
|
|
153
|
-
throw new Error('Invalid authentication event user ID');
|
|
154
|
-
}
|
|
155
|
-
if (eventArg.resolvedAuthSource !== undefined
|
|
156
|
-
&& eventArg.resolvedAuthSource !== 'local'
|
|
157
|
-
&& eventArg.resolvedAuthSource !== 'idp.global') {
|
|
158
|
-
throw new Error('Invalid resolved authentication source');
|
|
159
|
-
}
|
|
160
|
-
if (eventArg.failureReason !== undefined
|
|
161
|
-
&& ![
|
|
162
|
-
'invalidCredentials',
|
|
163
|
-
'serviceUnavailable',
|
|
164
|
-
'identityIssuanceFailed',
|
|
165
|
-
'internalError',
|
|
166
|
-
].includes(eventArg.failureReason)) {
|
|
167
|
-
throw new Error('Invalid authentication failure reason');
|
|
168
|
-
}
|
|
169
|
-
if (eventArg.success && eventArg.failureReason) {
|
|
170
|
-
throw new Error('Successful authentication events cannot carry a failure reason');
|
|
171
|
-
}
|
|
172
|
-
if (!eventArg.success && !eventArg.failureReason) {
|
|
173
|
-
throw new Error('Failed authentication events require a failure reason');
|
|
174
|
-
}
|
|
75
|
+
if (!eventArg.success && !eventArg.failureReason) {
|
|
76
|
+
throw new Error('Failed authentication events require a failure reason');
|
|
175
77
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
for (const event of eventsArg) {
|
|
183
|
-
AuthenticationEventDoc.validateEvent(event);
|
|
184
|
-
}
|
|
185
|
-
const collection = await AuthenticationEventDoc.getNativeCollection();
|
|
186
|
-
await collection.bulkWrite(eventsArg.map((event) => {
|
|
187
|
-
const timestamp = new Date(event.timestamp).toISOString();
|
|
188
|
-
const persistedEvent = AuthenticationEventDoc.toPersistedFields(event);
|
|
189
|
-
return {
|
|
190
|
-
updateOne: {
|
|
191
|
-
filter: { id: event.id },
|
|
192
|
-
update: {
|
|
193
|
-
$setOnInsert: {
|
|
194
|
-
...persistedEvent,
|
|
195
|
-
_createdAt: timestamp,
|
|
196
|
-
_updatedAt: timestamp,
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
upsert: true,
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
}), { ordered: false, timeoutMS: DB_OPERATION_TIMEOUT_MS });
|
|
78
|
+
}
|
|
79
|
+
static async upsertMany(eventsArg) {
|
|
80
|
+
if (eventsArg.length === 0)
|
|
81
|
+
return;
|
|
82
|
+
if (eventsArg.length > 500) {
|
|
83
|
+
throw new Error('AuthenticationEventDoc.upsertMany accepts at most 500 events');
|
|
203
84
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
throw new Error('AuthenticationEventDoc.getWindowSummary requires a valid cutoff');
|
|
207
|
-
}
|
|
208
|
-
if (!Number.isSafeInteger(limitArg) || limitArg <= 0 || limitArg > 500) {
|
|
209
|
-
throw new Error('AuthenticationEventDoc.getWindowSummary requires a limit from 1 to 500');
|
|
210
|
-
}
|
|
211
|
-
const collection = await AuthenticationEventDoc.getNativeCollection();
|
|
212
|
-
const selector = { timestamp: { $gte: cutoffArg } };
|
|
213
|
-
const cursor = collection
|
|
214
|
-
.find(selector, { timeoutMS: DB_OPERATION_TIMEOUT_MS })
|
|
215
|
-
.sort({ timestamp: -1, id: -1 })
|
|
216
|
-
.limit(limitArg);
|
|
217
|
-
try {
|
|
218
|
-
const [successes, failures, rows] = await Promise.all([
|
|
219
|
-
collection.countDocuments({ ...selector, success: true }, { timeoutMS: DB_OPERATION_TIMEOUT_MS }),
|
|
220
|
-
collection.countDocuments({ ...selector, success: false }, { timeoutMS: DB_OPERATION_TIMEOUT_MS }),
|
|
221
|
-
cursor.toArray(),
|
|
222
|
-
]);
|
|
223
|
-
return {
|
|
224
|
-
successes,
|
|
225
|
-
failures,
|
|
226
|
-
events: rows.map((row) => AuthenticationEventDoc
|
|
227
|
-
.createInstanceFromMongoDbNativeDoc(row)
|
|
228
|
-
.toApiObject()),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
finally {
|
|
232
|
-
await cursor.close({ timeoutMS: DB_OPERATION_TIMEOUT_MS });
|
|
233
|
-
}
|
|
85
|
+
for (const event of eventsArg) {
|
|
86
|
+
AuthenticationEventDoc.validateEvent(event);
|
|
234
87
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
.toArray();
|
|
246
|
-
return new Set(rows.map((row) => String(row.id)));
|
|
88
|
+
const documents = new Map();
|
|
89
|
+
for (const event of eventsArg) {
|
|
90
|
+
if (documents.has(event.id))
|
|
91
|
+
continue;
|
|
92
|
+
const timestamp = new Date(event.timestamp).toISOString();
|
|
93
|
+
documents.set(event.id, Object.assign(new AuthenticationEventDoc(), {
|
|
94
|
+
...AuthenticationEventDoc.toPersistedFields(event),
|
|
95
|
+
_createdAt: timestamp,
|
|
96
|
+
_updatedAt: timestamp,
|
|
97
|
+
}));
|
|
247
98
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const rows = await collection
|
|
256
|
-
.find({ timestamp: { $lt: cutoffArg } }, { projection: { _id: 1 }, timeoutMS: DB_OPERATION_TIMEOUT_MS })
|
|
257
|
-
.sort({ timestamp: 1, _id: 1 })
|
|
258
|
-
.limit(500)
|
|
259
|
-
.toArray();
|
|
260
|
-
if (rows.length === 0)
|
|
261
|
-
break;
|
|
262
|
-
const result = await collection.deleteMany({ _id: { $in: rows.map((row) => row._id) } }, { timeoutMS: DB_OPERATION_TIMEOUT_MS });
|
|
263
|
-
deletedCount += result.deletedCount;
|
|
264
|
-
if (rows.length < 500)
|
|
265
|
-
break;
|
|
266
|
-
}
|
|
267
|
-
return deletedCount;
|
|
99
|
+
await AuthenticationEventDoc.insertManyIfAbsent([...documents.values()], {
|
|
100
|
+
identityField: 'id', timeoutMS: DB_OPERATION_TIMEOUT_MS,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
static async getWindowSummary(cutoffArg, limitArg = 100) {
|
|
104
|
+
if (!Number.isSafeInteger(cutoffArg) || cutoffArg < 0) {
|
|
105
|
+
throw new Error('AuthenticationEventDoc.getWindowSummary requires a valid cutoff');
|
|
268
106
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC5kb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9kYi9kb2N1bWVudHMvY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC5kb2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBUXZELE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDO0FBRXRDLE1BQU0sS0FBSyxHQUFHLEdBQUcsRUFBRSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUd4QyxzQkFBc0I7NEJBRGxDLE9BQU8sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDOzs7O3NCQUNBLE9BQU8sQ0FBQyxTQUFTLENBQUMsY0FBYzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztzQ0FBeEMsU0FBUSxXQUczQzs7Ozs4QkFDRSxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUN2QixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtxQ0FHeEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUU7b0NBR3hCLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFO2tDQUd4QixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTttQ0FHeEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUU7K0NBR3hCLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFOzhDQUd4QixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTt5Q0FHeEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUU7WUFwQnpCLHdKQUFP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
|
|
107
|
+
if (!Number.isSafeInteger(limitArg) || limitArg <= 0 || limitArg > 500) {
|
|
108
|
+
throw new Error('AuthenticationEventDoc.getWindowSummary requires a limit from 1 to 500');
|
|
109
|
+
}
|
|
110
|
+
await AuthenticationEventDoc.ensureInitialized();
|
|
111
|
+
const selector = { timestamp: { $gte: cutoffArg } };
|
|
112
|
+
const [totalsResult, rowsResult] = await Promise.allSettled([
|
|
113
|
+
AuthenticationEventDoc.getGroupedTotals({
|
|
114
|
+
filter: selector, groupBy: ['success'], limit: 3,
|
|
115
|
+
maxTimeMS: DB_OPERATION_TIMEOUT_MS, timeoutMS: DB_OPERATION_TIMEOUT_MS,
|
|
116
|
+
}),
|
|
117
|
+
AuthenticationEventDoc.getOffsetPage(selector, {
|
|
118
|
+
skip: 0, limit: limitArg, sort: { timestamp: -1, id: -1 },
|
|
119
|
+
maxTimeMS: DB_OPERATION_TIMEOUT_MS, timeoutMS: DB_OPERATION_TIMEOUT_MS,
|
|
120
|
+
}),
|
|
121
|
+
]);
|
|
122
|
+
// Both public queries own a cursor; drain both before releasing this computation.
|
|
123
|
+
if (totalsResult.status === 'rejected')
|
|
124
|
+
throw totalsResult.reason;
|
|
125
|
+
if (rowsResult.status === 'rejected')
|
|
126
|
+
throw rowsResult.reason;
|
|
127
|
+
const totals = totalsResult.value;
|
|
128
|
+
const rows = rowsResult.value;
|
|
129
|
+
let successes = 0;
|
|
130
|
+
let failures = 0;
|
|
131
|
+
for (const total of totals) {
|
|
132
|
+
if (total.group.success === true)
|
|
133
|
+
successes = total.count;
|
|
134
|
+
else if (total.group.success === false)
|
|
135
|
+
failures = total.count;
|
|
136
|
+
else
|
|
137
|
+
throw new Error('Authentication events contain an invalid success value');
|
|
138
|
+
}
|
|
139
|
+
return { successes, failures, events: rows.map((row) => row.toApiObject()) };
|
|
140
|
+
}
|
|
141
|
+
static async findExistingIds(idsArg) {
|
|
142
|
+
const ids = [...new Set(idsArg)];
|
|
143
|
+
if (ids.length === 0)
|
|
144
|
+
return new Set();
|
|
145
|
+
if (ids.length > 500) {
|
|
146
|
+
throw new Error('AuthenticationEventDoc.findExistingIds accepts at most 500 ids');
|
|
147
|
+
}
|
|
148
|
+
await AuthenticationEventDoc.ensureInitialized();
|
|
149
|
+
const rows = await AuthenticationEventDoc.getOffsetPage({ id: { $in: ids } }, {
|
|
150
|
+
skip: 0, limit: ids.length, sort: { id: 1 }, projection: { id: 1, _id: 0 },
|
|
151
|
+
maxTimeMS: DB_OPERATION_TIMEOUT_MS, timeoutMS: DB_OPERATION_TIMEOUT_MS,
|
|
152
|
+
});
|
|
153
|
+
return new Set(rows.map((row) => row.id));
|
|
154
|
+
}
|
|
155
|
+
static async pruneBefore(cutoffArg) {
|
|
156
|
+
if (!Number.isSafeInteger(cutoffArg) || cutoffArg < 0) {
|
|
157
|
+
throw new Error('AuthenticationEventDoc.pruneBefore requires a valid cutoff');
|
|
158
|
+
}
|
|
159
|
+
await AuthenticationEventDoc.ensureInitialized();
|
|
160
|
+
let deletedCount = 0;
|
|
161
|
+
while (true) {
|
|
162
|
+
const rows = await AuthenticationEventDoc.getOffsetPage({ timestamp: { $lt: cutoffArg } }, {
|
|
163
|
+
skip: 0, limit: 500, sort: { timestamp: 1, id: 1 }, projection: { id: 1, _id: 0 },
|
|
164
|
+
maxTimeMS: DB_OPERATION_TIMEOUT_MS, timeoutMS: DB_OPERATION_TIMEOUT_MS,
|
|
165
|
+
});
|
|
166
|
+
if (rows.length === 0)
|
|
167
|
+
break;
|
|
168
|
+
const result = await AuthenticationEventDoc.atomicDeleteMany({ timestamp: { $lt: cutoffArg }, $or: rows.map((row) => ({ id: row.id })) }, { timeoutMS: DB_OPERATION_TIMEOUT_MS });
|
|
169
|
+
deletedCount += result.deletedCount;
|
|
170
|
+
if (rows.length < 500)
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
return deletedCount;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Match the names installed by create-monitoring-event-indexes on existing hubs.
|
|
177
|
+
plugins.smartdata.defineCollectionModel(AuthenticationEventDoc, getDb, {
|
|
178
|
+
collectionName: 'AuthenticationEventDoc',
|
|
179
|
+
persistedFields: [
|
|
180
|
+
'id', 'timestamp', 'username', 'userId', 'success',
|
|
181
|
+
'requestedAuthSource', 'resolvedAuthSource', 'failureReason',
|
|
182
|
+
],
|
|
183
|
+
identityFields: ['id'],
|
|
184
|
+
indexes: [
|
|
185
|
+
{ name: 'authentication_event_id_unique', key: { id: 1 }, options: { unique: true } },
|
|
186
|
+
{ name: 'authentication_event_timestamp', key: { timestamp: -1 } },
|
|
187
|
+
{ name: 'authentication_event_success_timestamp', key: { success: 1, timestamp: -1 } },
|
|
188
|
+
],
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC5kb2MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9kYi9kb2N1bWVudHMvY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC5kb2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFRdkQsTUFBTSx1QkFBdUIsR0FBRyxLQUFLLENBQUM7QUFFdEMsTUFBTSxLQUFLLEdBQUcsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO0FBRXJELE1BQU0sT0FBTyxzQkFBdUIsU0FBUSxPQUFPLENBQUMsU0FBUyxDQUFDLGNBRzdEO0lBQ1EsRUFBRSxDQUFVO0lBRVosU0FBUyxDQUFVO0lBRW5CLFFBQVEsQ0FBVTtJQUVsQixNQUFNLENBQVU7SUFFaEIsT0FBTyxDQUFXO0lBRWxCLG1CQUFtQixDQUF5QjtJQUU1QyxrQkFBa0IsQ0FBaUM7SUFFbkQsYUFBYSxDQUFnQztJQUVwRDtRQUNFLEtBQUssRUFBRSxDQUFDO0lBQ1YsQ0FBQztJQUVNLFdBQVc7UUFDaEIsT0FBTztZQUNMLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUNYLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO1lBQ3JCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxtQkFBbUI7WUFDN0MsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9DLEdBQUcsQ0FBQyxJQUFJLENBQUMsa0JB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
|