Files
Secure-Pastebin-Self-Hosted/index.html
T
2026-04-23 19:01:17 +03:30

281 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Pastebin - End-to-End Encrypted Message Sharing</title>
<meta name="description" content="Share sensitive messages securely with AES-256 encryption. Zero-knowledge architecture, password protection, self-destructing messages.">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div class="container">
<header>
<div class="logo">🔐</div>
<h1>Secure Pastebin</h1>
<p class="subtitle">End-to-End Encrypted • Password Protected • Self-Destructing</p>
<div class="security-badges">
<span class="badge">🔒 AES-256-GCM</span>
<span class="badge">🔑 Password</span>
<span class="badge">🛡️ Zero-Knowledge</span>
<span class="badge">⚡ Web Crypto API</span>
</div>
</header>
<div id="errorDisplay" class="card alert alert-error" style="display: none;">
<span></span>
<div style="flex: 1;">
<strong>Error</strong>
<div id="errorMessage"></div>
</div>
</div>
<div id="passwordPrompt" class="card password-prompt">
<div class="alert alert-info" style="margin-bottom: 20px;">
<span>🔐</span>
<div>This message is password protected.</div>
</div>
<h3>Enter Password to Decrypt</h3>
<input type="password" id="decryptPassword" placeholder="Password">
<button class="btn" onclick="decryptWithPassword()">
<span id="decryptBtnText">🔓 Decrypt</span>
</button>
<p id="passwordError" style="color: var(--error); margin-top: 12px; display: none;">
❌ Wrong password!
</p>
</div>
<div id="decryptView" class="card decrypt-view">
<div id="burnNotice" class="burn-warning" style="display: none;">
<span>🔥</span>
<span>This message will be permanently deleted after you view it.</span>
</div>
<div class="decrypt-header">
<div>
<h3 class="section-title">🔓 Decrypted Content</h3>
<div id="decryptedSubjectWrapper" class="decrypted-subject-wrapper" style="display: none;">
<span class="subject-label">Subject</span>
<div id="decryptedSubject" class="subject-display" dir="auto"></div>
</div>
</div>
<button id="copyDecryptedBtn" class="btn btn-copy btn-copy-content" type="button" onclick="copyDecryptedContent()">📋 Copy Text</button>
</div>
<div id="decryptedContent" class="content-box" dir="auto"></div>
<button class="btn btn-secondary" onclick="window.location.href='/'" style="margin-top: 18px;">
📝 Create New Message
</button>
</div>
<div id="createView" class="card">
<div class="alert alert-warning">
<span>⚠️</span>
<div>
<strong>Important:</strong> The encryption key is stored only in the URL fragment (after #).
If you lose the URL, the data is permanently lost. We cannot recover it.
</div>
</div>
<div class="form-group form-group-full">
<label for="subject">📝 Subject</label>
<input type="text" id="subject" placeholder="Add a subject for this secure message (optional)" maxlength="120" dir="auto">
</div>
<div class="form-group form-group-full">
<div class="editor-shell">
<div class="editor-shell-head">
<label for="content">✍️ Secret Message</label>
<div class="editor-toolbar" role="toolbar" aria-label="Formatting toolbar">
<button type="button" class="toolbar-btn" data-action="bold" title="Bold" aria-label="Bold"><strong>B</strong></button>
<button type="button" class="toolbar-btn" data-action="italic" title="Italic" aria-label="Italic"><em>I</em></button>
<button type="button" class="toolbar-btn" data-action="strike" title="Strikethrough" aria-label="Strikethrough"><span class="toolbar-strike">S</span></button>
<button type="button" class="toolbar-btn" data-action="heading" title="Heading" aria-label="Heading">H</button>
<button type="button" class="toolbar-btn" data-action="quote" title="Quote" aria-label="Quote"></button>
<button type="button" class="toolbar-btn" data-action="bullet" title="Bullet list" aria-label="Bullet list"></button>
<button type="button" class="toolbar-btn" data-action="numbered" title="Numbered list" aria-label="Numbered list">1.</button>
<button type="button" class="toolbar-btn" data-action="link" title="Link" aria-label="Link">🔗</button>
<button type="button" class="toolbar-btn" data-action="code" title="Inline code" aria-label="Inline code">&lt;/&gt;</button>
<button type="button" class="toolbar-btn" data-action="codeblock" title="Code block" aria-label="Code block">{ }</button>
</div>
</div>
<textarea id="content" placeholder="Enter your secret message here... Supports Markdown too (#, **bold**, lists, code blocks, links)" dir="auto"></textarea>
</div>
<div class="input-help">Use the toolbar to insert Markdown quickly. The raw text is what gets encrypted, and the Markdown is rendered only after decryption.</div>
</div>
<div class="settings-grid">
<div class="form-group option-panel expiry-panel full-width-option">
<label for="expiresIn">⏱️ Expiration</label>
<select id="expiresIn">
<option value="3600">1 Hour</option>
<option value="86400" selected>1 Day</option>
<option value="604800">1 Week</option>
<option value="2592000">30 Days</option>
<option value="custom">Custom date &amp; time</option>
</select>
<div id="customExpiryWrapper" class="custom-expiry-wrapper">
<input type="datetime-local" id="customExpiry">
<small>Choose the exact expiration moment in your local timezone.</small>
</div>
</div>
<div class="security-stack">
<div class="option-panel option-panel-password">
<label class="feature-toggle">
<input type="checkbox" id="enablePassword" onchange="togglePassword()">
<span class="feature-toggle-main">
<span class="feature-icon">🔐</span>
<span class="feature-copy">
<span class="feature-title">Protect with password</span>
<span class="feature-description">Add a second secret that you share separately with the recipient.</span>
</span>
</span>
<span class="switch-ui" aria-hidden="true"></span>
</label>
<div id="passwordWrapper" class="password-input-wrapper">
<label for="passwordInput">Enter Password</label>
<input type="password" id="passwordInput" placeholder="Minimum 4 characters">
<div id="passwordStrength" class="password-strength" data-strength="empty">
<div class="password-strength-bar">
<div id="passwordStrengthFill" class="password-strength-fill"></div>
</div>
<div id="passwordStrengthLabel" class="password-strength-label">Password strength will appear here</div>
</div>
<small class="helper-text">This password will be required to decrypt the message. Share it separately.</small>
</div>
</div>
<div class="option-panel option-panel-burn">
<label class="feature-toggle">
<input type="checkbox" id="burnAfterRead">
<span class="feature-toggle-main">
<span class="feature-icon">🔥</span>
<span class="feature-copy">
<span class="feature-title">Burn after reading</span>
<span class="feature-description">Delete the encrypted paste automatically after the first successful view.</span>
</span>
</span>
<span class="switch-ui" aria-hidden="true"></span>
</label>
</div>
</div>
</div>
<button id="createBtn" class="btn" onclick="createPaste()">
<span id="btnText">🔐 Encrypt &amp; Save</span>
</button>
<div id="resultBox" class="result-box">
<div class="alert alert-success compact-alert">
<span></span>
<strong>Successfully encrypted.</strong>
</div>
<div id="passwordNotice" class="alert alert-info compact-alert" style="display: none;">
<span>🔑</span>
<div>
<strong>Password Protected</strong><br>
Remember to share the password separately. It is not in the URL.
</div>
</div>
<div class="share-link-group">
<label for="shareUrl">🔗 Full secure link</label>
<div class="url-container">
<input type="text" id="shareUrl" class="url-input" readonly>
<div class="url-actions">
<button id="copyUrlBtn" class="btn btn-copy" type="button" onclick="copyUrl()">📋 Copy</button>
<button id="copyShortUrlBtn" class="btn btn-copy" type="button" onclick="copyShortUrl()">⚡ Copy short</button>
</div>
</div>
<div class="helper-copy">The short link uses the compact format and still keeps the key in the URL fragment.</div>
</div>
<div class="meta-info">
⏰ Expires: <span id="expiryTime"></span> • 🔑 Key never leaves your browser • ✨ Full + short share links
</div>
</div>
</div>
<div class="card how-it-works">
<h2>🔍 How It Works</h2>
<div class="steps">
<div class="step">
<div class="step-number">1</div>
<div class="step-content">
<h3>Client-Side Encryption</h3>
<p>Your message is encrypted in your browser using AES-256-GCM before being sent to the server. The encryption key is generated locally and never transmitted.</p>
</div>
</div>
<div class="step">
<div class="step-number">2</div>
<div class="step-content">
<h3>Zero-Knowledge Storage</h3>
<p>The server only stores the encrypted ciphertext. It cannot read, decrypt, or access your original message. We have zero knowledge of your content.</p>
</div>
</div>
<div class="step">
<div class="step-number">3</div>
<div class="step-content">
<h3>Key in URL Fragment</h3>
<p>The decryption key is embedded in the URL fragment (after #) which never reaches the server. Only the recipient with the full URL can decrypt.</p>
</div>
</div>
<div class="step">
<div class="step-number">4</div>
<div class="step-content">
<h3>Password Protection (Optional)</h3>
<p>You can add an extra password layer. The password is used to derive the encryption key via PBKDF2 with 100,000 iterations. Share it separately.</p>
</div>
</div>
<div class="step">
<div class="step-number">5</div>
<div class="step-content">
<h3>Self-Destruction</h3>
<p>Choose burn-after-read to automatically delete the message after first view, or set a preset expiration or exact custom date and time.</p>
</div>
</div>
</div>
<div class="tech-specs">
<h3>🛡️ Technical Specifications</h3>
<div class="specs-grid">
<div class="spec-item">AES-256-GCM Encryption</div>
<div class="spec-item">PBKDF2 Key Derivation (100k iterations)</div>
<div class="spec-item">Random 12-byte IV per message</div>
<div class="spec-item">256-bit Encryption Keys</div>
<div class="spec-item">No Server-Side Logs</div>
<div class="spec-item">MySQL Database Storage</div>
<div class="spec-item">Web Crypto API (Native)</div>
<div class="spec-item">Custom Expiration Support</div>
<div class="spec-item">Markdown Rendering After Decryption</div>
</div>
</div>
</div>
<footer>
<p>🛡️ Zero-Knowledge Architecture • Server cannot read your data</p>
<p class="footer-subtitle">Built with privacy in mind. No tracking. No analytics. Open source.</p>
<div class="footer-manifesto">
<div class="footer-manifesto-tag">#InternetForAll</div>
<p><strong>Internet access is a fundamental human right.</strong></p>
<p>Restricting internet access violates human rights and limits freedom of expression, access to information, and the ability to communicate securely. We believe in free, open, and secure internet for everyone — regardless of borders, politics, or censorship.</p>
</div>
<div class="footer-links">
<a href="https://github.com/TheGreatAzizi/Secure-Pastebin-Self-Hosted/" target="_blank" rel="noopener" title="GitHub" aria-label="GitHub">
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.744.083-.729.083-.729 1.205.084 1.839 1.236 1.839 1.236 1.07 1.834 2.807 1.304 3.492.997.108-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.958-.266 1.983-.399 3.003-.404 1.02.005 2.045.138 3.005.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
</a>
<a href="https://x.com/the_azzi" target="_blank" rel="noopener" title="X" aria-label="X">
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M18.901 1.153h3.68l-8.04 9.19 9.458 12.504h-7.406l-5.8-7.584-6.637 7.584H.476l8.601-9.83L0 1.154h7.594l5.243 6.932 6.064-6.932Zm-1.293 19.487h2.039L6.486 3.24H4.298L17.608 20.64Z"/></svg>
</a>
<a href="https://t.me/luluch_code" target="_blank" rel="noopener" title="Telegram" aria-label="Telegram">
<svg width="18" height="18" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M9.993 15.674 9.62 20.92c.534 0 .765-.229 1.042-.504l2.502-2.394 5.185 3.796c.951.524 1.624.248 1.881-.875l3.408-15.97.001-.001c.302-1.41-.51-1.962-1.437-1.617L2.155 11.11c-1.367.534-1.346 1.296-.233 1.64l5.115 1.595L18.86 6.88c.556-.368 1.062-.164.646.204"/></svg>
</a>
</div>
<a class="footer-doc-link" href="/api/docs">API Docs</a>
</footer>
</div>
<script src="/script.js"></script>
</body>
</html>