218 lines
10 KiB
HTML
218 lines
10 KiB
HTML
<!DOCTYPE html>
|
|||
|
|
<html lang="zh-CN">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
|
<link rel="stylesheet" href="popup.css">
|
||
|
|
<title>Auto Login Manager</title>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<!-- 锁定/设置口令覆盖层 -->
|
||
|
|
<div id="lockScreen" class="lock-screen">
|
||
|
|
<div class="lock-card">
|
||
|
|
<img src="icons/icon128.png" alt="logo" class="lock-logo">
|
||
|
|
<h2 id="lockTitle">设置口令</h2>
|
||
|
|
<p id="lockHint" class="lock-hint">口令用于加密存储所有配置,忘记将无法恢复</p>
|
||
|
|
<div class="form-group">
|
||
|
|
<input type="password" id="lockPassword" placeholder="请输入口令" autocomplete="off">
|
||
|
|
</div>
|
||
|
|
<div class="form-group" id="lockConfirmGroup">
|
||
|
|
<label for="lockPasswordConfirm">确认口令</label>
|
||
|
|
<input type="password" id="lockPasswordConfirm" placeholder="再次输入口令" autocomplete="off">
|
||
|
|
</div>
|
||
|
|
<div class="lock-warn" id="lockWarn"></div>
|
||
|
|
<button type="button" id="lockSubmitBtn" class="btn-primary lock-submit">设置口令</button>
|
||
|
|
<p class="lock-footnote">口令仅用于本地加密,不会上传到任何服务器</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="container" id="mainContainer" style="display:none;">
|
||
|
|
<header>
|
||
|
|
<div class="header-title">
|
||
|
|
<img src="icons/icon128.png" alt="logo" class="header-logo">
|
||
|
|
<h1>Auto Login Manager</h1>
|
||
|
|
<button type="button" id="lockBtn" class="btn-lock" title="锁定(清除内存中的明文)">🔒 锁定</button>
|
||
|
|
</div>
|
||
|
|
<div class="env-bar">
|
||
|
|
<label class="env-label">当前环境</label>
|
||
|
|
<div class="env-controls">
|
||
|
|
<select id="envSelect" class="env-select"></select>
|
||
|
|
<button type="button" id="addEnvBtn" class="btn-env" title="新建环境">+</button>
|
||
|
|
<button type="button" id="renameEnvBtn" class="btn-env" title="重命名当前环境">✎</button>
|
||
|
|
<button type="button" id="deleteEnvBtn" class="btn-env btn-env-danger" title="删除当前环境">🗑</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<section class="add-section">
|
||
|
|
<h2>添加域名配置</h2>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="domain">域名 / URL 匹配规则</label>
|
||
|
|
<div class="domain-wrapper">
|
||
|
|
<input type="text" id="domain" placeholder="example.com 或 *.example.com 或 site.com/admin/*">
|
||
|
|
<button type="button" id="fillDomain" class="btn-fill-domain" title="填入当前标签页域名">填入当前域名</button>
|
||
|
|
</div>
|
||
|
|
<small>支持通配符 *。带 / 时按 hostname+path 匹配,如 oa.com/login/*;不带 / 时只匹配域名</small>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="alias">别名(可选)</label>
|
||
|
|
<input type="text" id="alias" placeholder="例如: 公司OA、GitLab、邮箱">
|
||
|
|
<small>方便识别该配置,留空则显示域名</small>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="username">用户名</label>
|
||
|
|
<input type="text" id="username" placeholder="输入用户名">
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="password">密码</label>
|
||
|
|
<div class="password-wrapper">
|
||
|
|
<input type="password" id="password" placeholder="输入密码">
|
||
|
|
<button class="toggle-pwd" type="button" data-target="password">显示</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="form-row">
|
||
|
|
<div class="form-group form-group-inline">
|
||
|
|
<label for="autoSubmit">自动提交登录</label>
|
||
|
|
<select id="autoSubmit">
|
||
|
|
<option value="true">是 - 自动点击登录按钮</option>
|
||
|
|
<option value="false">否 - 仅填充不提交</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
<div class="form-group form-group-inline">
|
||
|
|
<label for="enabled">启用</label>
|
||
|
|
<label class="toggle-switch">
|
||
|
|
<input type="checkbox" id="enabled" checked>
|
||
|
|
<span class="toggle-slider"></span>
|
||
|
|
</label>
|
||
|
|
<small>关闭后该配置不再参与匹配(保留数据)</small>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="delayMs">填充延迟(毫秒,可选)</label>
|
||
|
|
<input type="number" id="delayMs" min="0" max="10000" step="100" placeholder="留空=默认 300ms,可填 500-2000 用于 SPA 页面">
|
||
|
|
<small>某些页面(Ant Design、ASP.NET)需 JS 初始化,立即填充会失效</small>
|
||
|
|
</div>
|
||
|
|
<details class="selector-help">
|
||
|
|
<summary>高级选项:自定义输入框和登录按钮位置(选填)</summary>
|
||
|
|
<div class="selector-help-body">
|
||
|
|
<p class="help-tip">下面三项通常<strong>留空即可</strong>,插件会自动找到登录框。只有当自动填充失败、或填错位置时才需要填。</p>
|
||
|
|
<p class="help-step">1. 在登录页面按 <kbd>F12</kbd> 打开开发者工具,切到"Elements(元素)"标签</p>
|
||
|
|
<p class="help-step">2. 点开发者工具左上角的 <span class="icon-arrow">箭头图标</span>,再去点页面上的输入框/按钮</p>
|
||
|
|
<p class="help-step">3. 工具会跳到对应的 HTML 行,在 <code><input></code> 或 <code><button></code> 标签上看 <code>id</code>、<code>name</code>、<code>class</code>、<code>type</code> 属性</p>
|
||
|
|
<p class="help-step">4. 按 <span class="rule-tag">#id</span>、<span class="rule-tag">.class</span>、<span class="rule-tag">[name=xxx]</span>、<span class="rule-tag">tag[属性=值]</span> 规则组合填写即可</p>
|
||
|
|
</div>
|
||
|
|
</details>
|
||
|
|
<div class="form-group">
|
||
|
|
<label>用户名输入框位置</label>
|
||
|
|
<input type="text" id="usernameSelector" placeholder="留空=自动查找,如 #username 或 input[name=account]">
|
||
|
|
<small>留空即可。填错会导致用户名填不进框。</small>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label>密码输入框位置</label>
|
||
|
|
<input type="text" id="passwordSelector" placeholder="留空=自动查找,如 #password 或 input[type=password]">
|
||
|
|
<small>留空即可。填错会导致密码填不进框。</small>
|
||
|
|
</div>
|
||
|
|
<div class="form-group">
|
||
|
|
<label>登录按钮位置</label>
|
||
|
|
<input type="text" id="submitSelector" placeholder="留空=自动查找,如 #loginBtn 或 button[type=submit]">
|
||
|
|
<small>留空即可。填错会导致不会自动点击登录。</small>
|
||
|
|
</div>
|
||
|
|
<button id="addBtn" class="btn-primary">添加配置</button>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="list-section">
|
||
|
|
<div class="list-header">
|
||
|
|
<h2>已配置域名</h2>
|
||
|
|
<div class="list-actions">
|
||
|
|
<button type="button" id="exportBtn" class="btn-io">导出</button>
|
||
|
|
<button type="button" id="importBtn" class="btn-io">导入</button>
|
||
|
|
<input type="file" id="importFile" accept="application/json,.json" hidden>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div id="configList" class="config-list">
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="current-section">
|
||
|
|
<button id="fillCurrent" class="btn-secondary">在当前页面填充</button>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<footer class="footer">
|
||
|
|
<p class="powered-by">power by chenxuan</p>
|
||
|
|
</footer>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="toast" class="toast"></div>
|
||
|
|
|
||
|
|
<div id="envModal" class="modal">
|
||
|
|
<div class="modal-content">
|
||
|
|
<h3 id="envModalTitle">新建环境</h3>
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="envNameInput">环境名称</label>
|
||
|
|
<input type="text" id="envNameInput" placeholder="例如: 个人 / 测试 / 生产 / 客户A">
|
||
|
|
</div>
|
||
|
|
<div class="preset-env-tags" id="presetEnvTags">
|
||
|
|
<span class="preset-tag" data-name="个人">个人</span>
|
||
|
|
<span class="preset-tag" data-name="测试">测试</span>
|
||
|
|
<span class="preset-tag" data-name="生产">生产</span>
|
||
|
|
<span class="preset-tag" data-name="开发">开发</span>
|
||
|
|
<span class="preset-tag" data-name="预发">预发</span>
|
||
|
|
</div>
|
||
|
|
<div class="modal-warn" id="envModalWarn" style="display:none;"></div>
|
||
|
|
<div class="modal-actions">
|
||
|
|
<button type="button" id="envModalCancel" class="btn-edit">取消</button>
|
||
|
|
<button type="button" id="envModalConfirm" class="btn-primary">确认</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="pwdModal" class="modal">
|
||
|
|
<div class="modal-content">
|
||
|
|
<h3 id="modalTitle">加密导出</h3>
|
||
|
|
<div id="encryptToggleGroup" class="form-group modal-toggle">
|
||
|
|
<label class="toggle-label">
|
||
|
|
<input type="checkbox" id="encryptToggle" checked>
|
||
|
|
<span>加密导出文件</span>
|
||
|
|
</label>
|
||
|
|
<small>勾选后用口令加密;不勾选则导出明文 JSON</small>
|
||
|
|
</div>
|
||
|
|
<div id="pwdFields" class="modal-fields">
|
||
|
|
<div class="form-group">
|
||
|
|
<label for="modalPwd">口令</label>
|
||
|
|
<div class="password-wrapper">
|
||
|
|
<input type="password" id="modalPwd" placeholder="输入口令">
|
||
|
|
<button class="toggle-pwd" type="button" data-target="modalPwd">显示</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="form-group" id="confirmGroup">
|
||
|
|
<label for="modalPwdConfirm">确认口令</label>
|
||
|
|
<div class="password-wrapper">
|
||
|
|
<input type="password" id="modalPwdConfirm" placeholder="再次输入口令">
|
||
|
|
<button class="toggle-pwd" type="button" data-target="modalPwdConfirm">显示</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="modal-warn" id="modalWarn">口令将用于 AES-GCM 加密,无法找回,请妥善保存</div>
|
||
|
|
<div class="strength-block" id="strengthBlock">
|
||
|
|
<div class="strength-bar-bg">
|
||
|
|
<div class="strength-bar-fg" id="strengthBar"></div>
|
||
|
|
</div>
|
||
|
|
<div class="strength-info">
|
||
|
|
<span id="strengthLabel">尚未输入</span>
|
||
|
|
<span id="crackTime"></span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="modal-actions">
|
||
|
|
<button type="button" id="modalCancel" class="btn-edit">取消</button>
|
||
|
|
<button type="button" id="modalConfirm" class="btn-primary">确认</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<script src="utils.js"></script>
|
||
|
|
<script src="env-store.js"></script>
|
||
|
|
<script src="crypto-store.js"></script>
|
||
|
|
<script src="popup.js"></script>
|
||
|
|
</body>
|
||
|
|
</html>
|