feat: register Shareit IDs with QR
This commit is contained in:
+84
-44
@@ -2,9 +2,7 @@
|
||||
const auth = window.TrafficAuth;
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const enrollmentByUser = new Map();
|
||||
const userSelect = $('loginUser');
|
||||
|
||||
auth.users.forEach((user) => userSelect.add(new Option(`${user.username} · ${user.role === 'admin' ? '管理员' : '普通用户'}`, user.username)));
|
||||
let selectedUsername = '';
|
||||
|
||||
function nextPage() {
|
||||
const next = new URLSearchParams(location.search).get('next');
|
||||
@@ -18,36 +16,86 @@
|
||||
}
|
||||
|
||||
function currentEnrollment() {
|
||||
const username = userSelect.value;
|
||||
if (!enrollmentByUser.has(username)) enrollmentByUser.set(username, auth.createEnrollment(username));
|
||||
return enrollmentByUser.get(username);
|
||||
if (!enrollmentByUser.has(selectedUsername)) enrollmentByUser.set(selectedUsername, auth.createEnrollment(selectedUsername));
|
||||
return enrollmentByUser.get(selectedUsername);
|
||||
}
|
||||
|
||||
function renderMode() {
|
||||
const username = userSelect.value;
|
||||
const user = auth.findUser(username);
|
||||
const enrolled = auth.isEnrolled(username);
|
||||
$('selectedRole').innerHTML = `<span class="user-role ${user.role}">${user.role === 'admin' ? '管理员' : '普通用户'}</span><small>${enrolled ? '已在当前浏览器绑定' : '首次使用,需要完成本机设置'}</small>`;
|
||||
$('signinForm').classList.toggle('hidden', !enrolled);
|
||||
$('enrollForm').classList.toggle('hidden', enrolled);
|
||||
$('loginTitle').textContent = enrolled ? '用户登录' : '首次绑定';
|
||||
$('loginSubtitle').textContent = enrolled ? '密码和动态验证码双重验证' : '设置密码并绑定 Google Authenticator';
|
||||
$('signinMessage').textContent = '';
|
||||
$('enrollMessage').textContent = '';
|
||||
if (!enrolled) {
|
||||
const enrollment = currentEnrollment();
|
||||
$('setupKey').textContent = enrollment.secret.match(/.{1,4}/g).join(' ');
|
||||
$('authAccountName').textContent = `Traffic Intelligence (${username})`;
|
||||
function renderQr(otpauthUrl) {
|
||||
const container = $('qrCode');
|
||||
container.innerHTML = '';
|
||||
if (typeof window.qrcode !== 'function') {
|
||||
container.innerHTML = '<span class="qr-error">二维码加载失败,请刷新页面重试</span>';
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const qr = window.qrcode(0, 'M');
|
||||
qr.addData(otpauthUrl);
|
||||
qr.make();
|
||||
container.innerHTML = qr.createSvgTag(5, 4);
|
||||
return true;
|
||||
} catch (_) {
|
||||
container.innerHTML = '<span class="qr-error">二维码生成失败,请刷新页面重试</span>';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function resetForms() {
|
||||
['signinPassword','signinCode','newPassword','confirmPassword','setupCode'].forEach((id) => { $(id).value = ''; });
|
||||
$('accountMessage').textContent = '';
|
||||
$('signinMessage').textContent = '';
|
||||
$('enrollMessage').textContent = '';
|
||||
}
|
||||
|
||||
function openAccount(username) {
|
||||
selectedUsername = username;
|
||||
const enrolled = auth.isEnrolled(username);
|
||||
$('accountForm').classList.add('hidden');
|
||||
$('confirmedAccount').classList.remove('hidden');
|
||||
$('confirmedUser').textContent = username;
|
||||
$('signinForm').classList.toggle('hidden', !enrolled);
|
||||
$('enrollForm').classList.toggle('hidden', enrolled);
|
||||
$('loginTitle').textContent = enrolled ? '欢迎回来' : '首次注册';
|
||||
$('loginSubtitle').textContent = enrolled ? '输入密码和动态验证码登录' : '扫描二维码并设置本机密码';
|
||||
if (!enrolled) {
|
||||
const ready = renderQr(currentEnrollment().otpauthUrl);
|
||||
$('enrollMessage').textContent = ready ? '' : '二维码组件加载失败,暂时无法完成注册';
|
||||
}
|
||||
}
|
||||
|
||||
function changeAccount() {
|
||||
selectedUsername = '';
|
||||
resetForms();
|
||||
$('confirmedAccount').classList.add('hidden');
|
||||
$('signinForm').classList.add('hidden');
|
||||
$('enrollForm').classList.add('hidden');
|
||||
$('accountForm').classList.remove('hidden');
|
||||
$('loginTitle').textContent = 'Shareit ID 登录';
|
||||
$('loginSubtitle').textContent = '输入你的 Shareit ID 继续';
|
||||
$('loginUser').focus();
|
||||
}
|
||||
|
||||
$('accountForm').addEventListener('submit', (event) => {
|
||||
event.preventDefault();
|
||||
const username = $('loginUser').value.trim().toLowerCase();
|
||||
if (!username) {
|
||||
$('accountMessage').textContent = '请输入 Shareit ID';
|
||||
return;
|
||||
}
|
||||
if (!auth.findUser(username)) {
|
||||
$('accountMessage').textContent = '该 Shareit ID 不在授权名单中';
|
||||
return;
|
||||
}
|
||||
resetForms();
|
||||
openAccount(username);
|
||||
});
|
||||
|
||||
$('signinForm').addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
const button = event.submitter;
|
||||
button.disabled = true;
|
||||
$('signinMessage').textContent = '正在验证…';
|
||||
try {
|
||||
await auth.login(userSelect.value, $('signinPassword').value, $('signinCode').value);
|
||||
await auth.login(selectedUsername, $('signinPassword').value, $('signinCode').value);
|
||||
location.href = nextPage();
|
||||
} catch (error) {
|
||||
$('signinMessage').textContent = error.message;
|
||||
@@ -62,11 +110,15 @@
|
||||
$('enrollMessage').textContent = '两次输入的密码不一致';
|
||||
return;
|
||||
}
|
||||
if (typeof window.qrcode !== 'function') {
|
||||
$('enrollMessage').textContent = '二维码组件尚未加载,请刷新页面重试';
|
||||
return;
|
||||
}
|
||||
const button = event.submitter;
|
||||
button.disabled = true;
|
||||
$('enrollMessage').textContent = '正在绑定…';
|
||||
$('enrollMessage').textContent = '正在注册…';
|
||||
try {
|
||||
await auth.enroll(userSelect.value, password, currentEnrollment().secret, $('setupCode').value);
|
||||
await auth.enroll(selectedUsername, password, currentEnrollment().secret, $('setupCode').value);
|
||||
location.href = nextPage();
|
||||
} catch (error) {
|
||||
$('enrollMessage').textContent = error.message;
|
||||
@@ -74,32 +126,20 @@
|
||||
}
|
||||
});
|
||||
|
||||
$('copySetupKey').addEventListener('click', async () => {
|
||||
const secret = currentEnrollment().secret;
|
||||
try { await navigator.clipboard.writeText(secret); }
|
||||
catch (_) {
|
||||
const area = document.createElement('textarea'); area.value = secret;
|
||||
document.body.appendChild(area); area.select(); document.execCommand('copy'); area.remove();
|
||||
}
|
||||
showToast('设置密钥已复制');
|
||||
});
|
||||
|
||||
$('changeAccount').addEventListener('click', changeAccount);
|
||||
$('resetEnrollment').addEventListener('click', () => {
|
||||
const username = userSelect.value;
|
||||
if (!window.confirm(`确定清除 ${username} 在当前浏览器的密码和 Authenticator 绑定吗?`)) return;
|
||||
if (!window.confirm(`确定清除 ${selectedUsername} 在当前浏览器的密码和 Authenticator 绑定吗?`)) return;
|
||||
try {
|
||||
auth.clearEnrollment(username);
|
||||
enrollmentByUser.delete(username);
|
||||
$('signinPassword').value = '';
|
||||
$('signinCode').value = '';
|
||||
renderMode();
|
||||
showToast('本机绑定已清除,请重新设置');
|
||||
auth.clearEnrollment(selectedUsername);
|
||||
enrollmentByUser.delete(selectedUsername);
|
||||
resetForms();
|
||||
openAccount(selectedUsername);
|
||||
showToast('本机绑定已清除,请重新注册');
|
||||
} catch (error) {
|
||||
$('signinMessage').textContent = error.message;
|
||||
}
|
||||
});
|
||||
|
||||
userSelect.addEventListener('change', renderMode);
|
||||
if (auth.currentUser()) location.replace(nextPage());
|
||||
else renderMode();
|
||||
else $('loginUser').focus();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user