fix mine
This commit is contained in:
parent
17a02ea47e
commit
70e7a113e6
22 changed files with 967 additions and 285 deletions
|
@ -222,14 +222,17 @@ Page({
|
|||
|
||||
// 为每个token计算正确的时间戳
|
||||
const updatePromises = tokensToUpdate.map(token => {
|
||||
// 优先使用令牌中的时间戳(如果有的话)
|
||||
const tokenTimestamp = token.timestamp || currentTimestamp;
|
||||
|
||||
if (token.type === 'totp') {
|
||||
// 计算时间窗口的开始时间
|
||||
const period = token.period || 30;
|
||||
const windowStart = Math.floor(currentTimestamp / period) * period;
|
||||
const windowStart = Math.floor(tokenTimestamp / period) * period;
|
||||
return this.updateTokenCode(token, windowStart);
|
||||
} else {
|
||||
// 对于HOTP类型,直接使用当前时间戳
|
||||
return this.updateTokenCode(token, currentTimestamp);
|
||||
// 对于HOTP类型,直接使用时间戳
|
||||
return this.updateTokenCode(token, tokenTimestamp);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -263,14 +266,17 @@ Page({
|
|||
|
||||
// 并行更新所有令牌的验证码,为每个令牌计算其时间窗口的开始时间
|
||||
const updatePromises = tokens.map(token => {
|
||||
// 优先使用令牌中的时间戳(如果有的话)
|
||||
const tokenTimestamp = token.timestamp || currentTimestamp;
|
||||
|
||||
if (token.type === 'totp') {
|
||||
// 计算时间窗口的开始时间
|
||||
const period = token.period || 30;
|
||||
const windowStart = Math.floor(currentTimestamp / period) * period;
|
||||
const windowStart = Math.floor(tokenTimestamp / period) * period;
|
||||
return this.updateTokenCode(token, windowStart);
|
||||
} else {
|
||||
// 对于HOTP类型,直接使用当前时间戳
|
||||
return this.updateTokenCode(token, currentTimestamp);
|
||||
// 对于HOTP类型,直接使用时间戳
|
||||
return this.updateTokenCode(token, tokenTimestamp);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -426,73 +432,33 @@ Page({
|
|||
try {
|
||||
// 解析二维码内容
|
||||
const qrContent = res.result;
|
||||
// 如果是otpauth://格式的URL
|
||||
if (qrContent.startsWith('otpauth://')) {
|
||||
// 小程序兼容的URL解析
|
||||
const [protocolAndPath, search] = qrContent.split('?');
|
||||
const [protocol, path] = protocolAndPath.split('://');
|
||||
const type = protocol.replace('otpauth:', '');
|
||||
|
||||
// 解析路径部分
|
||||
const decodedPath = decodeURIComponent(path.substring(1)); // 移除开头的/
|
||||
let [issuer, remark] = decodedPath.split(':');
|
||||
if (!remark) {
|
||||
remark = issuer;
|
||||
issuer = '';
|
||||
}
|
||||
|
||||
// 解析查询参数
|
||||
const params = {};
|
||||
if (search) {
|
||||
search.split('&').forEach(pair => {
|
||||
const [key, value] = pair.split('=');
|
||||
if (key && value) {
|
||||
params[key] = decodeURIComponent(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 从参数中获取issuer(如果存在)
|
||||
if (params.issuer) {
|
||||
issuer = params.issuer;
|
||||
}
|
||||
|
||||
// 验证secret参数
|
||||
if (!params.secret) {
|
||||
wx.showToast({
|
||||
title: '无效的二维码:缺少secret参数',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 将otpauth类型转换为实际类型
|
||||
let validType = type.toLowerCase();
|
||||
if (validType === 'otpauth') {
|
||||
// 从URI路径中提取实际类型
|
||||
validType = path.split('/')[0].toLowerCase();
|
||||
}
|
||||
|
||||
// 构建表单数据,确保数字类型参数正确转换
|
||||
|
||||
// 导入util.js中的parseURL函数
|
||||
const { parseURL } = require('../../utils/util');
|
||||
|
||||
// 使用parseURL函数解析二维码内容
|
||||
const parsedToken = parseURL(qrContent);
|
||||
|
||||
if (parsedToken) {
|
||||
// 构建表单数据
|
||||
const formData = {
|
||||
type: validType,
|
||||
issuer,
|
||||
remark,
|
||||
secret: params.secret,
|
||||
algorithm: params.algorithm || 'SHA1',
|
||||
digits: params.digits ? parseInt(params.digits, 10) : 6,
|
||||
period: validType === 'totp' ? (params.period ? parseInt(params.period, 10) : 30) : undefined,
|
||||
counter: validType === 'hotp' ? (params.counter ? parseInt(params.counter, 10) : 0) : undefined
|
||||
type: parsedToken.type,
|
||||
issuer: parsedToken.issuer || '',
|
||||
account: parsedToken.account || '',
|
||||
secret: parsedToken.secret || '',
|
||||
algorithm: parsedToken.algorithm || 'SHA1',
|
||||
digits: parsedToken.digits || 6,
|
||||
period: parsedToken.type === 'totp' ? (parsedToken.period || 30) : undefined,
|
||||
counter: parsedToken.type === 'hotp' ? (parsedToken.counter || 0) : undefined
|
||||
};
|
||||
|
||||
|
||||
// 验证必要参数
|
||||
if (formData.digits < 6 || formData.digits > 8) {
|
||||
formData.digits = 6;
|
||||
console.warn('验证码位数无效,已设置为默认值6');
|
||||
}
|
||||
|
||||
if (validType === 'totp' && (formData.period < 15 || formData.period > 60)) {
|
||||
if (formData.type === 'totp' && (formData.period < 15 || formData.period > 60)) {
|
||||
formData.period = 30;
|
||||
console.warn('TOTP周期无效,已设置为默认值30秒');
|
||||
}
|
||||
|
@ -640,14 +606,22 @@ Page({
|
|||
// 获取当前令牌列表
|
||||
const tokens = await wx.getStorageSync('tokens') || [];
|
||||
|
||||
// 生成唯一ID和时间戳
|
||||
// 生成唯一ID和时间戳
|
||||
const newToken = {
|
||||
...tokenData,
|
||||
id: Date.now().toString(),
|
||||
createdAt: new Date().toISOString(),
|
||||
lastUpdate: new Date().toISOString()
|
||||
createTime: formatTime(new Date()),
|
||||
lastUpdate: formatTime(new Date()),
|
||||
code: '' // 初始化为空字符串
|
||||
};
|
||||
|
||||
// 对于HOTP类型,添加counter字段
|
||||
if (tokenData.type && tokenData.type.toUpperCase() === 'HOTP') {
|
||||
newToken.counter = 0; // HOTP类型需要counter >= 0
|
||||
}
|
||||
// 对于TOTP类型,不设置counter字段,让它在JSON序列化时被忽略
|
||||
|
||||
// 如果是TOTP类型,先初始化剩余时间
|
||||
if ((newToken.type || 'totp').toLowerCase() === 'totp') {
|
||||
const period = parseInt(newToken.period || '30', 10);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue