Compare commits

...

2 Commits

Author SHA1 Message Date
7f5c9202bb fix fix fix 2024-09-16 14:10:51 +02:00
2e5fd2024f this contains bug next commit is fix 2024-09-16 13:54:54 +02:00
5 changed files with 55 additions and 120 deletions

34
app.py
View File

@ -233,6 +233,8 @@ def serve_user_page(username, filename=None):
@app.route('/<vanity>/<password>', methods=['GET', 'POST']) @app.route('/<vanity>/<password>', methods=['GET', 'POST'])
@app.route('/<vanity>/download', methods=['GET', 'POST']) @app.route('/<vanity>/download', methods=['GET', 'POST'])
@app.route('/<vanity>/download/<password>', methods=['GET', 'POST']) @app.route('/<vanity>/download/<password>', methods=['GET', 'POST'])
@app.route('/<vanity>/raw', methods=['GET', 'POST'])
@app.route('/<vanity>/raw/<password>', methods=['GET', 'POST'])
def redirect_vanity(vanity, password=None): def redirect_vanity(vanity, password=None):
app.logger.info(f"Accessing redirect_vanity: vanity={vanity}, password={password}") app.logger.info(f"Accessing redirect_vanity: vanity={vanity}, password={password}")
app.logger.info(f"Request path: {request.path}") app.logger.info(f"Request path: {request.path}")
@ -245,6 +247,7 @@ def redirect_vanity(vanity, password=None):
cursor = db.cursor() cursor = db.cursor()
is_download = 'download' in request.path is_download = 'download' in request.path
is_raw = 'raw' in request.path
# First, try to find the content with the full vanity (including extension) # First, try to find the content with the full vanity (including extension)
cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity = ?", (vanity,)) cursor.execute("SELECT content.*, users.username FROM content LEFT JOIN users ON content.user_id = users.id WHERE content.vanity = ?", (vanity,))
@ -272,22 +275,29 @@ def redirect_vanity(vanity, password=None):
elif request.method == 'POST': elif request.method == 'POST':
entered_password = request.form.get('password') entered_password = request.form.get('password')
if entered_password != stored_password: if entered_password != stored_password:
return render_template('password_prompt.html', vanity=vanity, error="Incorrect password") return render_template('password_prompt.html', vanity=vanity, error="Incorrect password", content_type=content_type)
password = entered_password # Set the password for use in raw_url
else: else:
return render_template('password_prompt.html', vanity=vanity, error=None) return render_template('password_prompt.html', vanity=vanity, error=None, content_type=content_type)
if content_type == 'url': if content_type == 'url':
return render_template('og_shorturl.html', long_url=content_data, username=username, created_at=created_at) return render_template('og_shorturl.html', long_url=content_data, username=username, created_at=created_at, vanity=vanity, is_private=is_private)
elif content_type == 'file': elif content_type == 'file':
file_path = os.path.join(app.config['UPLOAD_FOLDER'], content_data) file_path = os.path.join(app.config['UPLOAD_FOLDER'], content_data)
if os.path.exists(file_path): if os.path.exists(file_path):
file_size = os.path.getsize(file_path) file_size = os.path.getsize(file_path)
file_extension = os.path.splitext(content_data)[1].lower() file_extension = os.path.splitext(content_data)[1].lower()
is_embeddable = file_extension in ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.pdf'] is_embeddable = file_extension in ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.pdf']
file_url = url_for('redirect_vanity', vanity=vanity, _external=True) file_url = f"{request.scheme}://{request.host}/{vanity}"
raw_url = f"{file_url}/raw"
if is_private and password:
raw_url += f'/{password}'
if is_download: if is_download:
return send_file(file_path, as_attachment=True) return send_file(file_path, as_attachment=True)
elif is_raw:
return send_file(file_path)
else: else:
return render_template('file_info.html', return render_template('file_info.html',
filename=content_data, filename=content_data,
@ -296,8 +306,11 @@ def redirect_vanity(vanity, password=None):
created_at=created_at, created_at=created_at,
is_embeddable=is_embeddable, is_embeddable=is_embeddable,
file_url=file_url, file_url=file_url,
raw_url=raw_url,
vanity=vanity, vanity=vanity,
user_id=user_id) user_id=user_id,
is_private=is_private,
password=password)
elif content_type == 'pastebin': elif content_type == 'pastebin':
try: try:
lexer = guess_lexer(content_data) lexer = guess_lexer(content_data)
@ -458,7 +471,7 @@ def user_files(username, subpath=''):
uploads = [] uploads = []
for upload in user_uploads: for upload in user_uploads:
vanity, content_type, data, created_at, _, is_private = upload[:6] vanity, content_type, data, created_at, _, is_private = upload[:6]
url = url_for('redirect_vanity', vanity=vanity, _external=True) url = f"{request.scheme}://{request.host}/{vanity}"
uploads.append({ uploads.append({
'type': content_type, 'type': content_type,
'vanity': vanity, 'vanity': vanity,
@ -466,7 +479,7 @@ def user_files(username, subpath=''):
'created_at': created_at, 'created_at': created_at,
'is_private': is_private, 'is_private': is_private,
'url': url, 'url': url,
'download_url': url + '/download' if content_type == 'file' else None 'download_url': f"{url}/download" if content_type == 'file' else None
}) })
parent_folder = os.path.dirname(subpath.rstrip('/')) if subpath else None parent_folder = os.path.dirname(subpath.rstrip('/')) if subpath else None
@ -680,7 +693,7 @@ def upload_pastebin():
inserted_data = cursor.fetchone() inserted_data = cursor.fetchone()
print(f"Inserted data: {inserted_data}") print(f"Inserted data: {inserted_data}")
short_url = url_for('redirect_vanity', vanity=vanity, _external=True) short_url = f"{request.scheme}://{request.host}/{vanity}"
deletion_url = url_for('delete_content', vanity=vanity, _external=True) deletion_url = url_for('delete_content', vanity=vanity, _external=True)
print(f"Generated short URL: {short_url}") print(f"Generated short URL: {short_url}")
print(f"Generated deletion URL: {deletion_url}") print(f"Generated deletion URL: {deletion_url}")
@ -1172,12 +1185,11 @@ def upload_file():
app.logger.info("Generating URLs") app.logger.info("Generating URLs")
app.logger.info("Code: short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme)") app.logger.info("Code: short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme)")
short_url = url_for('redirect_vanity', vanity=vanity_with_extension, _external=True, _scheme=scheme) short_url = f"{scheme}://{request.host}/{vanity_with_extension}"
short_url = short_url.rstrip('/download') # Remove the '/download' suffix if present
app.logger.info(f"Generated short URL: {short_url}") app.logger.info(f"Generated short URL: {short_url}")
app.logger.info("Code: download_url = short_url + '/download'") app.logger.info("Code: download_url = short_url + '/download'")
download_url = short_url + '/download' download_url = f"{short_url}/download"
app.logger.info(f"Generated download URL: {download_url}") app.logger.info(f"Generated download URL: {download_url}")
app.logger.info("Code: deletion_url = url_for('delete_content', vanity=vanity_with_extension, _external=True, _scheme=scheme)") app.logger.info("Code: deletion_url = url_for('delete_content', vanity=vanity_with_extension, _external=True, _scheme=scheme)")

View File

@ -7,9 +7,9 @@
<meta property="og:title" content="{{ filename }}"> <meta property="og:title" content="{{ filename }}">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="{{ request.url }}"> <meta property="og:url" content="{{ request.url }}">
<meta property="og:description" content="File size: {{ file_size|filesizeformat }} | Uploaded by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}"> <meta property="og:description" content="File size: {{ file_size|filesizeformat }} | Uploaded by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}{% if is_private %} | Password Protected{% endif %}">
{% if is_embeddable %} {% if is_embeddable %}
<meta property="og:image" content="{{ file_url }}"> <meta property="og:image" content="{{ raw_url }}">
{% endif %} {% endif %}
<meta property="og:site_name" content="sxbin"> <meta property="og:site_name" content="sxbin">
<meta property="theme-color" content="#4CAF50"> <meta property="theme-color" content="#4CAF50">
@ -115,16 +115,16 @@
{% if is_embeddable %} {% if is_embeddable %}
<div class="embed-container"> <div class="embed-container">
{% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %} {% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %}
<img src="{{ file_url }}" alt="{{ filename }}"> <img src="{{ raw_url }}" alt="{{ filename }}">
{% elif filename.lower().endswith('.pdf') %} {% elif filename.lower().endswith('.pdf') %}
<embed src="{{ file_url }}" type="application/pdf" width="100%" height="600px"> <embed src="{{ raw_url }}" type="application/pdf" width="100%" height="600px">
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
<div class="btn-container"> <div class="btn-container">
<a href="{{ file_url }}/download" class="btn">Download</a> <a href="{{ file_url }}/download{% if password %}/{{ password }}{% endif %}" class="btn">Download</a>
<a href="{{ file_url }}" class="btn">View Raw</a> <a href="{{ raw_url }}" class="btn">View Raw</a>
{% if current_user.is_authenticated and current_user.id == user_id %} {% if current_user.is_authenticated and current_user.id == user_id %}
{% if filename.lower().endswith(('.txt', '.html', '.css', '.js', '.py', '.md')) or '.' not in filename %} {% if filename.lower().endswith(('.txt', '.html', '.css', '.js', '.py', '.md')) or '.' not in filename %}
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a> <a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a>

View File

@ -4,20 +4,21 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shortened URL - sxbin</title> <title>Shortened URL - sxbin</title>
<meta property="og:title" content="Shortened URL"> <meta property="og:title" content="Shortened URL - sxbin">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="{{ request.url }}"> <meta property="og:url" content="{{ request.url }}">
<meta property="og:description" content="Shortened link created by {{ username }} on {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}"> <meta property="og:description" content="Shortened URL {% if is_private %}(Password Protected){% endif %} | Created by: {{ username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
<meta property="og:site_name" content="sxbin"> <meta property="og:site_name" content="sxbin">
<meta property="theme-color" content="#4CAF50"> <meta property="theme-color" content="#4CAF50">
<meta http-equiv="refresh" content="0;url={{ long_url }}">
</head> </head>
<body> <body>
<h1>Shortened URL</h1> <h1>Shortened URL</h1>
<p>Redirecting to: {{ long_url }}</p> <p>Original URL: {{ long_url }}</p>
<p>Created by: {{ username }}</p> <p>Created by: {{ username }}</p>
<p>Date: {{ created_at.strftime('%Y-%m- <p>Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}</p>
{% if is_private %}
%d %H:%M:%S') }}</p> <p>This URL is password protected.</p>
{% endif %}
<a href="{{ url_for('redirect_vanity', vanity=vanity) }}">Access the URL</a>
</body> </body>
</html> </html>

View File

@ -3,104 +3,26 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enter Password</title> <title>Password Protected Content - sxbin</title>
<meta property="og:title" content="Password Protected Content - sxbin">
<meta property="og:type" content="website">
<meta property="og:url" content="{{ request.url }}">
<meta property="og:description" content="This {{ content_type }} is password protected. Enter the password to view.">
<meta property="og:site_name" content="sxbin">
<meta property="theme-color" content="#4CAF50">
<style> <style>
body { /* Add your styles here */
font-family: Arial, sans-serif;
background-color: #1a1a1a;
color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.container {
background-color: #2a2a2a;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
width: 300px;
}
h2 {
text-align: center;
color: #4CAF50;
}
form {
display: flex;
flex-direction: column;
}
input[type="password"] {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #4CAF50;
border-radius: 4px;
background-color: #333;
color: #f0f0f0;
}
.button-container {
display: flex;
justify-content: space-between;
}
button {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button[type="submit"] {
background-color: #4CAF50;
color: white;
}
button[type="button"] {
background-color: #888;
color: white;
}
.error {
color: #ff6b6b;
text-align: center;
margin-bottom: 10px;
}
.alert {
background-color: #ff6b6b;
color: white;
padding: 10px;
border-radius: 4px;
margin-bottom: 10px;
display: none;
}
</style> </style>
</head> </head>
<body> <body>
<div class="container"> <h1>Password Protected Content</h1>
<h2>This content is password protected</h2> <p>This {{ content_type }} is password protected. Please enter the password to view.</p>
<div id="errorAlert" class="alert"> {% if error %}
Incorrect password. Please try again. <p style="color: red;">{{ error }}</p>
</div> {% endif %}
<form method="POST" action="{{ url_for('redirect_vanity', vanity=vanity) }}"> <form method="POST">
<input type="password" name="password" placeholder="Enter password"> <input type="password" name="password" required>
<button type="submit">Submit</button> <button type="submit">Submit</button>
</form> </form>
</div>
<script>
function validatePassword() {
var password = document.getElementById('password').value;
if (password.trim() === '') {
document.getElementById('errorAlert').style.display = 'block';
document.getElementById('errorAlert').textContent = 'Please enter a password.';
return false;
}
return true;
}
{% if error %}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('errorAlert').style.display = 'block';
document.getElementById('errorAlert').textContent = '{{ error }}';
});
{% endif %}
</script>
</body> </body>
</html> </html>

View File

@ -7,7 +7,7 @@
<meta property="og:title" content="Pastebin {{ vanity }} - sxbin"> <meta property="og:title" content="Pastebin {{ vanity }} - sxbin">
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:url" content="{{ request.url }}"> <meta property="og:url" content="{{ request.url }}">
<meta property="og:description" content="Uploaded by: {{ content.username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}"> <meta property="og:description" content="Pastebin{% if is_private %} (Password Protected){% endif %} | Uploaded by: {{ content.username }} | Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}">
<meta property="og:site_name" content="sxbin"> <meta property="og:site_name" content="sxbin">
<meta property="theme-color" content="#4CAF50"> <meta property="theme-color" content="#4CAF50">
<style> <style>