169 lines
No EOL
3.9 KiB
JavaScript
169 lines
No EOL
3.9 KiB
JavaScript
// otp-add/index.js
|
||
import { createOTP } from '../../services/otp';
|
||
|
||
Page({
|
||
data: {
|
||
form: {
|
||
name: '',
|
||
issuer: '',
|
||
secret: '',
|
||
algorithm: 'SHA1',
|
||
digits: 6,
|
||
period: 30
|
||
},
|
||
algorithms: ['SHA1', 'SHA256', 'SHA512'],
|
||
digitOptions: [6, 8],
|
||
periodOptions: [30, 60],
|
||
submitting: false,
|
||
scanMode: false
|
||
},
|
||
|
||
// 处理输入变化
|
||
handleInputChange(e) {
|
||
const { field } = e.currentTarget.dataset;
|
||
const { value } = e.detail;
|
||
|
||
this.setData({
|
||
[`form.${field}`]: value
|
||
});
|
||
},
|
||
|
||
// 处理选择器变化
|
||
handlePickerChange(e) {
|
||
const { field } = e.currentTarget.dataset;
|
||
const { value } = e.detail;
|
||
|
||
const options = this.data[`${field}Options`] || this.data[field];
|
||
const selectedValue = options[value];
|
||
|
||
this.setData({
|
||
[`form.${field}`]: selectedValue
|
||
});
|
||
},
|
||
|
||
// 扫描二维码
|
||
handleScanQRCode() {
|
||
this.setData({ scanMode: true });
|
||
|
||
wx.scanCode({
|
||
scanType: ['qrCode'],
|
||
success: (res) => {
|
||
try {
|
||
// 解析otpauth://协议的URL
|
||
const url = res.result;
|
||
if (url.startsWith('otpauth://totp/')) {
|
||
const parsedUrl = new URL(url);
|
||
const path = parsedUrl.pathname.substring(1); // 移除开头的斜杠
|
||
|
||
// 解析路径中的issuer和name
|
||
let issuer = '';
|
||
let name = path;
|
||
|
||
if (path.includes(':')) {
|
||
const parts = path.split(':');
|
||
issuer = parts[0];
|
||
name = parts[1];
|
||
}
|
||
|
||
// 从查询参数中获取其他信息
|
||
const secret = parsedUrl.searchParams.get('secret') || '';
|
||
const algorithm = parsedUrl.searchParams.get('algorithm') || 'SHA1';
|
||
const digits = parseInt(parsedUrl.searchParams.get('digits') || '6');
|
||
const period = parseInt(parsedUrl.searchParams.get('period') || '30');
|
||
|
||
// 如果查询参数中有issuer,优先使用
|
||
if (parsedUrl.searchParams.get('issuer')) {
|
||
issuer = parsedUrl.searchParams.get('issuer');
|
||
}
|
||
|
||
this.setData({
|
||
form: {
|
||
name,
|
||
issuer,
|
||
secret,
|
||
algorithm,
|
||
digits,
|
||
period
|
||
}
|
||
});
|
||
|
||
wx.showToast({
|
||
title: '二维码解析成功',
|
||
icon: 'success'
|
||
});
|
||
} else {
|
||
wx.showToast({
|
||
title: '不支持的二维码格式',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
} catch (err) {
|
||
wx.showToast({
|
||
title: '二维码解析失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
fail: () => {
|
||
wx.showToast({
|
||
title: '扫描取消',
|
||
icon: 'none'
|
||
});
|
||
},
|
||
complete: () => {
|
||
this.setData({ scanMode: false });
|
||
}
|
||
});
|
||
},
|
||
|
||
// 提交表单
|
||
handleSubmit() {
|
||
const { form } = this.data;
|
||
|
||
// 表单验证
|
||
if (!form.name) {
|
||
wx.showToast({
|
||
title: '请输入名称',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
if (!form.secret) {
|
||
wx.showToast({
|
||
title: '请输入密钥',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
this.setData({ submitting: true });
|
||
|
||
createOTP(form)
|
||
.then(() => {
|
||
wx.showToast({
|
||
title: '添加成功',
|
||
icon: 'success'
|
||
});
|
||
|
||
// 返回上一页
|
||
setTimeout(() => {
|
||
wx.navigateBack();
|
||
}, 1500);
|
||
})
|
||
.catch(err => {
|
||
wx.showToast({
|
||
title: err.message || '添加失败',
|
||
icon: 'none'
|
||
});
|
||
})
|
||
.finally(() => {
|
||
this.setData({ submitting: false });
|
||
});
|
||
},
|
||
|
||
// 取消
|
||
handleCancel() {
|
||
wx.navigateBack();
|
||
}
|
||
}); |