Compare commits
75 commits
dependabot
...
master
Author | SHA1 | Date | |
---|---|---|---|
55a4b89b24 | |||
fc736da1d3 | |||
1c1f7934fb | |||
4bac2b0542 | |||
bad5e26a86 | |||
42de741e08 | |||
7198b136a6 | |||
8d18437dfa | |||
37e109f739 | |||
dc9f6a45a6 | |||
995962a497 | |||
fbdeb5dc7b | |||
5789eb88a2 | |||
5dada52da5 | |||
d16aa9b3f3 | |||
|
c0037f256e | ||
|
6531460cd0 | ||
|
95219d7298 | ||
|
c7159725e2 | ||
|
b4e88f8b22 | ||
|
ee706b339f | ||
|
726d22f096 | ||
|
f244e0f003 | ||
|
010e954d7d | ||
|
38209621b9 | ||
|
1bef1f1615 | ||
|
1549b64317 | ||
|
e4776f36ad | ||
|
2f64e8b41f | ||
|
b483e91f1e | ||
|
8b6a491ed5 | ||
|
252984a504 | ||
|
dda48fc695 | ||
|
d1c7f53d16 | ||
|
981d139755 | ||
|
d484a3557b | ||
|
14fa018ec1 | ||
|
6d93ff50eb | ||
|
bfd42f9fa7 | ||
|
357ad09eaa | ||
|
f70f63e41c | ||
|
3f43c17b9e | ||
|
5ef8a09ff0 | ||
|
1eee3a31f8 | ||
|
1b6b848cef | ||
|
f36b1ae72a | ||
|
3b07296b75 | ||
|
8a2bf6c631 | ||
|
3a10c82fb3 | ||
|
e9c68dcf9f | ||
|
c6afbb7d6f | ||
|
842f9bf8c5 | ||
|
cbc14de39d | ||
|
afd1928f02 | ||
|
1cdea46b28 | ||
|
434db9cd0f | ||
|
af7b08ce56 | ||
|
44580739d2 | ||
|
d5dedb091c | ||
|
5439fadf09 | ||
|
0c6344b8e0 | ||
|
cd0c61e813 | ||
|
039b5b14c8 | ||
|
84f489be00 | ||
|
379052e5d2 | ||
|
88f3a44242 | ||
|
187c68e703 | ||
|
d8aebf9372 | ||
|
9337ec75ac | ||
|
b664e3f3f1 | ||
|
c57bcb26f9 | ||
|
84b29939b7 | ||
|
22c36901ee | ||
|
f3b089768f | ||
|
d750fef706 |
18 changed files with 8009 additions and 83 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1 +1,5 @@
|
|||
node_modules
|
||||
seedium-linux-x64
|
||||
sneedium-win32-x64
|
||||
seedium-linux-arm64
|
||||
sneedium-win32-arm64
|
|
@ -1,6 +1,6 @@
|
|||
The Samuel Public License Revision 5 (SPL-R5)
|
||||
The Sammy Public License Revision 5 Sub-Revision 2 (SPL-R5 SR2)
|
||||
|
||||
Copyright (c) 2024 Maxwell Drake
|
||||
Copyright (c) Sneed Group
|
||||
|
||||
This document grants permission, without charge, to any individual acquiring a copy of the software and its associated documentation files (hereinafter referred to as the "Software"). Such individuals are authorized to engage in activities related to the Software with certain restrictions (listed below), including, but not limited to, the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. These permissions extend to persons to whom the Software is furnished, subject to compliance with the specified conditions outlined below.
|
||||
|
||||
|
@ -10,10 +10,20 @@ In making contributions to the Software, contributors irrevocably assign, transf
|
|||
|
||||
Furthermore, this document permits the reuse and redistribution of both executable binaries and source code, contingent upon the inclusion of the previously mentioned copyright notice and permission notice in all copies or substantial portions of the Software. It is imperative that you explicitly acknowledge and agree that the owner(s) retain ownership rights over the aforementioned source code.
|
||||
|
||||
Moreover, companies using the Software are encouraged to contribute upstream. Fortune 500 companies are required to make an annual contribution of at least 20,000 USD or an equivalent amount to support the project's sustainability unless no donation option is provided.
|
||||
Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owner(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development.
|
||||
|
||||
Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owners(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development.
|
||||
In addition, the owner of the code is granted the authority to update their copy of The Sammy Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Sammy Public License.
|
||||
|
||||
In addition, the owner of the code is granted the authority to update their copy of The Samuel Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Samuel Public License.
|
||||
Minimum Payment Requirements by Business Size:
|
||||
|
||||
1. Fortune 500 Companies: Companies that are included in the Fortune 500 list are required to make an annual contribution of at least 42,069 USD or an equivalent amount per project used to support the sustainability of the Software, unless no donation option is provided. Additionally, Fortune 500 companies are required to contribute their changes upstream to the Software.
|
||||
|
||||
2. Large Non-Fortune 500 Companies: Non-Fortune 500 large companies (defined as companies with 128 or more employees) must pay a minimum of 15,000 USD per year for the continued use of the Software.
|
||||
|
||||
3. Medium Businesses: Medium businesses (defined as companies with 42 to 128 employees) are required to pay a minimum of 420 USD per year for the continued use of the Software.
|
||||
|
||||
4. Small Businesses: Small businesses (defined as companies with 42 or fewer employees) are required to pay a minimum of 69 USD per year for the continued use of the Software.
|
||||
|
||||
These fees are intended to ensure the sustainability of the project and may be subject to change by the project owner(s). Payment is due annually, and the corresponding amount must be paid no later than 30 days after the beginning of each calendar year. Failure to comply with these payment terms may result in revocation of the right to use the Software.
|
||||
|
||||
The aforementioned copyright notice and this permission notice must be included in all copies or substantial portions of the Software.
|
37
README.md
37
README.md
|
@ -1,7 +1,20 @@
|
|||
<img src="logo.png" align="right" width="15%"/>
|
||||
<img src="https://github.com/Sneed-Group/sneedium/blob/master/logo.png?raw=true" align="right" width="15%"/>
|
||||
|
||||
# F-Stopium
|
||||
A basic web browser in Electron. ***Now with our own, functioning adblocker and privacy redirection technologies!***
|
||||
# Sneedium
|
||||
A basic web browser in Electron. ***With a functioning adblocker and privacy redirection technologies!***
|
||||
|
||||
[![Download latest build.](https://github.com/Sneed-Group/sneedium/blob/master/download.png?raw=true)](https://github.com/Sneed-Group/sneedium/releases)
|
||||
|
||||
## Testing, compiling, and creation notes
|
||||
|
||||
To clone and run this repository you'll need [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
# Run the app
|
||||
npm start
|
||||
```
|
||||
|
||||
Supports compiling via electron packager. Install and run it with:
|
||||
|
||||
|
@ -19,26 +32,14 @@ A basic Electron application needs just these files:
|
|||
- `index.html` - A web page to render. This is the app's **renderer process**.
|
||||
- `preload.js` - A content script that runs before the renderer process loads.
|
||||
|
||||
|
||||
## To Use
|
||||
|
||||
To clone and run this repository you'll need [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line:
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
# Run the app
|
||||
npm start
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT Modified](LICENSE.md)
|
||||
[SPL-R5](https://github.com/Sneed-Group/sneedium/blob/master/LICENSE.md)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
"Insider's Look" builds are outdated and meant for people who are just testing core functionality by default, and aren't interested in changes! If you want changes, compile it or download the new binaries.
|
||||
"Insider's Look" builds are outdated. If you want changes, compile it or download the new binaries.
|
||||
|
||||
## What is Privacy Redirection Technology (PRT)?
|
||||
|
||||
This is a simple technology that replaces a bad URL with a more privacy friendly service, when we know that ADs aren't 100% blocked, or just to provide a better UX. TLDR: Clickjacking for good.
|
||||
This is a simple technology that replaces a bad URL with a more privacy friendly service, when we know that ADs aren't 100% blocked, or just to provide a better UX. TLDR: Clickjacking for the greater good.
|
||||
|
|
BIN
download.png
Normal file
BIN
download.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 236 KiB |
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'">
|
||||
<title>F-Stopium</title>
|
||||
<title>Sneedium</title>
|
||||
<link href="./styles.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
|
@ -12,15 +12,18 @@
|
|||
<button id="nwBtn">📄</button>
|
||||
<input id="txtUrl" placeholder="Put the website here" name="url" type="text" onkeypress="clickPress(event)" />
|
||||
<button onclick="go(); return false;" id="goBtn">✅</button>
|
||||
<button onclick="refresh(); return false;" id="refreshBtn">🔄</button>
|
||||
<button onclick="stop(); return false;" id="stopBtn">🛑</button>
|
||||
<button onclick="back(); return false;" id="backBtn">⬅️</button>
|
||||
<button onclick="forward(); return false;" id="forwardBtn">➡️</button>
|
||||
<button id="camBtn">🎦</button>
|
||||
</div>
|
||||
<div id="whProtection">
|
||||
<tab-group new-tab-button="true" sortable="true">
|
||||
<webview id="foo" autosize plugins disablewebsecurity></webview>
|
||||
</tab-group>
|
||||
</div>
|
||||
<script src="node_modules/electron-tabs/dist/electron-tabs.js"></script>
|
||||
<script type="text/javascript" src="./userscript/userscripts.js"></script>
|
||||
<script type="text/javascript" src="./config.js"></script>
|
||||
<script type="text/javascript" src="./libbrowz.js"></script>
|
||||
</body>
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<!-- This is the Sneedium new tab page. -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'">
|
||||
<title>F-Stopium works!</title>
|
||||
<title>Sneedium works!</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<img src="logo.png" align="right" width="20%"/>
|
||||
<h1>Welcome to F-Stopium!</h1>
|
||||
<p>Put a list of URLs to userscripts in ./userscript/userscripts.js. It uses a standard JS array format and uses URLs. Config is located at: ./config.js.</p>
|
||||
<h1>Welcome to Sneedium!</h1>
|
||||
<p>Welcome to the Sneedium Browser! You can easily compile for for macOS, Windows, and Linux as of the time of writing this. We hope you enjoy this browser as much as we did making it.</br></br>From all of us at Sneed Group.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
86
libbrowz.js
86
libbrowz.js
|
@ -1,22 +1,69 @@
|
|||
const userAgents = [
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/128.0",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edg/120.0.0.0",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Edg/98.0.0.0",
|
||||
"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"
|
||||
];
|
||||
|
||||
function getRandomUserAgent() {
|
||||
const randomIndex = Math.floor(Math.random() * userAgents.length);
|
||||
return userAgents[randomIndex];
|
||||
}
|
||||
|
||||
let currentUA = "" // We haven't loaded any websites yet. It should be blank.
|
||||
|
||||
let tabGroup = document.querySelector("tab-group");
|
||||
function normalizeUrl(url) {
|
||||
// Define regex patterns for matching URL schemes and local addresses
|
||||
const httpPattern = /^http:\/\//i;
|
||||
const httpsPattern = /^https:\/\//i;
|
||||
const filePattern = /^file:\/\//i;
|
||||
const indexPattern = /^index\.html/i;
|
||||
const localPattern = /^(192\.168|127\.0|localhost)/i;
|
||||
|
||||
// Check if the URL already has a valid scheme
|
||||
if (httpPattern.test(url) || httpsPattern.test(url) || filePattern.test(url) || indexPattern.test(url)) {
|
||||
return url;
|
||||
}
|
||||
|
||||
// Determine if the URL starts with a local address or needs HTTPS
|
||||
if (localPattern.test(url)) {
|
||||
return `http://${url}`;
|
||||
} else {
|
||||
return `https://${url}`;
|
||||
}
|
||||
}
|
||||
|
||||
let url = undefined
|
||||
let browserFrame = undefined
|
||||
function go() {
|
||||
let browserFrame = tabGroup.getActiveTab().webview
|
||||
currentUA = getRandomUserAgent()
|
||||
browserFrame = tabGroup.getActiveTab().webview
|
||||
let browser = tabGroup.getActiveTab()
|
||||
let url = document.getElementById("txtUrl").value
|
||||
url = normalizeUrl(document.getElementById("txtUrl").value)
|
||||
if (url.includes("youtube.com") || url.includes("youtu.be")) {
|
||||
url = url.replaceAll("youtube.com", "yewtu.be")
|
||||
url = url.replaceAll("youtu.be", "yewtu.be")
|
||||
} else if (url.includes("google.com/?q")) {
|
||||
url = url.replaceAll("google.com/?q", "startpage.com/?q")
|
||||
} else if (url.includes("google.com") && !url.includes("maps") && !url.includes("news") && !url.includes("webstore") && !url.includes("mail")) {
|
||||
url = url.replaceAll("google.com", "startpage.com")
|
||||
url = url.replaceAll("youtube.com", "invidious.nerdvpn.de")
|
||||
url = url.replaceAll("youtu.be", "invidious.nerdvpn.de")
|
||||
} else if (url.includes("google.com/search?q") || url.includes("google.com/?q")) {
|
||||
// Define the URL object
|
||||
const serachUrlObj = new URL(url);
|
||||
//Get query from old url
|
||||
const query = serachUrlObj.searchParams.get('q');
|
||||
// Define the pattern for URL replacement
|
||||
const searchPattern = "https://search.sparksammy.com/search.php?q=!!!QUERY!!!&p=0&t=0";
|
||||
url = searchPattern.replaceAll("!!!QUERY!!!", query)
|
||||
} else if (url.includes("https://news.google.com")) {
|
||||
url = url.replaceAll("https://news.google.com", "http://68k.news")
|
||||
} else if (url.includes("news.google.com")) {
|
||||
url = url.replaceAll("news.google.com", "68k.news")
|
||||
} else if (url.includes("google.com") && !url.includes("maps") && !url.includes("news") && !url.includes("webstore") && !url.includes("drive") && !url.includes("docs") && !url.includes("sheets") && !url.includes("slides") && !url.includes("mail") && !url.includes("webstore") && !url.includes("in") && !url.includes("on") && !url.includes("jp")) {
|
||||
url = url.replaceAll("google.com", "search.sparksammy.com")
|
||||
}
|
||||
document.getElementById("txtUrl").value = ""
|
||||
browserFrame.loadURL(url);
|
||||
browserFrame.loadURL(url,
|
||||
{userAgent: currentUA});
|
||||
browserFrame.addEventListener('dom-ready', () => {
|
||||
browserFrame.insertCSS(`
|
||||
::-webkit-scrollbar {
|
||||
|
@ -30,11 +77,6 @@ function go() {
|
|||
tabGroup.getActiveTab().setTitle(title)
|
||||
console.log(title)
|
||||
})
|
||||
for (let i = 0; i < userscripts.length; i++) {
|
||||
fetch(userscripts[i]).then( r => r.text() ).then( t => userscripts.executeJavaScript(t)).catch(() => {
|
||||
console.log("Error loading userscripts! (Did you provide any?)")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function stop() {
|
||||
|
@ -52,6 +94,15 @@ function forward() {
|
|||
browserFrame.goForward()
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
if (typeof url != undefined) {
|
||||
browserFrame.loadURL(browserFrame.getURL(),
|
||||
{userAgent: currentUA});
|
||||
} else {
|
||||
window.location.reload()
|
||||
}
|
||||
}
|
||||
|
||||
tabGroup.setDefaultTab({
|
||||
title: CONF.homepageTitle,
|
||||
src: CONF.homepage,
|
||||
|
@ -63,5 +114,4 @@ function clickPress(keyEvent) {
|
|||
if (keyEvent.keyCode == 13) {
|
||||
go()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
BIN
logo.png
BIN
logo.png
Binary file not shown.
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 32 KiB |
144
main.js
144
main.js
|
@ -1,34 +1,111 @@
|
|||
// Modules to control application life and create native browser window
|
||||
const {app, BrowserWindow, session, ipcMain} = require('electron')
|
||||
const {app, BrowserWindow, session, ipcMain, systemPreferences} = require('electron')
|
||||
const path = require('path')
|
||||
const fetch = require("cross-fetch")
|
||||
const { ElectronChromeExtensions } = require('electron-chrome-extensions')
|
||||
const { ElectronBlocker } = require('@ghostery/adblocker-electron');
|
||||
const http = require('http');
|
||||
const fs = require('fs');
|
||||
const { createProxy } = require('proxy');
|
||||
const buildChromeContextMenu = require('electron-chrome-context-menu').default
|
||||
var extensions
|
||||
var mic
|
||||
var cam
|
||||
app.on('web-contents-created', (event, webContents) => {
|
||||
webContents.on('context-menu', (e, params) => {
|
||||
const menu = buildChromeContextMenu({
|
||||
params,
|
||||
webContents,
|
||||
openLink: (url, disposition) => {
|
||||
webContents.loadURL(url)
|
||||
}
|
||||
})
|
||||
|
||||
menu.popup()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
ipcMain.on('windowmaker', (event, arg) => {
|
||||
createWindow();
|
||||
})
|
||||
|
||||
ipcMain.on('allowCam', (event, arg) => {
|
||||
mic = systemPreferences.askForMediaAccess('microphone');
|
||||
cam = systemPreferences.askForMediaAccess('camera');
|
||||
})
|
||||
|
||||
const proxy = createProxy(http.createServer());
|
||||
proxy.listen(3129)
|
||||
//Function to enable AD Blocking...
|
||||
let blocker = undefined
|
||||
async function enableGoodies(s) {
|
||||
blocker = await ElectronBlocker.fromLists(fetch, [
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/ubol-filters.txt",
|
||||
'https://easylist.to/easylist/easylist.txt',
|
||||
'https://secure.fanboy.co.nz/fanboy-annoyance.txt',
|
||||
'https://easylist.to/easylist/easyprivacy.txt',
|
||||
'https://easylist-downloads.adblockplus.org/antiadblockfilters.txt',
|
||||
'https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/nocoin.txt',
|
||||
'https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.plus.txt',
|
||||
"https://github.com/yokoffing/filterlists/raw/refs/heads/main/youtube_clear_view.txt",
|
||||
"https://pgl.yoyo.org/as/serverlist.php?showintro=0;hostformat=adblock",
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/unbreak.txt",
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/quick-fixes.txt",
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/privacy.txt",
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/badware.txt",
|
||||
"https://github.com/uBlockOrigin/uAssets/raw/refs/heads/master/filters/filters.txt"
|
||||
])
|
||||
blocker.enableBlockingInSession(s);
|
||||
}
|
||||
|
||||
// 0.0.0.0 day fix
|
||||
const locals = [
|
||||
'0.0.0.0', '127.0.0.1', '192.168', '.local', '.example', '.staging', 'fe80::', '::1'
|
||||
];
|
||||
|
||||
// Function to check if a URL is restricted
|
||||
function isLocal(url) {
|
||||
return locals.some(local => url.includes(local));
|
||||
}
|
||||
|
||||
function createWindow () {
|
||||
// Create the browser window.
|
||||
|
||||
const extensions = new ElectronChromeExtensions({
|
||||
session: session.defaultSession
|
||||
})
|
||||
|
||||
try {
|
||||
extensions = new ElectronChromeExtensions()
|
||||
} catch {
|
||||
console.log("Creating a new window in the same extension session...")
|
||||
}
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 1000,
|
||||
width: 1220,
|
||||
height: 600,
|
||||
minWidth: 1220,
|
||||
minHeight: 600,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
webviewTag: true,
|
||||
devTools: false,
|
||||
nodeIntegration: true,
|
||||
nodeIntegration: false,
|
||||
sandbox: true,
|
||||
contextIsolation: true
|
||||
}
|
||||
})
|
||||
|
||||
mainWindow.removeMenu()
|
||||
const homePath = app.getPath('home');
|
||||
const extensionsDir = path.join(homePath, 'SneedExtensions');
|
||||
|
||||
if (!fs.existsSync(extensionsDir)) {
|
||||
fs.mkdirSync(extensionsDir, { recursive: true });
|
||||
}
|
||||
|
||||
const extensionFolders = fs.readdirSync(extensionsDir, { withFileTypes: true })
|
||||
.filter(dirent => dirent.isDirectory())
|
||||
.map(dirent => path.join(extensionsDir, dirent.name));
|
||||
|
||||
for (const extensionPath of extensionFolders) {
|
||||
extensions.loadExtension(extensionPath);
|
||||
}
|
||||
|
||||
extensions.addTab(mainWindow.webContents, mainWindow)
|
||||
mainWindow.setMinimumSize(1000, 300)
|
||||
|
||||
|
||||
|
@ -94,20 +171,42 @@ const regexPatterns = [
|
|||
return false;
|
||||
}
|
||||
|
||||
session.defaultSession.setProxy({
|
||||
proxyRules: 'http=localhost:3129;https=localhost:3129',
|
||||
proxyBypassRules: '<local>'
|
||||
})
|
||||
|
||||
session.defaultSession.webRequest.onBeforeRequest((details, callback) => {
|
||||
if (containsAD(details.url)) {
|
||||
return callback({cancel: true})
|
||||
}
|
||||
return callback({})
|
||||
})
|
||||
|
||||
extensions.addTab(mainWindow.webContents, mainWindow)
|
||||
const url = new URL(details.url);
|
||||
const hostname = url.hostname;
|
||||
const isLocalDomain = isLocal(hostname);
|
||||
|
||||
// Check if the request is to a local domain
|
||||
if (isLocalDomain) {
|
||||
// Check if the request is initiated by a remote domain
|
||||
const initiator = details.initiator ? new URL(details.initiator).hostname : '';
|
||||
const isInitiatorLocal = isLocal(initiator);
|
||||
|
||||
if (initiator && !isInitiatorLocal) {
|
||||
console.log(`[W] Local domain is being accessed by external source (${initiator}), don't allow!`);
|
||||
callback({ cancel: true }); // Block request to local domains from remote sources
|
||||
} else {
|
||||
//console.log("Local domain is not being accessed by external source, allow..."); // debug
|
||||
callback({ cancel: false }); // Allow request
|
||||
}
|
||||
} else {
|
||||
//console.log("Request is not to a local domain, allow..."); //debug
|
||||
callback({ cancel: false }); // Allow non-local requests
|
||||
}
|
||||
})
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile('index.html')
|
||||
|
||||
// Open the DevTools.
|
||||
mainWindow.webContents.openDevTools()
|
||||
|
||||
return mainWindow;
|
||||
}
|
||||
|
@ -117,6 +216,7 @@ const regexPatterns = [
|
|||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
let x = createWindow()
|
||||
enableGoodies().then()
|
||||
app.on('activate', function () {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
|
@ -128,8 +228,20 @@ app.whenReady().then(() => {
|
|||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on('window-all-closed', function () {
|
||||
if (process.platform !== 'darwin') app.quit()
|
||||
if (process.platform !== 'darwin') { app.quit() }
|
||||
})
|
||||
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
|
||||
// Set DNS and enable mic/cam
|
||||
app.on('ready', () => {
|
||||
app.configureHostResolver({
|
||||
mode: 'secure',
|
||||
dohServers: [
|
||||
'https://dns9.quad9.net/dns-query',
|
||||
'https://cloudflare-dns.com/dns-query'
|
||||
]
|
||||
});
|
||||
});
|
7674
package-lock.json
generated
Normal file
7674
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
23
package.json
23
package.json
|
@ -1,14 +1,15 @@
|
|||
{
|
||||
"name": "fstopium",
|
||||
"name": "sneedium",
|
||||
"version": "1.0.0",
|
||||
"description": "A Electron browser",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron-forge start",
|
||||
"package": "electron-forge package",
|
||||
"make": "npx electron-packager --platform linux,win32 --arch x64,arm64 ."
|
||||
"make": "npx electron-packager --platform linux,win32 --arch x64,arm64 .",
|
||||
"make-mac": "npx electron-packager --platform darwin --arch x64,arm64 ."
|
||||
},
|
||||
"repository": "https://github.com/electron/electron-quick-start",
|
||||
"repository": "https://github.com/Sneed-Group/sneedium",
|
||||
"keywords": [
|
||||
"Electron",
|
||||
"quick",
|
||||
|
@ -16,8 +17,8 @@
|
|||
"tutorial",
|
||||
"demo"
|
||||
],
|
||||
"author": "FStop Tech",
|
||||
"license": "MIT (Modified)",
|
||||
"author": "Sneed Group",
|
||||
"license": "SPL-R5",
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "^6.0.5",
|
||||
"@electron-forge/maker-deb": "^6.0.5",
|
||||
|
@ -25,14 +26,18 @@
|
|||
"@electron-forge/maker-rpm": "^6.0.5",
|
||||
"@electron-forge/maker-squirrel": "^6.0.5",
|
||||
"@electron-forge/maker-zip": "^6.0.5",
|
||||
"electron": "^25.4.0",
|
||||
"electron": "^31.0.1",
|
||||
"electron-forge-maker-appimage": "^24.6.3",
|
||||
"electron-packager": "^17.1.1"
|
||||
"electron-packager": "^17.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ghostery/adblocker": "^2.1.1",
|
||||
"@ghostery/adblocker-electron": "^2.1.1",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"electron-chrome-context-menu": "^1.1.0",
|
||||
"electron-chrome-extensions": "^3.10.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"electron-tabs": "^1.0.1"
|
||||
"electron-squirrel-startup": "^1.0.1",
|
||||
"electron-tabs": "^1.0.1",
|
||||
"proxy": "^2.2.0"
|
||||
}
|
||||
}
|
||||
|
|
23
preload.js
23
preload.js
|
@ -5,6 +5,14 @@
|
|||
*
|
||||
* https://www.electronjs.org/docs/latest/tutorial/sandbox
|
||||
*/
|
||||
|
||||
const { contextBridge, ipcRenderer } = require('electron');
|
||||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
enforceDomainRestrictions: (url) => ipcRenderer.sendSync('check-domain', url),
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const replaceText = (selector, text) => {
|
||||
const element = document.getElementById(selector)
|
||||
|
@ -12,15 +20,24 @@ window.addEventListener('DOMContentLoaded', () => {
|
|||
}
|
||||
|
||||
for (const type of ['chrome', 'node', 'electron']) {
|
||||
replaceText(`${type}-version`, process.versions[type])
|
||||
replaceText(`${type}-version`, 'sneedium-version')
|
||||
}
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.on('windowmaker', (event, arg) => {
|
||||
console.log(arg) // prints "pong"
|
||||
console.log(arg)
|
||||
})
|
||||
|
||||
ipcRenderer.on('allowCam', (event, arg) => {
|
||||
console.log(arg)
|
||||
})
|
||||
//button and its event listener
|
||||
const makeWindowButton = document.getElementById('nwBtn');
|
||||
makeWindowButton.addEventListener('click', () => {
|
||||
ipcRenderer.send('windowmaker', 'ping')
|
||||
})
|
||||
|
||||
const camButton = document.getElementById('camBtn');
|
||||
camButton.addEventListener('click', () => {
|
||||
ipcRenderer.send('allowCam', 'ping')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,3 +5,5 @@
|
|||
* `contextIsolation` is turned on. Use the contextBridge API in `preload.js`
|
||||
* to expose Node.js functionality from the main process.
|
||||
*/
|
||||
|
||||
require('electron-chrome-extension/preload');
|
1
sneedium-maker-mac.sh
Normal file
1
sneedium-maker-mac.sh
Normal file
|
@ -0,0 +1 @@
|
|||
npm run make-mac
|
10
sneedium-maker.sh
Executable file
10
sneedium-maker.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
y=$(date +%Y)
|
||||
read -p "Sneedium # of year $y (1,2,3,4...):" v
|
||||
npm run make
|
||||
mkdir "Sneedium $y.$v"
|
||||
mv sneedium-linux-* "Sneedium $y.$v"
|
||||
mv sneedium-win32-* "Sneedium $y.$v"
|
||||
tar -czvf "Sneedium $y.$v.tar.gz" "Sneedium $y.$v"
|
||||
rm -rf "Sneedium $y.$v"
|
||||
mkdir ~/sneedium-bins
|
||||
mv "Sneedium $y.$v.tar.gz" ~/sneedium-bins
|
51
styles.css
51
styles.css
|
@ -33,6 +33,17 @@ body {
|
|||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#camBtn {
|
||||
background-color: #a6b70d; /* Gold */
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 1% 1%;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#goBtn {
|
||||
background-color: #4CAF50; /* Green */
|
||||
border: none;
|
||||
|
@ -78,6 +89,17 @@ body {
|
|||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#refreshBtn {
|
||||
background-color: #507fac; /* Aqua */
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 1% 1%;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#txtUrl {
|
||||
border: none;
|
||||
padding: 1% 1%;
|
||||
|
@ -89,17 +111,30 @@ body {
|
|||
}
|
||||
|
||||
html, body {
|
||||
height: 98%;
|
||||
width: 100%;
|
||||
justify-content: center; /* Center horizontally */
|
||||
align-items: center; /* Center vertically */
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#whProtection {
|
||||
width: 100%; /* % of viewport width */
|
||||
height: 100%; /* % of viewport height */
|
||||
border: 2vw solid rgb(70, 70, 70); /* Border color and thickness */
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
webview {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
max-height: 90% !important;
|
||||
max-width: 100%;
|
||||
width: 1rem;
|
||||
height: 90% !important;
|
||||
display: inline-flex !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
box-sizing: border-box; /* Ensures any padding or border inside the webview is included in the total size */
|
||||
display: block; /* Ensure it behaves as a block element */
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
var userscripts = [""]
|
Loading…
Reference in a new issue