RenaiApp/src/main/modules/session/session-helper.ts

47 lines
1.8 KiB
TypeScript

import { injectable } from 'inversify';
import { isDev } from '../../core/env';
import type { SessionHelperInterface } from './session-helper-interface';
const defaultCsp: Session.ContentSecurityPolicy = {
'default-src': ["'self'"],
'style-src': ["'unsafe-inline'"],
'object-src': ["'none'"],
};
@injectable()
export class SessionHelper implements SessionHelperInterface {
private static stringifyCspHeader(csp: Session.ContentSecurityPolicy): string {
return Object.entries(csp)
.map(
(directive: [string, Session.CspValue[] | undefined]) =>
`${directive[0]} ${directive[1] ? directive[1]?.join(' ') : ''}`
)
.join('; ');
}
public setCsp(window: Electron.BrowserWindow, csp: Session.ContentSecurityPolicy): void {
const mergedCsp: Session.ContentSecurityPolicy = { ...defaultCsp, ...csp };
if (isDev()) {
mergedCsp['default-src'] = ['devtools:'].concat(mergedCsp['default-src'] ?? []);
mergedCsp['script-src'] = ["'unsafe-eval'"].concat(mergedCsp['script-src'] ?? []);
mergedCsp['script-src-elem'] = ['file:', 'devtools:', "'unsafe-inline'"].concat(
mergedCsp['script-src-elem'] ?? []
);
mergedCsp['style-src'] = ['devtools:', "'unsafe-inline'"].concat(mergedCsp['style-src'] ?? []);
mergedCsp['img-src'] = ['devtools:'].concat(mergedCsp['img-src'] ?? []);
mergedCsp['connect-src'] = ['devtools:', 'data:'].concat(mergedCsp['connect-src'] ?? []);
mergedCsp['worker-src'] = ['devtools:'].concat(mergedCsp['worker-src'] ?? []);
}
window.webContents.session.webRequest.onHeadersReceived((details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
'Content-Security-Policy': SessionHelper.stringifyCspHeader(mergedCsp),
},
});
});
}
}