diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml
new file mode 100644
index 0000000..c5cfd80
--- /dev/null
+++ b/.github/workflows/build-linux.yml
@@ -0,0 +1,31 @@
+name: Build Linux Installer
+
+on:
+ push:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ build-linux:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 20
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build Linux AppImage
+ run: npm run dist:linux
+
+ - name: Upload Linux installer
+ uses: actions/upload-artifact@v3
+ with:
+ name: linux-installer
+ path: dist/*.AppImage
diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml
new file mode 100644
index 0000000..2a094cf
--- /dev/null
+++ b/.github/workflows/build-macos.yml
@@ -0,0 +1,31 @@
+name: Build macOS Installer
+
+on:
+ push:
+ branches: [ main ]
+ workflow_dispatch:
+
+jobs:
+ build-macos:
+ runs-on: macos-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version: 20
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build macOS app
+ run: npm run dist:mac
+
+ - name: Upload macOS installer
+ uses: actions/upload-artifact@v3
+ with:
+ name: macos-installer
+ path: dist/*.dmg
diff --git a/README.md b/README.md
index baa31a7..7783ec4 100644
--- a/README.md
+++ b/README.md
@@ -1,67 +1,109 @@
-# Soterios
+
+
+
-Soterios is a local-first Windows desktop security and maintenance app built with Electron. It combines ClamAV-backed scanning, Windows security visibility, process inspection, real-time protection, reports, quarantine, password tools, and safe maintenance utilities in one desktop UI.
+Soterios
-Version: 1.0.2
+
+ Open-source, local-first desktop security & maintenance toolkit.
+ Scan files, inspect processes, audit your system, manage your firewall, check passwords — all without telemetry.
+
+
+
+
+
+
+
+
+---
+
+## Download & Install
+
+Pick the installer for your operating system from the [latest release](https://github.com/chrisriv10/Soterios/releases/latest):
+
+| Platform | Installer | Notes |
+|----------|-----------|-------|
+| **Windows** | `Soterios-Setup-x.x.x.exe` | NSIS installer · requires admin for system-level checks |
+| **macOS** | `Soterios-x.x.x.dmg` | Drag to Applications · may require Gatekeeper approval |
+| **Linux** | `Soterios-x.x.x.AppImage` | `chmod +x` and run · no install needed |
+
+---
## Features
-- Security Dashboard with health score, scan status, warnings, ignored warnings, quarantine count, and real-time protection controls
-- Virus Scan with quick, full, and custom scans, ClamAV definition updates, progress, cancellation, quarantine, and saved scan reports
-- In-app Reports page for browsing, viewing, generating, and deleting scan/security reports
-- Process Inspector with risk-first sorting, then highest CPU/RAM impact inside the same risk level
-- Windows Security Audit for Defender, UAC, Windows Update, BitLocker, PowerShell policy, and Secure Boot
-- Firewall Management for Windows Firewall profile status and rule summaries
-- Network Monitor for active connections and interface activity
-- Password tools with generator, local strength checks, HIBP k-anonymity password leak checks, and XposedOrNot email breach checks
-- Real-Time Protection through a local file system watcher
-- Quarantine Management for restoring or permanently deleting isolated files
-- Tools & Maintenance scripts for temp cleanup, disk reports, large files, browser cache reports, startup items, network reports, and Windows services reports
+- **Security Dashboard** — health score, scan status, warnings, ignored warnings, quarantine count, and real-time protection controls
+- **Virus Scan** — quick, full, and custom scans powered by ClamAV with definition updates, progress, cancellation, quarantine, and saved reports
+- **Reports** — browse, view, generate, and delete scan and security reports in-app
+- **Process Inspector** — risk-first sorting, then highest CPU/RAM impact within the same risk level
+- **Windows Security Audit** — Defender, UAC, Windows Update, BitLocker, PowerShell policy, and Secure Boot
+- **Firewall Management** — Windows Firewall profile status and rule summaries
+- **Network Monitor** — active connections and interface activity
+- **Password Tools** — local generator, strength checker, HIBP k-anonymity password leak checks, and XposedOrNot email breach checks
+- **Real-Time Protection** — local file-system watcher for live threat detection
+- **Quarantine Management** — restore or permanently delete isolated files
+- **Tools & Maintenance** — temp cleanup, disk reports, large file finder, browser cache reports, startup items, network reports, and Windows services reports
+
+---
-Soterios does not collect telemetry or analytics. Local scanning and system analysis happen on your machine. Network calls occur only when you trigger features that need them, such as ClamAV definition updates, HIBP password checks, or XposedOrNot email breach checks.
+## Privacy
-## Requirements
+Soterios does **not** collect telemetry or analytics. All scanning and system analysis happens locally on your machine. Network calls occur **only** when you explicitly trigger features that require them (ClamAV updates, HIBP checks, XposedOrNot lookups).
-- Windows 10 or Windows 11
-- Node.js 22 or newer for development/builds
-- Administrator rights are requested by the packaged Windows app for system-level checks
-- Internet access is optional, but needed for ClamAV definition updates and breach lookups
+---
-## Setup
+## Development Setup
+
+### Prerequisites
+
+- [Node.js](https://nodejs.org/) 22 or newer
+- [Git](https://git-scm.com/)
+
+### Clone & Run
```bash
+git clone https://github.com/chrisriv10/Soterios.git
+cd Soterios
npm install
npm start
```
-## Build
+### Build Installers
```bash
-npm run pack
+# Windows (NSIS .exe)
npm run dist:win
-```
-The Windows installer is written to:
+# macOS (.dmg)
+npm run dist:mac
-```text
-dist/Soterios-Setup-1.0.2.exe
+# Linux (.AppImage)
+npm run dist:linux
```
+Built artifacts are output to the `dist/` directory.
+
+---
+
## Usage
-1. Open Soterios.
-2. Review the Dashboard for current health, warnings, and real-time protection status.
-3. Run a quick, full, or custom scan from Virus Scan.
-4. View scan details from Reports without leaving the app.
-5. Use Windows Audit for non-firewall Windows security posture checks.
-6. Use Firewall Management for firewall profile and rule visibility.
-7. Use Process Inspector to review high-risk or high-impact processes.
-8. Use Passwords for local generation/strength checks and optional breach lookups.
+1. **Dashboard** — review your health score, active warnings, and real-time protection status.
+2. **Virus Scan** — run a quick, full, or custom scan.
+3. **Reports** — view detailed scan results without leaving the app.
+4. **Windows Audit** — check Defender, UAC, BitLocker, and other Windows security settings.
+5. **Firewall** — inspect firewall profile status and rules.
+6. **Process Inspector** — review high-risk or resource-heavy processes.
+7. **Passwords** — generate secure passwords, check strength locally, and optionally look up breaches.
+
+---
## API Notes
-- Password leak checks use Have I Been Pwned Pwned Passwords k-anonymity. Only the first 5 SHA-1 hash characters are sent.
-- Email breach checks use the free XposedOrNot email API.
+| Feature | Service | Privacy |
+|---------|---------|---------|
+| Password leak checks | [Have I Been Pwned – Pwned Passwords](https://haveibeenpwned.com/Passwords) | Only the first 5 characters of the SHA-1 hash are sent (k-anonymity) |
+| Email breach checks | [XposedOrNot](https://xposedornot.com/) | Free public email breach API |
+
+---
## Project Structure
@@ -76,4 +118,26 @@ src/scripts/ maintenance scripts and registry
src/ui/ shell, CSS, shared JS, and page modules
assets/ Soterios icons and bundled ClamAV files
build/ installer resources
-```
\ No newline at end of file
+tests/ test suites
+```
+
+---
+
+## Contributing
+
+Contributions are welcome! To get started:
+
+1. **Fork** the repository.
+2. **Create a branch** for your feature or fix: `git checkout -b feature/my-feature`.
+3. **Commit** your changes with clear messages.
+4. **Push** to your fork and open a **Pull Request**.
+
+Please make sure your changes work locally (`npm start`) before submitting.
+
+---
+
+## License
+
+Soterios is released under the [MIT License](build/LICENSE.txt).
+
+**Copyright © 2026 Chris Rivera**
\ No newline at end of file
diff --git a/assets/icon.ico b/assets/icon.ico
index d58056e..24db0c8 100644
Binary files a/assets/icon.ico and b/assets/icon.ico differ
diff --git a/package.json b/package.json
index a8f8859..a05a7d8 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "soterios",
"version": "1.0.2",
"description": "A local-first desktop toolkit for system maintenance, monitoring, and basic security checks.",
- "main": "main.js",
+ "main": "src/main/main.js",
"author": "Soterios",
"license": "MIT",
"private": true,
@@ -33,6 +33,7 @@
"appId": "com.soterios.app",
"productName": "Soterios",
"copyright": "Copyright (c) 2026 Chris Rivera",
+ "icon": "assets/icon.ico",
"directories": {
"output": "dist",
"buildResources": "build"
@@ -41,7 +42,7 @@
"assets/clamav/**"
],
"files": [
- "main.js",
+ "src/main/main.js",
"preload.js",
"src/**/*",
"assets/**/*",
@@ -60,7 +61,7 @@
"icon": "assets/icon.ico",
"artifactName": "${productName}-Setup-${version}.${ext}",
"publisherName": "Chris Rivera",
- "signAndEditExecutable": false,
+ "signAndEditExecutable": true,
"requestedExecutionLevel": "requireAdministrator"
},
"nsis": {
diff --git a/src/main/main.js b/src/main/main.js
index e67feb7..e6c6a9e 100644
--- a/src/main/main.js
+++ b/src/main/main.js
@@ -31,15 +31,15 @@ function logLine(level, message, meta) {
} catch (_) { }
}
-function createShieldIcon() {
- const iconPath = path.join(__dirname, '..', '..', 'assets', 'icon.ico');
+function createIcon() {
+ const iconPath = path.join(__dirname, '../../assets/icon.ico');
return nativeImage.createFromPath(iconPath);
}
function showNotification(title, body) {
if (!Notification.isSupported()) return;
try {
- new Notification({ title, body, icon: createShieldIcon() }).show();
+ new Notification({ title, body, icon: createIcon() }).show();
} catch (_) {}
}
@@ -51,7 +51,7 @@ function createWindow() {
minHeight: 640,
backgroundColor: '#0e1117',
title: 'Soterios',
- icon: createShieldIcon(),
+ icon: createIcon(),
webPreferences: {
preload: path.join(__dirname, '../preload/preload.js'),
contextIsolation: true,
@@ -74,7 +74,7 @@ function createWindow() {
function buildAppMenu() {
const isMac = process.platform === 'darwin';
-
+
const aboutHandler = () => {
dialog.showMessageBox(mainWindow, {
type: 'info',
@@ -130,16 +130,16 @@ app.whenReady().then(async () => {
const heuristicEngine = new HeuristicEngine();
const reputationEngine = new ReputationEngine(db);
const quarantineManager = new QuarantineManager(db);
-
+
const scanEngine = new ScanEngine(
- db,
- eventBus,
- clamEngine,
- heuristicEngine,
- reputationEngine,
+ db,
+ eventBus,
+ clamEngine,
+ heuristicEngine,
+ reputationEngine,
quarantineManager
);
-
+
const realtimeWatcher = new RealTimeWatcher(db, eventBus, scanEngine);
const processInspector = new ProcessInspector();
const systemAudit = new SystemAudit();
diff --git a/src/ui/js/pages/dashboard.js b/src/ui/js/pages/dashboard.js
index 843444d..49fad76 100644
--- a/src/ui/js/pages/dashboard.js
+++ b/src/ui/js/pages/dashboard.js
@@ -110,13 +110,12 @@ window.Pages['dashboard'] = {
let isRtpActive = true;
async function loadLastScan() {
+ const el = container.querySelector('#lastScanTime');
+ if (!el) return;
const latest = await window.api.invoke('scanReports:latest');
- const el = document.getElementById('lastScanTime');
- if (!latest) {
- el.textContent = 'Never';
- return;
- }
- el.textContent = `${new Date(latest.timestamp).toLocaleString()} (${latest.status})`;
+ el.textContent = latest
+ ? `${new Date(latest.timestamp).toLocaleString()} (${latest.status})`
+ : 'Never';
}
async function loadWarnings() {
@@ -200,7 +199,8 @@ window.Pages['dashboard'] = {
healthDetail.textContent = e.message || 'Unable to calculate health score.';
healthIcon.className = 'status-icon warning';
}
- document.getElementById('btnRefreshWarnings').addEventListener('click', loadWarnings);
+ const btnRefreshWarnings = container.querySelector('#btnRefreshWarnings');
+ if (btnRefreshWarnings) btnRefreshWarnings.addEventListener('click', loadWarnings);
await loadWarnings();
btnToggleRtp.addEventListener('click', async () => {
@@ -222,12 +222,13 @@ window.Pages['dashboard'] = {
// Scan buttons
document.getElementById('btnQuickScan').addEventListener('click', async () => {
- document.getElementById('lastScanTime').textContent = 'Scanning...';
+ const lastScanEl = container.querySelector('#lastScanTime');
+ if (lastScanEl) lastScanEl.textContent = 'Scanning...';
try {
const res = await window.api.invoke('scan:quick');
if (res.error) alert(res.error);
else {
- await loadLastScan();
+ if (container.querySelector('#lastScanTime')) await loadLastScan();
alert(res.canceled ? 'Scan canceled.' : 'Scan completed.');
}
} catch(e) {
@@ -236,12 +237,13 @@ window.Pages['dashboard'] = {
});
document.getElementById('btnFullScan').addEventListener('click', async () => {
- document.getElementById('lastScanTime').textContent = 'Scanning...';
+ const lastScanEl = container.querySelector('#lastScanTime');
+ if (lastScanEl) lastScanEl.textContent = 'Scanning...';
try {
const res = await window.api.invoke('scan:full');
if (res.error) alert(res.error);
else {
- await loadLastScan();
+ if (container.querySelector('#lastScanTime')) await loadLastScan();
alert(res.canceled ? 'Scan canceled.' : 'Scan completed.');
}
} catch(e) {