This repository has been archived by the owner on Aug 17, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CasLogin.js
180 lines (147 loc) · 5.78 KB
/
CasLogin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// ==UserScript==
// @name 中大自动验证码认证
// @name:en SYSU CAS Auto Captcha Login
// @name:zh 中大自动验证码认证
// @namespace https://github.com/KumaTea
// @namespace https://greasyfork.org/en/users/169784-kumatea
// @homepage https://github.com/KumaTea/SYSU-CAS
// @version 1.2.0.0
// @description 中山大学身份验证系统自动识别验证码登录
// @description:en Automatic Script for Solving captcha of CAS (Central Authentication Service) of Sun Yat-sen University
// @description:zh 中山大学身份验证系统自动识别验证码登录
// @description:zh-cn 中山大学身份验证系统自动识别验证码登录
// @author KumaTea
// @match https://cas.sysu.edu.cn/cas/login*
// @match https://cas-443.webvpn.sysu.edu.cn/cas/login*
// @license GPLv3
// @require https://greasyfork.org/scripts/437298-tesseract-fast-min-js/code/tesseract-fastminjs.js
// @require https://cdn.jsdelivr.net/npm/sweetalert2@11.3.0/dist/sweetalert2.all.min.js
// ==/UserScript==
/*
为省去手动激活页面的操作
请在此输入您的 NetID 账号密码
此操作不会上传任何信息
*/
const username = '';
const password = '';
/*
Whoa! You found here!
Please replace "tesseract-fastminjs.js" with this link before reading the following instructions:
https://gitee.com/kumatea/tesseract-dist/raw/master/2.1.5/tesseract-fast.min.js
Use fast trained data (1.89 MB) by default.
If you want to use the better trained data (10.4 MB),
replace the "tesseract-fast.min.js" with "tesseract.min.js"
in the '@require' section above.
There is also a best version: "tesseract-best.min.js".
默认使用精简训练数据(1.89 MB)。
如果你想使用标准训练数据(10.4 MB),在上面的 '@require' 部分
把 "tesseract-fast.min.js" 替换为 "tesseract.min.js"。
另有一个最佳版本:"tesseract-best.min.js"。
*/
/* jshint esversion: 8 */
// "use strict";
const delay = 2*1000;
const captcha_regex = /[A-Za-z0-9]/g;
const black_threshold = 50;
console.log("Fetching: https://raw.github.cnpmjs.org/naptha/tessdata/gh-pages/4.0.0_fast/eng.traineddata.gz")
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const mouseClickEvents = ['mousedown', 'click', 'mouseup'];
function simulateMouseClick(element) {
// https://stackoverflow.com/a/54316368
// https://stackoverflow.com/a/69977098
mouseClickEvents.forEach(mouseEventType =>
element.dispatchEvent(
new MouseEvent(mouseEventType)
)
);
}
function react_input(component, value) {
// Credit: https://github.com/facebook/react/issues/11488#issuecomment-347775628
let last_value = component.value;
component.value = value;
let event = new Event("input", {bubbles: true});
// React 15
event.simulated = true;
// React 16
let tracker = component._valueTracker;
if (tracker) {
tracker.setValue(last_value);
}
component.dispatchEvent(event);
}
function load_js(src) {
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = src;
document.head.appendChild(script);
}
function replace_color_in_canvas(canvas) {
let ctx = canvas.getContext("2d");
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
let data = imageData.data;
let len = data.length / 3;
let first_pixel_array = [data[0], data[1], data[2]];
for (let i = 0; i < len; i += 1) {
let r = data[i * 3];
let g = data[i * 3 + 1];
let b = data[i * 3 + 2];
if (r + g < black_threshold || r + b < black_threshold || g + b < black_threshold) {
data[i*3] = first_pixel_array[0];
data[i*3 + 1] = first_pixel_array[1];
data[i*3 + 2] = first_pixel_array[2];
}
}
ctx.putImageData(imageData, 0, 0);
return ctx;
}
function img_src_to_base64(img) {
// Ref: https://stackoverflow.com/a/22172860/10714490
let canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
ctx = replace_color_in_canvas(ctx.canvas);
return ctx.canvas.toDataURL("image/png");
}
function clone_image(img) {
let new_img = document.createElement("img");
new_img.src = img_src_to_base64(img)
return new_img;
}
async function recognize() {
let result = "";
await Tesseract.recognize(clone_image(document.getElementById('captchaImg')), "eng")
.then(({ data: { text } }) => {result = text.match(captcha_regex).join("");});
console.log("Recognized: " + result);
return result;
}
async function solve() {
if (document.getElementById("captcha")) {
Swal.fire({title: "正在加载识别组件……", showConfirmButton: false, timer: 3000});
react_input(document.getElementById("captcha"), "正在加载识别组件,请耐心等待……");
let result = await recognize();
react_input(document.getElementById("captcha"), result);
if (result.length !== 4) {
location.reload();
}
console.log("Submitting: " + result);
if (document.querySelector("input.btn.btn-submit.btn-block").disabled) {
if (username && password) {
react_input(document.getElementById("username"), username);
react_input(document.getElementById("password"), password);
} else {
while (document.querySelector("input.btn.btn-submit.btn-block").disabled) {
console.log("Login button is not clickable!");
Swal.fire({title: "请点击网页以激活登录按钮", showConfirmButton: false, timer: 1000});
await sleep(delay);
}
}
}
document.querySelector("input.btn.btn-submit.btn-block").click();
// simulateMouseClick(document.querySelector("input.btn.btn-submit.btn-block"));
}
}
solve();