Skip to content

Instantly share code, notes, and snippets.

@AllanChain
Last active February 24, 2024 08:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AllanChain/c0782061f9e9836e2807a81acfe3b254 to your computer and use it in GitHub Desktop.
Save AllanChain/c0782061f9e9836e2807a81acfe3b254 to your computer and use it in GitHub Desktop.
PKU Auto Click
// ==UserScript==
// @name PKU Auto Click
// @namespace https://gist.github.com/AllanChain/c0782061f9e9836e2807a81acfe3b254
// @version 3.5
// @description 自动点击 PKU IAAA,教学网和邮箱的登录键,首次使用需手动点击一次以使插件记录密码。
// @icon https://www.pku.edu.cn/favicon.ico
// @author Allan Chain
// @copyright 2020 - 2024, Allan Chain
// @homepageURL https://gist.github.com/AllanChain/c0782061f9e9836e2807a81acfe3b254
// @supportURL https://gist.github.com/AllanChain/c0782061f9e9836e2807a81acfe3b254
// @updateURL https://gist.github.com/AllanChain/c0782061f9e9836e2807a81acfe3b254/raw/PKUAutoClick.user.js
// @downloadURL https://gist.github.com/AllanChain/c0782061f9e9836e2807a81acfe3b254/raw/PKUAutoClick.user.js
// @match https://portal.pku.edu.cn/portal2017/
// @match https://course.pku.edu.cn/
// @match https://iaaa.pku.edu.cn/iaaa/oauth.jsp*
// @match https://mail.pku.edu.cn/
// @match https://mail.stu.pku.edu.cn/
// @match https://its.pku.edu.cn/
// @match https://its.pku.edu.cn/index*
// @match https://treehole.pku.edu.cn/web/login
// @license MIT
// @grant none
// ==/UserScript==
/* CHANGELOG
* 2024-02-24 3.5 支持树洞登录
* 2023-10-07 3.4 对需要 OTP 的 IAAA 登录不执行自动点击
* 2023-07-27 3.3 增加 STU 邮箱页面
* 2021-04-22 3.2 增加 ITS 匹配页面
* 2021-03-12 3.1 修改点掉共克时艰的框的时长
* 2021-03-12 3.0 改用简单的加密存储用户名密码。原有的数据需要用户自行删除
* 2021-03-12 2.3 重构代码、添加少量 JSDoc、并支持校内访问门户自动点击登录和自动点掉共克时艰的框
* 2020-10-20 2.2 增加连上 WiFi 后自动打开的 ITS 登录界面的支持
* 2020-10-15 2.1 增加了 ITS 网关的自动点击
* 2020-03-09 2.0 增加手机版(kiwi browser)的支持
* 2020-03-07 1.4 添加 URL
* 2020-03-07 1.3 整理代码
* 2020-03-06 1.2 改用 localStorage 分站点存储(比如使用英文邮箱登录的情况)
* 2020-03-06 1.1 改用对登录键监听而非循环判断密码是否自动填入
* 2020-03-06 1.0 使用 GM.setValue 记住用户名密码
* 2020-02-19 0.1 自动点击 course,IAAA 和邮箱,成功概率玄学,需要用户交互后密码才会自动填写
*/
'use strict'
const $ = document.querySelector.bind(document)
const OTP_APPS = ["HPCSCOWDEV"]
/**
* Do auxiliary action on some pages
* @returns {boolean} Should terminate script
*/
const auxiliaryAction = () => {
if (location.host === 'course.pku.edu.cn') {
location.href = '/webapps/bb-sso-bb_bb60/login.html'
return true
}
if (location.host === 'portal.pku.edu.cn') {
if (location.hash === '#/index') location.hash = '#/bizCenter'
else if (location.hash.startsWith('#/bizCenter')) {
setTimeout(() => {
const infoTip = $('#infoTipBg')
if (infoTip) infoTip.click()
}, 1700)
}
return true
}
if (location.host === 'iaaa.pku.edu.cn') {
return OTP_APPS.includes($('#appid').value)
}
if (location.host === 'treehole.pku.edu.cn') {
$('input[type=checkbox]').click()
return false
}
return false
}
/**
* Login page context, i.e. inputs and button
* @typedef {Object} PageCtx
* @property {HTMLInputElement} username - Username input element.
* @property {HTMLInputElement} password - Password input element.
* @property {HTMLElement} loginBtn - Login button to click.
*/
/**
* Get login page context
* @returns {PageCtx} page context
*/
const loginPageCtx = () => {
if (location.host === 'iaaa.pku.edu.cn') {
return {
username: $('#user_name'),
password: $('#password'),
loginBtn: $('#logon_button')
}
} else if (location.host === 'mail.pku.edu.cn') {
return {
username: $('#username'),
password: $('#password'),
loginBtn: $('#login_button')
}
} else if (location.host == 'mail.stu.pku.edu.cn') {
return {
username: $('#account_name'),
password: $('#password'),
loginBtn: $('#btn_submit')
}
} else if (location.host === 'its.pku.edu.cn') {
return {
username: $('#username'),
password: $('#password'),
loginBtn: $('.loginPanel_v2_btn')
}
} else if (location.host === 'treehole.pku.edu.cn') {
return {
username: $('input'),
password: $('input[type=password]'),
loginBtn: $('button')
}
}
}
/**
* Encrypt / Decrypt with simple xor + key transform
* @param {string} key Encrypt / Decrypt key
* @param {string} s Data to encrypt / decrypt
* @returns {string} Encrypted / Decrypted data
*/
const xorCipher = (key, s) => {
let o = ''
for (let i = 0; i < s.length; i++) {
const char = s.charCodeAt(i)
const codedChar = key ^ char
o += String.fromCharCode(codedChar)
key = (key ^ ((char + codedChar) / 3)) % 128
}
return o
}
/**
* Listen for login buton click and update password
* @param {PageCtx} page The page context
*/
const listenPasswordUpdate = (page) => {
page.loginBtn.addEventListener('click', () => {
localStorage.setItem(
'PKUAuto',
xorCipher(42, JSON.stringify({
username: page.username.value,
password: page.password.value
}))
)
})
}
function main() {
if (auxiliaryAction()) return
const page = loginPageCtx()
const loginData = localStorage.getItem('PKUAuto')
if (loginData === null) return listenPasswordUpdate(page)
try {
const { username, password } = JSON.parse(xorCipher(42, loginData))
page.username.value = username
page.password.value = password
page.loginBtn.click()
} catch (err) {
console.warn(err)
}
listenPasswordUpdate(page)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment