this repo has no description

Add support for extensions extending the Content-Security-Policy header (#202)

Maxine 4f38e7b4 00037f6d

Changed files
+25 -2
packages
injector
src
types
+19 -2
packages/injector/src/index.ts
···
blockedUrls = compiled;
});
-
function patchCsp(headers: Record<string, string[]>) {
const directives = ["script-src", "style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"];
const values = ["*", "blob:", "data:", "'unsafe-inline'", "'unsafe-eval'", "disclip:"];
···
parts[directive] = values;
}
const stringified = Object.entries<string[]>(parts)
.map(([key, value]) => {
return `${key} ${value.join(" ")}`;
···
// Event for when a window is created
moonlightHost.events.emit("window-created", this, isMainWindow);
this.webContents.session.webRequest.onHeadersReceived((details, cb) => {
if (details.responseHeaders != null) {
// Patch CSP so things can use externally hosted assets
if (details.resourceType === "mainFrame") {
-
patchCsp(details.responseHeaders);
}
// Allow plugins to bypass CORS for specific URLs
···
blockedUrls = compiled;
});
+
function patchCsp(headers: Record<string, string[]>, extensionCspOverrides: Record<string, string[]>) {
const directives = ["script-src", "style-src", "connect-src", "img-src", "font-src", "media-src", "worker-src"];
const values = ["*", "blob:", "data:", "'unsafe-inline'", "'unsafe-eval'", "disclip:"];
···
parts[directive] = values;
}
+
for (const [directive, urls] of Object.entries(extensionCspOverrides)) {
+
parts[directive] ??= [];
+
parts[directive].push(...urls);
+
}
+
const stringified = Object.entries<string[]>(parts)
.map(([key, value]) => {
return `${key} ${value.join(" ")}`;
···
// Event for when a window is created
moonlightHost.events.emit("window-created", this, isMainWindow);
+
const extensionCspOverrides: Record<string, string[]> = {};
+
+
{
+
const extCsps = moonlightHost.processedExtensions.extensions.map((x) => x.manifest.csp ?? {});
+
for (const csp of extCsps) {
+
for (const [directive, urls] of Object.entries(csp)) {
+
extensionCspOverrides[directive] ??= [];
+
extensionCspOverrides[directive].push(...urls);
+
}
+
}
+
}
+
this.webContents.session.webRequest.onHeadersReceived((details, cb) => {
if (details.responseHeaders != null) {
// Patch CSP so things can use externally hosted assets
if (details.resourceType === "mainFrame") {
+
patchCsp(details.responseHeaders, extensionCspOverrides);
}
// Allow plugins to bypass CORS for specific URLs
+6
packages/types/src/extension.ts
···
* @example https://moonlight-mod.github.io/
*/
blocked?: string[];
};
export enum ExtensionEnvironment {
···
* @example https://moonlight-mod.github.io/
*/
blocked?: string[];
+
+
/**
+
* A mapping from CSP directives to URLs to allow.
+
* @example { "script-src": ["https://example.com"] }
+
*/
+
csp?: Record<string, string[]>;
};
export enum ExtensionEnvironment {