fix(extensions): pin schemas to trusted bootstrap state (#5094)

This commit is contained in:
Rod Boev committed 2026-06-28 17:59:36 -04:00
1 parent cb96a5cf39
commit 615b023eb0
4 files changed
+57 -3

No files matched your search

+4 -2
View File
@@ -1575,9 +1575,11 @@ def inject_extension_tags(index_html: str) -> str:
else:
result = block + result
if script_tags:
if runtime_config["extensions"] or script_tags:
body_marker = "</body>"
block = runtime_tag + "\n" + "\n".join(script_tags) + "\n"
block = runtime_tag + "\n"
if script_tags:
block += "\n".join(script_tags) + "\n"
if body_marker in result:
result = result.replace(body_marker, block + body_marker, 1)
else:
+2 -1
View File
@@ -125,6 +125,7 @@
id:entry.id,
name:entry.name,
storage_owned:entry.storage_owned,
settings_schema:entry.settings_schema,
});
}
trustedSeeded=true;
@@ -137,7 +138,7 @@
id:entry.id,
name:entry.name,
storage_owned:trusted.storage_owned===true,
settings_schema:trusted.storage_owned===true?entry.settings_schema:[],
settings_schema:trusted.storage_owned===true?trusted.settings_schema:[],
});
}
}
+31
View File
@@ -160,6 +160,37 @@ def test_extension_settings_runtime_config_injects_before_extension_scripts(tmp_
assert injected.index("window.__HERMES_EXTENSION_CONFIG__") < injected.index("/extensions/settings-ok.js")
def test_extension_settings_only_manifest_still_injects_runtime_config(tmp_path, monkeypatch):
root = tmp_path / "extensions"
root.mkdir()
(root / "manifest.json").write_text(
"""
{
"extensions": [
{
"id": "settings-only",
"permissions": {"storage": {"owned": true}},
"settings_schema": [
{"key": "flag", "type": "boolean", "default": true}
]
}
]
}
""",
encoding="utf-8",
)
monkeypatch.setenv("HERMES_WEBUI_EXTENSION_DIR", str(root))
monkeypatch.setenv("HERMES_WEBUI_EXTENSION_MANIFEST", "manifest.json")
from api.extensions import inject_extension_tags
injected = inject_extension_tags("<html><head></head><body></body></html>")
assert "window.__HERMES_EXTENSION_CONFIG__" in injected
assert '"id":"settings-only"' in injected
assert injected.index("window.__HERMES_EXTENSION_CONFIG__") < injected.index("</body>")
def test_extension_route_remains_behind_webui_auth(monkeypatch):
monkeypatch.setenv("HERMES_WEBUI_PASSWORD", "test-password")
+20
View File
@@ -100,6 +100,26 @@ def test_extension_settings_runtime_normalizes_persists_resets_and_clears():
const unknownSettings = window.HermesExtensionSettings.settingsForExtension('unknown.ext');
assert.strictEqual(unknownSettings.setAll({{flag: true}}).ok, false);
assert.strictEqual(store.has('hermes.ext.settings.unknown.ext'), false);
window.HermesExtensionSettings.primeFromStatus({{
extensions: [{{
id: 'demo.ext',
name: 'Demo',
storage_owned: true,
settings_schema: [{{key: 'evil', type: 'string', default: ''}}],
}}, {{
id: 'denied.ext',
name: 'Denied',
storage_owned: false,
settings_schema: [{{key: 'flag', type: 'boolean', default: false}}],
}}]
}});
const reprobe = window.HermesExtensionSettings.settingsForExtension('demo.ext');
assert.deepStrictEqual(reprobe.schema.map(field => field.key), ['flag', 'mode', 'count']);
assert.strictEqual(reprobe.set('evil', 'owned').ok, true);
assert.strictEqual(reprobe.get('evil'), undefined);
assert.strictEqual(store.has('hermes.ext.settings.demo.ext'), false);
"""
)
_run_node(script)