Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f2d56c05a | |||
| bb8690b74f | |||
| ed11ccd2a1 | |||
| db00538aee | |||
| 05a9ada8d9 |
@@ -1,9 +1,9 @@
|
||||
# PacCrypt WebApp
|
||||
# PacCrypt
|
||||
|
||||
**PacCrypt** is a secure, feature-rich web app for encrypting and decrypting text and files — built with Flask, JavaScript, and AES-GCM encryption.
|
||||
Now with an admin control panel, GitHub updater, and a built-in Pac-Man easter egg! 🕹️
|
||||
|
||||
Live demo: [paccrypt.unnaturalll.dev](http://paccrypt.unnaturalll.dev)
|
||||
Officially Hosted Here: [paccrypt.unnaturalll.dev](http://paccrypt.unnaturalll.dev)
|
||||
|
||||
---
|
||||
|
||||
@@ -35,8 +35,9 @@ Live demo: [paccrypt.unnaturalll.dev](http://paccrypt.unnaturalll.dev)
|
||||
- Flask 3+
|
||||
- Cryptography 42+
|
||||
- Waitress 2.1+
|
||||
- Git (for update feature)
|
||||
- Nginx (recommended)
|
||||
- Git (For update feature)
|
||||
- Nginx (Recommended)
|
||||
- Cockpit (Recommended if hosted on **Linux**)
|
||||
|
||||
---
|
||||
|
||||
@@ -54,45 +55,49 @@ Then run:
|
||||
|
||||
- Development Mode:
|
||||
```bash
|
||||
./start_dev.sh # or start_dev.bat
|
||||
./start_dev.sh #<-- start_dev.bat (Windows)
|
||||
```
|
||||
|
||||
- Production Mode:
|
||||
```bash
|
||||
./start_prod.sh # or start_prod.bat
|
||||
./start_prod.sh #<-- start_prod.bat (Windows)
|
||||
```
|
||||
|
||||
Visit [http://127.0.0.1:5000](http://127.0.0.1:5000)
|
||||
Visit [http://127.0.0.1:5000](http://127.0.0.1:5000) or [http://localhost:5000](http://localhost:5000) - *If* you **are** on the host system
|
||||
Visit http://hosts_private_ip - *If* you are **not** on the host system
|
||||
|
||||
---
|
||||
|
||||
## 🧭 Navigation & Usage
|
||||
|
||||
### 🔑 Generate Passwords
|
||||
|
||||
- Click Generate
|
||||
- Then hit `📋 Copy Password`
|
||||
- **Note:** This is also used as a seed generator for the Pac-Man *like* game
|
||||
|
||||
### 🔐 Encrypt & Decrypt
|
||||
|
||||
- Choose between Basic Cipher or Advanced AES
|
||||
- Type your message or upload a file
|
||||
- Enter password (if AES)
|
||||
- Select mode using toggle (Encrypt/Decrypt)
|
||||
- Type your message or upload a file
|
||||
- Enter password (Advanced AES)
|
||||
- Hit Execute
|
||||
- Then hit `📋 Copy Output`
|
||||
|
||||
### 📤 Share Files
|
||||
|
||||
- Upload a file with two passwords:
|
||||
- Encryption password
|
||||
- Pickup password
|
||||
- Get a shareable URL and click 📋 Copy Link
|
||||
- Get a shareable URL and click `📋 Copy Link`
|
||||
|
||||
### 🔑 Generate Passwords
|
||||
|
||||
- Click Generate
|
||||
- Then hit 📋 Copy
|
||||
|
||||
### 🎮 Pac-Man Game
|
||||
### 🎮 Pac-Man *like* Game
|
||||
|
||||
- Type `pacman` in the input box
|
||||
- Game appears with Restart/Exit controls
|
||||
- Classic arrow key controls 🕹️
|
||||
- Game appears with `Restart` and `Exit` buttons
|
||||
- Arrow key and Swipe controls 🕹️
|
||||
- Game restarts and a new seed is generated once all dots are eaten
|
||||
|
||||
---
|
||||
|
||||
@@ -111,31 +116,117 @@ Features:
|
||||
---
|
||||
|
||||
## 🛡️ Deployment Tips
|
||||
##### I recommend using Linux as the host server, the follow confs are Linux focused
|
||||
The official PacCrypt host is **Debian** minimal install.
|
||||
|
||||
Minimal Nginx config:
|
||||
**HTTP** Nginx config (Not recommended):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com;
|
||||
server_name yourdomain.com; #<-- Your URL here
|
||||
|
||||
# Basic Privacy-Respecting Logging
|
||||
access_log off; #<-- set to syslog:server=unix:/dev/log; for logging
|
||||
error_log syslog:server=unix:/dev/log crit; #<-- Currently set for only critical logs, remove crit for all logs
|
||||
|
||||
# Hardened Proxy Settings
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Connection "";
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 5s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# Basic Hardening Headers
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "geolocation=(), microphone=()" always;
|
||||
|
||||
# Prevent Abuse
|
||||
client_max_body_size 10M;
|
||||
keepalive_timeout 10;
|
||||
server_tokens off;
|
||||
}
|
||||
```
|
||||
|
||||
Use Let's Encrypt to add SSL/TLS support.
|
||||
**HTTPS** Nginx config (Recommended):
|
||||
|
||||
```nginx
|
||||
# Redirect HTTP to HTTPS
|
||||
server {
|
||||
listen 80;
|
||||
server_name yourdomain.com; #<-- Your URL here
|
||||
|
||||
# Basic Privacy-Respecting Logging
|
||||
access_log off; #<-- set to syslog:server=unix:/dev/log; for logging
|
||||
error_log syslog:server=unix:/dev/log crit; #<-- Currently set for only critical logs, remove crit for all logs
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS Server Block
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name yourdomain.com;
|
||||
|
||||
ssl_certificate path/to/yourdomain.com.cert; #<-- Could also be .cert.pem
|
||||
ssl_certificate_key path/to/yourdomain.com.key; #<-- Could also be .key.pem
|
||||
|
||||
# SSL Hardening
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# Strong security headers (adjust as needed)
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||
add_header X-Content-Type-Options nosniff always;
|
||||
add_header X-Frame-Options DENY always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "geolocation=(), camera=()" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
|
||||
# Basic Privacy-Respecting Logging
|
||||
access_log off; #<-- set to syslog:server=unix:/dev/log; for logging
|
||||
error_log syslog:server=unix:/dev/log crit; #<-- Currently set for only critical logs, remove crit for all logs
|
||||
|
||||
client_max_body_size xG; #<-- Change to what the max upload for PacCrypt Share
|
||||
|
||||
# Reverse proxy to Flask
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:5000;
|
||||
proxy_set_header Host $host;
|
||||
|
||||
# Comment these out if you want complete anonymity between client and app
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# Optional privacy: strip identifying headers
|
||||
proxy_hide_header X-Powered-By;
|
||||
}
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
## 🗂️ Project Structure
|
||||
|
||||
```
|
||||
paccrypt-webapp-final/
|
||||
PacCrypt/
|
||||
├── app.py
|
||||
├── requirements.txt
|
||||
├── README.md
|
||||
|
||||
@@ -6,11 +6,11 @@ import html
|
||||
import base64
|
||||
import hashlib
|
||||
import secrets
|
||||
import datetime
|
||||
import subprocess
|
||||
import platform
|
||||
from datetime import UTC
|
||||
from datetime import datetime, timedelta
|
||||
import sys
|
||||
import psutil
|
||||
|
||||
# ===== Third-Party Imports =====
|
||||
from flask import (
|
||||
@@ -138,7 +138,7 @@ def log_admin_event(message: str):
|
||||
try:
|
||||
key = load_admin_key()
|
||||
cipher = Fernet(key)
|
||||
timestamp = datetime.datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S")
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
encrypted = cipher.encrypt(f"[{timestamp}] {message}".encode())
|
||||
with open(ADMIN_LOG_FILE, 'ab') as f:
|
||||
f.write(encrypted + b"\n")
|
||||
@@ -149,12 +149,12 @@ def log_admin_event(message: str):
|
||||
def cleanup_expired_files():
|
||||
"""Remove files older than MAX_FILE_AGE_DAYS."""
|
||||
try:
|
||||
now = datetime.datetime.now(UTC)
|
||||
now = datetime.now()
|
||||
for fname in os.listdir(UPLOAD_FOLDER):
|
||||
if fname.endswith(".enc") or fname.endswith(".json"):
|
||||
path = os.path.join(UPLOAD_FOLDER, fname)
|
||||
try:
|
||||
file_time = datetime.datetime.fromtimestamp(os.path.getmtime(path), UTC)
|
||||
file_time = datetime.datetime.fromtimestamp(os.path.getmtime(path), )
|
||||
age = (now - file_time).days
|
||||
if age > MAX_FILE_AGE_DAYS:
|
||||
os.remove(path)
|
||||
@@ -208,7 +208,7 @@ def handle_file_upload(request):
|
||||
meta = {
|
||||
'pickup_password': base64.urlsafe_b64encode(hashlib.sha256(pickup_password.encode()).digest()).decode(),
|
||||
'original_name': filename,
|
||||
'timestamp': datetime.datetime.now(UTC).isoformat()
|
||||
'timestamp': datetime.datetime.now().isoformat()
|
||||
}
|
||||
with open(os.path.join(UPLOAD_FOLDER, f"{random_id}.json"), 'w') as f:
|
||||
json.dump(meta, f)
|
||||
@@ -408,48 +408,30 @@ def admin_page():
|
||||
cleanup_expired_files()
|
||||
routes = [rule.rule for rule in app.url_map.iter_rules() if rule.endpoint != 'static']
|
||||
|
||||
# Get uptime based on OS
|
||||
if platform.system() == "Windows":
|
||||
try:
|
||||
# Windows uptime using PowerShell
|
||||
ps_command = "(Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime"
|
||||
uptime_output = subprocess.check_output(["powershell", "-Command", ps_command], shell=True).decode()
|
||||
# Convert the PowerShell DateTime to Python datetime
|
||||
boot_time = datetime.datetime.strptime(uptime_output.strip(), "%A, %B %d, %Y %I:%M:%S %p")
|
||||
# Make boot_time timezone-aware (assuming local time)
|
||||
boot_time = boot_time.replace(tzinfo=datetime.timezone.utc)
|
||||
current_time = datetime.datetime.now(UTC)
|
||||
uptime = current_time - boot_time
|
||||
uptime_str = f"{uptime.days} days, {uptime.seconds // 3600} hours, {(uptime.seconds % 3600) // 60} minutes"
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to get Windows uptime: {str(e)}")
|
||||
uptime_str = "Unavailable"
|
||||
else:
|
||||
try:
|
||||
# Try reading from /proc/uptime first
|
||||
with open('/proc/uptime', 'r') as f:
|
||||
uptime_seconds = float(f.readline().split()[0])
|
||||
days = int(uptime_seconds // 86400)
|
||||
hours = int((uptime_seconds % 86400) // 3600)
|
||||
minutes = int((uptime_seconds % 3600) // 60)
|
||||
uptime_str = f"{days} days, {hours} hours, {minutes} minutes"
|
||||
except Exception:
|
||||
try:
|
||||
# Fallback to uptime command if /proc/uptime fails
|
||||
uptime_str = subprocess.check_output("uptime -p", shell=True).decode().strip()
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to get Linux uptime: {str(e)}")
|
||||
uptime_str = "Unavailable"
|
||||
now = datetime.now()
|
||||
try:
|
||||
boot_time = datetime.fromtimestamp(psutil.boot_time())
|
||||
|
||||
uptime = now - boot_time
|
||||
days = uptime.days
|
||||
hours, remainder = divmod(uptime.seconds, 3600)
|
||||
minutes = remainder // 60
|
||||
uptime_str = f"{days} days, {hours} hours, {minutes} minutes"
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Uptime calculation failed: {e}")
|
||||
uptime_str = "Unavailable"
|
||||
|
||||
server_info = {
|
||||
"uptime": uptime_str,
|
||||
"time": datetime.datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"python": platform.python_version(),
|
||||
"debug": app.debug
|
||||
"server_time": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"python_version": platform.python_version(),
|
||||
"debug_mode": app.debug
|
||||
}
|
||||
|
||||
return render_template("admin.html", routes=routes, server_info=server_info)
|
||||
|
||||
|
||||
|
||||
@app.route("/restart-server", methods=["POST"])
|
||||
def restart_server():
|
||||
"""Restart the server."""
|
||||
@@ -458,9 +440,7 @@ def restart_server():
|
||||
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
# Get the current process ID
|
||||
current_pid = os.getpid()
|
||||
# Create a batch file to restart the server
|
||||
restart_script = f"""
|
||||
@echo off
|
||||
timeout /t 2 /nobreak
|
||||
@@ -470,33 +450,30 @@ def restart_server():
|
||||
"""
|
||||
with open("restart.bat", "w") as f:
|
||||
f.write(restart_script)
|
||||
|
||||
# Start the restart script and exit
|
||||
subprocess.Popen(["restart.bat"], shell=True)
|
||||
return jsonify({"message": "Server restart initiated"}), 200
|
||||
else:
|
||||
# For Linux/Unix systems, use a Python-based restart
|
||||
# Get the current Python interpreter and script path
|
||||
current_pid = os.getpid()
|
||||
python_path = sys.executable
|
||||
script_path = os.path.abspath(__file__)
|
||||
current_pid = os.getpid()
|
||||
|
||||
# Create a shell script to restart the server
|
||||
restart_script = f"""#!/bin/bash
|
||||
sleep 2
|
||||
kill -9 {current_pid}
|
||||
export PRODUCTION=true
|
||||
{python_path} {script_path}
|
||||
"""
|
||||
# Create a safer and cleaner restart script
|
||||
restart_script = """#!/bin/bash
|
||||
sleep 2
|
||||
PID=$1
|
||||
kill "$PID"
|
||||
while kill -0 "$PID" 2>/dev/null; do sleep 0.5; done
|
||||
export PRODUCTION=true
|
||||
exec "$2" "$3"
|
||||
"""
|
||||
|
||||
# Write and make the script executable
|
||||
with open("restart.sh", "w") as f:
|
||||
f.write(restart_script)
|
||||
os.chmod("restart.sh", 0o755)
|
||||
|
||||
# Start the restart script and exit
|
||||
subprocess.Popen(["./restart.sh"], shell=True)
|
||||
subprocess.Popen(["./restart.sh", str(current_pid), python_path, script_path])
|
||||
return jsonify({"message": "Server restart initiated"}), 200
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Failed to restart server: {str(e)}")
|
||||
return jsonify({"error": f"Failed to restart server: {str(e)}"}), 500
|
||||
|
||||
@@ -4,6 +4,7 @@ flask==3.0.3
|
||||
cryptography==42.0.5
|
||||
waitress==2.1.2
|
||||
werkzeug==3.0.1
|
||||
psutil>=5.9.0,<6.0.0
|
||||
|
||||
# nginx - Only needed for Nginx integration, not installed via pip
|
||||
# Run pip install -r requirements.txt
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
@echo off
|
||||
timeout /t 2 /nobreak
|
||||
taskkill /F /PID 15428
|
||||
set PRODUCTION=true
|
||||
start "" "python" "app.py"
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
sleep 2
|
||||
|
||||
# Save current process PID
|
||||
PID=$1
|
||||
|
||||
# Gracefully stop the current server
|
||||
kill "$PID"
|
||||
|
||||
# Wait until it exits
|
||||
while kill -0 "$PID" 2>/dev/null; do
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
# Restart with the same interpreter and script
|
||||
export PRODUCTION=true
|
||||
exec "$2" "$3"
|
||||
+306
-112
@@ -1,15 +1,17 @@
|
||||
/* ===== Global Reset ===== */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 3px;
|
||||
gap: 6px !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ===== Body ===== */
|
||||
body {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
background-color: #121212;
|
||||
color: #00ff99;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
background-color: #0e0e0e;
|
||||
color: #28E060;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
@@ -18,27 +20,137 @@ body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ===== Header ===== */
|
||||
header {
|
||||
text-align: center;
|
||||
padding: 25px;
|
||||
background-color: #1c1c1c;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 153, 0.4);
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin-bottom: 40px !important;
|
||||
@media (max-width: 600px) {
|
||||
#sitemap-section,
|
||||
#password-change-section,
|
||||
#server-update-section,
|
||||
#server-status-section,
|
||||
#server-logs-section,
|
||||
#system-settings-section {
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#sitemap-section li,
|
||||
#server-status-section li {
|
||||
font-size: 0.9em;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#logContainer {
|
||||
font-size: 0.9em;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 11px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.button-group,
|
||||
.admin-button-grid {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button-group button,
|
||||
.admin-button-grid button {
|
||||
min-width: 75%;
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
header {
|
||||
flex-direction: column;
|
||||
height: auto;
|
||||
padding-inline: 15px;
|
||||
padding-block: 20px;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
height: 100px !important;
|
||||
margin-top: -15px !important;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
margin-left: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo-text h1 {
|
||||
font-size: 1.4em;
|
||||
margin-top: -30px !important;
|
||||
margin-left: 0 !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.logo-text p {
|
||||
font-size: 0.8em;
|
||||
margin-left: 0 !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.admin-button-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.status-list {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.8em;
|
||||
color: #00ff99;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
/* ===== Header ===== */
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #111;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px #28E060;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin-bottom: 25px;
|
||||
padding: 25px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo-container img {
|
||||
height: 200px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.logo-text h1 {
|
||||
font-size: clamp(1.4em, 6vw, 2.8em);
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
color: #28E060;
|
||||
margin: 0;
|
||||
margin-left: -30px; /* overlap effect */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.logo-text p {
|
||||
font-size: 1.2em;
|
||||
color: #28E060;
|
||||
margin: 0;
|
||||
margin-left: -30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
header p {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
/* ===== Main Layout ===== */
|
||||
main {
|
||||
@@ -49,7 +161,6 @@ main {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
padding: 0;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
/* ===== Card Styling ===== */
|
||||
@@ -58,7 +169,7 @@ main {
|
||||
padding: 25px;
|
||||
width: 100%;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 153, 0.4);
|
||||
box-shadow: 0 0 15px #28E060;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -67,26 +178,46 @@ main {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0px;
|
||||
max-width: 725px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.status-list {
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
|
||||
/* ===== Inputs, Textareas, Selects ===== */
|
||||
|
||||
button,
|
||||
select,
|
||||
input,
|
||||
textarea {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 12px !important;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea,
|
||||
select,
|
||||
input[type="file"] {
|
||||
width: 80%;
|
||||
max-width: 500px;
|
||||
padding: 12px 20px;
|
||||
border: 1px solid #00ff99;
|
||||
padding-inline: 20px;
|
||||
padding-block: 12px;
|
||||
border: 1px solid #28E060;
|
||||
border-radius: 8px;
|
||||
background-color: #2c2f33;
|
||||
color: #00ff99;
|
||||
font-size: 1em;
|
||||
color: #28E060;
|
||||
text-align: left;
|
||||
transition: 0.3s;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
select {
|
||||
@@ -98,35 +229,41 @@ textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
input[type="password"] {
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
/* ===== File Input Customization ===== */
|
||||
input[type="file"] {
|
||||
border: 2px dashed #00ff99;
|
||||
border: 2px dashed #28E060;
|
||||
cursor: pointer;
|
||||
color: #28E060;
|
||||
background-color: #2c2f33;
|
||||
}
|
||||
|
||||
input[type="file"]::file-selector-button {
|
||||
background-color: #00ff99;
|
||||
color: #121212;
|
||||
border: none;
|
||||
padding: 8px 15px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
input[type="file"]::file-selector-button {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 12px;
|
||||
background-color: #2c2f33;
|
||||
color: #28E060;
|
||||
border: 2px solid #28E060;
|
||||
padding-inline: 10px;
|
||||
padding-block: 8px;
|
||||
margin-right: 10px;
|
||||
border-radius: 6px;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
|
||||
input[type="file"]::file-selector-button:hover {
|
||||
background-color: #00cc77;
|
||||
}
|
||||
input[type="file"]::file-selector-button:hover {
|
||||
background-color: #28E060;
|
||||
color: #000;
|
||||
box-shadow: 0 0 10px #28E060;
|
||||
}
|
||||
|
||||
/* ===== Focus Effects ===== */
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 10px rgba(0, 255, 153, 0.8);
|
||||
box-shadow: 0 0 10px #28E060;
|
||||
}
|
||||
|
||||
/* ===== Textareas Specific Widths ===== */
|
||||
@@ -142,47 +279,132 @@ select:focus {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
border: 0px solid #00ff99;
|
||||
padding-inline: 20px;
|
||||
padding-block: 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background-color: #2c2f33;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
width: auto;
|
||||
min-width: 225px;
|
||||
max-width: 300px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #00ff99;
|
||||
background-color: #28E060;
|
||||
color: #121212;
|
||||
box-shadow: 0 0 10px rgba(0, 255, 153, 0.4);
|
||||
box-shadow: 0 0 10px #28E060;
|
||||
}
|
||||
|
||||
.danger-button {
|
||||
background-color: #5f3131;
|
||||
box-shadow: 0 0 20px rgba(185, 0, 0, 0.4);
|
||||
box-shadow: 0 0 10px #991717;
|
||||
}
|
||||
|
||||
.danger-button:hover {
|
||||
background-color: #ff0000;
|
||||
background-color: #af0000;
|
||||
color: #121212;
|
||||
box-shadow: 0 0 40px rgb(255, 0, 0);
|
||||
box-shadow: 0 0 40px #ff0000;
|
||||
}
|
||||
|
||||
.admin-button-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
justify-items: center;
|
||||
width: 100%;
|
||||
max-width: 640px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.admin-button-grid button {
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ===== Toggle Switch Styling ===== */
|
||||
.toggle-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.toggle-label {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 12px;
|
||||
color: #28E060;
|
||||
}
|
||||
|
||||
.material-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
.material-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.material-slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background-color: #222;
|
||||
border: 2px solid #28E060;
|
||||
border-radius: 34px;
|
||||
transition: 0.4s;
|
||||
margin: unset;
|
||||
}
|
||||
|
||||
.material-slider::before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
background-color: #28E060;
|
||||
border-radius: 50%;
|
||||
transition: 0.4s;
|
||||
box-shadow: 0 0 6px #28E060;
|
||||
}
|
||||
|
||||
.material-switch input:checked + .material-slider {
|
||||
background-color: #28E060;
|
||||
}
|
||||
|
||||
.material-switch input:checked + .material-slider::before {
|
||||
transform: translateX(26px);
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
|
||||
/* Label beside switch */
|
||||
#toggle-label {
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
color: #28E060;
|
||||
margin-left: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.toggle-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -211,7 +433,7 @@ button {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #2c2f33;
|
||||
border: 2px solid #00ff99;
|
||||
border: 2px solid #28E060;
|
||||
border-radius: 34px;
|
||||
transition: .4s;
|
||||
display: flex;
|
||||
@@ -223,7 +445,7 @@ button {
|
||||
content: "";
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
background-color: #00ff99;
|
||||
background-color: #28E060;
|
||||
border-radius: 50%;
|
||||
transition: .4s;
|
||||
transform: translateX(2px);
|
||||
@@ -243,7 +465,7 @@ input:checked + .slider::before {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.9em;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
@@ -265,7 +487,7 @@ input:checked + .slider::before {
|
||||
max-width: 500px;
|
||||
min-height: 50px;
|
||||
background-color: #333;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
@@ -306,16 +528,16 @@ footer {
|
||||
text-align: center;
|
||||
padding: 25px;
|
||||
background-color: #1c1c1c;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 153, 0.4);
|
||||
box-shadow: 0 0 15px #28E060;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin-top: 40px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -330,18 +552,19 @@ footer {
|
||||
select,
|
||||
#input-text,
|
||||
#output-text {
|
||||
width: 100%;
|
||||
max-width: 90%;
|
||||
width: 100% !important;
|
||||
max-width: 90% !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Copy Feedback Message ===== */
|
||||
.copy-feedback, #shared-link-feedback {
|
||||
background-color: #2c2f33;
|
||||
padding: 6px 12px;
|
||||
padding-inline: 12px;
|
||||
padding-block: 6px;
|
||||
margin-top: 6px;
|
||||
border-radius: 6px;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
font-size: 0.9em;
|
||||
display: none;
|
||||
opacity: 0;
|
||||
@@ -361,7 +584,6 @@ footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
@@ -369,9 +591,10 @@ footer {
|
||||
#share-link {
|
||||
display: block;
|
||||
background-color: #2c2f33;
|
||||
padding: 8px 16px;
|
||||
padding-inline: 16px;
|
||||
padding-block: 8px;
|
||||
border-radius: 6px;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
max-width: 720px;
|
||||
@@ -394,11 +617,6 @@ form {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
form input {
|
||||
width: 80%;
|
||||
max-width: 500px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* ===== Section Card Styling ===== */
|
||||
section.card {
|
||||
@@ -411,7 +629,7 @@ section.card {
|
||||
#pacmanCanvas {
|
||||
background-color: black;
|
||||
display: block;
|
||||
border: 2px solid #00ff99;
|
||||
border: 2px solid #28E060;
|
||||
border-radius: 12px;
|
||||
max-width: 700px;
|
||||
width: 100%;
|
||||
@@ -423,7 +641,6 @@ section.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 25px;
|
||||
max-width: 725px;
|
||||
width: 100%;
|
||||
@@ -533,7 +750,7 @@ section.card {
|
||||
padding: 25px;
|
||||
background-color: #1e1e1e;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 153, 0.4);
|
||||
box-shadow: 0 0 15px #28E060;
|
||||
}
|
||||
|
||||
.sitemap-header {
|
||||
@@ -544,17 +761,18 @@ section.card {
|
||||
}
|
||||
|
||||
.sitemap-header h3 {
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.collapse-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
font-size: 1.2em;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
padding-inline: 10px;
|
||||
padding-block: 5px;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -576,11 +794,11 @@ section.card {
|
||||
|
||||
#sitemap-section li,
|
||||
#server-status-section li {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 6px;
|
||||
padding: 8px;
|
||||
background-color: #2c2f33;
|
||||
border-radius: 6px;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
}
|
||||
|
||||
#server-logs-section button {
|
||||
@@ -590,14 +808,14 @@ section.card {
|
||||
}
|
||||
|
||||
#logLoader {
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#logContainer {
|
||||
background-color: #2c2f33;
|
||||
color: #00ff99;
|
||||
color: #28E060;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
max-height: 400px;
|
||||
@@ -611,29 +829,5 @@ section.card {
|
||||
padding: 25px;
|
||||
background-color: #1e1e1e;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 15px rgba(0, 255, 153, 0.4);
|
||||
}
|
||||
|
||||
/* ===== Mobile Responsive Adjustments ===== */
|
||||
@media (max-width: 768px) {
|
||||
#sitemap-section,
|
||||
#password-change-section,
|
||||
#server-update-section,
|
||||
#server-status-section,
|
||||
#server-logs-section,
|
||||
#system-settings-section {
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#sitemap-section li,
|
||||
#server-status-section li {
|
||||
font-size: 0.9em;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
#logContainer {
|
||||
font-size: 0.9em;
|
||||
padding: 10px;
|
||||
}
|
||||
box-shadow: 0 0 15px #28E060;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 300 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 235 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 236 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 300 KiB |
+53
-1
@@ -52,7 +52,11 @@ function setupElementListeners(elements) {
|
||||
elements.generateBtn.addEventListener("click", generateRandomPassword);
|
||||
elements.copyPasswordBtn.addEventListener("click", () => copyToClipboard("generated-password", "password-copy-feedback"));
|
||||
elements.copyOutputBtn?.addEventListener("click", () => copyToClipboard("output-text", "output-copy-feedback"));
|
||||
elements.toggleSwitch.addEventListener("change", updateToggleLabels);
|
||||
elements.toggleSwitch.addEventListener("change", () => {
|
||||
console.log("Mode:", elements.toggleSwitch.checked ? "Decrypt" : "Encrypt");
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Add file input change listener
|
||||
const fileInput = document.getElementById("file-input");
|
||||
@@ -294,6 +298,54 @@ function checkForPacman() {
|
||||
window.exitGame();
|
||||
}
|
||||
}
|
||||
function copyShareLink() {
|
||||
const linkEl = document.getElementById("share-link");
|
||||
const feedback = document.getElementById("shared-link-feedback");
|
||||
|
||||
if (!linkEl) return;
|
||||
|
||||
const linkText = linkEl.href || linkEl.textContent.trim();
|
||||
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
navigator.clipboard.writeText(linkText).then(() => {
|
||||
showCopyFeedback(feedback);
|
||||
}).catch(() => {
|
||||
fallbackCopy(linkText, feedback);
|
||||
});
|
||||
} else {
|
||||
fallbackCopy(linkText, feedback);
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackCopy(text, feedbackEl) {
|
||||
const tempInput = document.createElement("input");
|
||||
tempInput.value = text;
|
||||
document.body.appendChild(tempInput);
|
||||
tempInput.select();
|
||||
|
||||
try {
|
||||
document.execCommand("copy");
|
||||
showCopyFeedback(feedbackEl);
|
||||
} catch (err) {
|
||||
alert("Copy failed. Please copy manually.");
|
||||
}
|
||||
|
||||
document.body.removeChild(tempInput);
|
||||
}
|
||||
|
||||
function showCopyFeedback(feedbackEl) {
|
||||
if (!feedbackEl) return;
|
||||
feedbackEl.style.display = "block";
|
||||
feedbackEl.classList.add("show");
|
||||
|
||||
setTimeout(() => {
|
||||
feedbackEl.classList.remove("show");
|
||||
setTimeout(() => {
|
||||
feedbackEl.style.display = "none";
|
||||
}, 300);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
|
||||
function startPacman() { }
|
||||
function exitGame() { }
|
||||
|
||||
+13
-8
@@ -10,31 +10,36 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt</h1>
|
||||
<p>Encrypt and share your text or files securely</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Securely Share Text and Files</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<section class="card form-group" style="padding: 50px 30px;">
|
||||
<h2 style="color: #00ff99; font-size: 2.5em;">🚫 403 - Forbidden</h2>
|
||||
<h2 style="color: #00ff99; font-size: 2.5em;">403 - Forbidden</h2>
|
||||
<p class="mt-4" style="font-size: 1.2em; color: #cccccc;">
|
||||
Looks like this area is locked behind a secret ghost door! 🛡️👻
|
||||
Looks like this area is locked behind a secret ghost door!
|
||||
</p>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="button-group mt-4">
|
||||
<a href="{{ url_for('index') }}">
|
||||
<button type="button">⬅️ Return Home</button>
|
||||
<button type="button">Return Home</button>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+15
-10
@@ -10,31 +10,36 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt</h1>
|
||||
<p>Encrypt and share your text or files securely</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Securely Share Text and Files</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<section class="card form-group" style="padding: 50px 30px;">
|
||||
<h2 style="color: #ff0066; font-size: 2.5em;">❓ 404 - Not Found</h2>
|
||||
<p class="mt-4" style="font-size: 1.2em; color: #cccccc;">
|
||||
Whoops! That page doesn't seem to exist. Maybe it got encrypted? 🧩🔐
|
||||
<h2 style="color: #ff0066; font-size: 2.5em;">404 - Not Found</h2>
|
||||
<p style="font-size: 1.2em; color: #cccccc;">
|
||||
Whoops! That page doesn't seem to exist. Maybe it got encrypted?
|
||||
</p>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="button-group mt-4">
|
||||
<div class="button-group">
|
||||
<a href="{{ url_for('index') }}">
|
||||
<button type="button">⬅️ Return Home</button>
|
||||
<button type="button">Return Home</button>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+13
-8
@@ -10,32 +10,37 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt</h1>
|
||||
<p>Encrypt and share your text or files securely</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Securely Share Text and Files</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<section class="card form-group" style="padding: 50px 30px;">
|
||||
<h2 style="color: #ff3300; font-size: 2.5em;">💥 500 - Server Error</h2>
|
||||
<h2 style="color: #ff3300; font-size: 2.5em;">500 - Server Error</h2>
|
||||
<p class="mt-4" style="font-size: 1.2em; color: #cccccc;">
|
||||
Uh oh! The ghosts chomped the server wires. 🧟♂️👾
|
||||
Uh oh! The ghosts chomped the server wires.
|
||||
We're working on patching it up.
|
||||
</p>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="button-group mt-4">
|
||||
<a href="{{ url_for('index') }}">
|
||||
<button type="button">⬅️ Return Home</button>
|
||||
<button type="button">Return Home</button>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+37
-37
@@ -10,24 +10,30 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt Admin Panel</h1>
|
||||
<p>Site Overview & Controls</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>ADMIN PANEL</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- Site Map Section -->
|
||||
<section id="sitemap-section" class="card form-group">
|
||||
<h2>💾 Server Management</h2>
|
||||
<h2>Server Management</h2>
|
||||
|
||||
<div class="sitemap-header">
|
||||
<button onclick="toggleSitemap()" style="margin-bottom: 10px;">Show Site Map</button>
|
||||
@@ -36,32 +42,25 @@
|
||||
<div id="sitemap-list" class="sitemap-content" style="display: none;">
|
||||
<ul style="list-style: none; padding-left: 0;">
|
||||
{% for route in routes %}
|
||||
<li style="margin-bottom: 5px;">🔗 <code>{{ route }}</code></li>
|
||||
<li style="margin-bottom: 5px;"><code>{{ route }}</code></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="button-group">
|
||||
<button onclick="restartServer()">🔁 Restart Server</button>
|
||||
<a href="{{ url_for('admin_logout') }}">
|
||||
<button type="button">🚪 Log Out</button>
|
||||
</a>
|
||||
<!-- Server Management Buttons -->
|
||||
<div class="admin-button-grid">
|
||||
<button onclick="restartServer()">Restart Server</button>
|
||||
<form action="{{ url_for('admin_logout') }}" method="GET" style="display: inline;">
|
||||
<button type="submit">Log Out</button>
|
||||
</form>
|
||||
<button onclick="updateServer()">Update Server</button>
|
||||
<form action="{{ url_for('admin_settings') }}" method="GET" style="display: inline;">
|
||||
<button type="submit">Settings</button>
|
||||
</form>
|
||||
<button onclick="resetAdmin()" class="danger-button">Reset Admin</button>
|
||||
<button onclick="clearUploads()" class="danger-button">Clear PacShare</button>
|
||||
</div>
|
||||
|
||||
<!-- Update and Settings Buttons -->
|
||||
<div class="button-group">
|
||||
<button onclick="updateServer()">🔁 Pull Latest Changes</button>
|
||||
<a href="{{ url_for('admin_settings') }}">
|
||||
<button type="button">🛠️ Manage Upload Settings</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Admin Reset and Clear Uploads Buttons -->
|
||||
<div class="button-group">
|
||||
<button onclick="resetAdmin()" class="danger-button">⚠️ Reset Admin</button>
|
||||
<button onclick="clearUploads()" class="danger-button">🗑 Clear Uploaded Files</button>
|
||||
</div>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
<div id="admin-feedback" class="copy-feedback" style="display: none;"></div>
|
||||
@@ -69,7 +68,7 @@
|
||||
|
||||
<!-- Password Change Section -->
|
||||
<section id="password-change-section" class="card form-group">
|
||||
<h2>🔑 Change Admin Password</h2>
|
||||
<h2>Change Admin Password</h2>
|
||||
|
||||
<!-- Password Feedback -->
|
||||
{% with messages = get_flashed_messages(with_categories=true, category_filter=['password-feedback']) %}
|
||||
@@ -88,19 +87,20 @@
|
||||
|
||||
<!-- Server Status Section -->
|
||||
<section id="server-status-section" class="card form-group">
|
||||
<h2>📊 Server Status</h2>
|
||||
<ul style="list-style: none; padding-left: 0;">
|
||||
<li>🕒 Uptime: <code>{{ server_info.uptime }}</code></li>
|
||||
<li>📅 Server Time: <code>{{ server_info.time }}</code></li>
|
||||
<li>🐍 Python Version: <code>{{ server_info.python }}</code></li>
|
||||
<li>⚙️ Flask Debug Mode: <code>{{ server_info.debug }}</code></li>
|
||||
<h2>Server Status</h2>
|
||||
<ul class="status-list">
|
||||
<li>Uptime: <code>{{ server_info.uptime }}</code></li>
|
||||
<li>Server Time: <code>{{ server_info.server_time }}</code></li>
|
||||
<li>Python Version: <code>{{ server_info.python_version }}</code></li>
|
||||
<li>Flask Debug Mode: <code>{{ server_info.debug_mode }}</code></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- Server Logs Section -->
|
||||
<section id="server-logs-section" class="card form-group">
|
||||
<h2>📜 Server Logs</h2>
|
||||
<button onclick="toggleLogs()" style="margin-bottom: 10px;">🔽 Show/Hide Logs</button>
|
||||
<h2>Server Logs</h2>
|
||||
<button onclick="toggleLogs()" style="margin-bottom: 10px;">Show/Hide Logs</button>
|
||||
<div id="logLoader" style="display: none; margin-bottom: 10px;">Loading logs...</div>
|
||||
<pre id="logContainer" style="display: none;"></pre>
|
||||
</section>
|
||||
@@ -123,10 +123,10 @@
|
||||
const logLoader = document.getElementById('logLoader');
|
||||
if (logContainer.style.display === 'none') {
|
||||
logLoader.style.display = 'block';
|
||||
const response = await fetch('{{ url_for('admin_logs') }}');
|
||||
const response = await fetch("{{ url_for('admin_logs') }}");
|
||||
const data = await response.json();
|
||||
logLoader.style.display = 'none';
|
||||
logContainer.innerText = data.logs.join('\\n');
|
||||
logContainer.innerText = data.logs.join('\n');
|
||||
logContainer.style.display = 'block';
|
||||
} else {
|
||||
logContainer.style.display = 'none';
|
||||
|
||||
@@ -10,24 +10,28 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt Admin</h1>
|
||||
<p>Administrator Login</p>
|
||||
</header>
|
||||
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Admin Login</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- Login Form Section -->
|
||||
<section class="card form-group">
|
||||
<h2>🔑 Admin Login</h2>
|
||||
<h2>Admin Login</h2>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -41,7 +45,7 @@
|
||||
<input type="text" name="username" placeholder="Username" required />
|
||||
<input type="password" name="password" placeholder="Password" required />
|
||||
<div class="button-group mt-3">
|
||||
<button type="submit">🚪 Log In</button>
|
||||
<button type="submit">Log In</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
@@ -10,21 +10,27 @@
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt Admin Settings</h1>
|
||||
<p>Manage upload configuration</p>
|
||||
</header>
|
||||
|
||||
<!-- Header -->
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Server Settings</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- Settings Form Section -->
|
||||
<section class="card form-group">
|
||||
<h2>⚙️ Upload Settings</h2>
|
||||
<h2>Upload Settings</h2>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -50,9 +56,9 @@
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="button-group mt-4">
|
||||
<button type="submit">💾 Save Settings</button>
|
||||
<button type="submit">Save Settings</button>
|
||||
<a href="{{ url_for('admin_page') }}">
|
||||
<button type="button">⬅️ Back to Admin Panel</button>
|
||||
<button type="button">Back to Admin Panel</button>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -4,30 +4,35 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="PacCrypt - Admin Setup" />
|
||||
<title>Admin Setup - PacCrypt</title>
|
||||
<title>PacCrypt - Admin Setup</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" href="{{ url_for('static', filename='img/PacCrypt.png') }}" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt Admin</h1>
|
||||
<p>Admin Setup</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Admin Setup</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- Setup Form Section -->
|
||||
<section class="card form-group">
|
||||
<h2>🛡️ Create Admin Account</h2>
|
||||
<h2>Create Admin Account</h2>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -41,7 +46,7 @@
|
||||
<input type="text" name="username" placeholder="Username" required />
|
||||
<input type="password" name="password" placeholder="Password" required />
|
||||
<div class="button-group mt-3">
|
||||
<button type="submit">📝 Set Credentials</button>
|
||||
<button type="submit">Set Credentials</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
+35
-30
@@ -4,35 +4,40 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="PacCrypt - Secure text and file encryption with password generation" />
|
||||
<title>PacCrypt - Encrypt and share your text or files securely</title>
|
||||
<title>PacCrypt</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" href="{{ url_for('static', filename='img/PacCrypt.png') }}" type="image/png" />
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Scripts -->
|
||||
<script type="module" src="{{ url_for('static', filename='js/main.js') }}" defer></script>
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt</h1>
|
||||
<p>Encrypt and share your text or files securely</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Securely Share Text and Files</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- Password Generator Section -->
|
||||
<section id="password-generator-section" class="card form-group">
|
||||
<h2>🔑 Password Generator</h2>
|
||||
<h2>Password Generator</h2>
|
||||
<div class="form-group">
|
||||
<input type="text" id="generated-password" readonly />
|
||||
<div class="button-group">
|
||||
<button type="button" id="generate-btn">🎲 Generate</button>
|
||||
<button type="button" id="copy-btn">📋 Copy Password</button>
|
||||
<button type="button" id="generate-btn">Generate</button>
|
||||
<button type="button" id="copy-btn">Copy Password</button>
|
||||
</div>
|
||||
<div id="password-copy-feedback" class="copy-feedback">Password copied to clipboard!</div>
|
||||
</div>
|
||||
@@ -44,7 +49,7 @@
|
||||
<canvas id="pacmanCanvas" width="800" height="600"></canvas>
|
||||
</div>
|
||||
<audio id="chomp-sound" src="{{ url_for('static', filename='audio/chomp.mp3') }}"></audio>
|
||||
<div class="button-group">
|
||||
<div class="button-group" style="margin-top: 6px;">
|
||||
<button type="button" onclick="resetGame()">Restart Game</button>
|
||||
<button type="button" onclick="exitGame()">Exit Game</button>
|
||||
</div>
|
||||
@@ -52,7 +57,7 @@
|
||||
|
||||
<!-- Encryption/Decryption Section -->
|
||||
<section id="encoding-section" class="card form-group">
|
||||
<h2>🔐 Encrypt & Decrypt</h2>
|
||||
<h2>Encrypt & Decrypt</h2>
|
||||
<form id="crypto-form" class="form-group">
|
||||
<!-- Encryption Type Selection -->
|
||||
<div class="form-group">
|
||||
@@ -65,13 +70,14 @@
|
||||
|
||||
<!-- Operation Toggle -->
|
||||
<div class="toggle-container">
|
||||
<span id="toggle-left-label">Encrypt</span>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="operation-toggle" />
|
||||
<span class="slider round"></span>
|
||||
<span class="toggle-label">Encrypt</span>
|
||||
<label class="material-switch">
|
||||
<input type="checkbox" id="operation-toggle">
|
||||
<span class="material-slider"></span>
|
||||
</label>
|
||||
<span id="toggle-right-label">Decrypt</span>
|
||||
</div>
|
||||
<span class="toggle-label">Decrypt</span>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Text Input Section -->
|
||||
<div id="text-section" class="form-group">
|
||||
@@ -86,19 +92,19 @@
|
||||
<!-- File Input Section -->
|
||||
<div id="file-section" class="form-group" style="display: none;">
|
||||
<input type="file" id="file-input" />
|
||||
<button type="button" id="remove-file-btn">🗑 Remove File</button>
|
||||
<button type="button" id="remove-file-btn">Remove File</button>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="button-group">
|
||||
<button type="submit">⚡ Execute</button>
|
||||
<button type="button" id="copy-output-btn">📋 Copy Output</button>
|
||||
<button type="submit">Execute</button>
|
||||
<button type="button" id="copy-output-btn">Copy Output</button>
|
||||
</div>
|
||||
|
||||
<!-- Output Section -->
|
||||
<textarea id="output-text" readonly placeholder="Encrypted/Decrypted text will appear here..."></textarea>
|
||||
<textarea id="output-text" readonly placeholder="Encrypted/Decrypted Output"></textarea>
|
||||
<div class="button-group">
|
||||
<button type="button" id="clear-all-btn" class="danger-button">🧹 Clear All</button>
|
||||
<button type="button" id="clear-all-btn" class="danger-button">Clear All</button>
|
||||
</div>
|
||||
<div id="output-copy-feedback" class="copy-feedback">Text copied to clipboard!</div>
|
||||
</form>
|
||||
@@ -106,9 +112,8 @@
|
||||
|
||||
<!-- File Sharing Section -->
|
||||
<section id="sharing-section" class="card form-group">
|
||||
<h2>📤 PacCrypt Share</h2>
|
||||
<h3>Securely share encrypted files.</h3>
|
||||
<p>Do not lose your passwords, data will be lost forever!</p>
|
||||
<h2 style="margin-bottom: unset;">PacShare</h2>
|
||||
<p style="margin-top: unset;">Securely share encrypted files.</p>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -120,8 +125,7 @@
|
||||
{% if "pickup" in message %}
|
||||
<div class="share-link-container">
|
||||
<a id="share-link" href="{{ message.split(' at ')[1] }}" target="_blank">{{ message.split(" at ")[1] }}</a>
|
||||
<!--- <span id="share-link">{{ message.split(" at ")[1] }}</span> --->
|
||||
<button type="button" id="copy-share-btn">📋 Copy Link</button>
|
||||
<button type="button" onclick="copyShareLink()">Copy Link</button>
|
||||
<div id="shared-link-feedback" class="copy-feedback">Link copied to clipboard!</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -132,11 +136,12 @@
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
|
||||
<!-- File Upload Form -->
|
||||
<!-- Share Link Container (initially hidden) -->
|
||||
<div class="share-link-container" id="share-link-container" style="display: none;">
|
||||
<a id="share-link" href="#" target="_blank"></a>
|
||||
<button type="button" id="copy-share-btn">📋 Copy Link</button>
|
||||
<button type="button" id="copy-share-btn">Copy Link</button>
|
||||
<div id="shared-link-feedback" class="copy-feedback">Link copied to clipboard!</div>
|
||||
</div>
|
||||
<form method="POST" enctype="multipart/form-data" class="form-group" id="upload-form">
|
||||
@@ -144,10 +149,10 @@
|
||||
<input type="password" name="enc_password" placeholder="Encryption/Decryption Password" required />
|
||||
<input type="password" name="pickup_password" placeholder="Pickup Password" required />
|
||||
<div class="button-group">
|
||||
<button type="submit">🔒 Upload and Generate Link</button>
|
||||
<button type="submit">Upload and Generate Link</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p style="color: #9c0000;">BOTH PASSWORDS ARE REQUIRED FOR PICKUP</p>
|
||||
<script>
|
||||
document.getElementById('upload-form').addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
+13
-8
@@ -11,20 +11,25 @@
|
||||
|
||||
<!-- Stylesheets -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
<body class="dark">
|
||||
<!-- Header -->
|
||||
<header class="card">
|
||||
<h1>PacCrypt</h1>
|
||||
<p>Secure File Pickup and Decryption</p>
|
||||
</header>
|
||||
<header class="card logo-header">
|
||||
<div class="logo-container">
|
||||
<img src="{{ url_for('static', filename='img/PacCrypt.png') }}" alt="PacCrypt Logo" />
|
||||
<div class="logo-text">
|
||||
<h1>PACCRYPT</h1>
|
||||
<p>Encrypted File Pickup</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
<!-- File Pickup Section -->
|
||||
<section id="pickup-section" class="card form-group">
|
||||
<h2>🔐 File Pickup</h2>
|
||||
<h2>File Pickup</h2>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
@@ -61,14 +66,14 @@
|
||||
</div>
|
||||
|
||||
<div class="button-group">
|
||||
<button type="submit">📥 Decrypt and Download</button>
|
||||
<button type="submit">Decrypt and Download</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<!-- Security Notice Section -->
|
||||
<section id="security-notice-section" class="card form-group">
|
||||
<h2>🛡️ Security Notice</h2>
|
||||
<h2>Security Notice</h2>
|
||||
<p style="color: #00ff99; text-align: center;">
|
||||
Make sure you're on the correct domain before entering any passwords.<br>
|
||||
Your file will be permanently deleted after download.
|
||||
|
||||
Reference in New Issue
Block a user