added permissions for website

This commit is contained in:
2024-11-04 11:55:14 -05:00
parent 5c845ffe61
commit 014e4c8b7b
19 changed files with 507 additions and 71 deletions
+16
View File
@@ -0,0 +1,16 @@
import fs from 'fs';
import { finalTabCleanup } from "./clearCache.js";
export async function handleArgs() {
console.log(process.argv);
for (const arg of process.argv) {
console.log(arg);
if (arg === '--clear-cache') {
await finalTabCleanup();
fs.rmSync(`${import.meta.dirname}/cache`, { recursive: true });
}
else if (arg === '--no-cache') {
console.error('TODO: RUN WITH NEW SESSION/PARTITION');
}
}
}
+68 -3
View File
@@ -1,4 +1,8 @@
import { dialog } from 'electron';
import { BrowserWindow, dialog } from 'electron';
import { findPath } from './paths.js';
import { redisclient } from '../serverJS/history.cjs';
const preloadpath = await findPath('permspopup.cjs', true);
export async function askUserQuestion(window, title, question) {
const response = await dialog.showMessageBox(window, {
@@ -8,6 +12,67 @@ export async function askUserQuestion(window, title, question) {
title,
message: question,
});
return response.response === 0; // true if 'Yes' was clicked, false if 'No'
}
}
const perms = ["geolocation", "camera", "microphone", "notifications", "popups"];
export async function promptForPerms(window, origin) {
return new Promise(async (resolve) => {
const w = new BrowserWindow({
height: 600,
width: 400,
alwaysOnTop: true,
autoHideMenuBar: true,
darkTheme: true,
modal: true,
parent: window,
webPreferences: {
contextIsolation: true,
javascript: true,
allowRunningInsecureContent: false,
nodeIntegration: true,
preload: preloadpath
}
});
await w.loadFile(await findPath('permspopup.html'), {
search: `origin=${origin}`
});
w.show();
w.on('close', resolve);
});
}
/**
* @param {Electron.IpcMainEvent} e
* @param {String} sitehostname
* @param {String} id
* @param {String} value
*/
export async function setSitePerms(e, sitehostname, id, value = 'ask', all = false) {
const client = await redisclient(),
dataRaw = await client.get(`perms-${sitehostname}`),
data = dataRaw ? JSON.parse(dataRaw) : null;
if (all || !data) await client.set(`perms-${sitehostname}`, JSON.stringify(Object.fromEntries(perms.map(p => [p, value]))));
else {
data[id] = value;
await client.set(`perms-${sitehostname}`, JSON.stringify(data));
}
if (e?.sender) e.sender.send('site-perms', JSON.stringify(data));
}
/**
* @param {Electron.IpcMainEvent} e
* @param {String} sitehostname
*/
export async function getSitePerms(e, sitehostname) {
const client = await redisclient();
if (!e) return await client.get(`perms-${sitehostname}`);
else e.sender.send('site-perms', await client.get(`perms-${sitehostname}`));
}
+15 -10
View File
@@ -4,6 +4,7 @@ import fs from 'fs';
import { findPath } from './paths.js';
import * as tabModule from '../serverJS/tabs_server.js';
import loggermod from '../utils/logger.cjs';
import { getSitePerms, promptForPerms, setSitePerms } from './dialogue.js';
const { logger } = loggermod;
@@ -24,17 +25,19 @@ export default function init(customSession) {
ipcMain.on('tab-close', (e, id) => tabModule.closeTab(e, id, customSession));
ipcMain.on('tab-new', (e, id, url) => tabModule.addTab(e, id, customSession, url));
// TODO: add logic here to save/return site perms
ipcMain.on('set-site-perms', (e, sitehostname) => console.log(sitehostname));
ipcMain.on('get-site-perms', (e, sitehostname) => {
console.log(sitehostname);
e.sender.send('site-perms', { popups: false });
});
ipcMain.on('set-site-perms', (e, sitehostname, id, value) => setSitePerms(e, sitehostname, id, value));
ipcMain.on('set-site-perms-all', (e, sitehostname, id, value) => setSitePerms(e, sitehostname, id, value, true));
ipcMain.on('get-site-perms', getSitePerms);
ipcMain.on('prompt-terms', (e, sitehostname) => promptForPerms(tabModule.getCurrentWindow(), sitehostname));
// TODO: make an actual settings page
ipcMain.on('open-settings', async (e) => promptForPerms(tabModule.getCurrentWindow(), await tabModule.getCurrentTab()?.webContents.executeJavaScript('window.location.hostname')));
}
const renderer = (fs.readFileSync(await findPath('renderer.js'), 'utf-8')),
optimize = (fs.readFileSync(await findPath('optimize.js'), 'utf-8'));
optimize = (fs.readFileSync(await findPath('optimize.js'), 'utf-8')),
adblock = (fs.readFileSync(await findPath('clientAdBlock.js'), 'utf-8'))
/**
@@ -42,9 +45,11 @@ const renderer = (fs.readFileSync(await findPath('renderer.js'), 'utf-8')),
*/
export async function startinject(mainWindow, uid) {
// execute the script in the renderer process
mainWindow.webContents.executeJavaScript(renderer);
mainWindow.webContents.executeJavaScript(optimize);
// mainWindow.webContents.executeJavaScript(tabs);
await mainWindow.webContents.executeJavaScript(renderer);
await mainWindow.webContents.executeJavaScript(optimize);
await mainWindow.webContents.executeJavaScript(adblock);
const perms = (await getSitePerms(null, mainWindow.webContents.getURL())) || {};
await mainWindow.webContents.executeJavaScript(`setupAdBlock(${JSON.stringify(perms)})`);
const title = await mainWindow.webContents.executeJavaScript('document.title');
addHistory(uid, mainWindow.webContents.getURL(), 200, title);
+32
View File
@@ -5,6 +5,8 @@ import { addEl, isValidURL } from "./misc.js";
import { startinject } from "./ipc.js";
import intercept, { noworker } from "../serverJS/intercept.js";
import loggermod from '../utils/logger.cjs';
import { askUserQuestion, getSitePerms, promptForPerms, setSitePerms } from "./dialogue.js";
import { getCurrentWindow } from "../serverJS/tabs_server.js";
const { logger } = loggermod;
@@ -66,6 +68,36 @@ export async function createWebview(tabId, currentWindow, customSession, preload
startinject(view, uid);
});
let perms;
const refreshperms = async (_, u) => {
perms = await getSitePerms(null, isValidURL(u)?.hostname);
}
view.webContents.on('did-navigate', refreshperms);
view.webContents.setWindowOpenHandler((details) => {
// let run out for an automatic "deny"
const hostname = isValidURL(view.webContents.getURL())?.hostname;
if (!perms) promptForPerms(getCurrentWindow(), hostname).then(() => refreshperms(null, hostname));
// else if (perms['popups'] === 'ask') askUserQuestion(view, 'allow popups', `allow popups from ${hostname}`)
else {
const permsJSON = JSON.parse(perms);
if (permsJSON['popups'] === 'ask') {
askUserQuestion(getCurrentWindow(), 'safety prompt', `allow ${hostname} to open popups?`)
.then(allowed => setSitePerms(null, hostname, 'popups', allowed ? 'allow' : 'deny'))
.catch(console.error)
.finally(() => refreshperms(null, hostname));
}
if (permsJSON['popups'] === 'allow') return { action: 'allow' };
}
// fall through
return { action: 'deny' };
});
view.webContents.setBackgroundThrottling(true);
resizeWebView();
return view;