@serve.zone/dcrouter 18.1.0 → 18.2.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/deno.json +1 -1
- package/dist_serve/bundle.js +2072 -1624
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +64 -2
- package/dist_ts/classes.dcrouter.js +187 -6
- package/dist_ts/db/documents/classes.authentication-event.doc.d.ts +25 -0
- package/dist_ts/db/documents/classes.authentication-event.doc.js +273 -0
- package/dist_ts/db/documents/classes.email-traffic-bucket.doc.d.ts +25 -0
- package/dist_ts/db/documents/classes.email-traffic-bucket.doc.js +200 -0
- package/dist_ts/db/documents/index.d.ts +2 -0
- package/dist_ts/db/documents/index.js +3 -1
- package/dist_ts/email/classes.accepted-email-spool.d.ts +67 -0
- package/dist_ts/email/classes.accepted-email-spool.js +245 -17
- package/dist_ts/email/classes.workapp-mail-manager.js +5 -2
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +19 -0
- package/dist_ts/monitoring/classes.metricsmanager.js +240 -44
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +1 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +61 -14
- package/dist_ts/opsserver/handlers/security.handler.js +21 -3
- package/dist_ts/opsserver/handlers/stats.handler.js +27 -10
- package/dist_ts/security/classes.authentication-event-manager.d.ts +35 -0
- package/dist_ts/security/classes.authentication-event-manager.js +185 -0
- package/dist_ts/security/index.d.ts +1 -0
- package/dist_ts/security/index.js +2 -1
- package/dist_ts_interfaces/data/stats.d.ts +16 -0
- package/dist_ts_migrations/index.js +74 -15
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/overview/ops-view-overview.js +3 -2
- package/dist_ts_web/elements/security/ops-view-security-authentication.js +20 -13
- package/dist_ts_web/elements/security/ops-view-security-overview.js +8 -11
- package/package.json +3 -3
- package/readme.md +24 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +230 -6
- package/ts/db/documents/classes.authentication-event.doc.ts +248 -0
- package/ts/db/documents/classes.email-traffic-bucket.doc.ts +161 -0
- package/ts/db/documents/index.ts +2 -0
- package/ts/email/classes.accepted-email-spool.ts +319 -21
- package/ts/email/classes.workapp-mail-manager.ts +4 -1
- package/ts/monitoring/classes.metricsmanager.ts +287 -50
- package/ts/opsserver/handlers/admin.handler.ts +74 -15
- package/ts/opsserver/handlers/security.handler.ts +23 -2
- package/ts/opsserver/handlers/stats.handler.ts +29 -9
- package/ts/security/classes.authentication-event-manager.ts +221 -0
- package/ts/security/index.ts +1 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/overview/ops-view-overview.ts +2 -1
- package/ts_web/elements/security/ops-view-security-authentication.ts +20 -13
- package/ts_web/elements/security/ops-view-security-overview.ts +7 -12
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import { logger } from '../logger.js';
|
|
3
|
+
import { AuthenticationEventDoc } from '../db/documents/classes.authentication-event.doc.js';
|
|
4
|
+
import { SecurityEventType, SecurityLogLevel, SecurityLogger, } from './classes.securitylogger.js';
|
|
5
|
+
const MAX_IN_MEMORY_EVENTS = 10_000;
|
|
6
|
+
const MAX_PERSIST_BATCH_SIZE = 500;
|
|
7
|
+
export class AuthenticationEventManager {
|
|
8
|
+
dcRouterRef;
|
|
9
|
+
pendingEvents = new Map();
|
|
10
|
+
recentEvents = new Map();
|
|
11
|
+
flushInFlight;
|
|
12
|
+
pruneInFlight;
|
|
13
|
+
windowStatsInFlight = new Map();
|
|
14
|
+
constructor(dcRouterRef) {
|
|
15
|
+
this.dcRouterRef = dcRouterRef;
|
|
16
|
+
}
|
|
17
|
+
canPersist() {
|
|
18
|
+
return this.dcRouterRef.options.dbConfig?.enabled !== false
|
|
19
|
+
&& Boolean(this.dcRouterRef.dcRouterDb?.isReady());
|
|
20
|
+
}
|
|
21
|
+
rememberEvent(eventArg) {
|
|
22
|
+
this.pendingEvents.set(eventArg.id, eventArg);
|
|
23
|
+
this.recentEvents.set(eventArg.id, eventArg);
|
|
24
|
+
while (this.pendingEvents.size > MAX_IN_MEMORY_EVENTS) {
|
|
25
|
+
const oldestId = this.pendingEvents.keys().next().value;
|
|
26
|
+
if (!oldestId)
|
|
27
|
+
break;
|
|
28
|
+
this.pendingEvents.delete(oldestId);
|
|
29
|
+
logger.log('error', 'Authentication event persistence buffer reached its limit; oldest event dropped');
|
|
30
|
+
}
|
|
31
|
+
while (this.recentEvents.size > MAX_IN_MEMORY_EVENTS) {
|
|
32
|
+
const oldestId = this.recentEvents.keys().next().value;
|
|
33
|
+
if (!oldestId)
|
|
34
|
+
break;
|
|
35
|
+
this.recentEvents.delete(oldestId);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async flushBufferedUnlocked() {
|
|
39
|
+
if (!this.canPersist() || this.pendingEvents.size === 0)
|
|
40
|
+
return;
|
|
41
|
+
const events = [...this.pendingEvents.values()];
|
|
42
|
+
for (let offset = 0; offset < events.length; offset += MAX_PERSIST_BATCH_SIZE) {
|
|
43
|
+
const batch = events.slice(offset, offset + MAX_PERSIST_BATCH_SIZE);
|
|
44
|
+
await AuthenticationEventDoc.upsertMany(batch);
|
|
45
|
+
for (const event of batch) {
|
|
46
|
+
if (this.pendingEvents.get(event.id) === event) {
|
|
47
|
+
this.pendingEvents.delete(event.id);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async recordAttempt(optionsArg) {
|
|
53
|
+
const event = {
|
|
54
|
+
id: `auth-${plugins.uuid.v4()}`,
|
|
55
|
+
timestamp: Date.now(),
|
|
56
|
+
username: String(optionsArg.username || '').trim().toLowerCase() || 'unknown',
|
|
57
|
+
success: optionsArg.success,
|
|
58
|
+
requestedAuthSource: optionsArg.requestedAuthSource,
|
|
59
|
+
...(optionsArg.userId ? { userId: optionsArg.userId } : {}),
|
|
60
|
+
...(optionsArg.resolvedAuthSource
|
|
61
|
+
? { resolvedAuthSource: optionsArg.resolvedAuthSource }
|
|
62
|
+
: {}),
|
|
63
|
+
...(optionsArg.failureReason ? { failureReason: optionsArg.failureReason } : {}),
|
|
64
|
+
};
|
|
65
|
+
// Buffer before any asynchronous persistence so authentication cannot be
|
|
66
|
+
// held behind a slow database and the bounded drop policy remains effective.
|
|
67
|
+
this.rememberEvent(event);
|
|
68
|
+
try {
|
|
69
|
+
SecurityLogger.getInstance().logEvent({
|
|
70
|
+
level: event.success ? SecurityLogLevel.INFO : SecurityLogLevel.WARN,
|
|
71
|
+
type: SecurityEventType.AUTHENTICATION,
|
|
72
|
+
message: event.success ? 'Authentication succeeded' : 'Authentication failed',
|
|
73
|
+
userId: event.userId,
|
|
74
|
+
success: event.success,
|
|
75
|
+
details: { authenticationEvent: event },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger.log('warn', `Unable to mirror authentication event to the security log: ${error.message}`);
|
|
80
|
+
}
|
|
81
|
+
return event;
|
|
82
|
+
}
|
|
83
|
+
flushBuffered() {
|
|
84
|
+
if (this.flushInFlight)
|
|
85
|
+
return this.flushInFlight;
|
|
86
|
+
const run = this.flushBufferedUnlocked();
|
|
87
|
+
this.flushInFlight = run;
|
|
88
|
+
run.then(() => { if (this.flushInFlight === run)
|
|
89
|
+
this.flushInFlight = undefined; }, () => { if (this.flushInFlight === run)
|
|
90
|
+
this.flushInFlight = undefined; });
|
|
91
|
+
return run;
|
|
92
|
+
}
|
|
93
|
+
pruneBefore(cutoffArg) {
|
|
94
|
+
if (this.pruneInFlight)
|
|
95
|
+
return this.pruneInFlight;
|
|
96
|
+
const run = this.canPersist()
|
|
97
|
+
? AuthenticationEventDoc.pruneBefore(cutoffArg)
|
|
98
|
+
: Promise.resolve(0);
|
|
99
|
+
this.pruneInFlight = run;
|
|
100
|
+
run.then(() => { if (this.pruneInFlight === run)
|
|
101
|
+
this.pruneInFlight = undefined; }, () => { if (this.pruneInFlight === run)
|
|
102
|
+
this.pruneInFlight = undefined; });
|
|
103
|
+
return run;
|
|
104
|
+
}
|
|
105
|
+
getInMemoryWindow(cutoffArg, limitArg) {
|
|
106
|
+
const events = [...this.recentEvents.values()]
|
|
107
|
+
.filter((event) => event.timestamp >= cutoffArg)
|
|
108
|
+
.sort((a, b) => b.timestamp - a.timestamp || b.id.localeCompare(a.id));
|
|
109
|
+
return {
|
|
110
|
+
windowStart: cutoffArg,
|
|
111
|
+
successes: events.filter((event) => event.success).length,
|
|
112
|
+
failures: events.filter((event) => !event.success).length,
|
|
113
|
+
events: events.slice(0, limitArg),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async getWindowStatsUnlocked(windowMsArg = 24 * 60 * 60 * 1000, limitArg = 100) {
|
|
117
|
+
const cutoff = Date.now() - windowMsArg;
|
|
118
|
+
if (!this.canPersist()) {
|
|
119
|
+
return this.getInMemoryWindow(cutoff, limitArg);
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await this.flushBuffered();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
logger.log('warn', `Unable to flush authentication event buffer: ${error.message}`);
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const durable = await AuthenticationEventDoc.getWindowSummary(cutoff, limitArg);
|
|
129
|
+
const buffered = [...this.pendingEvents.values()]
|
|
130
|
+
.filter((event) => event.timestamp >= cutoff);
|
|
131
|
+
const existingIds = new Set();
|
|
132
|
+
const bufferedIds = buffered.map((event) => event.id);
|
|
133
|
+
for (let offset = 0; offset < bufferedIds.length; offset += MAX_PERSIST_BATCH_SIZE) {
|
|
134
|
+
const existingBatch = await AuthenticationEventDoc.findExistingIds(bufferedIds.slice(offset, offset + MAX_PERSIST_BATCH_SIZE));
|
|
135
|
+
existingBatch.forEach((id) => existingIds.add(id));
|
|
136
|
+
}
|
|
137
|
+
const unpersisted = buffered.filter((event) => !existingIds.has(event.id));
|
|
138
|
+
const mergedById = new Map();
|
|
139
|
+
for (const event of durable.events)
|
|
140
|
+
mergedById.set(event.id, event);
|
|
141
|
+
for (const event of unpersisted) {
|
|
142
|
+
if (!mergedById.has(event.id))
|
|
143
|
+
mergedById.set(event.id, event);
|
|
144
|
+
}
|
|
145
|
+
const mergedEvents = [...mergedById.values()]
|
|
146
|
+
.sort((a, b) => b.timestamp - a.timestamp || b.id.localeCompare(a.id))
|
|
147
|
+
.slice(0, limitArg);
|
|
148
|
+
return {
|
|
149
|
+
windowStart: cutoff,
|
|
150
|
+
successes: durable.successes + unpersisted.filter((event) => event.success).length,
|
|
151
|
+
failures: durable.failures + unpersisted.filter((event) => !event.success).length,
|
|
152
|
+
events: mergedEvents,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
logger.log('warn', `Unable to query durable authentication events: ${error.message}`);
|
|
157
|
+
return this.getInMemoryWindow(cutoff, limitArg);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
getWindowStats(windowMsArg = 24 * 60 * 60 * 1000, limitArg = 100) {
|
|
161
|
+
if (!Number.isSafeInteger(windowMsArg) || windowMsArg <= 0) {
|
|
162
|
+
return Promise.reject(new Error('Authentication window must be a positive integer'));
|
|
163
|
+
}
|
|
164
|
+
if (!Number.isSafeInteger(limitArg) || limitArg <= 0 || limitArg > 500) {
|
|
165
|
+
return Promise.reject(new Error('Authentication event limit must be from 1 to 500'));
|
|
166
|
+
}
|
|
167
|
+
const key = `${windowMsArg}:${limitArg}`;
|
|
168
|
+
const existing = this.windowStatsInFlight.get(key);
|
|
169
|
+
if (existing)
|
|
170
|
+
return existing;
|
|
171
|
+
const run = this.getWindowStatsUnlocked(windowMsArg, limitArg);
|
|
172
|
+
this.windowStatsInFlight.set(key, run);
|
|
173
|
+
run.then(() => { if (this.windowStatsInFlight.get(key) === run)
|
|
174
|
+
this.windowStatsInFlight.delete(key); }, () => { if (this.windowStatsInFlight.get(key) === run)
|
|
175
|
+
this.windowStatsInFlight.delete(key); });
|
|
176
|
+
return run;
|
|
177
|
+
}
|
|
178
|
+
/** Test-only reset for the DcRouter-owned in-process buffers. */
|
|
179
|
+
async resetForTests() {
|
|
180
|
+
await this.flushInFlight?.catch(() => undefined);
|
|
181
|
+
this.pendingEvents.clear();
|
|
182
|
+
this.recentEvents.clear();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc2VjdXJpdHkvY2xhc3Nlcy5hdXRoZW50aWNhdGlvbi1ldmVudC1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdEMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFPN0YsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsY0FBYyxHQUNmLE1BQU0sNkJBQTZCLENBQUM7QUFFckMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFDcEMsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUM7QUFTbkMsTUFBTSxPQUFPLDBCQUEwQjtJQU9qQjtJQU5aLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBZ0MsQ0FBQztJQUN4RCxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQWdDLENBQUM7SUFDdkQsYUFBYSxDQUFpQjtJQUM5QixhQUFhLENBQW1CO0lBQ2hDLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUErQyxDQUFDO0lBRXJGLFlBQW9CLFdBQXFCO1FBQXJCLGdCQUFXLEdBQVgsV0FBVyxDQUFVO0lBQUcsQ0FBQztJQUVyQyxVQUFVO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLE9BQU8sS0FBSyxLQUFLO2VBQ3RELE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFTyxhQUFhLENBQUMsUUFBOEI7UUFDbEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxRQUFRLENB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
|
|
@@ -3,3 +3,4 @@ export { IPReputationChecker, ReputationThreshold, IPType, type IReputationResul
|
|
|
3
3
|
export { ContentScanner, ThreatCategory, type IScanResult, type IContentScannerOptions } from './classes.contentscanner.js';
|
|
4
4
|
export { SecurityPolicyManager, type ISecurityPolicyManagerOptions, type IRemoteIngressFirewallSnapshot, } from './classes.security-policy-manager.js';
|
|
5
5
|
export * from './classes.route-policy-augmenter.js';
|
|
6
|
+
export * from './classes.authentication-event-manager.js';
|
|
@@ -3,4 +3,5 @@ export { IPReputationChecker, ReputationThreshold, IPType } from './classes.ipre
|
|
|
3
3
|
export { ContentScanner, ThreatCategory } from './classes.contentscanner.js';
|
|
4
4
|
export { SecurityPolicyManager, } from './classes.security-policy-manager.js';
|
|
5
5
|
export * from './classes.route-policy-augmenter.js';
|
|
6
|
-
|
|
6
|
+
export * from './classes.authentication-event-manager.js';
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zZWN1cml0eS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixpQkFBaUIsRUFFbEIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixNQUFNLEVBR1AsTUFBTSxrQ0FBa0MsQ0FBQztBQUUxQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFHZixNQUFNLDZCQUE2QixDQUFDO0FBRXJDLE9BQU8sRUFDTCxxQkFBcUIsR0FHdEIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxjQUFjLHFDQUFxQyxDQUFDO0FBQ3BELGNBQWMsMkNBQTJDLENBQUMifQ==
|
|
@@ -82,6 +82,19 @@ export interface ISecurityEvent {
|
|
|
82
82
|
domain?: string;
|
|
83
83
|
success?: boolean;
|
|
84
84
|
}
|
|
85
|
+
export type TAuthenticationSource = 'auto' | 'local' | 'idp.global';
|
|
86
|
+
export type TResolvedAuthenticationSource = Exclude<TAuthenticationSource, 'auto'>;
|
|
87
|
+
export type TAuthenticationFailureReason = 'invalidCredentials' | 'serviceUnavailable' | 'identityIssuanceFailed' | 'internalError';
|
|
88
|
+
export interface IAuthenticationEvent {
|
|
89
|
+
id: string;
|
|
90
|
+
timestamp: number;
|
|
91
|
+
username: string;
|
|
92
|
+
userId?: string;
|
|
93
|
+
success: boolean;
|
|
94
|
+
requestedAuthSource: TAuthenticationSource;
|
|
95
|
+
resolvedAuthSource?: TResolvedAuthenticationSource;
|
|
96
|
+
failureReason?: TAuthenticationFailureReason;
|
|
97
|
+
}
|
|
85
98
|
export interface ISecurityMetrics {
|
|
86
99
|
blockedIPs: string[];
|
|
87
100
|
reputationScores: {
|
|
@@ -91,6 +104,9 @@ export interface ISecurityMetrics {
|
|
|
91
104
|
malwareDetected: number;
|
|
92
105
|
phishingDetected: number;
|
|
93
106
|
authenticationFailures: number;
|
|
107
|
+
authenticationSuccesses: number;
|
|
108
|
+
authenticationWindowStart: number;
|
|
109
|
+
authenticationEvents?: IAuthenticationEvent[];
|
|
94
110
|
suspiciousActivities: number;
|
|
95
111
|
recentEvents?: ISecurityEvent[];
|
|
96
112
|
}
|