diff --git a/README.md b/README.md index 827c93e1..c46f131a 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 00000000..22b00c18 --- /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 0b7c15a3..0cb0bf4b 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.1", "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 591f37ee..5ad44d32 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.1", "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 00000000..39ed5169 --- /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 00000000..e1a74e3e --- /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 cb5f23ec..3a417671 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 3c44ca80..7cbdfb14 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 954d1272..00000000 --- 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 0e6ba3db..00000000 --- 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 54cc6f08..e9c6e858 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 0be0b8ef..e863cadd 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 a5a6ed24..4d96c27c 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 e6b9f933..c290103d 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 b2b4d47f..b3c70691 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 64b59756..a0280916 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 d2759eba..cfc592c9 100644 --- a/src/presentation/components/DevToolkit/DevToolkit.vue +++ b/src/presentation/components/DevToolkit/DevToolkit.vue @@ -17,16 +17,18 @@