Skip to content

Commit 693d6d8

Browse files
committed
fix: make custom policies authoritative
1 parent 30256dd commit 693d6d8

9 files changed

Lines changed: 19 additions & 110 deletions

File tree

defaults/public/_headers

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636
Cache-Control: no-store
3737
X-Robots-Tag: noindex, nofollow
3838

39+
/v8s-blocklist.json
40+
Cache-Control: no-store
41+
X-Robots-Tag: noindex, nofollow
42+
3943
/redirect-targets.json
4044
Cache-Control: no-store
4145
X-Robots-Tag: noindex, nofollow

defaults/public/de/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ <h1 id="brand-title"><span>Vanity</span><span>URLs</span></h1>
6363

6464
<noscript>
6565
<p>JavaScript ist deaktiviert</p>
66-
<p><span>Kurzlink öffnens directly in the address bar, for example:</span> <a href="/test">/test</a></p>
66+
<p><span>Öffne Kurzlinks direkt in der Adressleiste, zum Beispiel:</span> <a href="/test">/test</a></p>
6767
</noscript>
6868

6969
<script src="/script.js"></script>

defaults/public/es/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ <h1 id="brand-title"><span>Vanity</span><span>URLs</span></h1>
6363

6464
<noscript>
6565
<p>JavaScript está desactivado</p>
66-
<p><span>Abrir enlace cortos directly in the address bar, for example:</span> <a href="/test">/test</a></p>
66+
<p><span>Abre los enlaces cortos directamente en la barra de direcciones, por ejemplo:</span> <a href="/test">/test</a></p>
6767
</noscript>
6868

6969
<script src="/script.js"></script>

defaults/public/fr/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ <h1 id="brand-title"><span>Vanity</span><span>URLs</span></h1>
6363

6464
<noscript>
6565
<p>JavaScript est désactivé</p>
66-
<p><span>Ouvrir le lien courts directly in the address bar, for example:</span> <a href="/test">/test</a></p>
66+
<p><span>Ouvrez les liens courts directement dans la barre d'adresse, par exemple :</span> <a href="/test">/test</a></p>
6767
</noscript>
6868

6969
<script src="/script.js"></script>

defaults/public/it/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ <h1 id="brand-title"><span>Vanity</span><span>URLs</span></h1>
6363

6464
<noscript>
6565
<p>JavaScript è disattivato</p>
66-
<p><span>Apri link breves directly in the address bar, for example:</span> <a href="/test">/test</a></p>
66+
<p><span>Apri i link brevi direttamente nella barra degli indirizzi, ad esempio:</span> <a href="/test">/test</a></p>
6767
</noscript>
6868

6969
<script src="/script.js"></script>

defaults/v8s-policies.json

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,6 @@
8080
"source": "runtime-scanner-policy",
8181
"added_at": "2026-05-05"
8282
},
83-
{
84-
"keyword": "/wp-",
85-
"category": "scanner-probe",
86-
"severity": "low",
87-
"reason": "Common WordPress scanner probe prefix",
88-
"source": "runtime-scanner-policy",
89-
"added_at": "2026-05-07"
90-
},
91-
{
92-
"keyword": "/wp-content/",
93-
"category": "scanner-probe",
94-
"severity": "low",
95-
"reason": "Common WordPress content directory scanner probe",
96-
"source": "runtime-scanner-policy",
97-
"added_at": "2026-05-07"
98-
},
9983
{
10084
"keyword": "/wp-includes/",
10185
"category": "scanner-probe",

scripts/blocklist-policy.mjs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ export function loadBlocklistPolicy(path = DEFAULT_POLICY_PATH) {
1212
const raw = fs.existsSync(resolvedPath) ? JSON.parse(fs.readFileSync(resolvedPath, "utf8")) : {};
1313
const isDefaultPolicy = path === DEFAULT_POLICY_PATH || path === LEGACY_POLICY_PATH;
1414
const customPath = resolvePolicyPath(DEFAULT_CUSTOM_POLICY_PATH, LEGACY_CUSTOM_POLICY_PATH);
15-
const custom = isDefaultPolicy && fs.existsSync(customPath)
16-
? JSON.parse(fs.readFileSync(customPath, "utf8"))
17-
: {};
15+
const hasCustom = isDefaultPolicy && fs.existsSync(customPath);
16+
const custom = hasCustom ? JSON.parse(fs.readFileSync(customPath, "utf8")) : {};
1817
const generated = isDefaultPolicy && fs.existsSync(DEFAULT_GENERATED_POLICY_PATH)
1918
? JSON.parse(fs.readFileSync(DEFAULT_GENERATED_POLICY_PATH, "utf8"))
2019
: {};
21-
const ownerPolicy = isDefaultPolicy ? mergePolicy(custom, raw) : raw;
20+
const ownerPolicy = isDefaultPolicy && hasCustom ? custom : raw;
2221

2322
return normalizePolicy(mergePolicy(ownerPolicy, generated));
2423
}

scripts/build.mjs

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,10 @@ function copyRuntimeBlocklist() {
104104
path.join(CUSTOM_DIR, "v8s-policies.json"),
105105
path.join(CUSTOM_DIR, "v8s-blocklist.json")
106106
);
107-
const base = readJsonFile(defaultPath);
108-
const custom = readJsonFile(customPath);
109-
const merged = mergeRuntimeBlocklist(base, custom);
107+
const policyPath = fs.existsSync(customPath) ? customPath : defaultPath;
108+
const policy = readJsonFile(policyPath);
110109

111-
fs.writeFileSync(RUNTIME_BLOCKLIST_PATH, `${JSON.stringify(merged, null, 2)}\n`);
110+
fs.writeFileSync(RUNTIME_BLOCKLIST_PATH, `${JSON.stringify(policy, null, 2)}\n`);
112111
}
113112

114113
function readJsonFile(filePath) {
@@ -120,57 +119,6 @@ function firstExistingPath(...paths) {
120119
return paths.find((filePath) => fs.existsSync(filePath)) || paths[0];
121120
}
122121

123-
function mergeRuntimeBlocklist(base, custom) {
124-
return {
125-
...base,
126-
...custom,
127-
defaults: {
128-
...(base.defaults || {}),
129-
...(custom.defaults || {}),
130-
allowed_protocols: mergeArray(
131-
base.defaults?.allowed_protocols,
132-
custom.defaults?.allowed_protocols
133-
),
134-
blocked_file_extensions: mergeArray(
135-
base.defaults?.blocked_file_extensions,
136-
custom.defaults?.blocked_file_extensions
137-
)
138-
},
139-
generated_sources: {
140-
...(base.generated_sources || {}),
141-
...(custom.generated_sources || {})
142-
},
143-
allow_domains: mergeEntries(base.allow_domains, custom.allow_domains, "domain"),
144-
blocked_keywords: mergeEntries(base.blocked_keywords, custom.blocked_keywords, "keyword"),
145-
block_domains: mergeEntries(base.block_domains, custom.block_domains, "domain")
146-
};
147-
}
148-
149-
function mergeArray(first = [], second = []) {
150-
return [...new Set([...asArray(first), ...asArray(second)])];
151-
}
152-
153-
function mergeEntries(first = [], second = [], key) {
154-
const merged = new Map();
155-
156-
for (const entry of [...asArray(first), ...asArray(second)]) {
157-
if (!entry || typeof entry !== "object") continue;
158-
const value = String(entry[key] || "").trim().toLowerCase();
159-
if (!value) continue;
160-
161-
merged.set(value, {
162-
...entry,
163-
[key]: value
164-
});
165-
}
166-
167-
return [...merged.values()];
168-
}
169-
170-
function asArray(value) {
171-
return Array.isArray(value) ? value : [];
172-
}
173-
174122
function buildRedirectTargets() {
175123
log("Building v8s.json");
176124

scripts/generate-blocklist.mjs

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,12 @@ function loadGeneratedSources() {
5858
}
5959

6060
function loadPolicy() {
61-
const basePolicy = readJsonFile(resolvePath(POLICY_PATH, LEGACY_POLICY_PATH));
62-
const customPolicy = readJsonFile(resolvePath(CUSTOM_POLICY_PATH, LEGACY_CUSTOM_POLICY_PATH));
61+
const customPolicyPath = resolvePath(CUSTOM_POLICY_PATH, LEGACY_CUSTOM_POLICY_PATH);
62+
if (fs.existsSync(customPolicyPath)) {
63+
return readJsonFile(customPolicyPath);
64+
}
6365

64-
return mergePolicy(customPolicy, basePolicy);
66+
return readJsonFile(resolvePath(POLICY_PATH, LEGACY_POLICY_PATH));
6567
}
6668

6769
function loadCategories() {
@@ -88,41 +90,13 @@ function resolvePath(primary, legacy) {
8890
return primary;
8991
}
9092

91-
function mergePolicy(localPolicy, basePolicy) {
92-
const localDefaults = localPolicy.defaults || {};
93-
const baseDefaults = basePolicy.defaults || {};
94-
95-
return {
96-
...basePolicy,
97-
...localPolicy,
98-
defaults: {
99-
...baseDefaults,
100-
...localDefaults,
101-
allowed_protocols: mergeArray(baseDefaults.allowed_protocols, localDefaults.allowed_protocols),
102-
blocked_file_extensions: mergeArray(baseDefaults.blocked_file_extensions, localDefaults.blocked_file_extensions)
103-
},
104-
generated_sources: mergeObject(basePolicy.generated_sources, localPolicy.generated_sources),
105-
allow_domains: mergeArray(basePolicy.allow_domains, localPolicy.allow_domains),
106-
blocked_keywords: mergeArray(basePolicy.blocked_keywords, localPolicy.blocked_keywords),
107-
block_domains: mergeArray(basePolicy.block_domains, localPolicy.block_domains)
108-
};
109-
}
110-
11193
function mergeObject(first = {}, second = {}) {
11294
return {
11395
...(first || {}),
11496
...(second || {})
11597
};
11698
}
11799

118-
function mergeArray(first = [], second = []) {
119-
return [...asArray(first), ...asArray(second)];
120-
}
121-
122-
function asArray(value) {
123-
return Array.isArray(value) ? value : [];
124-
}
125-
126100
function normalizeAllowDomainEntry(entry) {
127101
if (typeof entry === "string") {
128102
return {

0 commit comments

Comments
 (0)