// ==UserScript== // @name 洛谷显示两步验证码 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 在两步验证的设置与验证页面添加验证码显示,设置页面添加一键设置密钥,且可分用户设置。请注意密钥明文存储于本地,一旦泄露将导致他人可以通过您的验证。如果功能未显示请尝试刷新。 // @author WYXkk // @match https://www.luogu.com.cn/auth/unlock // @match https://www.luogu.com.cn/user/twoFactorSetup // @icon https://www.google.com/s2/favicons?sz=64&domain=luogu.com.cn // @grant none // @downloadURL none // ==/UserScript== async function untilGet(id) { var u=undefined; while(u==undefined) { u=document.querySelectorAll(id)[0]; await new Promise(resolve => setTimeout(resolve, 100)); } return u; } (async function() { var user=await (async ()=>{ var x='x'; while(isNaN(parseInt(x))) x=(await untilGet('#app > div.main-container > div.wrapper.wrapped.lfe-body.header-layout.tiny > div.container > nav > span > span > a')).href.split('/').reverse()[0]; return x; })(); var secrets=JSON.parse(localStorage.getItem('twoFactorCode')||'{}'); var secret=secrets[user]; //copied from https://github.com/jiangts/JS-OTP (function(){var a,b;b=function(){function a(a,b){if(this.expiry=null!=a?a:30,this.length=null!=b?b:6,this.length>8||this.length<6)throw"Error: invalid code length"}return a.prototype.dec2hex=function(a){return(15.5>a?"0":"")+Math.round(a).toString(16)},a.prototype.hex2dec=function(a){return parseInt(a,16)},a.prototype.base32tohex=function(a){var b,c,d,e,f,g;for(b="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",c="",e="",f=0;f=a.length&&(a=Array(b+1-a.length).join(c)+a),a},a.prototype.getOtp=function(a,b){var c,d,e,f,g,h,i;if(null==b&&(b=(new Date).getTime()),e=this.base32tohex(a),c=Math.round(b/1e3),i=this.leftpad(this.dec2hex(Math.floor(c/this.expiry)),16,"0"),h=new jsSHA("SHA-1","HEX"),h.setHMACKey(e,"HEX"),h.update(i),d=h.getHMAC("HEX"),"KEY MUST BE IN BYTE INCREMENTS"===d)throw"Error: hex key must be in byte increments";return f=this.hex2dec(d.substring(d.length-1)),g=(this.hex2dec(d.substr(2*f,8))&this.hex2dec("7fffffff"))+"",g=g.substr(g.length-this.length,this.length)},a}(),a=function(){function a(a){if(this.length=null!=a?a:6,this.length>8||this.length<6)throw"Error: invalid code length"}return a.prototype.uintToString=function(a){var b,c;return c=String.fromCharCode.apply(null,a),b=decodeURIComponent(escape(c))},a.prototype.getOtp=function(a,b){var c,d,e,f,g;return f=new jsSHA("SHA-1","TEXT"),f.setHMACKey(a,"TEXT"),f.update(this.uintToString(new Uint8Array(this.intToBytes(b)))),c=f.getHMAC("HEX"),d=this.hexToBytes(c),e=15&d[19],g=(127&d[e])<<24|(255&d[e+1])<<16|(255&d[e+2])<<8|255&d[e+3],g+="",g.substr(g.length-this.length,this.length)},a.prototype.intToBytes=function(a){var b,c;for(b=[],c=7;c>=0;)b[c]=255&a,a>>=8,--c;return b},a.prototype.hexToBytes=function(a){var b,c,d;for(c=[],d=0,b=a.length;b>d;)c.push(parseInt(a.substr(d,2),16)),d+=2;return c},a}(),window.jsOTP={},jsOTP.totp=b,jsOTP.hotp=a}).call(this);var SUPPORTED_ALGS=7;!function(a){"use strict";function b(a,b){this.highOrder=a,this.lowOrder=b}function c(a,b,c,d){var e,f,g,h,i,j,k=[],l=[],m=0;if(k=c||[0],d=d||0,h=d>>>3,"UTF8"===b)for(f=0;fe?l.push(e):2048>e?(l.push(192|e>>>6),l.push(128|63&e)):55296>e||e>=57344?l.push(224|e>>>12,128|e>>>6&63,128|63&e):(f+=1,e=65536+((1023&e)<<10|1023&a.charCodeAt(f)),l.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|63&e)),g=0;g>>2;k.length<=i;)k.push(0);k[i]|=l[g]<<8*(3-j%4),m+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(f=0;f>>8),j=m+h,i=j>>>2;k.length<=i;)k.push(0);k[i]|=e<<8*(2-j%4),m+=2}return{value:k,binLen:8*m+d}}function d(a,b,c){var d,e,f,g,h,i,j=a.length;if(d=b||[0],c=c||0,i=c>>>3,0!==j%2)throw new Error("String of HEX type must be in byte increments");for(e=0;j>e;e+=2){if(f=parseInt(a.substr(e,2),16),isNaN(f))throw new Error("String of HEX type contains invalid characters");for(h=(e>>>1)+i,g=h>>>2;d.length<=g;)d.push(0);d[g]|=f<<8*(3-h%4)}return{value:d,binLen:4*j+c}}function e(a,b,c){var d,e,f,g,h,i=[];for(i=b||[0],c=c||0,f=c>>>3,e=0;e>>2,i.length<=g&&i.push(0),i[g]|=d<<8*(3-h%4);return{value:i,binLen:8*a.length+c}}function f(a,b,c){var d,e,f,g,h,i,j,k,l,m=[],n=0,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";if(m=b||[0],c=c||0,j=c>>>3,-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw new Error("Invalid character in base-64 string");if(i=a.indexOf("="),a=a.replace(/\=/g,""),-1!==i&&i div.main-container > main > div > div > div > div > div > div > div.form-item > label'); u.innerHTML="两步验证码:
114514
,1919s 后更新
"; update(); setInterval(update, 1000); } else if(url=='https://www.luogu.com.cn/user/twoFactorSetup') { var t=await untilGet('#app > div.main-container > main > div > div > div > div > div > div > ol > li:nth-child(2)'); t.append(document.createElement('button')); t.children[t.childElementCount-1].outerHTML=''; window.updateSecret=async ()=>{ var newSecret=(await untilGet('#app > div.main-container > main > div > div > div > div > div > div > ol > li:nth-child(2) > b')).innerText; secret=secrets[user]=newSecret;localStorage.setItem('twoFactorCode',JSON.stringify(secrets)); } var w=await untilGet('#app > div.main-container > main > div > div > div > div > div > div > ol > li:nth-child(3)'); var ww=w.children[w.childElementCount-1]; w.insertBefore(document.createElement('div'),ww); w.children[w.childElementCount-2].outerHTML="
114514
,1919s 后更新
"; update(); setInterval(update, 1000); } })();