From 30d67472cb597ac7348eb9e23d9fc36284d8cade Mon Sep 17 00:00:00 2001 From: Grzegorz Kucmierz Date: Fri, 27 Feb 2026 04:03:35 +0000 Subject: [PATCH] docs: add privacy policy and extension documentation --- .gitignore | 1 + README.md | 68 +++++++++++- extension/README.md | 28 +++++ scripts/build_extension.py | 58 +++++++++++ scripts/resize_screenshot.py | 61 +++++++++++ src/router/index.js | 6 ++ src/views/PrivacyPolicy.vue | 196 +++++++++++++++++++++++++++++++++++ 7 files changed, 417 insertions(+), 1 deletion(-) create mode 100644 extension/README.md create mode 100644 scripts/build_extension.py create mode 100644 scripts/resize_screenshot.py create mode 100644 src/views/PrivacyPolicy.vue diff --git a/.gitignore b/.gitignore index 43e1042..96c79c5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ dist-ssr *.sln *.sw? dev-dist +extension-release.zip diff --git a/README.md b/README.md index f28df31..24666ac 100644 --- a/README.md +++ b/README.md @@ -1 +1,67 @@ -# Tools App \ No newline at end of file +# Tools App 🛠️ + +A collection of useful developer tools in one place. Built with Vue 3 and Vite. + +**Live App:** [https://tools.7u.pl/](https://tools.7u.pl/) + +## Available Tools + +### 🔐 Bulk Passwords Generator +Generate strong, secure passwords in bulk. +- Customizable character sets (lowercase, uppercase, digits, special characters). +- Option to skip similar characters (e.g., `l`, `1`, `I`, `O`, `0`). +- Adjustable length and quantity. +- Generates thousands of passwords instantly. + +### 📋 Clipboard Sniffer +Monitor and capture your clipboard history in real-time. +- **Web Mode:** Works when the tab is active and focused. +- **Background Mode (with Extension):** Captures clipboard changes even when you are working in other applications or tabs. +- Clears history on demand. +- Privacy-focused: Data is processed locally and never sent to any server. + +--- + +## Chrome Extension 🧩 + +To unlock the full potential of the **Clipboard Sniffer**, you can install the companion Chrome Extension. + +### Why install the extension? +By default, web browsers restrict clipboard access to when the tab is active and focused. The **Tools App Extension** runs in the background, allowing the application to detect clipboard changes even when you are using other apps or browsing different websites. + +### Features +- **Background Monitoring:** seamlessly captures copied text while you work. +- **Smart Integration:** automatically connects to the Tools App when open. +- **Privacy First:** The extension only communicates with the Tools App (`tools.7u.pl` or `localhost`). No data is sent to third-party servers. [Privacy Policy](https://tools.7u.pl/extension-privacy-policy) + +### Installation +1. Download the latest release or build from source. +2. Open Chrome and navigate to `chrome://extensions/`. +3. Enable "Developer mode" in the top right. +4. Click "Load unpacked" and select the `extension` folder (or drag and drop the `.zip` file). + +--- + +## Development + +### Project Setup +```bash +npm install +``` + +### Run for Development +```bash +npm run dev +``` + +### Build for Production +```bash +npm run build +``` + +### Build Extension +To create a production-ready zip file for the Chrome Extension: +```bash +python3 scripts/build_extension.py +``` +This will generate `extension-release.zip` in the project root. diff --git a/extension/README.md b/extension/README.md new file mode 100644 index 0000000..6344cc4 --- /dev/null +++ b/extension/README.md @@ -0,0 +1,28 @@ +# Tools App Extension 🚀 + +This is the companion Chrome Extension for **Tools App** ([tools.7u.pl](https://tools.7u.pl/)). + +## Overview +**Tools App Extension** enhances your experience with the Tools App, specifically designed to power the **Clipboard Sniffer** tool. By default, web applications can only read your clipboard when the browser tab is active and focused. This extension runs in the background, allowing you to capture clipboard history seamlessly while you work in other applications or browse different websites. + +## Key Features +- **Background Clipboard Monitoring:** Automatically captures copied text even when the Tools App tab is in the background. +- **Privacy-First Design:** All clipboard data is processed locally within your browser and sent directly to the open Tools App tab. **No data is ever sent to external servers.** +- **Smart Activation:** The extension only activates when you explicitly start the "Clipboard Sniffer" tool in the web app. It stops monitoring immediately when you stop the tool or close the tab. +- **Visual Feedback:** The extension icon changes to indicate when it is actively monitoring your clipboard. + +## How it Works +1. Open [tools.7u.pl](https://tools.7u.pl/) and navigate to the **Clipboard Sniffer** tool. +2. The web app will detect the extension and show a "Connected" status. +3. Click "Start Sniffing". The extension will begin monitoring clipboard changes in the background. +4. Any text you copy (from any application) will appear in the Tools App list. +5. Click "Stop Sniffing" to disable monitoring. + +## Permissions Explained +- **Read data from the clipboard (`clipboardRead`):** Essential for detecting when you copy text. +- **Run scripts on tools.7u.pl (`scripting`):** Allows the extension to communicate with the Tools App web page to send clipboard updates. +- **Storage:** Used to save user preferences (e.g., sound notifications). +- **Alarms:** Used to keep the background process alive while sniffing is active (to prevent timeout). + +## Privacy Policy +We value your privacy. This extension does not collect, store, or transmit any personal data. Clipboard content is only temporarily read and passed to the local instance of the Tools App running in your browser tab. diff --git a/scripts/build_extension.py b/scripts/build_extension.py new file mode 100644 index 0000000..222e994 --- /dev/null +++ b/scripts/build_extension.py @@ -0,0 +1,58 @@ +import json +import os +import shutil +import zipfile + +# Configuration +SOURCE_DIR = "extension" +BUILD_DIR = "dist-extension" +OUTPUT_ZIP = "extension-release.zip" +MANIFEST_FILE = "manifest.json" + +# Remove build directory if exists +if os.path.exists(BUILD_DIR): + shutil.rmtree(BUILD_DIR) + +# Copy source directory to build directory +shutil.copytree(SOURCE_DIR, BUILD_DIR) + +# Modify manifest.json for production +manifest_path = os.path.join(BUILD_DIR, MANIFEST_FILE) +with open(manifest_path, "r") as f: + manifest = json.load(f) + +# Filter permissions and content scripts (remove localhost) +print("Removing localhost from manifest...") + +# Filter host_permissions +if "host_permissions" in manifest: + manifest["host_permissions"] = [ + perm for perm in manifest["host_permissions"] + if "localhost" not in perm + ] + +# Filter content_scripts matches +if "content_scripts" in manifest: + for script in manifest["content_scripts"]: + if "matches" in script: + script["matches"] = [ + match for match in script["matches"] + if "localhost" not in match + ] + +# Save modified manifest +with open(manifest_path, "w") as f: + json.dump(manifest, f, indent=2) + +# Create ZIP file +print(f"Creating {OUTPUT_ZIP}...") +with zipfile.ZipFile(OUTPUT_ZIP, "w", zipfile.ZIP_DEFLATED) as zipf: + for root, dirs, files in os.walk(BUILD_DIR): + for file in files: + file_path = os.path.join(root, file) + arcname = os.path.relpath(file_path, BUILD_DIR) + zipf.write(file_path, arcname) + +# Cleanup +shutil.rmtree(BUILD_DIR) +print(f"Done! {OUTPUT_ZIP} is ready for upload to Chrome Web Store.") \ No newline at end of file diff --git a/scripts/resize_screenshot.py b/scripts/resize_screenshot.py new file mode 100644 index 0000000..9ca9b3c --- /dev/null +++ b/scripts/resize_screenshot.py @@ -0,0 +1,61 @@ +from PIL import Image, ImageOps + +def resize_image_canvas(input_path, output_path, canvas_width, canvas_height, bg_color=(255, 255, 255)): + """ + Resizes an image to fit within a specific canvas size, centering it and adding padding. + """ + try: + original_image = Image.open(input_path) + + # Calculate aspect ratios + img_ratio = original_image.width / original_image.height + canvas_ratio = canvas_width / canvas_height + + # Determine new dimensions + if img_ratio > canvas_ratio: + # Image is wider than canvas + new_width = canvas_width + new_height = int(canvas_width / img_ratio) + else: + # Image is taller than canvas + new_height = canvas_height + new_width = int(canvas_height * img_ratio) + + # Resize the original image + resized_image = original_image.resize((new_width, new_height), Image.Resampling.LANCZOS) + + # Create a new canvas with the specified background color + new_image = Image.new("RGB", (canvas_width, canvas_height), bg_color) + + # Calculate position to center the image + x_offset = (canvas_width - new_width) // 2 + y_offset = (canvas_height - new_height) // 2 + + # Paste the resized image onto the canvas + new_image.paste(resized_image, (x_offset, y_offset)) + + # Save the result + new_image.save(output_path, quality=95) + print(f"Success! Image saved to {output_path}") + + except Exception as e: + print(f"Error: {e}") + +if __name__ == "__main__": + # Example usage: + # Replace 'screenshot.png' with your actual file name + # We will look for png or jpg files in current dir if not specified + import glob + import sys + + files = glob.glob("*.png") + glob.glob("*.jpg") + glob.glob("*.jpeg") + + if not files: + print("No image files found in the current directory.") + sys.exit(1) + + print("Found images:", files) + input_file = files[0] # Take the first one found + print(f"Processing {input_file}...") + + resize_image_canvas(input_file, "cws_screenshot_1280x800.png", 1280, 800, bg_color=(245, 247, 250)) # Light gray-ish background matching the app diff --git a/src/router/index.js b/src/router/index.js index e627a75..fbbeeec 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -2,6 +2,7 @@ import { createRouter, createWebHistory } from 'vue-router' import Main from '../components/Main.vue' import Passwords from '../components/tools/Passwords.vue' import ClipboardSniffer from '../components/tools/ClipboardSniffer.vue' +import PrivacyPolicy from '../views/PrivacyPolicy.vue' const routes = [ { @@ -18,6 +19,11 @@ const routes = [ path: '/clipboard-sniffer', name: 'ClipboardSniffer', component: ClipboardSniffer + }, + { + path: '/extension-privacy-policy', + name: 'PrivacyPolicy', + component: PrivacyPolicy } ] diff --git a/src/views/PrivacyPolicy.vue b/src/views/PrivacyPolicy.vue new file mode 100644 index 0000000..816bba5 --- /dev/null +++ b/src/views/PrivacyPolicy.vue @@ -0,0 +1,196 @@ + + + + + \ No newline at end of file