chore: add and update gitignore rules for project files

add a comprehensive gitignore file to exclude unnecessary files like dependencies, runtime data, uploads, local configs and debug temporary files
This commit is contained in:
yangxiangyuan
2026-06-12 09:48:21 +08:00
parent c223c79b36
commit d3856cb52a
60 changed files with 13144 additions and 525 deletions
@@ -2,8 +2,8 @@
"_comment": "私人剪贴板工具的前端鉴权配置",
"enable_auth_comment": "true:启用鉴权;false:关闭鉴权并放开访问",
"enable_auth": true,
"max_age_days_comment": "鉴权 Cookie 有效期(天),范围建议 1~365",
"max_age_days": 30,
"max_age_days_comment": "鉴权 Cookie 有效期(天),1天后过期需重新登录",
"max_age_days": 1,
"cookieName_comment": "鉴权 Cookie 名称,建议保持默认",
"cookieName": "private_clipboard_gate",
"requireGuid_comment": "true:入口必须带 guid 参数;false:允许仅凭 token 或会话访问",
@@ -11,5 +11,5 @@
"guidParam_comment": "URL 中的 GUID 参数名,建议使用小写 guid",
"guidParam": "guid",
"guidValue_comment": "GUID 参数值,建议使用高强度随机长串并定期更换",
"guidValue": "SD9KK-LW32S-9KJJH-JJH43-LJ432J"
"guidValue": "db8a2f1c-90e7-4b5a-a1d2-c3e4f5067890"
}
@@ -4,6 +4,68 @@ body {
font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
}
/* ===== 登录界面 ===== */
.pc-auth-card {
max-width: 360px;
margin: 120px auto 0;
padding: 32px 28px;
background: #1a1d24;
border: 1px solid #2a2d35;
border-radius: 12px;
text-align: center;
}
.pc-auth-card h2 {
margin: 0 0 24px;
font-size: 20px;
font-weight: 600;
}
.pc-auth-form {
display: flex;
flex-direction: column;
gap: 12px;
}
.pc-auth-form input {
padding: 10px 12px;
background: #0f1115;
border: 1px solid #2a2d35;
border-radius: 6px;
color: #e6e8ee;
font-size: 14px;
outline: none;
}
.pc-auth-form input:focus {
border-color: #4a9eff;
}
.pc-auth-status {
margin-top: 12px;
font-size: 13px;
color: #ff6b6b;
}
.pc-auth-status.ok {
color: #4ade80;
}
/* ===== 顶部栏 ===== */
.pc-topbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.pc-topbar-title {
font-size: 20px;
font-weight: 600;
}
.pc-btn-logout {
padding: 6px 16px;
font-size: 13px;
background: #2a2d35;
border: 1px solid #3a3d45;
}
.pc-btn-logout:hover {
background: #3a3d45;
}
.pc-main {
max-width: 1100px;
margin: 0 auto;
@@ -736,6 +736,99 @@ const createFolder = async () => {
}
const init = async () => {
// ===== set_token 处理:必须在 clearUrlQuery 之前 =====
try {
const params = new URLSearchParams(window.location.search)
const setToken = params.get('set_token')
if (setToken) {
localStorage.setItem('toolbox_creds_token', setToken)
}
} catch {}
clearUrlQuery()
// ===== 登录逻辑 =====
const $auth = $('pc-auth')
const $app = $('pc-app')
const $status = $('pc-auth-status')
const $user = $('pc-login-user')
const $pass = $('pc-login-pass')
async function doLogin() {
try {
const username = $user.value.trim()
const password = $pass.value
const res = await fetch(apiBase + '/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
credentials: 'same-origin',
cache: 'no-store'
})
const data = await res.json()
if (!data.ok) throw new Error(data.error || '登录失败')
$auth.style.display = 'none'
$app.style.display = ''
initApp()
} catch (e) {
$status.textContent = String(e.message || e)
$status.style.display = ''
$status.className = 'pc-auth-status'
}
}
async function doLogout() {
try {
await fetch(apiBase + '/auth/logout', { method: 'POST', credentials: 'same-origin' })
} catch {}
$app.style.display = 'none'
$auth.style.display = ''
$pass.value = ''
$status.textContent = '已注销'
$status.className = 'pc-auth-status ok'
$status.style.display = ''
}
// 自动填充
async function tryAutoFill() {
try {
const token = localStorage.getItem('toolbox_creds_token') || ''
if (!token) return
const res = await fetch(apiBase + '/auth/local_creds?token=' + encodeURIComponent(token), {
credentials: 'same-origin',
cache: 'no-store'
})
const data = await res.json().catch(() => null)
if (data && data.ok && data.creds) {
if (data.creds.username) $user.value = data.creds.username
if (data.creds.password) $pass.value = data.creds.password
}
} catch {}
}
$('pc-btn-login').onclick = doLogin
$('pc-btn-logout').onclick = doLogout
$user.removeAttribute('readonly')
$pass.removeAttribute('readonly')
$pass.addEventListener('keydown', e => { if (e.key === 'Enter') doLogin() })
// 先检查是否已登录
try {
const res = await fetch(apiBase + '/auth/me', { credentials: 'same-origin', cache: 'no-store' })
const data = await res.json()
if (data && data.ok) {
$auth.style.display = 'none'
$app.style.display = ''
initApp()
return
}
} catch {}
// 未登录,尝试自动填充
await tryAutoFill()
}
const initApp = async () => {
clearUrlQuery()
const isMobile = detectMobile()
const refreshBtn = $('pc-refresh')
+17 -1
View File
@@ -9,7 +9,23 @@
<link rel="stylesheet" href="/tools/private_clipboard/clipboard.css" />
</head>
<body>
<main class="pc-main">
<!-- 登录界面 -->
<section id="pc-auth" class="pc-auth-card">
<h2>私人剪贴板 - 登录</h2>
<div class="pc-auth-form" autocomplete="off">
<input id="pc-login-user" placeholder="用户名" autocomplete="off" readonly />
<input id="pc-login-pass" placeholder="密码" type="password" autocomplete="off" readonly />
<button id="pc-btn-login" class="btn">登录</button>
</div>
<div id="pc-auth-status" class="pc-auth-status" style="display:none"></div>
</section>
<!-- 主应用界面 -->
<main id="pc-app" class="pc-main" style="display:none">
<div class="pc-topbar">
<span class="pc-topbar-title">私人剪贴板</span>
<button id="pc-btn-logout" class="btn pc-btn-logout" type="button">注销</button>
</div>
<section class="pc-input">
<div id="paste-zone" class="pc-paste-zone pc-desktop-only" tabindex="0">
<div class="pc-paste-text">在这里粘贴文字 / 图片 / 文件</div>