Files
homelab/site/account.html
T

163 lines
9.0 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light">
<meta name="theme-color" content="#f0c94b">
<meta name="robots" content="noindex, nofollow">
<title>我的账户 / xiteng.site</title>
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/styles.css">
<script src="/account.js?v=2" defer></script>
</head>
<body class="admin-page">
<header class="topbar">
<nav class="shell nav" aria-label="账户导航">
<a class="brand" href="/">xiteng.site / account</a>
<div class="nav-links">
<a id="account-admin-link" href="/admin" hidden>系统管理</a>
<a href="/chat/">Chat</a>
<a href="/">公开主页</a>
</div>
</nav>
</header>
<main class="shell admin-main">
<section class="admin-heading">
<p class="eyebrow">PROFILE / SECURITY / KEY VAULT</p>
<h1>我的账户</h1>
<p>管理个人资料、密码、双因素认证、Passkey、登录会话和 AI Provider 凭据。</p>
<p id="account-session" class="admin-session" aria-live="polite">正在验证会话…</p>
</section>
<section class="admin-panel account-profile-panel">
<div class="admin-panel-heading"><div><p class="section-kicker">PROFILE</p><h2>个人资料</h2></div></div>
<div class="account-profile-layout">
<div class="account-avatar-card">
<img id="account-avatar" class="account-avatar" alt="当前用户头像" referrerpolicy="no-referrer">
<strong id="account-avatar-name">正在读取…</strong>
<span id="account-avatar-source" class="admin-help"></span>
<button id="account-avatar-refresh" class="admin-action" type="button">重新解析头像</button>
</div>
<form id="account-profile-form" class="admin-form compact">
<label>用户名<input id="account-username" disabled></label>
<label>显示名<input name="name" maxlength="150" required></label>
<label>邮箱<input name="email" type="email" maxlength="254" autocomplete="email"></label>
<button class="admin-action" type="submit">保存个人资料</button>
</form>
</div>
</section>
<section class="admin-panel">
<div class="admin-panel-heading">
<div><p class="section-kicker">SECURITY</p><h2>登录与安全</h2></div>
<button id="account-security-refresh" class="admin-action" type="button">刷新</button>
</div>
<div class="account-security-grid">
<section class="account-security-card">
<h3>密码</h3>
<p class="admin-help">生成 15 分钟有效的 Authentik 密码设置链接。现有会话不会自动注销。</p>
<button id="account-password" class="admin-action" type="button">修改密码</button>
</section>
<section class="account-security-card">
<div class="account-security-heading"><h3>TOTP 验证器</h3><button id="account-add-totp" class="admin-action" type="button">添加 TOTP</button></div>
<div id="account-totp" class="admin-list"><div class="loading-card">正在读取…</div></div>
</section>
<section class="account-security-card">
<div class="account-security-heading"><h3>Passkey</h3><button id="account-add-passkey" class="admin-action" type="button">添加 Passkey</button></div>
<div id="account-passkeys" class="admin-list"><div class="loading-card">正在读取…</div></div>
</section>
<section class="account-security-card account-sessions-card">
<div class="account-security-heading"><h3>登录会话</h3><button id="account-logout-all" class="admin-action dangerous" type="button">注销全部会话</button></div>
<div id="account-sessions" class="admin-list"><div class="loading-card">正在读取…</div></div>
</section>
</div>
</section>
<section class="admin-panel">
<div class="admin-panel-heading">
<div><p class="section-kicker">BUILT-IN + CUSTOM</p><h2>Provider Registry</h2></div>
<button id="account-refresh" class="admin-action" type="button">刷新</button>
</div>
<div class="admin-notice">只需填写 URL 与 API Key 即可先行探测;测试不会保存 Provider 或凭据。Backend Key 保存到 Key VaultFrontend Key 必须跳转到 Chat 后保存在 <code>xiteng.site/chat</code> 的浏览器存储中。</div>
<form id="account-provider-form" class="admin-form provider-editor-form">
<div class="provider-probe-fields">
<label>Provider URL<input name="baseUrl" type="url" required placeholder="https://api.example.com/v1"></label>
<label>API Key<input name="apiKey" type="password" maxlength="32768" autocomplete="new-password" placeholder="探测使用;Frontend 保存时会跳转到 Chat 重新输入"></label>
<button id="account-provider-test" class="admin-action" type="button">探测 Provider</button>
</div>
<details class="provider-advanced">
<summary>进阶设置</summary>
<div class="provider-advanced-grid">
<label>ID<input name="id" required maxlength="80" placeholder="自动根据域名生成"></label>
<label>名称<input name="name" required maxlength="160" placeholder="自动根据域名生成"></label>
<label>API 协议
<select name="api" required>
<option value="">自动探测</option>
<option value="openai-completions">OpenAI Completions</option>
<option value="openai-responses">OpenAI Responses</option>
<option value="anthropic-messages">Anthropic Messages</option>
<option value="google-generative-ai">Google Generative AI</option>
</select>
</label>
<label>连接
<select name="connectionType" required>
<option value="backend">Backend</option>
<option value="frontend">Frontend</option>
</select>
</label>
<label>认证
<select name="authType" required>
<option value="">自动探测</option>
<option value="bearer">Bearer</option>
<option value="header">Header</option>
<option value="none">None</option>
</select>
</label>
<label>认证 Header<input name="authHeader" maxlength="120" placeholder="x-api-key"></label>
<label>默认模型<input name="defaultModel" required maxlength="300" placeholder="探测后可从模型列表选择"></label>
<label>模型发现类型
<select name="discoveryType" required>
<option value="">根据 API 协议自动选择</option>
<option value="openai-models-list">OpenAI Models List</option>
<option value="anthropic-models-list">Anthropic Models List</option>
<option value="google-models-list">Google Models List</option>
</select>
</label>
<label>模型列表 URL<input name="discoveryUrl" type="url" placeholder="自动根据 Provider URL 生成"></label>
<label>Proxy 类型
<select name="proxyType">
<option value="">None</option>
<option value="http">HTTP</option>
<option value="https">HTTPS</option>
<option value="socks5">SOCKS5</option>
<option value="relay">Frontend Relay</option>
</select>
</label>
<label>Proxy URL<input name="proxyUrl" placeholder="socks5://proxy:1080" disabled></label>
<fieldset class="provider-credential-fields">
<legend>Proxy 凭据</legend>
<label>Proxy 用户名<input name="proxyUsername" autocomplete="off" disabled></label>
<label>Proxy 密码 / Relay Token<input name="proxyPassword" type="password" autocomplete="new-password" disabled></label>
</fieldset>
</div>
</details>
<div class="admin-actions provider-editor-actions">
<button class="admin-action" type="submit">保存 Provider 与凭据</button>
</div>
<div id="account-provider-test-result" class="provider-test-result" aria-live="polite"></div>
</form>
<div id="account-providers" class="admin-list"><div class="loading-card">正在读取 Provider…</div></div>
<div class="admin-panel-heading provider-credentials-heading"><div><p class="section-kicker">SAVED BACKEND SECRETS</p><h3>已保存的 Backend 凭据</h3></div></div>
<div id="account-credentials" class="admin-list"><div class="loading-card">正在读取凭据元数据…</div></div>
</section>
<section class="admin-panel">
<div class="admin-panel-heading"><div><p class="section-kicker">AUDIT</p><h2>我的审计记录</h2></div></div>
<div id="account-audit" class="admin-audit"></div>
</section>
</main>
</body>
</html>