diff --git a/README.md b/README.md index 827c93e1f..c46f131a5 100644 --- a/README.md +++ b/README.md @@ -124,9 +124,9 @@ - 🌍️ **Online**: [https://privacy.sexy](https://privacy.sexy). - 🖥️ **Offline**: Download directly for: [Windows](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.8/privacy.sexy-Setup-0.12.8.exe), [macOS](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.8/privacy.sexy-0.12.8.dmg), [Linux](https://github.com/undergroundwires/privacy.sexy/releases/download/0.12.8/privacy.sexy-0.12.8.AppImage). For more options, see [here](#additional-install-options). -Online version does not require to run any software on your computer. Offline version has more functions such as running the scripts directly. +For a detailed comparison of features between the desktop and web versions of privacy.sexy, see [Desktop vs. Web Features](./docs/desktop-vs-web-features.md). -💡 You should apply your configuration from time to time (more than once). It would strengthen your privacy and security control because privacy.sexy and its scripts get better and stronger in every new version. +💡 Regularly applying your configuration with privacy.sexy is recommended, especially after each new release and major operating system updates. Each version updates scripts to enhance stability, privacy, and security. [![privacy.sexy application](img/screenshot.png?raw=true )](https://privacy.sexy) diff --git a/docs/desktop-vs-web-features.md b/docs/desktop-vs-web-features.md new file mode 100644 index 000000000..22b00c18f --- /dev/null +++ b/docs/desktop-vs-web-features.md @@ -0,0 +1,36 @@ +# Desktop vs. Web Features + +This table outlines the differences between the desktop and web versions of `privacy.sexy`. + +| Feature | Desktop | Web | +| ------- |---------|-----| +| [Usage without installation](#usage-without-installation) | 🔴 Not available | 🟢 Available | +| [Offline usage](#offline-usage) | 🟢 Available | 🟡 Partially available | +| [Auto-updates](#auto-updates) | 🟢 Available | 🟢 Available | +| [Logging](#logging) | 🟢 Available | 🔴 Not available | +| [Script execution](#script-execution) | 🟢 Available | 🔴 Not available | + +## Feature Descriptions + +### Usage without installation + +The web version can be used directly in a browser without any installation, whereas the desktop version requires downloading and installing the software. + +> **Note for Linux:** For Linux users, privacy.sexy is available as an AppImage, which is a portable format that does not require traditional installation. This means Linux users can use the desktop version without installation, similar to the web version. + +### Offline usage + +Once loaded, the web version can be used offline. The desktop version inherently supports offline usage. + +### Auto-updates + +Both versions automatically update to ensure you have the latest features and security enhancements. + +### Logging + +The desktop version supports logging of activities to aid in troubleshooting. This feature is not available in the web version. + +### Script execution + +Direct execution of scripts is possible in the desktop version, offering a more integrated experience. +This functionality is not present in the web version due to browser limitations. diff --git a/package-lock.json b/package-lock.json index 0b7c15a3d..5291d00c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,14 +6,14 @@ "packages": { "": { "name": "privacy.sexy", - "version": "0.12.7", + "version": "0.12.8", "hasInstallScript": true, "dependencies": { "@floating-ui/vue": "^1.0.2", "@juggle/resize-observer": "^3.4.0", "ace-builds": "^1.30.0", "cross-fetch": "^4.0.0", - "electron-log": "^4.4.8", + "electron-log": "^5.0.0", "electron-progressbar": "^2.1.0", "electron-updater": "^6.1.4", "file-saver": "^2.0.5", @@ -6699,9 +6699,12 @@ } }, "node_modules/electron-log": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.8.tgz", - "integrity": "sha512-QQ4GvrXO+HkgqqEOYbi+DHL7hj5JM+nHi/j+qrN9zeeXVKy8ZABgbu4CnG+BBqDZ2+tbeq9tUC4DZfIWFU5AZA==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.0.1.tgz", + "integrity": "sha512-x4wnwHg00h/onWQgjmvcdLV7Mrd9TZjxNs8LmXVpqvANDf4FsSs5wLlzOykWLcaFzR3+5hdVEQ8ctmrUxgHlPA==", + "engines": { + "node": ">= 14" + } }, "node_modules/electron-progressbar": { "version": "2.1.0", @@ -24483,9 +24486,9 @@ } }, "electron-log": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.8.tgz", - "integrity": "sha512-QQ4GvrXO+HkgqqEOYbi+DHL7hj5JM+nHi/j+qrN9zeeXVKy8ZABgbu4CnG+BBqDZ2+tbeq9tUC4DZfIWFU5AZA==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-5.0.1.tgz", + "integrity": "sha512-x4wnwHg00h/onWQgjmvcdLV7Mrd9TZjxNs8LmXVpqvANDf4FsSs5wLlzOykWLcaFzR3+5hdVEQ8ctmrUxgHlPA==" }, "electron-progressbar": { "version": "2.1.0", diff --git a/package.json b/package.json index 591f37ee9..b783af34e 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@juggle/resize-observer": "^3.4.0", "ace-builds": "^1.30.0", "cross-fetch": "^4.0.0", - "electron-log": "^4.4.8", + "electron-log": "^5.0.0", "electron-progressbar": "^2.1.0", "electron-updater": "^6.1.4", "file-saver": "^2.0.5", diff --git a/src/application/Common/Log/Logger.ts b/src/application/Common/Log/Logger.ts new file mode 100644 index 000000000..39ed51690 --- /dev/null +++ b/src/application/Common/Log/Logger.ts @@ -0,0 +1,6 @@ +export interface Logger { + info(...params: unknown[]): void; + warn(...params: unknown[]): void; + error(...params: unknown[]): void; + debug(...params: unknown[]): void; +} diff --git a/src/application/Common/Log/LoggerFactory.ts b/src/application/Common/Log/LoggerFactory.ts new file mode 100644 index 000000000..e1a74e3e8 --- /dev/null +++ b/src/application/Common/Log/LoggerFactory.ts @@ -0,0 +1,5 @@ +import { Logger } from '@/application/Common/Log/Logger'; + +export interface LoggerFactory { + readonly logger: Logger; +} diff --git a/src/infrastructure/Log/ConsoleLogger.ts b/src/infrastructure/Log/ConsoleLogger.ts index cb5f23eca..3a417671f 100644 --- a/src/infrastructure/Log/ConsoleLogger.ts +++ b/src/infrastructure/Log/ConsoleLogger.ts @@ -1,17 +1,32 @@ -import { ILogger } from './ILogger'; +import { Logger } from '@/application/Common/Log/Logger'; -export class ConsoleLogger implements ILogger { - constructor(private readonly consoleProxy: Partial = console) { +export class ConsoleLogger implements Logger { + constructor(private readonly consoleProxy: ConsoleLogFunctions = globalThis.console) { if (!consoleProxy) { // do not trust strictNullChecks for global objects throw new Error('missing console'); } } public info(...params: unknown[]): void { - const logFunction = this.consoleProxy?.info; - if (!logFunction) { - throw new Error('missing "info" function'); - } - logFunction.call(this.consoleProxy, ...params); + this.consoleProxy.info(...params); + } + + public warn(...params: unknown[]): void { + this.consoleProxy.warn(...params); + } + + public error(...params: unknown[]): void { + this.consoleProxy.error(...params); } + + public debug(...params: unknown[]): void { + this.consoleProxy.debug(...params); + } +} + +interface ConsoleLogFunctions extends Partial { + readonly info: Console['info']; + readonly warn: Console['warn']; + readonly error: Console['error']; + readonly debug: Console['debug']; } diff --git a/src/infrastructure/Log/ElectronLogger.ts b/src/infrastructure/Log/ElectronLogger.ts index 3c44ca802..7cbdfb148 100644 --- a/src/infrastructure/Log/ElectronLogger.ts +++ b/src/infrastructure/Log/ElectronLogger.ts @@ -1,17 +1,15 @@ -import { ElectronLog } from 'electron-log'; -import { ILogger } from './ILogger'; +import log from 'electron-log/main'; +import { Logger } from '@/application/Common/Log/Logger'; +import type { LogFunctions } from 'electron-log'; // Using plain-function rather than class so it can be used in Electron's context-bridging. -export function createElectronLogger(logger: Partial): ILogger { - if (!logger) { - throw new Error('missing logger'); - } +export function createElectronLogger(logger: LogFunctions = log): Logger { return { - info: (...params) => { - if (!logger.info) { - throw new Error('missing "info" function'); - } - logger.info(...params); - }, + info: (...params) => logger.info(...params), + debug: (...params) => logger.debug(...params), + warn: (...params) => logger.warn(...params), + error: (...params) => logger.error(...params), }; } + +export const ElectronLogger = createElectronLogger(); diff --git a/src/infrastructure/Log/ILogger.ts b/src/infrastructure/Log/ILogger.ts deleted file mode 100644 index 954d12720..000000000 --- a/src/infrastructure/Log/ILogger.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface ILogger { - info (...params: unknown[]): void; -} diff --git a/src/infrastructure/Log/ILoggerFactory.ts b/src/infrastructure/Log/ILoggerFactory.ts deleted file mode 100644 index 0e6ba3dba..000000000 --- a/src/infrastructure/Log/ILoggerFactory.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ILogger } from './ILogger'; - -export interface ILoggerFactory { - readonly logger: ILogger; -} diff --git a/src/infrastructure/Log/NoopLogger.ts b/src/infrastructure/Log/NoopLogger.ts index 54cc6f08e..e9c6e8580 100644 --- a/src/infrastructure/Log/NoopLogger.ts +++ b/src/infrastructure/Log/NoopLogger.ts @@ -1,5 +1,11 @@ -import { ILogger } from './ILogger'; +import { Logger } from '@/application/Common/Log/Logger'; -export class NoopLogger implements ILogger { +export class NoopLogger implements Logger { public info(): void { /* NOOP */ } + + public warn(): void { /* NOOP */ } + + public error(): void { /* NOOP */ } + + public debug(): void { /* NOOP */ } } diff --git a/src/infrastructure/Log/WindowInjectedLogger.ts b/src/infrastructure/Log/WindowInjectedLogger.ts index 0be0b8ef2..e863cadde 100644 --- a/src/infrastructure/Log/WindowInjectedLogger.ts +++ b/src/infrastructure/Log/WindowInjectedLogger.ts @@ -1,8 +1,8 @@ +import { Logger } from '@/application/Common/Log/Logger'; import { WindowVariables } from '../WindowVariables/WindowVariables'; -import { ILogger } from './ILogger'; -export class WindowInjectedLogger implements ILogger { - private readonly logger: ILogger; +export class WindowInjectedLogger implements Logger { + private readonly logger: Logger; constructor(windowVariables: WindowVariables | undefined | null = window) { if (!windowVariables) { // do not trust strict null checks for global objects @@ -17,4 +17,16 @@ export class WindowInjectedLogger implements ILogger { public info(...params: unknown[]): void { this.logger.info(...params); } + + public warn(...params: unknown[]): void { + this.logger.warn(...params); + } + + public debug(...params: unknown[]): void { + this.logger.debug(...params); + } + + public error(...params: unknown[]): void { + this.logger.error(...params); + } } diff --git a/src/infrastructure/WindowVariables/WindowVariables.ts b/src/infrastructure/WindowVariables/WindowVariables.ts index a5a6ed24d..4d96c27cd 100644 --- a/src/infrastructure/WindowVariables/WindowVariables.ts +++ b/src/infrastructure/WindowVariables/WindowVariables.ts @@ -1,11 +1,11 @@ import { OperatingSystem } from '@/domain/OperatingSystem'; import { ISystemOperations } from '@/infrastructure/SystemOperations/ISystemOperations'; -import { ILogger } from '@/infrastructure/Log/ILogger'; +import { Logger } from '@/application/Common/Log/Logger'; /* Primary entry point for platform-specific injections */ export interface WindowVariables { - readonly isDesktop?: boolean; + readonly isDesktop: boolean; readonly system?: ISystemOperations; readonly os?: OperatingSystem; - readonly log?: ILogger; + readonly log: Logger; } diff --git a/src/presentation/bootstrapping/ClientLoggerFactory.ts b/src/presentation/bootstrapping/ClientLoggerFactory.ts index e6b9f933f..c290103d0 100644 --- a/src/presentation/bootstrapping/ClientLoggerFactory.ts +++ b/src/presentation/bootstrapping/ClientLoggerFactory.ts @@ -1,15 +1,15 @@ import { RuntimeEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironment'; import { IRuntimeEnvironment } from '@/infrastructure/RuntimeEnvironment/IRuntimeEnvironment'; import { ConsoleLogger } from '@/infrastructure/Log/ConsoleLogger'; -import { ILogger } from '@/infrastructure/Log/ILogger'; -import { ILoggerFactory } from '@/infrastructure/Log/ILoggerFactory'; +import { Logger } from '@/application/Common/Log/Logger'; +import { LoggerFactory } from '@/application/Common/Log/LoggerFactory'; import { NoopLogger } from '@/infrastructure/Log/NoopLogger'; import { WindowInjectedLogger } from '@/infrastructure/Log/WindowInjectedLogger'; -export class ClientLoggerFactory implements ILoggerFactory { - public static readonly Current: ILoggerFactory = new ClientLoggerFactory(); +export class ClientLoggerFactory implements LoggerFactory { + public static readonly Current: LoggerFactory = new ClientLoggerFactory(); - public readonly logger: ILogger; + public readonly logger: Logger; protected constructor(environment: IRuntimeEnvironment = RuntimeEnvironment.CurrentEnvironment) { if (environment.isDesktop) { diff --git a/src/presentation/bootstrapping/DependencyProvider.ts b/src/presentation/bootstrapping/DependencyProvider.ts index b2b4d47fb..b3c70691f 100644 --- a/src/presentation/bootstrapping/DependencyProvider.ts +++ b/src/presentation/bootstrapping/DependencyProvider.ts @@ -12,6 +12,7 @@ import { } from '@/presentation/injectionSymbols'; import { PropertyKeys } from '@/TypeHelpers'; import { useUserSelectionState } from '@/presentation/components/Shared/Hooks/UseUserSelectionState'; +import { useLogger } from '@/presentation/components/Shared/Hooks/UseLogger'; export function provideDependencies( context: IApplicationContext, @@ -57,6 +58,10 @@ export function provideDependencies( return useUserSelectionState(state, events); }, ), + useLogger: (di) => di.provide( + InjectionKeys.useLogger, + useLogger, + ), }; registerAll(Object.values(resolvers), api); } diff --git a/src/presentation/bootstrapping/Modules/AppInitializationLogger.ts b/src/presentation/bootstrapping/Modules/AppInitializationLogger.ts index 64b59756f..a0280916f 100644 --- a/src/presentation/bootstrapping/Modules/AppInitializationLogger.ts +++ b/src/presentation/bootstrapping/Modules/AppInitializationLogger.ts @@ -1,10 +1,10 @@ -import { ILogger } from '@/infrastructure/Log/ILogger'; +import { Logger } from '@/application/Common/Log/Logger'; import { Bootstrapper } from '../Bootstrapper'; import { ClientLoggerFactory } from '../ClientLoggerFactory'; export class AppInitializationLogger implements Bootstrapper { constructor( - private readonly logger: ILogger = ClientLoggerFactory.Current.logger, + private readonly logger: Logger = ClientLoggerFactory.Current.logger, ) { } public async bootstrap(): Promise { diff --git a/src/presentation/components/DevToolkit/DevToolkit.vue b/src/presentation/components/DevToolkit/DevToolkit.vue index d2759ebab..cfc592c9c 100644 --- a/src/presentation/components/DevToolkit/DevToolkit.vue +++ b/src/presentation/components/DevToolkit/DevToolkit.vue @@ -17,16 +17,18 @@