2FA TOTP
// ==UserScript==
// @name 2FA TOTP
// @namespace 2FA TOTP
// @version 0.1.0
// @description 脚本猫后台脚本,一键计算2FA TOTP TOKEN
// @author DreamNya
// @require https://jiangts.github.io/JS-OTP/dist/jsOTP.min.js#sha256-kduNB64Frzc2wd/FnTAUL1dRIvGOqPwsBlb0Su29Z5w=
// @grant GM_setClipboard
// @grant GM_notification
// @grant GM_getValue
// @grant CAT_userConfig
// @background
// ==/UserScript==
/* ==UserConfig==
TOTP设置:
Clipboard:
title: 是否自动复制TOTP到剪贴板
default: '复制'
type: select
values: ['复制','不复制']
Notify:
title: 是否通知TOTP结果
default: '通知'
type: select
values: ['通知','不通知']
NotifyTitle:
title: 通知标题
description: 可选,留空代表默认标题
type: text
NotifyTimeout:
title: 通知持续时间
description: 默认5000ms,最小1000ms
type: number
default: 5000
min: 1000
unit: ms
Secret:
title: TOTP Secret Key
description: 明文存储在脚本猫本地,脚本无任何通讯功能
type: text
==/UserConfig== */
const userConfig = {};
Object.entries(GM_info.userConfig).forEach(([mainKey, configs]) => {
Object.entries(configs).forEach(([subKey, { default: defaultValue, type }]) => {
const value = GM_getValue(`${mainKey}.${subKey}`, defaultValue);
if (type == "select") {
userConfig[subKey] = value == defaultValue;
} else {
userConfig[subKey] = value;
}
});
});
userConfig.FormatNotifyTitle = (userConfig.NotifyTitle ? userConfig.NotifyTitle : "") + " TOTP ";
return new Promise((resolve, reject) => {
try {
const totp = new jsOTP.totp();
const timeCode = totp.getOtp(userConfig.Secret);
userConfig.Clipboard && GM_setClipboard(timeCode);
userConfig.Notify &&
GM_notification({
title: userConfig.FormatNotifyTitle + (userConfig.Clipboard ? "已复制" : ""),
text: timeCode,
timeout: userConfig.NotifyTimeout,
});
resolve();
} catch (err) {
console.error(err);
GM_notification({
title: userConfig.FormatNotifyTitle + "错误",
text: err.message,
});
reject(err.message);
}
});