first commit

This commit is contained in:
usernames122
2025-08-10 23:42:02 +02:00
commit 877a246134
24 changed files with 957 additions and 0 deletions

122
pages/findings.py Normal file
View File

@@ -0,0 +1,122 @@
from flask import Blueprint, render_template
from models import Finding, User
from sqlalchemy import desc
findings_bp = Blueprint('findings', __name__, url_prefix='/findings')
@findings_bp.route('/')
def latest_findings():
latest = Finding.query.order_by(desc(Finding.find_time)).limit(20).all()
# Eager load user data if needed
user_map = {u.id: u for u in User.query.filter(User.id.in_([f.found_by for f in latest])).all()}
return render_template('latest_findings.html', findings=latest, user_map=user_map)
@findings_bp.route('/<int:finding_id>')
def finding_detail(finding_id):
finding = Finding.query.get_or_404(finding_id)
user = User.query.get(finding.found_by)
return render_template('finding_detail.html', finding=finding, user=user)
import requests
from flask import Blueprint, render_template, request, session, flash, redirect, url_for
from datetime import datetime
from bs4 import BeautifulSoup
from models import db, Finding
@findings_bp.route('/create', methods=['GET', 'POST'])
def create_finding():
if not session.get('loggedin'):
flash("Please log in to create a finding.", "warning")
return redirect(url_for('login.login'))
if request.method == 'POST':
path = request.form.get('path', '').strip()
lorekey = request.form.get('lorekey', '').strip()
# Validate inputs
if not path and not lorekey:
flash("Title, Path, and Lorekey are required.", "danger")
return render_template('create_finding.html', path=path, lorekey=lorekey)
# Validate path exists on laminax.org (non-404)
if path:
try:
path_res = requests.get(f'https://laminax.org/{path}')
if path_res.status_code == 404:
flash(f"The path '{path}' does not exist on laminax.org.", "danger")
return render_template('create_finding.html', path=path, lorekey=lorekey)
else:
soup = BeautifulSoup(path_res.text, 'html.parser')
for hr in soup.find_all('hr'):
hr.replace_with('----------')
content_text = soup.get_text(separator='\n')
content_text = soup.get_text(separator='\n')
# Get title element
title = (soup.title.string if soup.title else None) or "No title found"
# Save finding
new_finding = Finding(
title=f'https://laminax.org/{path}',
path=f'https://laminax.org/{path}',
find_time=datetime.utcnow(),
found_by=session.get('id'),
content_preview=content_text
)
db.session.add(new_finding)
db.session.commit()
flash("Finding created successfully!", "success")
return redirect("/findings/"+str(new_finding.id)) # Resort to manually redirecting for now
except Exception as e:
flash(f"Error validating path: {e}", "danger")
return render_template('create_finding.html', path=path, lorekey=lorekey)
# Check lorekey with external service
if lorekey:
try:
res = requests.post('https://worker.laminax.org/check-password', json={"password": lorekey})
if res.ok:
data = res.json()
if data.get('redirect'):
redirect_url = data['redirect']
# Fetch redirect page content
page_res = requests.get(redirect_url)
title = None
if page_res.ok:
# Parse html and replace all <hr> with 10 dashes using bs4
soup = BeautifulSoup(page_res.text, 'html.parser')
for hr in soup.find_all('hr'):
hr.replace_with('----------')
content_text = soup.get_text(separator='\n')
# Get title element
title = (soup.title.string if soup.title else None) or "No title found"
else:
content_text = None
title = "Unable to fetch redirect page content."
# Save finding
new_finding = Finding(
title=redirect_url,
path=redirect_url,
find_time=datetime.utcnow(),
found_by=session.get('id'),
content_preview=content_text
)
db.session.add(new_finding)
db.session.commit()
flash("Finding created successfully!", "success")
return redirect(url_for('findings.finding_detail', finding_id=new_finding.id))
else:
flash("Lorekey check failed or no redirect returned.", "danger")
elif res.status_code == 401:
flash("Invalid Lorekey provided.", "danger")
else:
flash("Lorekey service error, try again later.", "danger")
except Exception as e:
flash(f"An error occurred: {e}", "danger")
# GET or fallback render
return render_template('create_finding.html')

7
pages/index.py Normal file
View File

@@ -0,0 +1,7 @@
from flask import Blueprint, render_template
from models import db, User
index_bp = Blueprint('index', __name__)
@index_bp.route('/')
def index():
return render_template('home.html',users=User.query.limit(20).all()) # or your index page template

56
pages/login.py Normal file
View File

@@ -0,0 +1,56 @@
from flask import Blueprint, render_template, request, redirect, url_for, session
from werkzeug.security import check_password_hash
from models import db, User
login_bp = Blueprint('login', __name__, url_prefix='/login')
@login_bp.route('/', methods=['GET', 'POST'])
def login():
if session.get('loggedin'):
return redirect(url_for('index.index'))
username = ""
username_err = ""
password_err = ""
login_err = ""
if request.method == 'POST':
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
if not username:
username_err = "Please enter username."
if not password:
password_err = "Please enter your password."
if not username_err and not password_err:
# Admin bypass (same as before) but don't do this in production!
if False: # username == "adm" and password == "dont add this in please":
session['loggedin'] = True
session['id'] = -1
session['username'] = "Admin"
return redirect(url_for('index.index'))
# Query User via SQLAlchemy
user = User.query.filter_by(username=username).first()
if user:
# Here you need to store hashed passwords somewhere
# Your User model doesn't have a password field yet, so let's assume:
# You should add it like: password = db.Column(db.String(128), nullable=False)
# For now, assuming you have a password attribute
if hasattr(user, 'password') and check_password_hash(user.password, password):
session['loggedin'] = True
session['id'] = user.id
session['username'] = user.username
return redirect(url_for('index.index'))
else:
login_err = "Invalid username or password."
else:
login_err = "Invalid username or password."
return render_template('login.html',
username=username,
username_err=username_err,
password_err=password_err,
login_err=login_err)

8
pages/logout.py Normal file
View File

@@ -0,0 +1,8 @@
from flask import Blueprint, session, redirect, url_for
logout_bp = Blueprint('logout', __name__)
@logout_bp.route('/logout')
def logout():
session.clear() # Clear all session data
return redirect(url_for('login.login')) # Redirect to login page

28
pages/profile.py Normal file
View File

@@ -0,0 +1,28 @@
from flask import Blueprint, render_template, session, redirect, url_for
from models import User, Finding
profile_bp = Blueprint('profile', __name__, url_prefix='/profile')
@profile_bp.route('/')
def my_findings():
# Check if user is logged in
if not session.get('loggedin'):
return redirect(url_for('login.login'))
user_id = session.get('id')
user = User.query.get(user_id)
if not user:
return redirect(url_for('login.login'))
# Get all findings by this user, exclude content_preview
findings = Finding.query.filter_by(found_by=user_id).all()
return render_template('profile.html', user=user, findings=findings)
@profile_bp.route('/get/<int:id>', methods=['GET'])
def view_profile(id):
user = User.query.get(id)
if not user:
return "User not found. Please try again later.",
findings = Finding.query.filter_by(found_by=id).all()
return render_template('view_profile.html', user=user, findings=findings)

68
pages/register.py Normal file
View File

@@ -0,0 +1,68 @@
import re
from datetime import datetime
from flask import Blueprint, render_template, request, redirect, url_for, flash
from werkzeug.security import generate_password_hash
from models import db, User
register_bp = Blueprint('register', __name__, url_prefix='/register')
@register_bp.route('/', methods=['GET', 'POST'])
def register():
username = ''
password = ''
confirm_password = ''
username_err = ''
password_err = ''
confirm_password_err = ''
if request.method == 'POST':
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
confirm_password = request.form.get('confirm_password', '').strip()
# Validate username
if not username:
username_err = "Please enter a username."
elif not re.match(r'^[a-zA-Z0-9_]+$', username):
username_err = "Username can only contain letters, numbers, and underscores."
else:
# Check if username already exists
if User.query.filter_by(username=username).first():
username_err = "This username is already taken."
# Validate password
if not password:
password_err = "Please enter a password."
elif len(password) < 6:
password_err = "Password must have at least 6 characters."
# Validate confirm password
if not confirm_password:
confirm_password_err = "Please confirm password."
elif password != confirm_password:
confirm_password_err = "Password did not match."
# If no errors, insert new user
if not username_err and not password_err and not confirm_password_err:
hashed_password = generate_password_hash(password)
new_user = User(
username=username,
password=hashed_password,
register_time=datetime.utcnow()
)
try:
db.session.add(new_user)
db.session.commit()
flash("Registration successful! Please login.", "success")
return redirect(url_for('login.login'))
except Exception as e:
db.session.rollback()
flash("Oops! Something went wrong. Please try again.", "danger")
return render_template('register.html',
username=username,
password=password,
confirm_password=confirm_password,
username_err=username_err,
password_err=password_err,
confirm_password_err=confirm_password_err)