update token generation gui

This commit is contained in:
lelo 2025-05-01 21:37:29 +02:00
parent 4b37684593
commit 7b73facc16
4 changed files with 124 additions and 27 deletions

33
app.py
View File

@ -17,7 +17,8 @@ from functools import lru_cache
from urllib.parse import urlparse, unquote
from werkzeug.middleware.proxy_fix import ProxyFix
import re
import qrcode
import base64
import search
import auth
import analytics as a
@ -415,6 +416,7 @@ def get_transcript(subpath):
@auth.require_secret
def create_share(subpath):
scheme = request.scheme # current scheme (http or https)
host = request.host
if 'admin ' not in session and not session.get('admin'):
return "Unauthorized", 403
@ -440,20 +442,25 @@ def create_share(subpath):
]
}
print (data)
token = auth.generate_secret_key_compressed(data)
content = f"""Ordner:\\
{foldername}\\
\\
Gültig bis:\\
{validity_date}\\
\\
Link:\\
`{scheme}://{request.host}?token={token}`"""
return content, 200, {'Content-Type': 'text/markdown; charset=utf-8'}
url = f"{scheme}://{host}?token={token}"
qr = qrcode.QRCode(version=1, box_size=10, border=4)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
buffer = io.BytesIO()
img.save(buffer, format="PNG")
buffer.seek(0)
img_base64 = base64.b64encode(buffer.getvalue()).decode('ascii')
token_item = auth.decode_secret_key_compressed(token)
return render_template('view_token.html',
token_qr_code=img_base64,
token_folder=token_item.get('folders'),
token_url=url,
token_valid_to=token_item.get('validity', 'Unbekannt')
)
def query_recent_connections():

View File

@ -100,17 +100,11 @@ div.directory-item a, li.directory-item a, li.file-item a, li.link-item a {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 10px;
}
.directories-grid .directory-item {
background-color: #fff;
padding: 15px;
border-radius: 5px;
text-align: center;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
/* File Item Styles (for both music and image files) */
.file-item {
.file-item, .directory-item{
display: grid;
grid-template-columns: 1fr auto;
align-items: center;

View File

@ -77,26 +77,30 @@ function renderContent(data) {
share_link = '';
// Render directories normally
if (data.directories.length > 0) {
const areAllShort = data.directories.every(dir => dir.name.length <= 15) && data.files.length === 0;
const areAllShort = data.directories.every(dir => dir.name.length <= 10) && data.files.length === 0;
if (areAllShort && data.breadcrumbs.length !== 1) {
contentHTML += '<div class="directories-grid">';
data.directories.forEach(dir => {
if (admin_enabled && data.breadcrumbs.length != 1) {
share_link = `<a href="#" class="create-share" data-url="${dir.path}">🌐</a>`;
share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`;
}
contentHTML += `<div class="directory-item">📁 <a href="#" class="directory-link" data-path="${dir.path}">${dir.name}</a>${share_link}</div>`;
contentHTML += `<div class="directory-item"><a href="#" class="directory-link" data-path="${dir.path}">📁 ${dir.name}</a>
${share_link}
</div>`;
});
contentHTML += '</div>';
} else {
contentHTML += '<ul>';
data.directories.forEach(dir => {
if (admin_enabled && data.breadcrumbs.length != 1) {
share_link = `<a href="#" class="create-share" data-url="${dir.path}">🌐</a>`;
share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`;
}
contentHTML += `<li class="directory-item">📁 <a href="#" class="directory-link" data-path="${dir.path}">${dir.name}</a>${share_link}</li>`;
contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="${dir.path}">📁 ${dir.name}</a>
${share_link}
</li>`;
});
if (data.breadcrumbs.length === 1) {
contentHTML += `<li class="link-item" onclick="window.location.href='/search'">🔎 <a href="/search" class="link-link">Suche</a></li>`;
contentHTML += `<li class="link-item" onclick="window.location.href='/search'"><a href="/search" class="link-link">🔎 Suche</a></li>`;
}
contentHTML += '</ul>';
}
@ -385,7 +389,7 @@ document.querySelectorAll('.play-file').forEach(link => {
})
.then(data => {
console.log(data);
document.getElementById('transcriptContent').innerHTML = marked.parse(data);
document.getElementById('transcriptContent').innerHTML = data;
document.getElementById('transcriptModal').style.display = 'block';
})
.catch(error => {
@ -538,4 +542,34 @@ function syncThemeColor() {
.forEach(svg => svg.setAttribute('fill', cssVar));
}
function copyTokenUrl(url) {
if (navigator.clipboard && window.isSecureContext) {
// Modern approach
navigator.clipboard.writeText(url)
.then(() => {
alert('Token-URL in die Zwischenablage kopiert!');
})
.catch(err => {
console.error('Fehler beim Kopieren: ', err);
});
} else {
// Fallback for older browsers
const textarea = document.createElement('textarea');
textarea.value = url;
textarea.style.position = 'fixed'; // Verhindert Scrollen
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
alert('Token-URL in die Zwischenablage kopiert!');
} catch (err) {
console.error('Fallback: Kopieren fehlgeschlagen', err);
}
document.body.removeChild(textarea);
}
}
document.addEventListener('DOMContentLoaded', syncThemeColor);

62
templates/view_token.html Normal file
View File

@ -0,0 +1,62 @@
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.container-fluid {
height: 100%;
display: flex;
flex-direction: column;
}
.qr-code {
max-width: 300px;
display: block;
margin: auto;
}
.copy-btn {
margin-top: 1rem;
display: inline-flex;
align-items: center;
padding: 0.5rem 1rem;
font-size: 1rem;
cursor: pointer;
border: 1px solid #007bff;
background-color: #007bff;
color: white;
border-radius: 0.25rem;
}
.copy-btn:active {
background-color: #0056b3;
border-color: #0056b3;
}
</style>
<div class="container-fluid">
<div class="row">
<div class="col-md-4 mb-4">
<div class="card h-100 shadow-sm">
<img src="data:image/png;base64,{{ token_qr_code }}" class="card-img-top qr-code p-3" alt="QR Code for token">
<div class="card-body">
<div class="card-text mt-2">
<h2 class="card-title">Token-Link:</h2>
<a href="{{ token_url }}" class="copy-btn" id="tokenLink">Direct Link</a>
<button class="copy-btn" onclick="copyTokenUrl('{{ token_url }}')">Copy Link</button>
</div>
<div class="card-text mt-2">
<h2 class="mt-3">Gültig bis:</h2>
{{ token_valid_to }}
</div>
<div class="card-text mt-2">
<h2 class="mt-3">Ordner:</h2>
{% for folder in token_folder %}
{{ folder.foldername }}<br>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>