mirror of
https://github.com/Horizontal42/summarum.git
synced 2026-11-11 01:02:01 +03:00
fix: remove unsafe-eval from CSP and use blob urls for extensions
Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>
This commit is contained in:
parent
984275711a
commit
3923d7ff45
3 changed files with 38 additions and 9 deletions
|
|
@ -23,7 +23,7 @@
|
|||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src ipc: http://ipc.localhost https://open.er-api.com https://api.coingecko.com https://query1.finance.yahoo.com https://query2.finance.yahoo.com https://api.frankfurter.dev"
|
||||
"csp": "default-src 'self'; script-src 'self' blob:; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src ipc: http://ipc.localhost https://open.er-api.com https://api.coingecko.com https://query1.finance.yahoo.com https://query2.finance.yahoo.com https://api.frankfurter.dev"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
|
|
|
|||
|
|
@ -16,14 +16,43 @@ export function makeApi(engine: SumEngine): ExtensionApi {
|
|||
};
|
||||
}
|
||||
|
||||
export function runExtensions(engine: SumEngine, scripts: { name: string; code: string }[]): void {
|
||||
export async function runExtensions(engine: SumEngine, scripts: { name: string; code: string }[]): Promise<void> {
|
||||
const numi = makeApi(engine);
|
||||
let id = 0;
|
||||
for (const s of scripts) {
|
||||
try {
|
||||
const fn = new Function("numi", s.code);
|
||||
fn(numi);
|
||||
} catch (e) {
|
||||
console.error(`extension ${s.name} failed:`, e);
|
||||
}
|
||||
const globalName = `__numi_ext_${id++}`;
|
||||
(window as any)[globalName] = numi;
|
||||
|
||||
const code = `
|
||||
try {
|
||||
(function(numi) {
|
||||
${s.code}
|
||||
})(window.${globalName});
|
||||
} catch (e) {
|
||||
console.error(\`extension \${s.name} failed:\`, e);
|
||||
}
|
||||
`;
|
||||
|
||||
const blob = new Blob([code], { type: "text/javascript" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const script = document.createElement("script");
|
||||
script.src = url;
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
script.onload = () => {
|
||||
URL.revokeObjectURL(url);
|
||||
delete (window as any)[globalName];
|
||||
script.remove();
|
||||
resolve();
|
||||
};
|
||||
script.onerror = (e) => {
|
||||
console.error(`extension ${s.name} failed to load:`, e);
|
||||
URL.revokeObjectURL(url);
|
||||
delete (window as any)[globalName];
|
||||
script.remove();
|
||||
resolve();
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -710,7 +710,7 @@ async function boot(): Promise<void> {
|
|||
if (!data.docs.some((d) => d.id === data.activeId)) data.activeId = data.docs[0].id;
|
||||
|
||||
const scripts = await loadExtensionScripts();
|
||||
runExtensions(engine, scripts);
|
||||
await runExtensions(engine, scripts);
|
||||
|
||||
workspace = new Workspace(engine, () =>
|
||||
data.docs.map((d) => ({ id: d.id, title: d.title, text: data.contents[d.id] ?? "" })),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue