Add Two-Factor Authentication (2FA) support and key management features

- Implemented 2FA management in admin panel with enable/disable options.
- Added QR code display for 2FA setup and input for TOTP codes in login and pickup forms.
- Introduced key management section for generating, loading, and clearing RSA key pairs.
- Enhanced file upload and sharing functionality with optional 2FA.
- Added buttons for switching between development and production modes in admin panel.
- Updated API documentation to reflect new 2FA and key management features.
This commit is contained in:
Tyler Sammons
2025-09-14 13:10:04 -10:00
parent 36cf8f18f8
commit 5d568f7f89
19 changed files with 2625 additions and 990 deletions
+37 -11
View File
@@ -4,6 +4,7 @@ import signal
import time
import sys
import psutil
import platform
APP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../app.py"))
@@ -16,21 +17,37 @@ def log(msg):
def start_dev():
env = os.environ.copy()
env["PRODUCTION"] = "false"
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=sys.stdout,
stderr=sys.stderr
)
if platform.system() == "Windows":
return subprocess.Popen(
["python", APP_PATH],
env=env,
stdout=sys.stdout,
stderr=sys.stderr
)
else:
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=sys.stdout,
stderr=sys.stderr
)
def stop_by_port(port=5000):
for proc in psutil.process_iter(["pid", "name"]):
try:
for conn in proc.connections(kind="inet"):
for conn in proc.net_connections(kind="inet"):
if conn.laddr.port == port:
log(f"[*] Killing process {proc.pid} using port {port}")
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
if platform.system() == "Windows":
proc.terminate()
try:
proc.wait(timeout=5)
except psutil.TimeoutExpired:
proc.kill()
else:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
return
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
continue
@@ -39,8 +56,17 @@ def stop_by_port(port=5000):
def main():
log("[*] Restarting PacCrypt in DEVELOPMENT mode...")
stop_by_port()
time.sleep(1)
start_dev()
time.sleep(2)
proc = start_dev()
if proc:
log(f"[*] Started development server with PID {proc.pid}")
try:
proc.wait()
except KeyboardInterrupt:
log("[*] Interrupted, stopping server...")
stop_by_port()
else:
log("[!] Failed to start development server")
if __name__ == "__main__":
main()
@@ -4,27 +4,44 @@ import signal
import time
import sys
import psutil
import platform
APP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../app.py"))
def start_prod():
env = os.environ.copy()
env["PRODUCTION"] = "true"
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
if platform.system() == "Windows":
return subprocess.Popen(
["python", APP_PATH],
env=env,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
else:
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
def stop_by_port(port=5000):
for proc in psutil.process_iter(["pid", "name"]):
try:
for conn in proc.connections(kind="inet"):
for conn in proc.net_connections(kind="inet"):
if conn.laddr.port == port:
print(f"[*] Killing process {proc.pid} using port {port}")
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
if platform.system() == "Windows":
proc.terminate()
try:
proc.wait(timeout=5)
except psutil.TimeoutExpired:
proc.kill()
else:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
return
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
continue
@@ -33,8 +50,17 @@ def stop_by_port(port=5000):
def main():
print("[*] Restarting PacCrypt in PRODUCTION mode with Waitress...")
stop_by_port()
time.sleep(1)
start_prod()
time.sleep(2)
proc = start_prod()
if proc:
print(f"[*] Started production server with PID {proc.pid}")
try:
proc.wait()
except KeyboardInterrupt:
print("[*] Interrupted, stopping server...")
stop_by_port()
else:
print("[!] Failed to start production server")
if __name__ == "__main__":
main()
+17 -7
View File
@@ -2,6 +2,7 @@ import os
import subprocess
import time
import sys
import platform
APP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../app.py"))
@@ -14,13 +15,22 @@ def log(msg):
def start_dev():
env = os.environ.copy()
env["PRODUCTION"] = "false"
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=sys.stdout,
stderr=sys.stderr
)
if platform.system() == "Windows":
return subprocess.Popen(
["python", APP_PATH],
env=env,
stdout=sys.stdout,
stderr=sys.stderr
)
else:
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=sys.stdout,
stderr=sys.stderr
)
def main():
log("[*] Starting PacCrypt in DEVELOPMENT mode...")
+17 -7
View File
@@ -2,19 +2,29 @@ import os
import subprocess
import time
import sys
import platform
APP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../app.py"))
def start_prod():
env = os.environ.copy()
env["PRODUCTION"] = "true"
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
if platform.system() == "Windows":
return subprocess.Popen(
["python", APP_PATH],
env=env,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
else:
return subprocess.Popen(
["python3", APP_PATH],
env=env,
preexec_fn=os.setsid,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
def main():
print("[*] Starting PacCrypt in PRODUCTION mode with Waitress...")
+10 -2
View File
@@ -1,6 +1,7 @@
import psutil
import os
import signal
import platform
DEBUG = True
@@ -11,10 +12,17 @@ def log(msg):
def stop_by_port(port=5000):
for proc in psutil.process_iter(["pid", "name"]):
try:
for conn in proc.connections(kind="inet"):
for conn in proc.net_connections(kind="inet"):
if conn.laddr.port == port:
log(f"[*] Killing process {proc.pid} using port {port}")
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
if platform.system() == "Windows":
proc.terminate()
try:
proc.wait(timeout=5)
except psutil.TimeoutExpired:
proc.kill()
else:
os.killpg(os.getpgid(proc.pid), signal.SIGTERM)
return
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
continue