From 5b8bacfc740b53ac0334a107301d6b1ad059737a Mon Sep 17 00:00:00 2001 From: yangtb2024 <164613316+yangtb2024@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:18:13 +0800 Subject: [PATCH] Update index.php --- index.php | 2548 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 1526 insertions(+), 1022 deletions(-) diff --git a/index.php b/index.php index a07316c..87b1819 100644 --- a/index.php +++ b/index.php @@ -2,984 +2,1472 @@ - - - 阅后即焚 - - - - - - - '; - } else { - echo ''; - } - } - ?> - - +.copy-button:hover { + background-color: #2563eb; +} +.copy-button.copied { + background-color: #059669; +} - +.copy-button i { + font-size: 1rem; +} -
+.copy-feedback { + position: fixed; + top: 1rem; + left: 50%; + transform: translateX(-50%) translateY(-1rem); + background: #3B82F6; + color: white; + padding: 0.75rem 1.5rem; + border-radius: 9999px; + font-size: 0.875rem; + font-weight: 500; + opacity: 0; + transition: opacity 0.3s, visibility 0.3s; + z-index: 50; + pointer-events: none; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + align-items: center; + gap: 0.5rem; +} - $expirySeconds) { - echo '
'; - echo '

设置的过期时间超过系统允许的最大值(' . $messageExpiry . ')。

'; - echo '
'; - exit; - } +.share-button:active { + transform: translateY(1px); +} - if (!empty($_POST['message'])) { - $content = $_POST['message']; - - $verificationCode = generateVerificationCode(); - $hashedVerificationCode = hashVerificationCode($verificationCode); - $hashedSenderPassword = hashPassword($senderPassword); - - $randomKey = generateEncryptionKey(); - $encryptedMessage = encrypt($content, $randomKey); - $encryptedSenderName = encrypt($senderName, $randomKey); - $encryptedSenderNote = encrypt($senderNote, $randomKey); - - $keyEncryptedWithVerificationCode = encrypt($randomKey, $hashedVerificationCode); - $keyEncryptedWithSenderPassword = $hashedSenderPassword ? encrypt($randomKey, $hashedSenderPassword) : null; - - $filename = generateRandomFilename(); - - if (!file_exists('messages')) mkdir('messages', 0755, true); - - $messageData = [ - 'senderNameEncrypted' => $encryptedSenderName, - 'senderNoteEncrypted' => $encryptedSenderNote, - 'senderPasswordHash' => $hashedSenderPassword, - 'messageEncrypted' => $encryptedMessage, - 'keyEncryptedWithVerificationCode' => $keyEncryptedWithVerificationCode, - 'keyEncryptedWithSenderPassword' => $keyEncryptedWithSenderPassword, - 'hashedVerificationCode' => $hashedVerificationCode, - 'createdAt' => time(), - 'expirySeconds' => $userExpirySeconds > 0 ? $userExpirySeconds : $expirySeconds - ]; - - file_put_contents($filename, json_encode($messageData), LOCK_EX); - - $messageLink = "?file=" . urlencode(basename($filename)) . "&code=" . urlencode($verificationCode); - - echo '
'; - echo '

您的阅后即焚链接

'; - echo ''; - echo '
'; - echo ''; - } else { - echo '
'; - echo '

消息不能为空。

'; - echo '
'; - exit; - } - } else if (isset($_GET['file']) && isset($_GET['code'])) { - $filename = basename($_GET['file']); - $verificationCode = sanitizeInput($_GET['code']); +.share-button i { + font-size: 0.875rem; +} + +.copy-feedback { + position: fixed; + top: 1rem; + left: 50%; + transform: translateX(-50%) translateY(-1rem); + background: #3B82F6; + color: white; + padding: 0.75rem 1.5rem; + border-radius: 9999px; + font-size: 0.875rem; + font-weight: 500; + opacity: 0; + transition: opacity 0.3s, visibility 0.3s; + z-index: 50; + pointer-events: none; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + display: flex; + align-items: center; + gap: 0.5rem; +} + +.copy-feedback.show { + opacity: 1; + transform: translateX(-50%) translateY(0); +} + +.options-container { + display: flex; + align-items: center; + gap: 20px; + margin-bottom: 10px; +} + +@media (max-width: 640px) { + .options-container { + flex-direction: column; + gap: 15px; + } + + .options-container button { + width: 100%; + } +} + +.option-item { + display: flex; + align-items: center; + white-space: nowrap; +} + +.tab-active { + border-bottom: 2px solid #3b82f6; + color: #3b82f6; + background-color: #f8fafc; +} + +.editor-container { + border: 1px solid #e5e7eb; + border-radius: 0.375rem; + background-color: white; + overflow: hidden; +} - if (file_exists("messages/$filename")) { - $messageData = json_decode(file_get_contents("messages/$filename"), true); +.editor-toolbar { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.5rem; + border-bottom: 1px solid #e5e7eb; + background-color: #f8fafc; +} + +.editor-tabs { + display: flex; + gap: 1px; +} + +.editor-tab { + padding: 0.5rem 1rem; + font-size: 0.875rem; + cursor: pointer; + border: none; + background: none; +} + +.editor-options { + display: flex; + align-items: center; + gap: 1rem; +} + +.content-area { + padding: 1rem; +} + +.editor-content { + width: 100%; + height: 200px; + border: 1px solid #e5e7eb; + border-radius: 0.5rem; + padding: 0.5rem; + background-color: white; + overflow-y: auto; + position: relative; +} + +#message { +width: 100%; + height: 100%; + resize: none; + outline: none; + border: none; + padding: 0; + display: block; +} + +.auto-height .editor-container { + overflow: visible; +} + +.auto-height .editor-content { + height: auto; + min-height: 200px; + overflow: visible; + max-height: none; +} + +.auto-height #message { + height: 100% !important; +} + +.markdown { + line-height: 1.6; +} - $createdAt = isset($messageData['createdAt']) ? $messageData['createdAt'] : 0; - $currentTime = time(); - $messageExpirySeconds = isset($messageData['expirySeconds']) ? $messageData['expirySeconds'] : $expirySeconds; +.form-label { + display: block; + font-size: 1.1rem; + font-weight: bold; + color: #2d3748; + margin-bottom: 0.5rem; +} + +.form-label .optional, +.form-label .markdown-support, +.form-label .time-limit { + font-size: 0.875rem; + font-weight: normal; + color: #6B7280; + margin-left: 0.5rem; +} + +.form-label .optional, +.form-label .markdown-support, +.form-label .time-limit { + font-size: 0.875rem; + font-weight: normal; + color: #6B7280; + margin-left: 0.5rem; + text-sm text-gray-500 ml-2; +} + +.confirmation-container { + max-width: 500px; + margin: 2rem auto; + padding: 2rem; + background: #ffffff; + border-radius: 16px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + text-align: center; +} + +.confirmation-icon { + font-size: 3rem; + color: #3B82F6; + margin-bottom: 1.5rem; +} + +.confirmation-title { + font-size: 1.5rem; + font-weight: 600; + color: #1F2937; + margin-bottom: 1rem; +} + +.confirmation-text { + color: #4B5563; + margin-bottom: 1.5rem; + line-height: 1.6; +} + +.confirmation-buttons { + display: flex; + gap: 1rem; + justify-content: center; +} + +.confirm-button { + padding: 0.75rem 1.5rem; + background: #3B82F6; + color: white; + border: none; + border-radius: 8px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + min-width: 120px; +} + +.confirm-button:hover { + background: #2563EB; +} + +.back-button { + padding: 0.75rem 1.5rem; + background: #F3F4F6; + color: #4B5563; + border: none; + border-radius: 8px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; + min-width: 120px; +} + +.back-button:hover { + background: #E5E7EB; +} + +@media (max-width: 640px) { + .confirmation-container { + margin: 1rem; + padding: 1.5rem; + } + + .confirmation-buttons { + flex-direction: column; + } + + .confirm-button, + .back-button { + width: 100%; + } +} + +.content-box.markdown-mode #displayContent { + line-height: 1.6; +} + +.content-box.markdown-mode #displayContent h1 { + font-size: 28px; + font-weight: bold; + margin: 16px 0; +} + +.content-box.markdown-mode #displayContent h2 { + font-size: 24px; + font-weight: bold; + margin: 14px 0; +} + +.content-box.markdown-mode #displayContent h3 { + font-size: 20px; + font-weight: bold; + margin: 12px 0; +} + +.content-box.markdown-mode #displayContent h4 { + font-size: 18px; + font-weight: bold; + margin: 10px 0; +} + +.content-box.markdown-mode #displayContent h5 { + font-size: 16px; + font-weight: bold; + margin: 8px 0; +} + +.content-box.markdown-mode #displayContent h6 { + font-size: 14px; + font-weight: bold; + margin: 8px 0; +} + +.content-box.markdown-mode #displayContent p { + font-size: 14px; + margin: 8px 0; +} + +.content-box.markdown-mode #displayContent > h1:first-child, +.content-box.markdown-mode #displayContent > h2:first-child, +.content-box.markdown-mode #displayContent > h3:first-child, +.content-box.markdown-mode #displayContent > h4:first-child, +.content-box.markdown-mode #displayContent > h5:first-child, +.content-box.markdown-mode #displayContent > h6:first-child { + margin-top: 0; +} + +.content-box.markdown-mode #displayContent h1 { font-size: 32px; } +.content-box.markdown-mode #displayContent h2 { font-size: 24px; } +.content-box.markdown-mode #displayContent h3 { font-size: 20px; } +.content-box.markdown-mode #displayContent h4 { font-size: 16px; } +.content-box.markdown-mode #displayContent h5 { font-size: 14px; } +.content-box.markdown-mode #displayContent h6 { font-size: 12px; } +.content-box.markdown-mode #displayContent h1, +.content-box.markdown-mode #displayContent h2, +.content-box.markdown-mode #displayContent h3, +.content-box.markdown-mode #displayContent h4, +.content-box.markdown-mode #displayContent h5, +.content-box.markdown-mode #displayContent h6 { + font-weight: bold; + margin: 16px 0 8px 0; +} + +.content-box.markdown-mode #displayContent h1, +.preview-content h1 { font-size: 32px; } + +.content-box.markdown-mode #displayContent h2, +.preview-content h2 { font-size: 24px; } + +.content-box.markdown-mode #displayContent h3, +.preview-content h3 { font-size: 20px; } + +.content-box.markdown-mode #displayContent h4, +.preview-content h4 { font-size: 16px; } + +.content-box.markdown-mode #displayContent h5, +.preview-content h5 { font-size: 14px; } + +.content-box.markdown-mode #displayContent h6, +.preview-content h6 { font-size: 12px; } + +.content-box.markdown-mode #displayContent h1, +.content-box.markdown-mode #displayContent h2, +.content-box.markdown-mode #displayContent h3, +.content-box.markdown-mode #displayContent h4, +.content-box.markdown-mode #displayContent h5, +.content-box.markdown-mode #displayContent h6, +.preview-content h1, +.preview-content h2, +.preview-content h3, +.preview-content h4, +.preview-content h5, +.preview-content h6 { + font-weight: bold; + margin: 16px 0 8px 0; + line-height: 1.4; +} + +.preview-content { + padding: 16px; + background: #fff; + border: 1px solid #e5e7eb; + border-radius: 0.5rem; + min-height: 100px; +} + + + + + +
+ + $expirySeconds) { + echo '
'; + echo '

设置的过期时间超过系统允许的最大值(' . $messageExpiry . ')。

'; + echo '
'; + exit; + } + + if (!empty($_POST['message'])) { + $content = $_POST['message']; + + $verificationCode = generateVerificationCode(); + $hashedVerificationCode = hashVerificationCode($verificationCode); + $hashedSenderPassword = hashPassword($senderPassword); + + $randomKey = generateEncryptionKey(); + $encryptedMessage = encrypt($content, $randomKey); + $encryptedSenderName = encrypt($senderName, $randomKey); + $encryptedSenderNote = encrypt($senderNote, $randomKey); + + $keyEncryptedWithVerificationCode = encrypt($randomKey, $hashedVerificationCode); + $keyEncryptedWithSenderPassword = $hashedSenderPassword ? encrypt($randomKey, $hashedSenderPassword) : null; + + $filename = generateRandomFilename(); + + if (!file_exists('messages')) mkdir('messages', 0755, true); + + $messageData = [ + 'senderNameEncrypted' => $encryptedSenderName, + 'senderNoteEncrypted' => $encryptedSenderNote, + 'senderPasswordHash' => $hashedSenderPassword, + 'messageEncrypted' => $encryptedMessage, + 'keyEncryptedWithVerificationCode' => $keyEncryptedWithVerificationCode, + 'keyEncryptedWithSenderPassword' => $keyEncryptedWithSenderPassword, + 'hashedVerificationCode' => $hashedVerificationCode, + 'createdAt' => time(), + 'expirySeconds' => $userExpirySeconds > 0 ? $userExpirySeconds : $expirySeconds + ]; + + file_put_contents($filename, json_encode($messageData), LOCK_EX); + + $messageLink = "?file=" . urlencode(basename($filename)) . "&code=" . urlencode($verificationCode); + + echo '
+
+

链接生成成功

+

此链接仅可查看一次,阅读后将自动销毁

+
+ +
+ + + +
+
+
+ 复制成功 +
+ + '; + } else { + echo '
'; + echo '

消息不能为空。

'; + echo '
'; + exit; + } +} else if (isset($_GET['file']) && isset($_GET['code'])) { + $filename = basename($_GET['file']); + $verificationCode = sanitizeInput($_GET['code']); + + if (file_exists("messages/$filename")) { + $messageData = json_decode(file_get_contents("messages/$filename"), true); + + $createdAt = isset($messageData['createdAt']) ? $messageData['createdAt'] : 0; + $currentTime = time(); + $messageExpirySeconds = isset($messageData['expirySeconds']) ? $messageData['expirySeconds'] : $expirySeconds; + + if ($currentTime - $createdAt > $messageExpirySeconds) { + unlink("messages/$filename"); + echo '
'; + echo '

消息已过期。

'; + echo '
'; + exit; + } + + if (isset($messageData['hashedVerificationCode']) && hashVerificationCode($verificationCode) === $messageData['hashedVerificationCode']) { + if (isset($_GET['confirm'])) { + $enteredSenderPassword = isset($_POST['senderPassword']) ? sanitizeInput($_POST['senderPassword']) : ''; + $hashedEnteredSenderPassword = hashPassword($enteredSenderPassword); + + if (is_null($messageData['senderPasswordHash']) || (!empty($enteredSenderPassword) && $hashedEnteredSenderPassword === $messageData['senderPasswordHash'])) { + unlink("messages/$filename"); + + if (is_null($messageData['senderPasswordHash'])) { + $randomKey = decrypt($messageData['keyEncryptedWithVerificationCode'], $messageData['hashedVerificationCode']); + } else { + $randomKey = decrypt($messageData['keyEncryptedWithSenderPassword'], $hashedEnteredSenderPassword); + } + + + $decryptedMessage = decrypt($messageData['messageEncrypted'], $randomKey); + $decryptedSenderName = decrypt($messageData['senderNameEncrypted'], $randomKey); + $decryptedSenderNote = decrypt($messageData['senderNoteEncrypted'], $randomKey); + + echo '
'; + + if (!empty($decryptedSenderName) || !empty($decryptedSenderNote)) { ?> +
+ + + + () + +
+ +
+ + 无发件人(无备注) +
+ + +
+
+ + +
+ +
+ +
+
+ + +
+ + ' : - nl2br(htmlspecialchars($decryptedMessage))) . - '
'; - echo ''; - echo '
'; - - echo ''; - echo ''; - echo '
'; - } else { - echo '
'; - echo '

请输入密码

'; - echo '

此消息受密码保护,只能查看一次,查看后将被永久删除。

'; - echo '
'; - echo ''; - echo '
- - -
'; - echo '
'; - echo '
'; - } - } else { - if (!is_null($messageData['senderPasswordHash'])) { - echo '
'; - echo '

请输入密码

'; - echo '

此消息受密码保护,只能查看一次,查看后将被永久删除。

'; - echo '
'; - echo ''; - echo '
- - -
'; - echo '
'; - echo '
'; - } else { - echo '
'; - echo '

确认查看消息?

'; - echo '

此消息只能查看一次,查看后将被永久删除。

'; - echo '
'; - echo '
- - -
'; - echo '
'; - echo '
'; - } - } + } + + function toggleHeight(checkbox) { + const messageText = document.getElementById('message-text'); + const heightLabel = document.getElementById('heightLabel'); + + if (checkbox.checked) { + heightLabel.classList.add('active'); + messageText.classList.add('auto-height'); } else { - echo '
'; - echo '

验证码错误或链接已失效。

'; - echo '
'; + heightLabel.classList.remove('active'); + messageText.classList.remove('auto-height'); + messageText.scrollTop = 0; } + } + + document.addEventListener('DOMContentLoaded', function() { + const rawContent = document.getElementById('rawContent'); + const displayContent = document.getElementById('displayContent'); + rawContent.textContent = displayContent.textContent; + }); + + function copyMessage() { + const messageText = document.getElementById('message-text'); + const text = messageText.innerText; + + navigator.clipboard.writeText(text).then(() => { + const copyButton = document.querySelector('.copy-button'); + const originalContent = copyButton.innerHTML; + + copyButton.innerHTML = '已复制'; + copyButton.style.background = '#059669'; + + setTimeout(() => { + copyButton.innerHTML = originalContent; + copyButton.style.background = ''; + }, 2000); + }).catch(err => { + console.error('复制失败:', err); + const copyButton = document.querySelector('.copy-button'); + const originalContent = copyButton.innerHTML; + + copyButton.innerHTML = '复制失败'; + copyButton.style.background = '#DC2626'; + + setTimeout(() => { + copyButton.innerHTML = originalContent; + copyButton.style.background = ''; + }, 2000); + }); + } + + '; } else { - echo '
'; - echo '

链接已失效。

'; - echo '
'; - } - } else { ?> - -
-

发送阅后即焚消息

-
-
- - -
-
- - -
-
- - -
-
- -
-
-
- - -
-
- -
-
-
-
- -
-
- -
-
-
- -
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
- -
+ echo '
'; + echo '

请输入密码

'; + echo '

此消息受密码保护,查看后将被永久删除。

'; + $errorMsg = ''; + if (isset($_POST['senderPassword'])) { + if (!isset($messageData['password']) || !password_verify($_POST['senderPassword'], $messageData['password'])) { + $errorMsg = '密码错误,请重试'; + } + } + ?> +
+ +
+
+
+ + +
+ +
+ + +
+
+ + '; + } + } else { + if (!is_null($messageData['senderPasswordHash'])) { + echo '
'; + echo '

请输入密码

'; + echo '

此消息受密码保护,查看后将被永久删除。

'; + $errorMsg = ''; + if (isset($_POST['senderPassword'])) { + if (!isset($messageData['password']) || !password_verify($_POST['senderPassword'], $messageData['password'])) { + $errorMsg = '密码错误,请重试'; + } + } + ?> +
+ +
+
+
+ + +
+ +
+ + +
+
+ + '; + } else { + echo '
'; + echo '
'; + echo ''; + echo '
'; + echo '

确认查看消息?

'; + echo '

此消息只能查看一次,查看后将被永久删除。请确认是否现在查看?

'; + echo '
'; + echo '
'; + echo ''; + echo '
'; + echo ''; + echo ' 返回'; + echo ''; + echo '
'; + echo '
'; + } + } + } else { + echo '
'; + echo '

验证码错误或链接已失效。

'; + echo '
'; + } + } else { + echo '
'; + echo '

链接已失效。

'; + echo '
'; + } +} else { ?> + +
+

发送阅后即焚消息

+
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+
+ + +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ +
+
+ + + +
- - -
+