mirror of
https://github.com/cnlimiter/codex-register.git
synced 2026-05-06 20:02:51 +08:00
fix: restore protocol baseline, resolve 403/400 registration errors, and fully remove deprecated playwright dependency
This commit is contained in:
5
static/favicon.svg
Normal file
5
static/favicon.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<rect width="64" height="64" rx="14" fill="#111827"/>
|
||||
<path d="M18 20h28v6H18zm0 10h20v6H18zm0 10h28v6H18z" fill="#f9fafb"/>
|
||||
<circle cx="46" cy="33" r="6" fill="#22c55e"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 246 B |
@@ -1055,6 +1055,7 @@ function resetButtons() {
|
||||
elements.cancelBtn.disabled = true;
|
||||
currentTask = null;
|
||||
currentBatch = null;
|
||||
isBatchMode = false;
|
||||
// 重置完成标志
|
||||
taskCompleted = false;
|
||||
batchCompleted = false;
|
||||
@@ -1280,13 +1281,12 @@ function connectBatchWebSocket(batchId) {
|
||||
if (!toastShown) {
|
||||
toastShown = true;
|
||||
if (data.status === 'completed') {
|
||||
const batchLabel = isOutlookBatchMode ? 'Outlook 批量' : '批量';
|
||||
addLog('success', `[完成] ${batchLabel}任务完成!成功: ${data.success}, 失败: ${data.failed}, 跳过: ${data.skipped || 0}`);
|
||||
addLog('success', `[完成] Outlook 批量任务完成!成功: ${data.success}, 失败: ${data.failed}, 跳过: ${data.skipped || 0}`);
|
||||
if (data.success > 0) {
|
||||
toast.success(`${batchLabel}注册完成,成功 ${data.success} 个`);
|
||||
toast.success(`Outlook 批量注册完成,成功 ${data.success} 个`);
|
||||
loadRecentAccounts();
|
||||
} else {
|
||||
toast.warning(`${batchLabel}注册完成,但没有成功注册任何账号`);
|
||||
toast.warning('Outlook 批量注册完成,但没有成功注册任何账号');
|
||||
}
|
||||
} else if (data.status === 'failed') {
|
||||
addLog('error', '[错误] 批量任务执行失败');
|
||||
|
||||
@@ -72,25 +72,6 @@ const elements = {
|
||||
editOutlookForm: document.getElementById('edit-outlook-form'),
|
||||
closeEditOutlookModal: document.getElementById('close-edit-outlook-modal'),
|
||||
cancelEditOutlook: document.getElementById('cancel-edit-outlook'),
|
||||
|
||||
// 收件箱模态框
|
||||
inboxModal: document.getElementById('inbox-modal'),
|
||||
closeInboxModal: document.getElementById('close-inbox-modal'),
|
||||
inboxRefreshBtn: document.getElementById('inbox-refresh-btn'),
|
||||
inboxOnlyUnseen: document.getElementById('inbox-only-unseen'),
|
||||
inboxLoading: document.getElementById('inbox-loading'),
|
||||
inboxTable: document.getElementById('inbox-table'),
|
||||
inboxTbody: document.getElementById('inbox-tbody'),
|
||||
inboxEmpty: document.getElementById('inbox-empty'),
|
||||
inboxModalEmail: document.getElementById('inbox-modal-email'),
|
||||
|
||||
// 邮件正文模态框
|
||||
emailDetailModal: document.getElementById('email-detail-modal'),
|
||||
closeEmailDetailModal: document.getElementById('close-email-detail-modal'),
|
||||
emailDetailSubject: document.getElementById('email-detail-subject'),
|
||||
emailDetailSender: document.getElementById('email-detail-sender'),
|
||||
emailDetailDate: document.getElementById('email-detail-date'),
|
||||
emailDetailBody: document.getElementById('email-detail-body'),
|
||||
};
|
||||
|
||||
const CUSTOM_SUBTYPE_LABELS = {
|
||||
@@ -183,12 +164,6 @@ function initEventListeners() {
|
||||
document.addEventListener('click', () => {
|
||||
document.querySelectorAll('.dropdown-menu.active').forEach(m => m.classList.remove('active'));
|
||||
});
|
||||
|
||||
// 收件箱模态框事件
|
||||
elements.closeInboxModal.addEventListener('click', () => elements.inboxModal.classList.remove('active'));
|
||||
elements.closeEmailDetailModal.addEventListener('click', () => elements.emailDetailModal.classList.remove('active'));
|
||||
elements.inboxRefreshBtn.addEventListener('click', () => loadInbox(currentInboxServiceId, true));
|
||||
elements.inboxOnlyUnseen.addEventListener('change', () => loadInbox(currentInboxServiceId));
|
||||
}
|
||||
|
||||
function toggleEmailMoreMenu(btn) {
|
||||
@@ -272,7 +247,6 @@ async function loadOutlookServices() {
|
||||
<td>${format.date(service.last_used)}</td>
|
||||
<td>
|
||||
<div style="display:flex;gap:4px;align-items:center;white-space:nowrap;">
|
||||
<button class="btn btn-secondary btn-sm" onclick="openInboxModal(${service.id}, '${escapeHtml(service.config?.email || service.name)}')">收件箱</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="editOutlookService(${service.id})">编辑</button>
|
||||
<div class="dropdown" style="position:relative;">
|
||||
<button class="btn btn-secondary btn-sm" onclick="event.stopPropagation();toggleEmailMoreMenu(this)">更多</button>
|
||||
@@ -813,57 +787,3 @@ async function handleEditOutlook(e) {
|
||||
toast.error('更新失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// ============== 收件箱 ==============
|
||||
|
||||
let currentInboxServiceId = null;
|
||||
|
||||
async function openInboxModal(serviceId, email) {
|
||||
currentInboxServiceId = serviceId;
|
||||
elements.inboxModalEmail.textContent = email;
|
||||
elements.inboxOnlyUnseen.checked = false;
|
||||
elements.inboxModal.classList.add('active');
|
||||
await loadInbox(serviceId);
|
||||
}
|
||||
|
||||
async function loadInbox(serviceId) {
|
||||
if (!serviceId) return;
|
||||
const onlyUnseen = elements.inboxOnlyUnseen.checked;
|
||||
elements.inboxLoading.style.display = 'block';
|
||||
elements.inboxTable.style.display = 'none';
|
||||
elements.inboxEmpty.style.display = 'none';
|
||||
elements.inboxEmpty.textContent = '暂无邮件';
|
||||
try {
|
||||
const params = new URLSearchParams({ count: 50, only_unseen: onlyUnseen });
|
||||
const data = await api.get(`/email-services/${serviceId}/inbox?${params}`);
|
||||
const emails = data.emails || [];
|
||||
elements.inboxLoading.style.display = 'none';
|
||||
if (emails.length === 0) {
|
||||
elements.inboxEmpty.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
elements.inboxTbody.innerHTML = emails.map(m => {
|
||||
const dataAttr = escapeHtml(JSON.stringify(m));
|
||||
return `<tr style="cursor:pointer;" onclick="showEmailDetail(JSON.parse(this.dataset.mail))" data-mail="${dataAttr}">
|
||||
<td style="text-align:center;">${m.is_read ? '' : '<span style="color:var(--primary);font-size:10px;">●</span>'}</td>
|
||||
<td style="max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="${escapeHtml(m.subject)}">${escapeHtml(m.subject) || '(无主题)'}</td>
|
||||
<td style="max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="${escapeHtml(m.sender)}">${escapeHtml(m.sender)}</td>
|
||||
<td>${format.date(m.received_at)}</td>
|
||||
</tr>`;
|
||||
}).join('');
|
||||
elements.inboxTable.style.display = 'table';
|
||||
} catch (e) {
|
||||
elements.inboxLoading.style.display = 'none';
|
||||
elements.inboxEmpty.style.display = 'block';
|
||||
elements.inboxEmpty.textContent = '加载失败:' + (e.message || '未知错误');
|
||||
console.error('加载收件箱失败:', e);
|
||||
}
|
||||
}
|
||||
|
||||
function showEmailDetail(mail) {
|
||||
elements.emailDetailSubject.textContent = mail.subject || '(无主题)';
|
||||
elements.emailDetailSender.textContent = mail.sender || '';
|
||||
elements.emailDetailDate.textContent = format.date(mail.received_at);
|
||||
elements.emailDetailBody.textContent = mail.body || mail.body_preview || '(无正文)';
|
||||
elements.emailDetailModal.classList.add('active');
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ const elements = {
|
||||
proxiesTable: document.getElementById('proxies-table'),
|
||||
addProxyBtn: document.getElementById('add-proxy-btn'),
|
||||
testAllProxiesBtn: document.getElementById('test-all-proxies-btn'),
|
||||
deleteDisabledProxiesBtn: document.getElementById('delete-disabled-proxies-btn'),
|
||||
addProxyModal: document.getElementById('add-proxy-modal'),
|
||||
proxyItemForm: document.getElementById('proxy-item-form'),
|
||||
closeProxyModal: document.getElementById('close-proxy-modal'),
|
||||
@@ -207,10 +206,6 @@ function initEventListeners() {
|
||||
elements.testAllProxiesBtn.addEventListener('click', handleTestAllProxies);
|
||||
}
|
||||
|
||||
if (elements.deleteDisabledProxiesBtn) {
|
||||
elements.deleteDisabledProxiesBtn.addEventListener('click', handleDeleteDisabledProxies);
|
||||
}
|
||||
|
||||
if (elements.closeProxyModal) {
|
||||
elements.closeProxyModal.addEventListener('click', closeProxyModal);
|
||||
}
|
||||
@@ -678,16 +673,16 @@ async function handleOutlookBatchImport() {
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
const parts = line.split('----').map(p => p.trim());
|
||||
if (parts.length < 4) {
|
||||
errors.push(`第 ${index + 1} 行格式错误,必须为 邮箱----密码----client_id----refresh_token`);
|
||||
if (parts.length < 2) {
|
||||
errors.push(`第 ${index + 1} 行格式错误`);
|
||||
return;
|
||||
}
|
||||
|
||||
const account = {
|
||||
email: parts[0],
|
||||
password: parts[1],
|
||||
client_id: parts[2],
|
||||
refresh_token: parts[3],
|
||||
client_id: parts[2] || null,
|
||||
refresh_token: parts[3] || null,
|
||||
enabled: enabled,
|
||||
priority: priority
|
||||
};
|
||||
@@ -697,11 +692,6 @@ async function handleOutlookBatchImport() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!account.client_id || !account.refresh_token) {
|
||||
errors.push(`第 ${index + 1} 行 client_id 或 refresh_token 不能为空`);
|
||||
return;
|
||||
}
|
||||
|
||||
accounts.push(account);
|
||||
});
|
||||
|
||||
@@ -777,13 +767,11 @@ async function loadProxies() {
|
||||
try {
|
||||
const data = await api.get('/settings/proxies');
|
||||
renderProxies(data.proxies);
|
||||
updateProxyBulkActions(data.proxies || []);
|
||||
} catch (error) {
|
||||
console.error('加载代理列表失败:', error);
|
||||
updateProxyBulkActions([]);
|
||||
elements.proxiesTable.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="8">
|
||||
<td colspan="7">
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">❌</div>
|
||||
<div class="empty-state-title">加载失败</div>
|
||||
@@ -799,7 +787,7 @@ function renderProxies(proxies) {
|
||||
if (!proxies || proxies.length === 0) {
|
||||
elements.proxiesTable.innerHTML = `
|
||||
<tr>
|
||||
<td colspan="8">
|
||||
<td colspan="7">
|
||||
<div class="empty-state">
|
||||
<div class="empty-state-icon">🌐</div>
|
||||
<div class="empty-state-title">暂无代理</div>
|
||||
@@ -843,17 +831,6 @@ function renderProxies(proxies) {
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function updateProxyBulkActions(proxies) {
|
||||
if (!elements.deleteDisabledProxiesBtn) return;
|
||||
|
||||
const disabledCount = (proxies || []).filter(proxy => !proxy.enabled).length;
|
||||
elements.deleteDisabledProxiesBtn.disabled = disabledCount === 0;
|
||||
elements.deleteDisabledProxiesBtn.dataset.count = String(disabledCount);
|
||||
elements.deleteDisabledProxiesBtn.textContent = disabledCount > 0
|
||||
? `🧹 删除禁用项 (${disabledCount})`
|
||||
: '🧹 删除禁用项';
|
||||
}
|
||||
|
||||
function toggleSettingsMoreMenu(btn) {
|
||||
const menu = btn.nextElementSibling;
|
||||
const isActive = menu.classList.contains('active');
|
||||
@@ -949,12 +926,7 @@ async function testProxyItem(id) {
|
||||
if (result.success) {
|
||||
toast.success(result.message);
|
||||
} else {
|
||||
if (result.auto_disabled) {
|
||||
toast.warning(result.message);
|
||||
await loadProxies();
|
||||
} else {
|
||||
toast.error(result.message);
|
||||
}
|
||||
toast.error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error('测试失败: ' + error.message);
|
||||
@@ -987,22 +959,6 @@ async function deleteProxyItem(id) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteDisabledProxies() {
|
||||
const count = Number(elements.deleteDisabledProxiesBtn?.dataset.count || 0);
|
||||
if (!count) return;
|
||||
|
||||
const confirmed = await confirm(`确定要删除全部 ${count} 个已禁用代理吗?此操作不可恢复。`);
|
||||
if (!confirmed) return;
|
||||
|
||||
try {
|
||||
const result = await api.delete('/settings/proxies/disabled/batch-delete');
|
||||
toast.success(result.message);
|
||||
await loadProxies();
|
||||
} catch (error) {
|
||||
toast.error('批量删除失败: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 测试所有代理
|
||||
async function handleTestAllProxies() {
|
||||
elements.testAllProxiesBtn.disabled = true;
|
||||
@@ -1010,13 +966,8 @@ async function handleTestAllProxies() {
|
||||
|
||||
try {
|
||||
const result = await api.post('/settings/proxies/test-all');
|
||||
const summary = `测试完成: 成功 ${result.success}, 失败 ${result.failed}`;
|
||||
if (result.auto_disabled > 0) {
|
||||
toast.warning(`${summary},已自动禁用 ${result.auto_disabled} 个`);
|
||||
} else {
|
||||
toast.info(summary);
|
||||
}
|
||||
await loadProxies();
|
||||
toast.info(`测试完成: 成功 ${result.success}, 失败 ${result.failed}`);
|
||||
loadProxies();
|
||||
} catch (error) {
|
||||
toast.error('测试失败: ' + error.message);
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user