feat: Security
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import type { ElectronApi } from '../../../../core/platform/electron/electron-api.models';
|
||||
|
||||
export function pluginFileParentDir(filePath: string): string {
|
||||
const normalized = filePath.replace(/\\/g, '/').replace(/\/+$/, '');
|
||||
const index = normalized.lastIndexOf('/');
|
||||
|
||||
return index > 0 ? normalized.slice(0, index) : normalized;
|
||||
}
|
||||
|
||||
export function pluginReadRootForFileUrl(fileUrl: string): string {
|
||||
const filePath = fileUrlToPath(fileUrl).replace(/\\/g, '/').replace(/\/+$/, '');
|
||||
const basename = filePath.split('/').pop() ?? '';
|
||||
|
||||
if (fileUrl.endsWith('/') || !basename.includes('.')) {
|
||||
return filePath;
|
||||
}
|
||||
|
||||
return pluginFileParentDir(filePath);
|
||||
}
|
||||
|
||||
export function collectPluginReadRoots(...fileUrls: Array<string | undefined>): string[] {
|
||||
const roots = new Set<string>();
|
||||
|
||||
for (const fileUrl of fileUrls) {
|
||||
if (!fileUrl?.startsWith('file://')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
roots.add(pluginReadRootForFileUrl(fileUrl));
|
||||
}
|
||||
|
||||
return [...roots];
|
||||
}
|
||||
|
||||
export async function grantPluginReadRoots(
|
||||
api: Pick<ElectronApi, 'grantPluginReadRoot'> | null | undefined,
|
||||
...fileUrls: Array<string | undefined>
|
||||
): Promise<void> {
|
||||
if (!api?.grantPluginReadRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
const roots = collectPluginReadRoots(...fileUrls);
|
||||
|
||||
for (const root of roots) {
|
||||
await api.grantPluginReadRoot(root);
|
||||
}
|
||||
}
|
||||
|
||||
export function fileUrlToPath(fileUrl: string): string {
|
||||
const url = new URL(fileUrl);
|
||||
const decodedPath = decodeURIComponent(url.pathname);
|
||||
|
||||
if (/^\/[A-Za-z]:\//.test(decodedPath)) {
|
||||
return decodedPath.slice(1).replace(/\//g, '\\');
|
||||
}
|
||||
|
||||
return decodedPath;
|
||||
}
|
||||
Reference in New Issue
Block a user