@anyreplay/browser 0.2.0 → 0.2.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/README.md +4 -1
- package/dist/index.cjs +41 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3815,10 +3815,12 @@ var AssetCollector = class {
|
|
|
3815
3815
|
body: JSON.stringify(body)
|
|
3816
3816
|
});
|
|
3817
3817
|
const known = await post("/v1/ingest/assets/known", { projectKey, hashes: [sha256], ...app });
|
|
3818
|
-
if (known.ok) {
|
|
3819
|
-
|
|
3820
|
-
|
|
3818
|
+
if (!known.ok) {
|
|
3819
|
+
if (known.status === 401 || known.status === 403) this.stop();
|
|
3820
|
+
return false;
|
|
3821
3821
|
}
|
|
3822
|
+
const answer = await known.json();
|
|
3823
|
+
if (Array.isArray(answer.known) && answer.known.includes(sha256)) return true;
|
|
3822
3824
|
const upload = await post("/v1/ingest/assets", { projectKey, sha256, data: toBase64(bytes), ...app });
|
|
3823
3825
|
return upload.ok;
|
|
3824
3826
|
}
|
|
@@ -4123,6 +4125,13 @@ function looksLikeCardNumber(text) {
|
|
|
4123
4125
|
}
|
|
4124
4126
|
return sum % 10 === 0;
|
|
4125
4127
|
}
|
|
4128
|
+
function mayBecomeCardNumber(text) {
|
|
4129
|
+
if (!/^[2-6][0-9 -]*$/.test(text)) return false;
|
|
4130
|
+
const groups = text.split(/[ -]+/);
|
|
4131
|
+
if (groups.slice(0, -1).some((group) => group.length < 4)) return false;
|
|
4132
|
+
const digits = groups.join("").length;
|
|
4133
|
+
return digits > 6 && digits <= 19;
|
|
4134
|
+
}
|
|
4126
4135
|
function isMarkedByCustomer(node, maskClass) {
|
|
4127
4136
|
var _a;
|
|
4128
4137
|
let element = asElement(node);
|
|
@@ -4137,8 +4146,19 @@ function shouldMaskValue(text, node, policy) {
|
|
|
4137
4146
|
if (policy.maskEveryField) return true;
|
|
4138
4147
|
if (isSensitiveField(node)) return true;
|
|
4139
4148
|
if (isMarkedByCustomer(node, policy.maskClass)) return true;
|
|
4140
|
-
return
|
|
4149
|
+
return cardShaped(text);
|
|
4150
|
+
}
|
|
4151
|
+
var cardShaped = (text) => looksLikeCardNumber(text) || mayBecomeCardNumber(text);
|
|
4152
|
+
var EDITABLE = '[contenteditable]:not([contenteditable="false"])';
|
|
4153
|
+
function insideEditable(node) {
|
|
4154
|
+
var _a;
|
|
4155
|
+
const live = node;
|
|
4156
|
+
const element = (live == null ? void 0 : live.nodeType) === 3 ? (_a = live.parentElement) != null ? _a : null : asElement(live);
|
|
4157
|
+
return typeof (element == null ? void 0 : element.closest) === "function" && element.closest(EDITABLE) !== null;
|
|
4141
4158
|
}
|
|
4159
|
+
var isEditableSerialised = (attributes) => attributes.contenteditable !== void 0 && attributes.contenteditable !== "false";
|
|
4160
|
+
var typedCardShaped = (text) => cardShaped(text.replace(/\u00a0/g, " ").trim());
|
|
4161
|
+
var maskText = (text) => text.replace(/\S/g, "*");
|
|
4142
4162
|
var MUTATION = 0;
|
|
4143
4163
|
var INPUT = 5;
|
|
4144
4164
|
var ELEMENT_NODE = 2;
|
|
@@ -4153,23 +4173,27 @@ function maskTextChildren(node) {
|
|
|
4153
4173
|
maskTextChildren(child);
|
|
4154
4174
|
}
|
|
4155
4175
|
}
|
|
4156
|
-
function scrubTree(node, policy, masked) {
|
|
4176
|
+
function scrubTree(node, policy, masked, editable = false) {
|
|
4157
4177
|
var _a, _b;
|
|
4158
4178
|
if (!node) return;
|
|
4159
4179
|
const attributes = (_a = node.attributes) != null ? _a : {};
|
|
4160
4180
|
const inheritedMask = masked || hasClass(attributes, policy.maskClass);
|
|
4181
|
+
const inheritedEditable = editable || node.type === ELEMENT_NODE && isEditableSerialised(attributes);
|
|
4182
|
+
if (editable && node.type === TEXT_NODE && typeof node.textContent === "string" && typedCardShaped(node.textContent)) {
|
|
4183
|
+
node.textContent = maskText(node.textContent);
|
|
4184
|
+
}
|
|
4161
4185
|
if (node.type === ELEMENT_NODE && node.tagName && FIELD_TAGS.has(node.tagName.toLowerCase())) {
|
|
4162
4186
|
const value = attributes.value;
|
|
4163
|
-
const shouldMask = policy.maskEveryField || inheritedMask || isSensitiveSerialised(attributes) || typeof value === "string" &&
|
|
4187
|
+
const shouldMask = policy.maskEveryField || inheritedMask || isSensitiveSerialised(attributes) || typeof value === "string" && cardShaped(value);
|
|
4164
4188
|
if (shouldMask) {
|
|
4165
4189
|
if (typeof value === "string" && value !== "") attributes.value = maskValue(value);
|
|
4166
4190
|
if (node.tagName.toLowerCase() === "textarea") maskTextChildren(node);
|
|
4167
4191
|
}
|
|
4168
4192
|
}
|
|
4169
|
-
for (const child of (_b = node.childNodes) != null ? _b : []) scrubTree(child, policy, inheritedMask);
|
|
4193
|
+
for (const child of (_b = node.childNodes) != null ? _b : []) scrubTree(child, policy, inheritedMask, inheritedEditable);
|
|
4170
4194
|
}
|
|
4171
4195
|
function scrubEvent(event, getNode, policy) {
|
|
4172
|
-
var _a, _b, _c, _d, _e;
|
|
4196
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4173
4197
|
if (!event.data) return;
|
|
4174
4198
|
if (event.type === 2) {
|
|
4175
4199
|
scrubTree(event.data.node, policy, false);
|
|
@@ -4194,7 +4218,11 @@ function scrubEvent(event, getNode, policy) {
|
|
|
4194
4218
|
}
|
|
4195
4219
|
for (const add of (_e = data.adds) != null ? _e : []) {
|
|
4196
4220
|
const parent = typeof (add == null ? void 0 : add.parentId) === "number" ? getNode(add.parentId) : null;
|
|
4197
|
-
scrubTree(add == null ? void 0 : add.node, policy, isMarkedByCustomer(parent, policy.maskClass));
|
|
4221
|
+
scrubTree(add == null ? void 0 : add.node, policy, isMarkedByCustomer(parent, policy.maskClass), insideEditable(parent));
|
|
4222
|
+
}
|
|
4223
|
+
for (const change of (_f = data.texts) != null ? _f : []) {
|
|
4224
|
+
if (typeof (change == null ? void 0 : change.value) !== "string" || !typedCardShaped(change.value)) continue;
|
|
4225
|
+
if (typeof change.id === "number" && insideEditable(getNode(change.id))) change.value = maskText(change.value);
|
|
4198
4226
|
}
|
|
4199
4227
|
}
|
|
4200
4228
|
|
|
@@ -5000,7 +5028,7 @@ var Transport = class {
|
|
|
5000
5028
|
|
|
5001
5029
|
// src/version.ts
|
|
5002
5030
|
var SDK_NAME = "@anyreplay/browser";
|
|
5003
|
-
var SDK_VERSION = true ? "0.2.
|
|
5031
|
+
var SDK_VERSION = true ? "0.2.1" : "0.0.0-dev";
|
|
5004
5032
|
var PLATFORM = "web";
|
|
5005
5033
|
|
|
5006
5034
|
// src/visitor.ts
|
|
@@ -5107,6 +5135,8 @@ function forgetVisitor(local, session) {
|
|
|
5107
5135
|
}
|
|
5108
5136
|
|
|
5109
5137
|
// src/recorder.ts
|
|
5138
|
+
var RRWEB_DOM_CONTENT_LOADED = 0;
|
|
5139
|
+
var RRWEB_LOAD = 1;
|
|
5110
5140
|
var RAGE_CLICK_COUNT = 3;
|
|
5111
5141
|
var RAGE_CLICK_WINDOW_MS = 1e3;
|
|
5112
5142
|
var RAGE_CLICK_RADIUS_PX = 30;
|
|
@@ -5304,6 +5334,7 @@ function createRecorder(rawOptions, shell) {
|
|
|
5304
5334
|
stopRecording = record({
|
|
5305
5335
|
emit: (event) => {
|
|
5306
5336
|
const typed = event;
|
|
5337
|
+
if (typed.type === RRWEB_DOM_CONTENT_LOADED || typed.type === RRWEB_LOAD) return;
|
|
5307
5338
|
scrubEvent(typed, (id) => record.mirror.getNode(id), policy);
|
|
5308
5339
|
assets == null ? void 0 : assets.scan(typed);
|
|
5309
5340
|
noteInteraction(typed, channel);
|