final fix for telegram
This commit is contained in:
parent
f96f4a40a5
commit
cb3d8efd72
36
app.py
36
app.py
@ -346,9 +346,16 @@ def api_browse(subpath):
|
|||||||
def serve_file(subpath):
|
def serve_file(subpath):
|
||||||
# 1) Locate the real file on disk
|
# 1) Locate the real file on disk
|
||||||
root, *relative_parts = subpath.split('/')
|
root, *relative_parts = subpath.split('/')
|
||||||
base_path = session['folders'].get(root)
|
|
||||||
full_path = os.path.join(base_path or '', *relative_parts)
|
dltoken = request.args.get('dltoken')
|
||||||
|
if dltoken:
|
||||||
|
as_attachment = True
|
||||||
|
full_path = auth.decode_token(dltoken)['filename']
|
||||||
|
else:
|
||||||
|
as_attachment = False
|
||||||
|
base_path = session['folders'].get(root)
|
||||||
|
full_path = os.path.join(base_path or '', *relative_parts)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
full_path = check_path(full_path)
|
full_path = check_path(full_path)
|
||||||
except (ValueError, PermissionError) as e:
|
except (ValueError, PermissionError) as e:
|
||||||
@ -463,9 +470,6 @@ def serve_file(subpath):
|
|||||||
|
|
||||||
# 6) Build response for non-image
|
# 6) Build response for non-image
|
||||||
filesize = os.path.getsize(file_path)
|
filesize = os.path.getsize(file_path)
|
||||||
|
|
||||||
# Figure out download flag and filename
|
|
||||||
ask_download = request.args.get('download') == 'true'
|
|
||||||
filename = os.path.basename(full_path)
|
filename = os.path.basename(full_path)
|
||||||
|
|
||||||
# Single send_file call with proper attachment handling
|
# Single send_file call with proper attachment handling
|
||||||
@ -473,10 +477,10 @@ def serve_file(subpath):
|
|||||||
file_path,
|
file_path,
|
||||||
mimetype=mime,
|
mimetype=mime,
|
||||||
conditional=True,
|
conditional=True,
|
||||||
as_attachment=ask_download,
|
as_attachment=as_attachment,
|
||||||
download_name=filename if ask_download else None
|
download_name=filename if as_attachment else None
|
||||||
)
|
)
|
||||||
if not ask_download:
|
if not as_attachment:
|
||||||
response.headers['Content-Disposition'] = 'inline'
|
response.headers['Content-Disposition'] = 'inline'
|
||||||
response.headers['Cache-Control'] = 'public, max-age=86400'
|
response.headers['Cache-Control'] = 'public, max-age=86400'
|
||||||
|
|
||||||
@ -562,12 +566,11 @@ def create_token(subpath):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/create_dl_token/<path:subpath>")
|
@app.route("/create_dltoken/<path:subpath>")
|
||||||
@auth.require_secret
|
@auth.require_secret
|
||||||
def create_dl_token(subpath):
|
def create_dltoken(subpath):
|
||||||
scheme = request.scheme # current scheme (http or https)
|
scheme = request.scheme # current scheme (http or https)
|
||||||
host = request.host
|
host = request.host
|
||||||
print(f"Creating download token for subpath: {subpath}")
|
|
||||||
# 1) Locate the real file on disk
|
# 1) Locate the real file on disk
|
||||||
root, *relative_parts = subpath.split('/')
|
root, *relative_parts = subpath.split('/')
|
||||||
base_path = session['folders'].get(root)
|
base_path = session['folders'].get(root)
|
||||||
@ -575,7 +578,6 @@ def create_dl_token(subpath):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
full_path = check_path(full_path)
|
full_path = check_path(full_path)
|
||||||
print(f"Full path after check: {full_path}")
|
|
||||||
except (ValueError, PermissionError) as e:
|
except (ValueError, PermissionError) as e:
|
||||||
return jsonify({'Unauthorized': str(e)}), 403
|
return jsonify({'Unauthorized': str(e)}), 403
|
||||||
|
|
||||||
@ -583,16 +585,14 @@ def create_dl_token(subpath):
|
|||||||
app.logger.error(f"File not found: {full_path}")
|
app.logger.error(f"File not found: {full_path}")
|
||||||
return "File not found", 404
|
return "File not found", 404
|
||||||
|
|
||||||
validity_date = (datetime.now() + timedelta(days=1)).strftime('%d.%m.%Y')
|
validity_date = datetime.now().strftime('%d.%m.%Y')
|
||||||
data = {
|
data = {
|
||||||
"validity": validity_date,
|
"validity": validity_date,
|
||||||
"filename": full_path
|
"filename": str(full_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
token = auth.generate_token(data)
|
token = auth.generate_token(data)
|
||||||
|
url = f"{scheme}://{host}/media/{subpath}?dltoken={token}"
|
||||||
url = f"{scheme}://{host}?dl_token={token}"
|
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
6
auth.py
6
auth.py
@ -73,6 +73,12 @@ def require_secret(f):
|
|||||||
# 1) Get secretand token from query params (if any)
|
# 1) Get secretand token from query params (if any)
|
||||||
args_secret = request.args.get('secret')
|
args_secret = request.args.get('secret')
|
||||||
args_token = request.args.get('token')
|
args_token = request.args.get('token')
|
||||||
|
args_dltoken = request.args.get('dltoken')
|
||||||
|
|
||||||
|
# 1b) immediately return if dltoken is provided
|
||||||
|
if args_dltoken:
|
||||||
|
if is_valid_token(args_dltoken):
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
|
||||||
# 2) Initialize 'valid_secrets' in the session if missing
|
# 2) Initialize 'valid_secrets' in the session if missing
|
||||||
if 'valid_secrets' not in session:
|
if 'valid_secrets' not in session:
|
||||||
|
|||||||
@ -139,20 +139,30 @@ class SimpleAudioPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fileDownload() {
|
async fileDownload() {
|
||||||
const src = this.audio.currentSrc || this.audio.src;
|
const src = this.audio.currentSrc || this.audio.src;
|
||||||
if (!src) return;
|
if (!src) return;
|
||||||
|
|
||||||
// Build the URL with your download flag + cache‑buster
|
// Extract the subpath from the src
|
||||||
const downloadUrl = new URL(src, window.location.href);
|
const urlObj = new URL(src, window.location.href);
|
||||||
downloadUrl.searchParams.set('download', 'true');
|
let subpath = urlObj.pathname;
|
||||||
downloadUrl.searchParams.set('_', Date.now());
|
subpath = subpath.slice('/media'.length);
|
||||||
|
|
||||||
// Create a “real” link to that URL and click it
|
// Fetch the tokenized URL from your backend
|
||||||
|
let tokenizedUrl;
|
||||||
|
try {
|
||||||
|
const resp = await fetch(`/create_dltoken${subpath}`);
|
||||||
|
if (!resp.ok) return;
|
||||||
|
tokenizedUrl = await resp.text();
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the URL with cache-buster
|
||||||
|
const downloadUrl = new URL(tokenizedUrl, window.location.href);
|
||||||
|
|
||||||
|
// Create a link and click it
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
a.href = downloadUrl.toString();
|
a.href = downloadUrl.toString();
|
||||||
a.download = ''; // tell Safari “this is a download”
|
|
||||||
a.target = '_blank'; // force a real navigation on iOS
|
|
||||||
// NOTE: do NOT set a.download here – we want the server's Content-Disposition to drive it
|
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user