204 lines
No EOL
5 KiB
JavaScript
204 lines
No EOL
5 KiB
JavaScript
// pages/form/form.js
|
|
const {
|
|
addToken,
|
|
parseURL,
|
|
validateToken,
|
|
showToast
|
|
} = require('../../utils/util');
|
|
|
|
Page({
|
|
/**
|
|
* 页面的初始数据
|
|
*/
|
|
data: {
|
|
type: 'totp', // 默认选择TOTP
|
|
isSubmitting: false // 防止重复提交
|
|
},
|
|
|
|
/**
|
|
* 生命周期函数--监听页面加载
|
|
*/
|
|
onLoad: function (options) {
|
|
// 准备初始数据
|
|
const type = (options.type || 'totp').toLowerCase();
|
|
const isHotp = type === 'hotp';
|
|
|
|
const initialData = {
|
|
type: type,
|
|
formData: {
|
|
issuer: '',
|
|
account: '',
|
|
secret: '',
|
|
algorithm: 'SHA1',
|
|
digits: '6',
|
|
period: '30',
|
|
// 只有HOTP类型才设置counter初始值
|
|
...(isHotp ? { counter: '0' } : {})
|
|
},
|
|
pageReady: true // 直接设置为ready状态
|
|
};
|
|
|
|
// 如果有扫描结果,预处理数据
|
|
if (options.scan) {
|
|
try {
|
|
const scanData = decodeURIComponent(options.scan);
|
|
const parsedToken = parseURL(scanData);
|
|
|
|
if (parsedToken) {
|
|
const type = (parsedToken.type || 'totp').toLowerCase();
|
|
const isHotp = type === 'hotp';
|
|
|
|
initialData.type = type;
|
|
initialData.formData = {
|
|
issuer: parsedToken.issuer || '',
|
|
account: parsedToken.account || '',
|
|
secret: parsedToken.secret || '',
|
|
algorithm: parsedToken.algorithm || 'SHA1',
|
|
digits: parsedToken.digits || '6',
|
|
period: parsedToken.period || '30',
|
|
// 只有HOTP类型才设置counter
|
|
...(isHotp ? { counter: parsedToken.counter || '0' } : {})
|
|
};
|
|
|
|
// 立即显示成功提示
|
|
wx.showToast({
|
|
title: '二维码解析成功',
|
|
icon: 'success',
|
|
duration: 1500
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('解析扫描数据失败:', error);
|
|
wx.showToast({
|
|
title: '无效的二维码数据',
|
|
icon: 'none',
|
|
duration: 1500
|
|
});
|
|
}
|
|
}
|
|
|
|
// 一次性设置所有数据
|
|
this.setData(initialData);
|
|
},
|
|
|
|
/**
|
|
* 处理类型切换
|
|
*/
|
|
onTypeChange: function(e) {
|
|
this.setData({
|
|
type: e.detail.value
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 验证并格式化表单数据
|
|
*/
|
|
validateAndFormatForm: function(values) {
|
|
try {
|
|
// 基本字段验证
|
|
if (!values.issuer || !values.issuer.trim()) {
|
|
throw new Error('请输入服务名称');
|
|
}
|
|
if (!values.account || !values.account.trim()) {
|
|
throw new Error('请输入账户名称');
|
|
}
|
|
if (!values.secret || !values.secret.trim()) {
|
|
throw new Error('请输入密钥');
|
|
}
|
|
|
|
// 格式化数据
|
|
const tokenData = {
|
|
type: this.data.type,
|
|
issuer: values.issuer.trim(),
|
|
account: values.account.trim(),
|
|
secret: values.secret.trim().toUpperCase(),
|
|
algorithm: values.algorithm,
|
|
digits: parseInt(values.digits, 10)
|
|
};
|
|
|
|
// 类型特定字段
|
|
if (this.data.type === 'totp') {
|
|
const period = parseInt(values.period, 10);
|
|
if (isNaN(period) || period < 15 || period > 300) {
|
|
throw new Error('更新周期必须在15-300秒之间');
|
|
}
|
|
tokenData.period = period;
|
|
} else {
|
|
const counter = parseInt(values.counter, 10);
|
|
if (isNaN(counter) || counter < 0) {
|
|
throw new Error('计数器初始值必须大于等于0');
|
|
}
|
|
tokenData.counter = counter;
|
|
}
|
|
|
|
// 使用工具函数验证完整的令牌数据
|
|
const errors = validateToken(tokenData);
|
|
if (errors) {
|
|
throw new Error(errors.join('\n'));
|
|
}
|
|
|
|
return tokenData;
|
|
} catch (error) {
|
|
showToast(error.message, 'none');
|
|
return null;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 提交数据
|
|
*/
|
|
keySubmit: async function (e) {
|
|
// 防止重复提交
|
|
if (this.data.isSubmitting) {
|
|
return;
|
|
}
|
|
|
|
this.setData({ isSubmitting: true });
|
|
|
|
try {
|
|
const values = e.detail.value;
|
|
const tokenData = this.validateAndFormatForm(values);
|
|
|
|
if (!tokenData) {
|
|
this.setData({ isSubmitting: false });
|
|
return;
|
|
}
|
|
|
|
// 添加令牌
|
|
await addToken(tokenData);
|
|
|
|
// 显示成功提示
|
|
wx.showToast({
|
|
title: '添加成功',
|
|
icon: 'success',
|
|
mask: true,
|
|
duration: 800
|
|
});
|
|
|
|
// 获取页面事件通道
|
|
const eventChannel = this.getOpenerEventChannel();
|
|
|
|
// 通知上一页面刷新数据
|
|
if (eventChannel && typeof eventChannel.emit === 'function') {
|
|
eventChannel.emit('tokenAdded');
|
|
}
|
|
|
|
// 立即跳转到首页
|
|
wx.switchTab({
|
|
url: '/pages/index/index'
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('添加令牌失败:', error);
|
|
wx.showToast({
|
|
title: error.message || '添加失败',
|
|
icon: 'none',
|
|
duration: 2000
|
|
});
|
|
} finally {
|
|
this.setData({ isSubmitting: false });
|
|
}
|
|
},
|
|
|
|
// 扫描功能已移至主页面
|
|
}) |