forked from ComputerTech/bastebin
Remove 'Never' expiry (1-year max) and fix Raw blob URL issue
This commit is contained in:
parent
d0289f85d5
commit
a46cba7143
20
app.py
20
app.py
|
|
@ -261,10 +261,11 @@ def create_paste():
|
||||||
else:
|
else:
|
||||||
return jsonify({'error': 'Provide either encrypted_data or content'}), 400
|
return jsonify({'error': 'Provide either encrypted_data or content'}), 400
|
||||||
|
|
||||||
allowed_expiry = set(_pastes.get('allow_expiry_options', ['never']))
|
allowed_expiry = set(_pastes.get('allow_expiry_options', ['1year']))
|
||||||
expires_in = data.get('expires_in', 'never')
|
expires_in = data.get('expires_in', _pastes.get('default_expiry', '1year'))
|
||||||
if expires_in not in allowed_expiry:
|
if expires_in not in allowed_expiry:
|
||||||
expires_in = 'never'
|
# Fallback to the first allowed option if everything is missing
|
||||||
|
expires_in = _pastes.get('default_expiry', list(allowed_expiry)[0])
|
||||||
|
|
||||||
expires_at = None
|
expires_at = None
|
||||||
if expires_in != 'never':
|
if expires_in != 'never':
|
||||||
|
|
@ -273,6 +274,7 @@ def create_paste():
|
||||||
'1day': datetime.timedelta(days=1),
|
'1day': datetime.timedelta(days=1),
|
||||||
'1week': datetime.timedelta(weeks=1),
|
'1week': datetime.timedelta(weeks=1),
|
||||||
'1month': datetime.timedelta(days=30),
|
'1month': datetime.timedelta(days=30),
|
||||||
|
'1year': datetime.timedelta(days=365),
|
||||||
}
|
}
|
||||||
delta = delta_map.get(expires_in)
|
delta = delta_map.get(expires_in)
|
||||||
if delta is None:
|
if delta is None:
|
||||||
|
|
@ -322,15 +324,21 @@ def view_paste_raw(paste_id):
|
||||||
paste = _get_paste_or_abort(paste_id)
|
paste = _get_paste_or_abort(paste_id)
|
||||||
stored = paste['encrypted_data']
|
stored = paste['encrypted_data']
|
||||||
|
|
||||||
# Plaintext pastes are stored as a JSON object; return the content directly.
|
# 1. Plaintext paste — Return content directly as text/plain
|
||||||
if not re.match(r'^[A-Za-z0-9_-]+:[A-Za-z0-9_-]+$', stored):
|
if not re.match(r'^[A-Za-z0-9_-]+:[A-Za-z0-9_-]+$', stored):
|
||||||
try:
|
try:
|
||||||
data = json.loads(stored)
|
data = json.loads(stored)
|
||||||
return Response(data.get('content', ''), mimetype='text/plain')
|
return Response(data.get('content', ''), mimetype='text/plain; charset=utf-8')
|
||||||
except (json.JSONDecodeError, TypeError):
|
except (json.JSONDecodeError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Encrypted paste — return the raw ciphertext blob for API consumers.
|
# 2. Encrypted paste — Browsers get a minimal decryptor; API consumers get JSON
|
||||||
|
accept = request.headers.get('Accept', '')
|
||||||
|
if 'text/html' in accept:
|
||||||
|
# Minimal HTML shell that handles decryption for browsers (E2E)
|
||||||
|
return render_template('raw_decryptor.html', paste=paste)
|
||||||
|
|
||||||
|
# API response
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'id': paste['id'],
|
'id': paste['id'],
|
||||||
'encrypted_data': stored,
|
'encrypted_data': stored,
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@
|
||||||
"id_length": 8,
|
"id_length": 8,
|
||||||
"recent_limit": 50,
|
"recent_limit": 50,
|
||||||
"default_language": "text",
|
"default_language": "text",
|
||||||
"default_expiry": "never",
|
"default_expiry": "1year",
|
||||||
"allow_expiry_options": ["never", "1hour", "1day", "1week", "1month"],
|
"allow_expiry_options": ["1hour", "1day", "1week", "1month", "1year"],
|
||||||
"expiry_labels": {
|
"expiry_labels": {
|
||||||
"never": "Never",
|
|
||||||
"1hour": "1 Hour",
|
"1hour": "1 Hour",
|
||||||
"1day": "1 Day",
|
"1day": "1 Day",
|
||||||
"1week": "1 Week",
|
"1week": "1 Week",
|
||||||
"1month": "1 Month"
|
"1month": "1 Month",
|
||||||
|
"1year": "1 Year"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,15 +137,9 @@ function showError(title, detail) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function rawView() {
|
function rawView() {
|
||||||
if (!_decryptedPaste) return;
|
const key = window.location.hash;
|
||||||
const blob = new Blob([_decryptedPaste.content], { type: 'text/plain; charset=utf-8' });
|
const url = window.location.href.split('?')[0].split('#')[0] + '/raw' + key;
|
||||||
const url = URL.createObjectURL(blob);
|
window.open(url, '_blank');
|
||||||
const a = Object.assign(document.createElement('a'),
|
|
||||||
{ href: url, target: '_blank', rel: 'noopener noreferrer' });
|
|
||||||
document.body.appendChild(a);
|
|
||||||
a.click();
|
|
||||||
document.body.removeChild(a);
|
|
||||||
setTimeout(() => URL.revokeObjectURL(url), 10000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function copyPaste() {
|
async function copyPaste() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Raw | {{ cfg.site.name }}</title>
|
||||||
|
<style>
|
||||||
|
body { margin: 0; padding: 1rem; background: #fff; color: #000; font-family: monospace; }
|
||||||
|
pre { white-space: pre-wrap; word-wrap: break-word; margin: 0; }
|
||||||
|
#error { display: none; color: red; font-weight: bold; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="rawContent"></pre>
|
||||||
|
<div id="error">Decryption Failed — Key missing or incorrect.</div>
|
||||||
|
|
||||||
|
<script src="{{ url_for('static', filename='js/crypto.js') }}" nonce="{{ csp_nonce }}"></script>
|
||||||
|
<script nonce="{{ csp_nonce }}">
|
||||||
|
(async function decryptRaw() {
|
||||||
|
const raw = {{ paste.encrypted_data | tojson }};
|
||||||
|
const keyBase64 = window.location.hash.slice(1);
|
||||||
|
const pre = document.getElementById('rawContent');
|
||||||
|
const error = document.getElementById('error');
|
||||||
|
|
||||||
|
if (!keyBase64) { error.style.display = 'block'; return; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
const key = await PasteCrypto.importKey(keyBase64);
|
||||||
|
const plaintext = await PasteCrypto.decrypt(raw, key);
|
||||||
|
const data = JSON.parse(plaintext);
|
||||||
|
pre.textContent = data.content;
|
||||||
|
} catch (e) {
|
||||||
|
error.style.display = 'block';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue