v0.36.5
This commit is contained in:
1 parent
34490fd5fc
commit
6ef01212ec
21 files changed
+204
-77
No files matched your search
@@ -727,3 +727,56 @@ const rustProxyAutoId = (() => {
|
||||
return { slugify, unique, attach };
|
||||
})();
|
||||
window.rustProxyAutoId = rustProxyAutoId;
|
||||
|
||||
// Automatic certificate choice: for a new entry, pick the stored certificate that covers every host name (exact names beat wildcards); the user can still choose another one.
|
||||
const rustProxyAutoCertificate = (() => {
|
||||
const states = new WeakMap();
|
||||
const covers = (pattern, host) => {
|
||||
pattern = String(pattern).toLowerCase(); host = String(host).toLowerCase();
|
||||
if (pattern === host) return true;
|
||||
if (host.startsWith("*.") || !pattern.startsWith("*.")) return false;
|
||||
const suffix = pattern.slice(1);
|
||||
return host.length > suffix.length && host.endsWith(suffix) && !host.slice(0, -suffix.length).includes(".");
|
||||
};
|
||||
function suggest(hosts, certificates) {
|
||||
const names = [...new Set((hosts || []).map(host => String(host).trim().toLowerCase()).filter(Boolean))];
|
||||
if (!names.length) return "";
|
||||
let best = "", bestScore = -Infinity;
|
||||
for (const cert of certificates || []) {
|
||||
const coverage = certificateInventory.get(cert.id)?.covered_hosts?.length ? certificateInventory.get(cert.id).covered_hosts : (cert.covered_hosts || []);
|
||||
let score = 0, all = true;
|
||||
for (const host of names) {
|
||||
if (coverage.some(pattern => String(pattern).toLowerCase() === host)) score += 2;
|
||||
else if (coverage.some(pattern => covers(pattern, host))) score += 1;
|
||||
else { all = false; break; }
|
||||
}
|
||||
if (!all) continue;
|
||||
score -= coverage.length / 1000;
|
||||
if (score > bestScore) { best = cert.id; bestScore = score; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
// options: { hosts: () => host names, certificates: () => certificate objects, auto: boolean, anchor: element after which the hint is placed }
|
||||
function attach(select, options) {
|
||||
let state = states.get(select);
|
||||
if (!state) {
|
||||
state = { hint: document.createElement("small") };
|
||||
state.hint.className = "fine auto-cert-hint"; state.hint.hidden = true;
|
||||
(options.anchor || select).after(state.hint);
|
||||
select.addEventListener("change", event => { if (!event.isTrusted) return; const current = states.get(select); current.auto = false; current.hint.hidden = true; });
|
||||
states.set(select, state);
|
||||
}
|
||||
state.options = options; state.auto = options.auto !== false && !select.value; state.hint.hidden = true;
|
||||
const refresh = hosts => {
|
||||
const current = states.get(select);
|
||||
if (!current.auto) return;
|
||||
const list = hosts || current.options.hosts();
|
||||
const best = suggest(list, current.options.certificates());
|
||||
if (select.value !== best) { select.value = best; select.dispatchEvent(new Event("change", { bubbles: true })); }
|
||||
current.hint.hidden = !best; current.hint.textContent = best ? t("autoCertHint").replace("{id}", best) : "";
|
||||
};
|
||||
return { refresh };
|
||||
}
|
||||
return { attach, suggest, covers };
|
||||
})();
|
||||
window.rustProxyAutoCertificate = rustProxyAutoCertificate;
|
||||
Reference in new issue
Block a user