forked from spitkov/sxbin
opengraph fix v2
This commit is contained in:
parent
a2544633e6
commit
67bdc5c325
50
app.py
50
app.py
@ -233,13 +233,15 @@ 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 vanity: {vanity}, password: {password}")
|
app.logger.info(f"Accessing vanity: {vanity}, password: {password}")
|
||||||
db = get_db()
|
db = get_db()
|
||||||
cursor = db.cursor()
|
cursor = db.cursor()
|
||||||
|
|
||||||
# Check if it's a download request
|
|
||||||
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,))
|
||||||
@ -255,11 +257,9 @@ def redirect_vanity(vanity, password=None):
|
|||||||
content_type, content_data, created_at, user_id, is_private, stored_password, username = content[1], content[2], content[3], content[4], content[5], content[6], content[7]
|
content_type, content_data, created_at, user_id, is_private, stored_password, username = content[1], content[2], content[3], content[4], content[5], content[6], content[7]
|
||||||
app.logger.info(f"Content found: type={content_type}, data={content_data}, is_private={is_private}")
|
app.logger.info(f"Content found: type={content_type}, data={content_data}, is_private={is_private}")
|
||||||
|
|
||||||
# Convert created_at to datetime object, including microseconds
|
|
||||||
try:
|
try:
|
||||||
created_at = datetime.strptime(created_at, '%Y-%m-%d %H:%M:%S.%f')
|
created_at = datetime.strptime(created_at, '%Y-%m-%d %H:%M:%S.%f')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# If the above fails, try without microseconds
|
|
||||||
created_at = datetime.strptime(created_at, '%Y-%m-%d %H:%M:%S')
|
created_at = datetime.strptime(created_at, '%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
if is_private and stored_password:
|
if is_private and stored_password:
|
||||||
@ -278,19 +278,41 @@ def redirect_vanity(vanity, password=None):
|
|||||||
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):
|
||||||
if is_download:
|
file_size = os.path.getsize(file_path)
|
||||||
# Force download
|
file_extension = os.path.splitext(content_data)[1].lower()
|
||||||
return send_file(file_path, as_attachment=True, download_name=content_data)
|
is_embeddable = file_extension in ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.pdf']
|
||||||
else:
|
file_url = url_for('redirect_vanity', vanity=vanity, _external=True)
|
||||||
# Serve the file for viewing/embedding
|
|
||||||
|
if is_download or (not is_embeddable and not is_raw):
|
||||||
|
return send_file(file_path, as_attachment=True)
|
||||||
|
elif is_raw and is_embeddable:
|
||||||
return send_file(file_path)
|
return send_file(file_path)
|
||||||
elif content_type == 'pastebin':
|
else:
|
||||||
first_lines = '\n'.join(content_data.split('\n')[:5]) # Get first 5 lines
|
return render_template('file_info.html',
|
||||||
return render_template('og_pastebin.html',
|
filename=content_data,
|
||||||
vanity=vanity,
|
file_size=file_size,
|
||||||
first_lines=first_lines,
|
|
||||||
username=username,
|
username=username,
|
||||||
created_at=created_at)
|
created_at=created_at,
|
||||||
|
is_embeddable=is_embeddable,
|
||||||
|
file_url=file_url,
|
||||||
|
vanity=vanity,
|
||||||
|
user_id=user_id)
|
||||||
|
elif content_type == 'pastebin':
|
||||||
|
try:
|
||||||
|
lexer = guess_lexer(content_data)
|
||||||
|
except ClassNotFound:
|
||||||
|
lexer = get_lexer_by_name('text')
|
||||||
|
formatter = HtmlFormatter(style='monokai', linenos=True, cssclass="source")
|
||||||
|
highlighted_content = highlight(content_data, lexer, formatter)
|
||||||
|
css = formatter.get_style_defs('.source')
|
||||||
|
return render_template('pastebin.html',
|
||||||
|
content={'data': content_data, 'user_id': user_id, 'username': username},
|
||||||
|
highlighted_content=highlighted_content,
|
||||||
|
css=css,
|
||||||
|
raw_content=content_data,
|
||||||
|
created_at=created_at,
|
||||||
|
vanity=vanity,
|
||||||
|
is_private=is_private)
|
||||||
|
|
||||||
app.logger.error(f"Content not found for vanity: {vanity}")
|
app.logger.error(f"Content not found for vanity: {vanity}")
|
||||||
return "Not found", 404
|
return "Not found", 404
|
||||||
|
164
templates/file_info.html
Normal file
164
templates/file_info.html
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{ filename }} - sxbin</title>
|
||||||
|
<meta property="og:title" content="{{ filename }}">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<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') }}">
|
||||||
|
{% if is_embeddable %}
|
||||||
|
<meta property="og:image" content="{{ file_url }}">
|
||||||
|
{% endif %}
|
||||||
|
<meta property="og:site_name" content="sxbin">
|
||||||
|
<meta property="theme-color" content="#4CAF50">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: #e0e0e0;
|
||||||
|
background-color: #1e1e1e;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #4CAF50;
|
||||||
|
}
|
||||||
|
.info-item {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.embed-container {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.embed-container img, .embed-container embed {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 600px;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.btn-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 10px 15px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 4px 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
.home-button {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #4CAF50;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.home-button:hover {
|
||||||
|
color: #45a049;
|
||||||
|
}
|
||||||
|
#theme-toggle {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background-color: #333;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.edit-btn, .delete-btn {
|
||||||
|
background-color: #f44336;
|
||||||
|
}
|
||||||
|
.edit-btn:hover, .delete-btn:hover {
|
||||||
|
background-color: #d32f2f;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a href="/" class="home-button">⌂</a>
|
||||||
|
<div class="container">
|
||||||
|
<h2>{{ filename }}</h2>
|
||||||
|
<div class="info-item"><strong>File size:</strong> {{ file_size|filesizeformat }}</div>
|
||||||
|
<div class="info-item"><strong>Uploaded by:</strong> {{ username }}</div>
|
||||||
|
<div class="info-item"><strong>Date:</strong> {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}</div>
|
||||||
|
|
||||||
|
{% if is_embeddable %}
|
||||||
|
<div class="embed-container">
|
||||||
|
{% if filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.svg')) %}
|
||||||
|
<img src="{{ file_url }}" alt="{{ filename }}">
|
||||||
|
{% elif filename.lower().endswith('.pdf') %}
|
||||||
|
<embed src="{{ file_url }}" type="application/pdf" width="100%" height="600px">
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="btn-container">
|
||||||
|
<a href="{{ url_for('redirect_vanity', vanity=vanity, _external=True) }}/download" class="btn">Download</a>
|
||||||
|
<a href="{{ url_for('redirect_vanity', vanity=vanity, _external=True) }}/raw" class="btn">View Raw</a>
|
||||||
|
{% 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 %}
|
||||||
|
<a href="{{ url_for('edit_content', vanity=vanity) }}" class="btn edit-btn">Edit</a>
|
||||||
|
{% endif %}
|
||||||
|
<form action="{{ url_for('delete_content', vanity=vanity) }}" method="post" style="display: inline;">
|
||||||
|
<button type="submit" class="btn delete-btn" onclick="return confirm('Are you sure you want to delete this file?')">Delete</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="theme-toggle">Toggle Theme</button>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>
|
||||||
|
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||||
|
<a href="https://office.bence.lol/form/#/2/form/view/z5Cf3CL6tZtPjzKsbcEPync6JE3iyMl22h6thUQg1a4/" target="_blank">Suggestions & Bugs</a> |
|
||||||
|
<a href="https://office.bence.lol/kanban/#/2/kanban/view/hx6RTcpN0pR7hc1HHkMzG4awMoMdHjR2zbHjG7Xh+wU/embed/" target="_blank">Todo List</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const themeToggle = document.getElementById('theme-toggle');
|
||||||
|
const body = document.body;
|
||||||
|
|
||||||
|
themeToggle.addEventListener('click', () => {
|
||||||
|
body.classList.toggle('light-mode');
|
||||||
|
localStorage.setItem('theme', body.classList.contains('light-mode') ? 'light' : 'dark');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check for saved theme preference
|
||||||
|
const savedTheme = localStorage.getItem('theme');
|
||||||
|
if (savedTheme === 'light') {
|
||||||
|
body.classList.add('light-mode');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -285,19 +285,8 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instant-upload-result {
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background-color: #2a2a2a;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
z-index: 10000;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instant-upload-overlay {
|
.instant-upload-overlay {
|
||||||
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -305,16 +294,29 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
display: none;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.instant-upload-result .close-btn {
|
.instant-upload-result {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
position: relative;
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-modal {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 15px;
|
||||||
color: white;
|
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-modal:hover {
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
@ -405,13 +407,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="instant-upload-overlay"></div>
|
<div class="instant-upload-overlay">
|
||||||
<div class="instant-upload-result">
|
<div class="instant-upload-result">
|
||||||
<span class="close-btn" onclick="closeInstantUploadResult()">×</span>
|
<span class="close-modal">×</span>
|
||||||
<h3>File Uploaded</h3>
|
<h3>File Uploaded</h3>
|
||||||
<p>Direct download URL: <a id="directDownloadUrl" href="#" target="_blank"></a></p>
|
<p>Direct download URL: <a id="directDownloadUrl" href="#" target="_blank"></a></p>
|
||||||
<p>Normal URL: <a id="normalUrl" href="#" target="_blank"></a></p>
|
<p>Normal URL: <a id="normalUrl" href="#" target="_blank"></a></p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<p>Source code available on:
|
<p>Source code available on:
|
||||||
@ -782,8 +785,7 @@
|
|||||||
document.getElementById('directDownloadUrl').textContent = data.download_url;
|
document.getElementById('directDownloadUrl').textContent = data.download_url;
|
||||||
document.getElementById('normalUrl').href = data.url;
|
document.getElementById('normalUrl').href = data.url;
|
||||||
document.getElementById('normalUrl').textContent = data.url;
|
document.getElementById('normalUrl').textContent = data.url;
|
||||||
document.querySelector('.instant-upload-overlay').style.display = 'block';
|
document.querySelector('.instant-upload-overlay').style.display = 'flex';
|
||||||
document.querySelector('.instant-upload-result').style.display = 'block';
|
|
||||||
} else {
|
} else {
|
||||||
alert('Error uploading file: ' + data.error);
|
alert('Error uploading file: ' + data.error);
|
||||||
}
|
}
|
||||||
@ -794,11 +796,25 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeInstantUploadResult() {
|
// Add this new function to close the modal
|
||||||
|
function closeInstantUploadModal() {
|
||||||
document.querySelector('.instant-upload-overlay').style.display = 'none';
|
document.querySelector('.instant-upload-overlay').style.display = 'none';
|
||||||
document.querySelector('.instant-upload-result').style.display = 'none';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add event listeners for closing the modal
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const closeModalButton = document.querySelector('.close-modal');
|
||||||
|
const instantUploadOverlay = document.querySelector('.instant-upload-overlay');
|
||||||
|
|
||||||
|
closeModalButton.addEventListener('click', closeInstantUploadModal);
|
||||||
|
|
||||||
|
instantUploadOverlay.addEventListener('click', function(event) {
|
||||||
|
if (event.target === instantUploadOverlay) {
|
||||||
|
closeInstantUploadModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Paste functionality for file upload
|
// Paste functionality for file upload
|
||||||
document.addEventListener('paste', function(e) {
|
document.addEventListener('paste', function(e) {
|
||||||
if (document.getElementById('fileModal').style.display === 'block') {
|
if (document.getElementById('fileModal').style.display === 'block') {
|
||||||
|
@ -8,19 +8,15 @@
|
|||||||
<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_image %}
|
{% if is_embeddable %}
|
||||||
<meta property="og:image" content="{{ file_url }}">
|
<meta property="og:image" content="{{ file_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">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>{{ filename }}</h1>
|
<script>
|
||||||
<p>File size: {{ file_size|filesizeformat }}</p>
|
window.location.href = "{{ file_url }}/download";
|
||||||
<p>Uploaded by: {{ username }}</p>
|
</script>
|
||||||
<p>Date: {{ created_at.strftime('%Y-%m-%d %H:%M:%S') }}</p>
|
|
||||||
{% if is_image %}
|
|
||||||
<img src="{{ file_url }}" alt="{{ filename }}">
|
|
||||||
{% endif %}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,9 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" class="dark-mode">
|
<html lang="en">
|
||||||
<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>Content</title>
|
<title>Pastebin {{ vanity }} - sxbin</title>
|
||||||
|
<meta property="og:title" content="Pastebin {{ vanity }} - sxbin">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:url" content="{{ request.url }}">
|
||||||
|
<meta property="og:description" content="{{ content.data[:200] }}">
|
||||||
|
<meta property="og:site_name" content="sxbin">
|
||||||
|
<meta property="theme-color" content="#4CAF50">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg-color: #1e1e1e;
|
--bg-color: #1e1e1e;
|
||||||
@ -123,68 +129,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal {
|
|
||||||
display: none;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 1000;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0,0,0,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
background-color: var(--bg-color);
|
|
||||||
margin: 15% auto;
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid var(--highlight-border);
|
|
||||||
width: 300px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content h3 {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content input[type="password"] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 0;
|
|
||||||
border: 1px solid var(--highlight-border);
|
|
||||||
background-color: var(--highlight-bg);
|
|
||||||
color: var(--text-color);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-buttons button {
|
|
||||||
padding: 10px 20px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-ok {
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-cancel {
|
|
||||||
background-color: #888;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-remove {
|
|
||||||
background-color: #f44336;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.home-button {
|
.home-button {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 20px;
|
top: 20px;
|
||||||
@ -231,19 +175,6 @@
|
|||||||
|
|
||||||
<button id="theme-toggle">Toggle Theme</button>
|
<button id="theme-toggle">Toggle Theme</button>
|
||||||
|
|
||||||
<div id="editPasswordModal" class="modal">
|
|
||||||
<div class="modal-content">
|
|
||||||
<h3 id="passwordModalTitle">Edit Password</h3>
|
|
||||||
<input type="password" id="newPassword1" placeholder="Enter new password">
|
|
||||||
<input type="password" id="newPassword2" placeholder="Confirm new password">
|
|
||||||
<div class="modal-buttons">
|
|
||||||
<button onclick="closePasswordModal()" class="btn-cancel">Cancel</button>
|
|
||||||
<button onclick="updatePassword()" class="btn-ok">OK</button>
|
|
||||||
<button onclick="removePassword()" class="btn-remove" id="removePasswordBtn">Remove Password</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer style="text-align: center; margin-top: 20px; padding: 10px; background-color: #2a2a2a; color: #f0f0f0;">
|
<footer style="text-align: center; margin-top: 20px; padding: 10px; background-color: #2a2a2a; color: #f0f0f0;">
|
||||||
<p>
|
<p>
|
||||||
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
Source code: <a href="https://git.spitkov.hu/cgcristi/aCloud" target="_blank">Spitkov's Git</a> |
|
||||||
@ -277,87 +208,6 @@
|
|||||||
if (localStorage.getItem('lightMode') === 'true') {
|
if (localStorage.getItem('lightMode') === 'true') {
|
||||||
html.classList.add('light-mode');
|
html.classList.add('light-mode');
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEditPasswordModal() {
|
|
||||||
document.getElementById('passwordModalTitle').textContent = 'Edit Password';
|
|
||||||
document.getElementById('removePasswordBtn').style.display = 'inline-block';
|
|
||||||
document.getElementById('editPasswordModal').style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function openAddPasswordModal() {
|
|
||||||
document.getElementById('passwordModalTitle').textContent = 'Add Password';
|
|
||||||
document.getElementById('removePasswordBtn').style.display = 'none';
|
|
||||||
document.getElementById('editPasswordModal').style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function closePasswordModal() {
|
|
||||||
document.getElementById('editPasswordModal').style.display = 'none';
|
|
||||||
document.getElementById('newPassword1').value = '';
|
|
||||||
document.getElementById('newPassword2').value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePassword() {
|
|
||||||
const password1 = document.getElementById('newPassword1').value;
|
|
||||||
const password2 = document.getElementById('newPassword2').value;
|
|
||||||
|
|
||||||
if (password1 !== password2) {
|
|
||||||
alert('Passwords do not match');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch('{{ url_for("edit_password", vanity=vanity) }}', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
action: 'update',
|
|
||||||
new_password: password1
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
alert('Password updated successfully');
|
|
||||||
closePasswordModal();
|
|
||||||
location.reload(); // Reload the page to reflect the changes
|
|
||||||
} else {
|
|
||||||
alert('Error updating password: ' + data.error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
alert('An error occurred while updating the password');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removePassword() {
|
|
||||||
if (confirm('Are you sure you want to remove the password?')) {
|
|
||||||
fetch('{{ url_for("edit_password", vanity=vanity) }}', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
action: 'remove'
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
if (data.success) {
|
|
||||||
alert('Password removed successfully');
|
|
||||||
closePasswordModal();
|
|
||||||
location.reload(); // Reload the page to reflect the changes
|
|
||||||
} else {
|
|
||||||
alert('Error removing password: ' + data.error);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
alert('An error occurred while removing the password');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user