@archie/devtools 0.0.6 → 0.0.7
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/chunk-DLRODACA.mjs +40 -0
- package/dist/{chunk-NYVHR4QL.mjs → chunk-JPNYFFBN.mjs} +13 -4
- package/dist/client/inject-inspector/auto.js +73 -5
- package/dist/client/inject-inspector/auto.mjs +2 -2
- package/dist/client/inject-inspector/injectInspector.d.mts +8 -3
- package/dist/client/inject-inspector/injectInspector.d.ts +8 -3
- package/dist/client/inject-inspector/injectInspector.js +73 -5
- package/dist/client/inject-inspector/injectInspector.mjs +2 -2
- package/dist/constants/archieOrigins.d.mts +16 -1
- package/dist/constants/archieOrigins.d.ts +16 -1
- package/dist/constants/archieOrigins.js +24 -2
- package/dist/constants/archieOrigins.mjs +9 -3
- package/dist/{inspector-LTHUYUGW.mjs → inspector-QDRZLXRP.mjs} +49 -4
- package/package.json +1 -1
- package/dist/chunk-6MYORGLK.mjs +0 -21
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/constants/archieOrigins.ts
|
|
2
|
+
var ARCHIE_HOST_ORIGINS = [
|
|
3
|
+
"https://app.dev.archie-platform.com",
|
|
4
|
+
"https://app.staging.archie-platform.com",
|
|
5
|
+
"https://app.archie.com"
|
|
6
|
+
];
|
|
7
|
+
var ARCHIE_PREVIEW_ORIGIN_SUFFIXES = [
|
|
8
|
+
".archie-platform.com",
|
|
9
|
+
".archie.com"
|
|
10
|
+
];
|
|
11
|
+
var LOCAL_DEV_ORIGINS = [
|
|
12
|
+
"http://localhost:3000",
|
|
13
|
+
"http://localhost:3001"
|
|
14
|
+
];
|
|
15
|
+
function getAllowedOrigins(includeLocal = false) {
|
|
16
|
+
const list = [...ARCHIE_HOST_ORIGINS];
|
|
17
|
+
if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
|
|
18
|
+
return list;
|
|
19
|
+
}
|
|
20
|
+
function getAllowedOriginPatterns() {
|
|
21
|
+
return [...ARCHIE_PREVIEW_ORIGIN_SUFFIXES];
|
|
22
|
+
}
|
|
23
|
+
function isPreviewOrigin(origin) {
|
|
24
|
+
if (!origin || typeof origin !== "string") return false;
|
|
25
|
+
try {
|
|
26
|
+
const host = new URL(origin).host;
|
|
27
|
+
return ARCHIE_PREVIEW_ORIGIN_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
ARCHIE_HOST_ORIGINS,
|
|
35
|
+
ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
|
|
36
|
+
LOCAL_DEV_ORIGINS,
|
|
37
|
+
getAllowedOrigins,
|
|
38
|
+
getAllowedOriginPatterns,
|
|
39
|
+
isPreviewOrigin
|
|
40
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
getAllowedOriginPatterns,
|
|
3
|
+
getAllowedOrigins,
|
|
4
|
+
isPreviewOrigin
|
|
5
|
+
} from "./chunk-DLRODACA.mjs";
|
|
4
6
|
|
|
5
7
|
// src/client/inject-inspector/injectInspector.ts
|
|
6
8
|
var DEFAULT_SCRIPT_ID = "archie-inspector-script";
|
|
@@ -32,12 +34,19 @@ function injectInspector(opts = {}) {
|
|
|
32
34
|
if (allowed.length > 0) {
|
|
33
35
|
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__"] = allowed;
|
|
34
36
|
}
|
|
37
|
+
const patterns = getAllowedOriginPatterns();
|
|
38
|
+
if (patterns.length > 0) {
|
|
39
|
+
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__"] = patterns;
|
|
40
|
+
}
|
|
35
41
|
let target;
|
|
36
42
|
if (opts.targetOrigin !== void 0 && opts.targetOrigin !== "*") {
|
|
37
43
|
target = opts.targetOrigin || void 0;
|
|
38
44
|
} else if (referrer) {
|
|
39
45
|
try {
|
|
40
|
-
|
|
46
|
+
const referrerOrigin = new URL(referrer).origin;
|
|
47
|
+
if (!isPreviewOrigin(referrerOrigin)) {
|
|
48
|
+
target = referrerOrigin;
|
|
49
|
+
}
|
|
41
50
|
} catch {
|
|
42
51
|
target = void 0;
|
|
43
52
|
}
|
|
@@ -48,7 +57,7 @@ function injectInspector(opts = {}) {
|
|
|
48
57
|
win["__ARCHIE_INSPECTOR_TARGET_ORIGIN__"] = target;
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
|
-
return import("./inspector-
|
|
60
|
+
return import("./inspector-QDRZLXRP.mjs").then((m) => {
|
|
52
61
|
try {
|
|
53
62
|
m.default();
|
|
54
63
|
} catch (err) {
|
|
@@ -87,10 +87,33 @@ function runInspector() {
|
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
var ALLOWED_ORIGINS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__ || null;
|
|
90
|
+
var ALLOWED_ORIGIN_PATTERNS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__ || [];
|
|
90
91
|
function isOriginAllowed(origin) {
|
|
91
92
|
if (!origin) return false;
|
|
92
|
-
if (
|
|
93
|
-
|
|
93
|
+
if (Array.isArray(ALLOWED_ORIGINS) && ALLOWED_ORIGINS.length > 0 && ALLOWED_ORIGINS !== "*") {
|
|
94
|
+
if (ALLOWED_ORIGINS.indexOf(origin) !== -1) return true;
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(ALLOWED_ORIGIN_PATTERNS) && ALLOWED_ORIGIN_PATTERNS.length > 0) {
|
|
97
|
+
try {
|
|
98
|
+
var host = new URL(origin).host;
|
|
99
|
+
for (var i = 0; i < ALLOWED_ORIGIN_PATTERNS.length; i++) {
|
|
100
|
+
if (host.endsWith(ALLOWED_ORIGIN_PATTERNS[i])) return true;
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
function isStyleValueSafe(value) {
|
|
108
|
+
if (value == null || typeof value !== "string") return false;
|
|
109
|
+
if (value.length > 1e4) return false;
|
|
110
|
+
var lower = value.toLowerCase();
|
|
111
|
+
if (lower.indexOf("javascript:") !== -1) return false;
|
|
112
|
+
if (lower.indexOf("expression(") !== -1) return false;
|
|
113
|
+
if (lower.indexOf("-moz-binding") !== -1) return false;
|
|
114
|
+
if (lower.indexOf("behavior") !== -1) return false;
|
|
115
|
+
if (lower.indexOf("vbscript:") !== -1) return false;
|
|
116
|
+
return true;
|
|
94
117
|
}
|
|
95
118
|
var SCROLL_LISTENER_OPTS = { capture: true, passive: true };
|
|
96
119
|
var RESIZE_LISTENER_OPTS = { passive: true };
|
|
@@ -691,6 +714,17 @@ function runInspector() {
|
|
|
691
714
|
property,
|
|
692
715
|
value
|
|
693
716
|
});
|
|
717
|
+
if (!property || typeof property !== "string" || property.length > 100 || !isStyleValueSafe(value)) {
|
|
718
|
+
inspectorWarn("[Inspector] Rejected invalid or unsafe style property/value");
|
|
719
|
+
postMessageToParent({
|
|
720
|
+
type: "STYLE_CHANGE_FAILED",
|
|
721
|
+
selector,
|
|
722
|
+
property: typeof property === "string" ? property : "",
|
|
723
|
+
value: value != null ? String(value).slice(0, 100) : "",
|
|
724
|
+
error: !isStyleValueSafe(value) ? "Invalid or unsafe style value" : "Invalid property"
|
|
725
|
+
});
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
694
728
|
let element = null;
|
|
695
729
|
element = getSelectedElement();
|
|
696
730
|
if (element) {
|
|
@@ -766,6 +800,7 @@ function runInspector() {
|
|
|
766
800
|
);
|
|
767
801
|
setTimeout(() => {
|
|
768
802
|
try {
|
|
803
|
+
if (!isStyleValueSafe(value)) return;
|
|
769
804
|
const retryElement = document.querySelector(selector);
|
|
770
805
|
if (retryElement) {
|
|
771
806
|
inspectorLog("[Inspector] Found element on retry");
|
|
@@ -858,7 +893,8 @@ function runInspector() {
|
|
|
858
893
|
});
|
|
859
894
|
return;
|
|
860
895
|
}
|
|
861
|
-
|
|
896
|
+
var classStr = typeof className === "string" ? className.slice(0, 2e3) : "";
|
|
897
|
+
const classes = classStr.split(/\s+/).filter(Boolean).slice(0, 100);
|
|
862
898
|
classes.forEach((cls) => {
|
|
863
899
|
if (action === "remove") {
|
|
864
900
|
element.classList.remove(cls);
|
|
@@ -898,6 +934,15 @@ function runInspector() {
|
|
|
898
934
|
});
|
|
899
935
|
} else if (event.data && event.data.type === "APPLY_TEXT_CHANGE") {
|
|
900
936
|
const { selector, text } = event.data;
|
|
937
|
+
if (text != null && typeof text === "string" && text.length > 5e5) {
|
|
938
|
+
postMessageToParent({
|
|
939
|
+
type: "TEXT_CHANGE_FAILED",
|
|
940
|
+
selector,
|
|
941
|
+
text: "",
|
|
942
|
+
error: "Text value too long"
|
|
943
|
+
});
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
901
946
|
const element = getSelectedElement();
|
|
902
947
|
if (!element) {
|
|
903
948
|
postMessageToParent({
|
|
@@ -908,7 +953,7 @@ function runInspector() {
|
|
|
908
953
|
});
|
|
909
954
|
return;
|
|
910
955
|
}
|
|
911
|
-
element.textContent = text;
|
|
956
|
+
element.textContent = text != null ? String(text) : "";
|
|
912
957
|
postMessageToParent({
|
|
913
958
|
type: "TEXT_CHANGE_APPLIED",
|
|
914
959
|
selector,
|
|
@@ -1116,6 +1161,10 @@ var ARCHIE_HOST_ORIGINS = [
|
|
|
1116
1161
|
"https://app.staging.archie-platform.com",
|
|
1117
1162
|
"https://app.archie.com"
|
|
1118
1163
|
];
|
|
1164
|
+
var ARCHIE_PREVIEW_ORIGIN_SUFFIXES = [
|
|
1165
|
+
".archie-platform.com",
|
|
1166
|
+
".archie.com"
|
|
1167
|
+
];
|
|
1119
1168
|
var LOCAL_DEV_ORIGINS = [
|
|
1120
1169
|
"http://localhost:3000",
|
|
1121
1170
|
"http://localhost:3001"
|
|
@@ -1125,6 +1174,18 @@ function getAllowedOrigins(includeLocal = false) {
|
|
|
1125
1174
|
if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
|
|
1126
1175
|
return list;
|
|
1127
1176
|
}
|
|
1177
|
+
function getAllowedOriginPatterns() {
|
|
1178
|
+
return [...ARCHIE_PREVIEW_ORIGIN_SUFFIXES];
|
|
1179
|
+
}
|
|
1180
|
+
function isPreviewOrigin(origin) {
|
|
1181
|
+
if (!origin || typeof origin !== "string") return false;
|
|
1182
|
+
try {
|
|
1183
|
+
const host = new URL(origin).host;
|
|
1184
|
+
return ARCHIE_PREVIEW_ORIGIN_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
1185
|
+
} catch {
|
|
1186
|
+
return false;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1128
1189
|
|
|
1129
1190
|
// src/client/inject-inspector/injectInspector.ts
|
|
1130
1191
|
var DEFAULT_SCRIPT_ID = "archie-inspector-script";
|
|
@@ -1156,12 +1217,19 @@ function injectInspector(opts = {}) {
|
|
|
1156
1217
|
if (allowed.length > 0) {
|
|
1157
1218
|
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__"] = allowed;
|
|
1158
1219
|
}
|
|
1220
|
+
const patterns = getAllowedOriginPatterns();
|
|
1221
|
+
if (patterns.length > 0) {
|
|
1222
|
+
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__"] = patterns;
|
|
1223
|
+
}
|
|
1159
1224
|
let target;
|
|
1160
1225
|
if (opts.targetOrigin !== void 0 && opts.targetOrigin !== "*") {
|
|
1161
1226
|
target = opts.targetOrigin || void 0;
|
|
1162
1227
|
} else if (referrer) {
|
|
1163
1228
|
try {
|
|
1164
|
-
|
|
1229
|
+
const referrerOrigin = new URL(referrer).origin;
|
|
1230
|
+
if (!isPreviewOrigin(referrerOrigin)) {
|
|
1231
|
+
target = referrerOrigin;
|
|
1232
|
+
}
|
|
1165
1233
|
} catch {
|
|
1166
1234
|
target = void 0;
|
|
1167
1235
|
}
|
|
@@ -8,8 +8,10 @@ type InjectOptions = {
|
|
|
8
8
|
*/
|
|
9
9
|
allowedOrigins?: string | string[];
|
|
10
10
|
/**
|
|
11
|
-
* Origin to which the inspector sends postMessage replies.
|
|
12
|
-
* If not set and in an iframe, uses document.referrer origin
|
|
11
|
+
* Origin to which the inspector sends postMessage replies (the parent window).
|
|
12
|
+
* If not set and in an iframe, uses document.referrer origin — except when the page
|
|
13
|
+
* is a preview iframe (*.previews.staging.archie-platform.com), in which case you
|
|
14
|
+
* must pass the parent app origin (e.g. https://app.dev.archie-platform.com).
|
|
13
15
|
* "*" is not allowed.
|
|
14
16
|
*/
|
|
15
17
|
targetOrigin?: string;
|
|
@@ -24,7 +26,10 @@ type InjectOptions = {
|
|
|
24
26
|
* Safe to call multiple times: avoids duplicate execution by id.
|
|
25
27
|
* No-op when run outside the browser (e.g. SSR).
|
|
26
28
|
*
|
|
27
|
-
* Origin restrictions are always set (never "*")
|
|
29
|
+
* Security: Origin restrictions are always set (never "*"). We do not inject
|
|
30
|
+
* script via eval/Function or write HTML (innerHTML/insertAdjacentHTML).
|
|
31
|
+
* The inspector only accepts postMessage from allowlisted origins and
|
|
32
|
+
* sanitizes style values before applying to the DOM.
|
|
28
33
|
*
|
|
29
34
|
* @returns Promise that resolves to the marker script element, or null if not in browser / already present
|
|
30
35
|
*/
|
|
@@ -8,8 +8,10 @@ type InjectOptions = {
|
|
|
8
8
|
*/
|
|
9
9
|
allowedOrigins?: string | string[];
|
|
10
10
|
/**
|
|
11
|
-
* Origin to which the inspector sends postMessage replies.
|
|
12
|
-
* If not set and in an iframe, uses document.referrer origin
|
|
11
|
+
* Origin to which the inspector sends postMessage replies (the parent window).
|
|
12
|
+
* If not set and in an iframe, uses document.referrer origin — except when the page
|
|
13
|
+
* is a preview iframe (*.previews.staging.archie-platform.com), in which case you
|
|
14
|
+
* must pass the parent app origin (e.g. https://app.dev.archie-platform.com).
|
|
13
15
|
* "*" is not allowed.
|
|
14
16
|
*/
|
|
15
17
|
targetOrigin?: string;
|
|
@@ -24,7 +26,10 @@ type InjectOptions = {
|
|
|
24
26
|
* Safe to call multiple times: avoids duplicate execution by id.
|
|
25
27
|
* No-op when run outside the browser (e.g. SSR).
|
|
26
28
|
*
|
|
27
|
-
* Origin restrictions are always set (never "*")
|
|
29
|
+
* Security: Origin restrictions are always set (never "*"). We do not inject
|
|
30
|
+
* script via eval/Function or write HTML (innerHTML/insertAdjacentHTML).
|
|
31
|
+
* The inspector only accepts postMessage from allowlisted origins and
|
|
32
|
+
* sanitizes style values before applying to the DOM.
|
|
28
33
|
*
|
|
29
34
|
* @returns Promise that resolves to the marker script element, or null if not in browser / already present
|
|
30
35
|
*/
|
|
@@ -98,10 +98,33 @@ function runInspector() {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
var ALLOWED_ORIGINS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__ || null;
|
|
101
|
+
var ALLOWED_ORIGIN_PATTERNS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__ || [];
|
|
101
102
|
function isOriginAllowed(origin) {
|
|
102
103
|
if (!origin) return false;
|
|
103
|
-
if (
|
|
104
|
-
|
|
104
|
+
if (Array.isArray(ALLOWED_ORIGINS) && ALLOWED_ORIGINS.length > 0 && ALLOWED_ORIGINS !== "*") {
|
|
105
|
+
if (ALLOWED_ORIGINS.indexOf(origin) !== -1) return true;
|
|
106
|
+
}
|
|
107
|
+
if (Array.isArray(ALLOWED_ORIGIN_PATTERNS) && ALLOWED_ORIGIN_PATTERNS.length > 0) {
|
|
108
|
+
try {
|
|
109
|
+
var host = new URL(origin).host;
|
|
110
|
+
for (var i = 0; i < ALLOWED_ORIGIN_PATTERNS.length; i++) {
|
|
111
|
+
if (host.endsWith(ALLOWED_ORIGIN_PATTERNS[i])) return true;
|
|
112
|
+
}
|
|
113
|
+
} catch (e) {
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function isStyleValueSafe(value) {
|
|
119
|
+
if (value == null || typeof value !== "string") return false;
|
|
120
|
+
if (value.length > 1e4) return false;
|
|
121
|
+
var lower = value.toLowerCase();
|
|
122
|
+
if (lower.indexOf("javascript:") !== -1) return false;
|
|
123
|
+
if (lower.indexOf("expression(") !== -1) return false;
|
|
124
|
+
if (lower.indexOf("-moz-binding") !== -1) return false;
|
|
125
|
+
if (lower.indexOf("behavior") !== -1) return false;
|
|
126
|
+
if (lower.indexOf("vbscript:") !== -1) return false;
|
|
127
|
+
return true;
|
|
105
128
|
}
|
|
106
129
|
var SCROLL_LISTENER_OPTS = { capture: true, passive: true };
|
|
107
130
|
var RESIZE_LISTENER_OPTS = { passive: true };
|
|
@@ -702,6 +725,17 @@ function runInspector() {
|
|
|
702
725
|
property,
|
|
703
726
|
value
|
|
704
727
|
});
|
|
728
|
+
if (!property || typeof property !== "string" || property.length > 100 || !isStyleValueSafe(value)) {
|
|
729
|
+
inspectorWarn("[Inspector] Rejected invalid or unsafe style property/value");
|
|
730
|
+
postMessageToParent({
|
|
731
|
+
type: "STYLE_CHANGE_FAILED",
|
|
732
|
+
selector,
|
|
733
|
+
property: typeof property === "string" ? property : "",
|
|
734
|
+
value: value != null ? String(value).slice(0, 100) : "",
|
|
735
|
+
error: !isStyleValueSafe(value) ? "Invalid or unsafe style value" : "Invalid property"
|
|
736
|
+
});
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
705
739
|
let element = null;
|
|
706
740
|
element = getSelectedElement();
|
|
707
741
|
if (element) {
|
|
@@ -777,6 +811,7 @@ function runInspector() {
|
|
|
777
811
|
);
|
|
778
812
|
setTimeout(() => {
|
|
779
813
|
try {
|
|
814
|
+
if (!isStyleValueSafe(value)) return;
|
|
780
815
|
const retryElement = document.querySelector(selector);
|
|
781
816
|
if (retryElement) {
|
|
782
817
|
inspectorLog("[Inspector] Found element on retry");
|
|
@@ -869,7 +904,8 @@ function runInspector() {
|
|
|
869
904
|
});
|
|
870
905
|
return;
|
|
871
906
|
}
|
|
872
|
-
|
|
907
|
+
var classStr = typeof className === "string" ? className.slice(0, 2e3) : "";
|
|
908
|
+
const classes = classStr.split(/\s+/).filter(Boolean).slice(0, 100);
|
|
873
909
|
classes.forEach((cls) => {
|
|
874
910
|
if (action === "remove") {
|
|
875
911
|
element.classList.remove(cls);
|
|
@@ -909,6 +945,15 @@ function runInspector() {
|
|
|
909
945
|
});
|
|
910
946
|
} else if (event.data && event.data.type === "APPLY_TEXT_CHANGE") {
|
|
911
947
|
const { selector, text } = event.data;
|
|
948
|
+
if (text != null && typeof text === "string" && text.length > 5e5) {
|
|
949
|
+
postMessageToParent({
|
|
950
|
+
type: "TEXT_CHANGE_FAILED",
|
|
951
|
+
selector,
|
|
952
|
+
text: "",
|
|
953
|
+
error: "Text value too long"
|
|
954
|
+
});
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
912
957
|
const element = getSelectedElement();
|
|
913
958
|
if (!element) {
|
|
914
959
|
postMessageToParent({
|
|
@@ -919,7 +964,7 @@ function runInspector() {
|
|
|
919
964
|
});
|
|
920
965
|
return;
|
|
921
966
|
}
|
|
922
|
-
element.textContent = text;
|
|
967
|
+
element.textContent = text != null ? String(text) : "";
|
|
923
968
|
postMessageToParent({
|
|
924
969
|
type: "TEXT_CHANGE_APPLIED",
|
|
925
970
|
selector,
|
|
@@ -1134,6 +1179,10 @@ var ARCHIE_HOST_ORIGINS = [
|
|
|
1134
1179
|
"https://app.staging.archie-platform.com",
|
|
1135
1180
|
"https://app.archie.com"
|
|
1136
1181
|
];
|
|
1182
|
+
var ARCHIE_PREVIEW_ORIGIN_SUFFIXES = [
|
|
1183
|
+
".archie-platform.com",
|
|
1184
|
+
".archie.com"
|
|
1185
|
+
];
|
|
1137
1186
|
var LOCAL_DEV_ORIGINS = [
|
|
1138
1187
|
"http://localhost:3000",
|
|
1139
1188
|
"http://localhost:3001"
|
|
@@ -1143,6 +1192,18 @@ function getAllowedOrigins(includeLocal = false) {
|
|
|
1143
1192
|
if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
|
|
1144
1193
|
return list;
|
|
1145
1194
|
}
|
|
1195
|
+
function getAllowedOriginPatterns() {
|
|
1196
|
+
return [...ARCHIE_PREVIEW_ORIGIN_SUFFIXES];
|
|
1197
|
+
}
|
|
1198
|
+
function isPreviewOrigin(origin) {
|
|
1199
|
+
if (!origin || typeof origin !== "string") return false;
|
|
1200
|
+
try {
|
|
1201
|
+
const host = new URL(origin).host;
|
|
1202
|
+
return ARCHIE_PREVIEW_ORIGIN_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
1203
|
+
} catch {
|
|
1204
|
+
return false;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1146
1207
|
|
|
1147
1208
|
// src/client/inject-inspector/injectInspector.ts
|
|
1148
1209
|
var DEFAULT_SCRIPT_ID = "archie-inspector-script";
|
|
@@ -1174,12 +1235,19 @@ function injectInspector(opts = {}) {
|
|
|
1174
1235
|
if (allowed.length > 0) {
|
|
1175
1236
|
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__"] = allowed;
|
|
1176
1237
|
}
|
|
1238
|
+
const patterns = getAllowedOriginPatterns();
|
|
1239
|
+
if (patterns.length > 0) {
|
|
1240
|
+
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__"] = patterns;
|
|
1241
|
+
}
|
|
1177
1242
|
let target;
|
|
1178
1243
|
if (opts.targetOrigin !== void 0 && opts.targetOrigin !== "*") {
|
|
1179
1244
|
target = opts.targetOrigin || void 0;
|
|
1180
1245
|
} else if (referrer) {
|
|
1181
1246
|
try {
|
|
1182
|
-
|
|
1247
|
+
const referrerOrigin = new URL(referrer).origin;
|
|
1248
|
+
if (!isPreviewOrigin(referrerOrigin)) {
|
|
1249
|
+
target = referrerOrigin;
|
|
1250
|
+
}
|
|
1183
1251
|
} catch {
|
|
1184
1252
|
target = void 0;
|
|
1185
1253
|
}
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
* @see https://app.archie.com
|
|
7
7
|
*/
|
|
8
8
|
declare const ARCHIE_HOST_ORIGINS: readonly ["https://app.dev.archie-platform.com", "https://app.staging.archie-platform.com", "https://app.archie.com"];
|
|
9
|
+
/**
|
|
10
|
+
* Origin suffix patterns for Archie preview iframes (e.g. deploy previews).
|
|
11
|
+
* The inspector allows any origin whose host ends with one of these suffixes,
|
|
12
|
+
*/
|
|
13
|
+
declare const ARCHIE_PREVIEW_ORIGIN_SUFFIXES: readonly [".archie-platform.com", ".archie.com"];
|
|
9
14
|
/**
|
|
10
15
|
* Common local origins for development. Add these when testing the inspector
|
|
11
16
|
* with the host running on localhost (e.g. host on :3000, preview iframe on :5173).
|
|
@@ -20,5 +25,15 @@ type ArchieHostOrigin = (typeof ARCHIE_HOST_ORIGINS)[number];
|
|
|
20
25
|
* @param includeLocal - If true, appends LOCAL_DEV_ORIGINS for local testing
|
|
21
26
|
*/
|
|
22
27
|
declare function getAllowedOrigins(includeLocal?: boolean): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Returns origin suffix patterns for preview iframes. The inspector allows any origin
|
|
30
|
+
* one of these suffixes (after the protocol).
|
|
31
|
+
*/
|
|
32
|
+
declare function getAllowedOriginPatterns(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Returns true if the given origin is a known Archie preview origin (e.g. deploy preview iframe).
|
|
35
|
+
* When the inspector runs inside a preview iframe, targetOrigin for postMessage must be
|
|
36
|
+
*/
|
|
37
|
+
declare function isPreviewOrigin(origin: string): boolean;
|
|
23
38
|
|
|
24
|
-
export { ARCHIE_HOST_ORIGINS, type ArchieHostOrigin, LOCAL_DEV_ORIGINS, getAllowedOrigins };
|
|
39
|
+
export { ARCHIE_HOST_ORIGINS, ARCHIE_PREVIEW_ORIGIN_SUFFIXES, type ArchieHostOrigin, LOCAL_DEV_ORIGINS, getAllowedOriginPatterns, getAllowedOrigins, isPreviewOrigin };
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
* @see https://app.archie.com
|
|
7
7
|
*/
|
|
8
8
|
declare const ARCHIE_HOST_ORIGINS: readonly ["https://app.dev.archie-platform.com", "https://app.staging.archie-platform.com", "https://app.archie.com"];
|
|
9
|
+
/**
|
|
10
|
+
* Origin suffix patterns for Archie preview iframes (e.g. deploy previews).
|
|
11
|
+
* The inspector allows any origin whose host ends with one of these suffixes,
|
|
12
|
+
*/
|
|
13
|
+
declare const ARCHIE_PREVIEW_ORIGIN_SUFFIXES: readonly [".archie-platform.com", ".archie.com"];
|
|
9
14
|
/**
|
|
10
15
|
* Common local origins for development. Add these when testing the inspector
|
|
11
16
|
* with the host running on localhost (e.g. host on :3000, preview iframe on :5173).
|
|
@@ -20,5 +25,15 @@ type ArchieHostOrigin = (typeof ARCHIE_HOST_ORIGINS)[number];
|
|
|
20
25
|
* @param includeLocal - If true, appends LOCAL_DEV_ORIGINS for local testing
|
|
21
26
|
*/
|
|
22
27
|
declare function getAllowedOrigins(includeLocal?: boolean): string[];
|
|
28
|
+
/**
|
|
29
|
+
* Returns origin suffix patterns for preview iframes. The inspector allows any origin
|
|
30
|
+
* one of these suffixes (after the protocol).
|
|
31
|
+
*/
|
|
32
|
+
declare function getAllowedOriginPatterns(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Returns true if the given origin is a known Archie preview origin (e.g. deploy preview iframe).
|
|
35
|
+
* When the inspector runs inside a preview iframe, targetOrigin for postMessage must be
|
|
36
|
+
*/
|
|
37
|
+
declare function isPreviewOrigin(origin: string): boolean;
|
|
23
38
|
|
|
24
|
-
export { ARCHIE_HOST_ORIGINS, type ArchieHostOrigin, LOCAL_DEV_ORIGINS, getAllowedOrigins };
|
|
39
|
+
export { ARCHIE_HOST_ORIGINS, ARCHIE_PREVIEW_ORIGIN_SUFFIXES, type ArchieHostOrigin, LOCAL_DEV_ORIGINS, getAllowedOriginPatterns, getAllowedOrigins, isPreviewOrigin };
|
|
@@ -21,8 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var archieOrigins_exports = {};
|
|
22
22
|
__export(archieOrigins_exports, {
|
|
23
23
|
ARCHIE_HOST_ORIGINS: () => ARCHIE_HOST_ORIGINS,
|
|
24
|
+
ARCHIE_PREVIEW_ORIGIN_SUFFIXES: () => ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
|
|
24
25
|
LOCAL_DEV_ORIGINS: () => LOCAL_DEV_ORIGINS,
|
|
25
|
-
|
|
26
|
+
getAllowedOriginPatterns: () => getAllowedOriginPatterns,
|
|
27
|
+
getAllowedOrigins: () => getAllowedOrigins,
|
|
28
|
+
isPreviewOrigin: () => isPreviewOrigin
|
|
26
29
|
});
|
|
27
30
|
module.exports = __toCommonJS(archieOrigins_exports);
|
|
28
31
|
var ARCHIE_HOST_ORIGINS = [
|
|
@@ -30,6 +33,10 @@ var ARCHIE_HOST_ORIGINS = [
|
|
|
30
33
|
"https://app.staging.archie-platform.com",
|
|
31
34
|
"https://app.archie.com"
|
|
32
35
|
];
|
|
36
|
+
var ARCHIE_PREVIEW_ORIGIN_SUFFIXES = [
|
|
37
|
+
".archie-platform.com",
|
|
38
|
+
".archie.com"
|
|
39
|
+
];
|
|
33
40
|
var LOCAL_DEV_ORIGINS = [
|
|
34
41
|
"http://localhost:3000",
|
|
35
42
|
"http://localhost:3001"
|
|
@@ -39,9 +46,24 @@ function getAllowedOrigins(includeLocal = false) {
|
|
|
39
46
|
if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
|
|
40
47
|
return list;
|
|
41
48
|
}
|
|
49
|
+
function getAllowedOriginPatterns() {
|
|
50
|
+
return [...ARCHIE_PREVIEW_ORIGIN_SUFFIXES];
|
|
51
|
+
}
|
|
52
|
+
function isPreviewOrigin(origin) {
|
|
53
|
+
if (!origin || typeof origin !== "string") return false;
|
|
54
|
+
try {
|
|
55
|
+
const host = new URL(origin).host;
|
|
56
|
+
return ARCHIE_PREVIEW_ORIGIN_SUFFIXES.some((suffix) => host.endsWith(suffix));
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
42
61
|
// Annotate the CommonJS export names for ESM import in node:
|
|
43
62
|
0 && (module.exports = {
|
|
44
63
|
ARCHIE_HOST_ORIGINS,
|
|
64
|
+
ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
|
|
45
65
|
LOCAL_DEV_ORIGINS,
|
|
46
|
-
|
|
66
|
+
getAllowedOriginPatterns,
|
|
67
|
+
getAllowedOrigins,
|
|
68
|
+
isPreviewOrigin
|
|
47
69
|
});
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ARCHIE_HOST_ORIGINS,
|
|
3
|
+
ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
|
|
3
4
|
LOCAL_DEV_ORIGINS,
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
getAllowedOriginPatterns,
|
|
6
|
+
getAllowedOrigins,
|
|
7
|
+
isPreviewOrigin
|
|
8
|
+
} from "../chunk-DLRODACA.mjs";
|
|
6
9
|
export {
|
|
7
10
|
ARCHIE_HOST_ORIGINS,
|
|
11
|
+
ARCHIE_PREVIEW_ORIGIN_SUFFIXES,
|
|
8
12
|
LOCAL_DEV_ORIGINS,
|
|
9
|
-
|
|
13
|
+
getAllowedOriginPatterns,
|
|
14
|
+
getAllowedOrigins,
|
|
15
|
+
isPreviewOrigin
|
|
10
16
|
};
|
|
@@ -72,10 +72,33 @@ function runInspector() {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
var ALLOWED_ORIGINS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__ || null;
|
|
75
|
+
var ALLOWED_ORIGIN_PATTERNS = typeof window !== "undefined" && window.__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__ || [];
|
|
75
76
|
function isOriginAllowed(origin) {
|
|
76
77
|
if (!origin) return false;
|
|
77
|
-
if (
|
|
78
|
-
|
|
78
|
+
if (Array.isArray(ALLOWED_ORIGINS) && ALLOWED_ORIGINS.length > 0 && ALLOWED_ORIGINS !== "*") {
|
|
79
|
+
if (ALLOWED_ORIGINS.indexOf(origin) !== -1) return true;
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(ALLOWED_ORIGIN_PATTERNS) && ALLOWED_ORIGIN_PATTERNS.length > 0) {
|
|
82
|
+
try {
|
|
83
|
+
var host = new URL(origin).host;
|
|
84
|
+
for (var i = 0; i < ALLOWED_ORIGIN_PATTERNS.length; i++) {
|
|
85
|
+
if (host.endsWith(ALLOWED_ORIGIN_PATTERNS[i])) return true;
|
|
86
|
+
}
|
|
87
|
+
} catch (e) {
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
function isStyleValueSafe(value) {
|
|
93
|
+
if (value == null || typeof value !== "string") return false;
|
|
94
|
+
if (value.length > 1e4) return false;
|
|
95
|
+
var lower = value.toLowerCase();
|
|
96
|
+
if (lower.indexOf("javascript:") !== -1) return false;
|
|
97
|
+
if (lower.indexOf("expression(") !== -1) return false;
|
|
98
|
+
if (lower.indexOf("-moz-binding") !== -1) return false;
|
|
99
|
+
if (lower.indexOf("behavior") !== -1) return false;
|
|
100
|
+
if (lower.indexOf("vbscript:") !== -1) return false;
|
|
101
|
+
return true;
|
|
79
102
|
}
|
|
80
103
|
var SCROLL_LISTENER_OPTS = { capture: true, passive: true };
|
|
81
104
|
var RESIZE_LISTENER_OPTS = { passive: true };
|
|
@@ -676,6 +699,17 @@ function runInspector() {
|
|
|
676
699
|
property,
|
|
677
700
|
value
|
|
678
701
|
});
|
|
702
|
+
if (!property || typeof property !== "string" || property.length > 100 || !isStyleValueSafe(value)) {
|
|
703
|
+
inspectorWarn("[Inspector] Rejected invalid or unsafe style property/value");
|
|
704
|
+
postMessageToParent({
|
|
705
|
+
type: "STYLE_CHANGE_FAILED",
|
|
706
|
+
selector,
|
|
707
|
+
property: typeof property === "string" ? property : "",
|
|
708
|
+
value: value != null ? String(value).slice(0, 100) : "",
|
|
709
|
+
error: !isStyleValueSafe(value) ? "Invalid or unsafe style value" : "Invalid property"
|
|
710
|
+
});
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
679
713
|
let element = null;
|
|
680
714
|
element = getSelectedElement();
|
|
681
715
|
if (element) {
|
|
@@ -751,6 +785,7 @@ function runInspector() {
|
|
|
751
785
|
);
|
|
752
786
|
setTimeout(() => {
|
|
753
787
|
try {
|
|
788
|
+
if (!isStyleValueSafe(value)) return;
|
|
754
789
|
const retryElement = document.querySelector(selector);
|
|
755
790
|
if (retryElement) {
|
|
756
791
|
inspectorLog("[Inspector] Found element on retry");
|
|
@@ -843,7 +878,8 @@ function runInspector() {
|
|
|
843
878
|
});
|
|
844
879
|
return;
|
|
845
880
|
}
|
|
846
|
-
|
|
881
|
+
var classStr = typeof className === "string" ? className.slice(0, 2e3) : "";
|
|
882
|
+
const classes = classStr.split(/\s+/).filter(Boolean).slice(0, 100);
|
|
847
883
|
classes.forEach((cls) => {
|
|
848
884
|
if (action === "remove") {
|
|
849
885
|
element.classList.remove(cls);
|
|
@@ -883,6 +919,15 @@ function runInspector() {
|
|
|
883
919
|
});
|
|
884
920
|
} else if (event.data && event.data.type === "APPLY_TEXT_CHANGE") {
|
|
885
921
|
const { selector, text } = event.data;
|
|
922
|
+
if (text != null && typeof text === "string" && text.length > 5e5) {
|
|
923
|
+
postMessageToParent({
|
|
924
|
+
type: "TEXT_CHANGE_FAILED",
|
|
925
|
+
selector,
|
|
926
|
+
text: "",
|
|
927
|
+
error: "Text value too long"
|
|
928
|
+
});
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
886
931
|
const element = getSelectedElement();
|
|
887
932
|
if (!element) {
|
|
888
933
|
postMessageToParent({
|
|
@@ -893,7 +938,7 @@ function runInspector() {
|
|
|
893
938
|
});
|
|
894
939
|
return;
|
|
895
940
|
}
|
|
896
|
-
element.textContent = text;
|
|
941
|
+
element.textContent = text != null ? String(text) : "";
|
|
897
942
|
postMessageToParent({
|
|
898
943
|
type: "TEXT_CHANGE_APPLIED",
|
|
899
944
|
selector,
|
package/package.json
CHANGED
package/dist/chunk-6MYORGLK.mjs
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// src/constants/archieOrigins.ts
|
|
2
|
-
var ARCHIE_HOST_ORIGINS = [
|
|
3
|
-
"https://app.dev.archie-platform.com",
|
|
4
|
-
"https://app.staging.archie-platform.com",
|
|
5
|
-
"https://app.archie.com"
|
|
6
|
-
];
|
|
7
|
-
var LOCAL_DEV_ORIGINS = [
|
|
8
|
-
"http://localhost:3000",
|
|
9
|
-
"http://localhost:3001"
|
|
10
|
-
];
|
|
11
|
-
function getAllowedOrigins(includeLocal = false) {
|
|
12
|
-
const list = [...ARCHIE_HOST_ORIGINS];
|
|
13
|
-
if (includeLocal) list.push(...LOCAL_DEV_ORIGINS);
|
|
14
|
-
return list;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
ARCHIE_HOST_ORIGINS,
|
|
19
|
-
LOCAL_DEV_ORIGINS,
|
|
20
|
-
getAllowedOrigins
|
|
21
|
-
};
|