@elliemae/microfe-common 2.24.0 → 2.25.1
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/cjs/auditThrottler.js +60 -0
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/remoting.js +9 -5
- package/dist/esm/auditThrottler.js +40 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/remoting.js +9 -5
- package/dist/types/lib/auditThrottler.d.ts +29 -0
- package/dist/types/lib/index.d.ts +3 -1
- package/dist/types/lib/remoting.d.ts +11 -1
- package/dist/types/lib/tests/auditThrottler.test.d.ts +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var auditThrottler_exports = {};
|
|
20
|
+
__export(auditThrottler_exports, {
|
|
21
|
+
AuditThrottler: () => AuditThrottler
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(auditThrottler_exports);
|
|
24
|
+
class AuditThrottler {
|
|
25
|
+
#logger;
|
|
26
|
+
#enabled;
|
|
27
|
+
#throttleMs;
|
|
28
|
+
#lastAudited = /* @__PURE__ */ new Map();
|
|
29
|
+
static DEFAULT_THROTTLE_MS = 1e4;
|
|
30
|
+
constructor(options) {
|
|
31
|
+
this.#logger = options.logger;
|
|
32
|
+
this.#enabled = options.enabled ?? true;
|
|
33
|
+
this.#throttleMs = options.throttleMs ?? AuditThrottler.DEFAULT_THROTTLE_MS;
|
|
34
|
+
}
|
|
35
|
+
get enabled() {
|
|
36
|
+
return this.#enabled;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Log a high-frequency operation. When audit is enabled and the throttle
|
|
40
|
+
* window allows it the payload is sent at `audit` level; otherwise `debug`.
|
|
41
|
+
* @param {string} key - dedup key for throttling (e.g. `invoke:loan.getField`)
|
|
42
|
+
* @param {LogRecord} payload - structured log payload
|
|
43
|
+
*/
|
|
44
|
+
log(key, payload) {
|
|
45
|
+
if (!this.#enabled) {
|
|
46
|
+
this.#logger.debug(payload);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (this.#throttleMs > 0) {
|
|
50
|
+
const now = performance.now();
|
|
51
|
+
const last = this.#lastAudited.get(key);
|
|
52
|
+
if (last !== void 0 && now - last < this.#throttleMs) {
|
|
53
|
+
this.#logger.debug(payload);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.#lastAudited.set(key, now);
|
|
57
|
+
}
|
|
58
|
+
this.#logger.audit(payload);
|
|
59
|
+
}
|
|
60
|
+
}
|
package/dist/cjs/index.js
CHANGED
|
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var index_exports = {};
|
|
20
20
|
__export(index_exports, {
|
|
21
|
+
AuditThrottler: () => import_auditThrottler.AuditThrottler,
|
|
21
22
|
Event: () => import_event2.Event,
|
|
22
23
|
MessageType: () => import_messageType.MessageType,
|
|
23
24
|
ProxyEvent: () => import_event.ProxyEvent,
|
|
@@ -39,3 +40,4 @@ var import_scriptingObject = require("./scriptingObject.js");
|
|
|
39
40
|
var import_messageType = require("./messageType.js");
|
|
40
41
|
var import_scriptingObjectManager = require("./scriptingObjectManager.js");
|
|
41
42
|
var import_proxy = require("./proxy.js");
|
|
43
|
+
var import_auditThrottler = require("./auditThrottler.js");
|
package/dist/cjs/remoting.js
CHANGED
|
@@ -66,17 +66,21 @@ class Remoting {
|
|
|
66
66
|
* The set of windows that are allowed to send messages to this window
|
|
67
67
|
*/
|
|
68
68
|
#allowedSenders = /* @__PURE__ */ new Map();
|
|
69
|
+
#disableOriginCheck;
|
|
69
70
|
/**
|
|
70
71
|
* Create a new instance of the Remoting class
|
|
71
72
|
* @param logger pui-diagnostic logger
|
|
72
73
|
* @param correlationId unique id for the current session
|
|
74
|
+
* @param options optional configuration
|
|
73
75
|
*/
|
|
74
|
-
constructor(logger, correlationId) {
|
|
76
|
+
constructor(logger, correlationId, options) {
|
|
75
77
|
if (!logger) throw new Error("logger is required");
|
|
76
78
|
if (!correlationId) throw new Error("correlationId is required");
|
|
77
79
|
this.#correlationId = correlationId;
|
|
78
80
|
this.#logger = logger;
|
|
81
|
+
this.#disableOriginCheck = options?.unsafeAllowAnyGuestOrigin ?? false;
|
|
79
82
|
}
|
|
83
|
+
#getTargetOrigin = (targetOrigin) => this.#disableOriginCheck ? "*" : targetOrigin;
|
|
80
84
|
// Evaluates the timeouts on any waiting invocations and schedules the next check
|
|
81
85
|
#evaluateTimeouts = () => {
|
|
82
86
|
this.#timeoutMonitorHandle = null;
|
|
@@ -259,7 +263,7 @@ class Remoting {
|
|
|
259
263
|
reject,
|
|
260
264
|
cancelTime: responseTimeoutMs ? Date.now() + responseTimeoutMs : null
|
|
261
265
|
});
|
|
262
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
266
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
263
267
|
const { requestId } = msg;
|
|
264
268
|
this.#logger.debug(
|
|
265
269
|
`Posted invocation message of type ${messageType} requestId: ${requestId || ""}`
|
|
@@ -306,7 +310,7 @@ class Remoting {
|
|
|
306
310
|
messageBody,
|
|
307
311
|
onewayMsg: true
|
|
308
312
|
});
|
|
309
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
313
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
310
314
|
this.#logger.debug(`Posted one-way message of type "${messageType}"`);
|
|
311
315
|
};
|
|
312
316
|
/**
|
|
@@ -328,7 +332,7 @@ class Remoting {
|
|
|
328
332
|
messageBody: response,
|
|
329
333
|
requestId
|
|
330
334
|
});
|
|
331
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
335
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
332
336
|
this.#logger.debug(
|
|
333
337
|
`Response sent to caller for invocation requestId: ${requestId}`
|
|
334
338
|
);
|
|
@@ -345,7 +349,7 @@ class Remoting {
|
|
|
345
349
|
messageBody,
|
|
346
350
|
requestId
|
|
347
351
|
});
|
|
348
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
352
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
349
353
|
this.#logger.debug(
|
|
350
354
|
`Exception sent to caller for invocation. requestId: ${requestId}`
|
|
351
355
|
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class AuditThrottler {
|
|
2
|
+
#logger;
|
|
3
|
+
#enabled;
|
|
4
|
+
#throttleMs;
|
|
5
|
+
#lastAudited = /* @__PURE__ */ new Map();
|
|
6
|
+
static DEFAULT_THROTTLE_MS = 1e4;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.#logger = options.logger;
|
|
9
|
+
this.#enabled = options.enabled ?? true;
|
|
10
|
+
this.#throttleMs = options.throttleMs ?? AuditThrottler.DEFAULT_THROTTLE_MS;
|
|
11
|
+
}
|
|
12
|
+
get enabled() {
|
|
13
|
+
return this.#enabled;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Log a high-frequency operation. When audit is enabled and the throttle
|
|
17
|
+
* window allows it the payload is sent at `audit` level; otherwise `debug`.
|
|
18
|
+
* @param {string} key - dedup key for throttling (e.g. `invoke:loan.getField`)
|
|
19
|
+
* @param {LogRecord} payload - structured log payload
|
|
20
|
+
*/
|
|
21
|
+
log(key, payload) {
|
|
22
|
+
if (!this.#enabled) {
|
|
23
|
+
this.#logger.debug(payload);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (this.#throttleMs > 0) {
|
|
27
|
+
const now = performance.now();
|
|
28
|
+
const last = this.#lastAudited.get(key);
|
|
29
|
+
if (last !== void 0 && now - last < this.#throttleMs) {
|
|
30
|
+
this.#logger.debug(payload);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.#lastAudited.set(key, now);
|
|
34
|
+
}
|
|
35
|
+
this.#logger.audit(payload);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
AuditThrottler
|
|
40
|
+
};
|
package/dist/esm/index.js
CHANGED
|
@@ -8,7 +8,9 @@ import {
|
|
|
8
8
|
SecurityContext
|
|
9
9
|
} from "./scriptingObjectManager.js";
|
|
10
10
|
import { ScriptingObjectProxy, isScriptingObjectProxy } from "./proxy.js";
|
|
11
|
+
import { AuditThrottler } from "./auditThrottler.js";
|
|
11
12
|
export {
|
|
13
|
+
AuditThrottler,
|
|
12
14
|
Event,
|
|
13
15
|
MessageType,
|
|
14
16
|
ProxyEvent,
|
package/dist/esm/remoting.js
CHANGED
|
@@ -42,17 +42,21 @@ class Remoting {
|
|
|
42
42
|
* The set of windows that are allowed to send messages to this window
|
|
43
43
|
*/
|
|
44
44
|
#allowedSenders = /* @__PURE__ */ new Map();
|
|
45
|
+
#disableOriginCheck;
|
|
45
46
|
/**
|
|
46
47
|
* Create a new instance of the Remoting class
|
|
47
48
|
* @param logger pui-diagnostic logger
|
|
48
49
|
* @param correlationId unique id for the current session
|
|
50
|
+
* @param options optional configuration
|
|
49
51
|
*/
|
|
50
|
-
constructor(logger, correlationId) {
|
|
52
|
+
constructor(logger, correlationId, options) {
|
|
51
53
|
if (!logger) throw new Error("logger is required");
|
|
52
54
|
if (!correlationId) throw new Error("correlationId is required");
|
|
53
55
|
this.#correlationId = correlationId;
|
|
54
56
|
this.#logger = logger;
|
|
57
|
+
this.#disableOriginCheck = options?.unsafeAllowAnyGuestOrigin ?? false;
|
|
55
58
|
}
|
|
59
|
+
#getTargetOrigin = (targetOrigin) => this.#disableOriginCheck ? "*" : targetOrigin;
|
|
56
60
|
// Evaluates the timeouts on any waiting invocations and schedules the next check
|
|
57
61
|
#evaluateTimeouts = () => {
|
|
58
62
|
this.#timeoutMonitorHandle = null;
|
|
@@ -235,7 +239,7 @@ class Remoting {
|
|
|
235
239
|
reject,
|
|
236
240
|
cancelTime: responseTimeoutMs ? Date.now() + responseTimeoutMs : null
|
|
237
241
|
});
|
|
238
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
242
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
239
243
|
const { requestId } = msg;
|
|
240
244
|
this.#logger.debug(
|
|
241
245
|
`Posted invocation message of type ${messageType} requestId: ${requestId || ""}`
|
|
@@ -282,7 +286,7 @@ class Remoting {
|
|
|
282
286
|
messageBody,
|
|
283
287
|
onewayMsg: true
|
|
284
288
|
});
|
|
285
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
289
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
286
290
|
this.#logger.debug(`Posted one-way message of type "${messageType}"`);
|
|
287
291
|
};
|
|
288
292
|
/**
|
|
@@ -304,7 +308,7 @@ class Remoting {
|
|
|
304
308
|
messageBody: response,
|
|
305
309
|
requestId
|
|
306
310
|
});
|
|
307
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
311
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
308
312
|
this.#logger.debug(
|
|
309
313
|
`Response sent to caller for invocation requestId: ${requestId}`
|
|
310
314
|
);
|
|
@@ -321,7 +325,7 @@ class Remoting {
|
|
|
321
325
|
messageBody,
|
|
322
326
|
requestId
|
|
323
327
|
});
|
|
324
|
-
targetWin.postMessage(msg, targetOrigin);
|
|
328
|
+
targetWin.postMessage(msg, this.#getTargetOrigin(targetOrigin));
|
|
325
329
|
this.#logger.debug(
|
|
326
330
|
`Exception sent to caller for invocation. requestId: ${requestId}`
|
|
327
331
|
);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger, LogRecord } from '@elliemae/pui-diagnostics';
|
|
2
|
+
export type AuditThrottlerOptions = {
|
|
3
|
+
logger: Logger;
|
|
4
|
+
/** When `true`, high-frequency operations are logged at `audit` level. @default true */
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
/** Throttle window (ms). Same operation key is audited at most once per window. @default 10000 */
|
|
7
|
+
throttleMs?: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Controls whether high-frequency operations are logged at `audit` level
|
|
11
|
+
* (sent to Splunk) or `debug` level (local only).
|
|
12
|
+
*
|
|
13
|
+
* When enabled, a per-key throttle window prevents the same operation from
|
|
14
|
+
* flooding Splunk. Operations outside the window or with throttling disabled
|
|
15
|
+
* (`throttleMs === 0`) go straight to `audit`.
|
|
16
|
+
*/
|
|
17
|
+
export declare class AuditThrottler {
|
|
18
|
+
#private;
|
|
19
|
+
static readonly DEFAULT_THROTTLE_MS = 10000;
|
|
20
|
+
constructor(options: AuditThrottlerOptions);
|
|
21
|
+
get enabled(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Log a high-frequency operation. When audit is enabled and the throttle
|
|
24
|
+
* window allows it the payload is sent at `audit` level; otherwise `debug`.
|
|
25
|
+
* @param {string} key - dedup key for throttling (e.g. `invoke:loan.getField`)
|
|
26
|
+
* @param {LogRecord} payload - structured log payload
|
|
27
|
+
*/
|
|
28
|
+
log(key: string, payload: LogRecord): void;
|
|
29
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Remoting, sendMessage } from './remoting.js';
|
|
2
|
-
export type { ListenerCallback, ListenerCallbackParams, ListenParam, InvokeParam, RaiseExceptionParam, RespondParam, SendParam, AddSenderParam, } from './remoting.js';
|
|
2
|
+
export type { ListenerCallback, ListenerCallbackParams, ListenParam, InvokeParam, RaiseExceptionParam, RemotingOptions, RespondParam, SendParam, AddSenderParam, } from './remoting.js';
|
|
3
3
|
export type { RemotingEventMessage } from './remotingEventMessage.js';
|
|
4
4
|
export { getEventId, ProxyEvent } from './event.js';
|
|
5
5
|
export type { IScriptingObjectProxyEvent, EventParam, DispatchEventParam, EventOptions, SubscribeParam, UnsubscribeParam, IEventManager, FilterCriteria, FilterOperator, } from './event.js';
|
|
@@ -12,3 +12,5 @@ export type { ISSFGuest, ConnectParam } from './guest.js';
|
|
|
12
12
|
export { ScriptingObjectManager, SecurityContext, } from './scriptingObjectManager.js';
|
|
13
13
|
export type { AddScriptingObjectParams, CallContext, CallerInfo, GetObjectParams, GuestContext, } from './scriptingObjectManager.js';
|
|
14
14
|
export { ScriptingObjectProxy, isScriptingObjectProxy } from './proxy.js';
|
|
15
|
+
export { AuditThrottler } from './auditThrottler.js';
|
|
16
|
+
export type { AuditThrottlerOptions } from './auditThrottler.js';
|
|
@@ -171,14 +171,24 @@ export type AddSenderParam = {
|
|
|
171
171
|
/**
|
|
172
172
|
* Provides core messaging capabilities for cross-frame interactions in a sandboxed environment.
|
|
173
173
|
*/
|
|
174
|
+
export type RemotingOptions = {
|
|
175
|
+
/**
|
|
176
|
+
* **UNSAFE**: When true, uses '*' as the targetOrigin for all outbound postMessage calls,
|
|
177
|
+
* bypassing the browser's origin check on the receiving window. This means any window
|
|
178
|
+
* can receive messages intended for the guest, potentially exposing sensitive data.
|
|
179
|
+
* Only enable this if you fully understand the security implications.
|
|
180
|
+
*/
|
|
181
|
+
unsafeAllowAnyGuestOrigin?: boolean;
|
|
182
|
+
};
|
|
174
183
|
export declare class Remoting {
|
|
175
184
|
#private;
|
|
176
185
|
/**
|
|
177
186
|
* Create a new instance of the Remoting class
|
|
178
187
|
* @param logger pui-diagnostic logger
|
|
179
188
|
* @param correlationId unique id for the current session
|
|
189
|
+
* @param options optional configuration
|
|
180
190
|
*/
|
|
181
|
-
constructor(logger: Logger, correlationId: string);
|
|
191
|
+
constructor(logger: Logger, correlationId: string, options?: RemotingOptions);
|
|
182
192
|
/**
|
|
183
193
|
* Adds window and its origin list of allowed senders
|
|
184
194
|
* @param {AddSenderParam} param - The sender to add
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|