USTC Helper

Various useful functions for USTC students: verification code bypass, auto login, rec performance improvement and more.

目前為 2022-10-31 提交的版本,檢視 最新版本

// ==UserScript==
// @name         USTC Helper
// @name:zh-CN   USTC 助手
// @license      unlicense
// @namespace    http://tampermonkey.net/
// @version      0.4.1
// @description  Various useful functions for USTC students: verification code bypass, auto login, rec performance improvement and more.
// @description:zh-CN  为 USTC 学生定制的各类实用功能:绕过验证码,自动登录(不可用),睿客网性能优化以及更多。
// @author       PRO
// @match        https://mail.ustc.edu.cn/
// @match        https://mail.ustc.edu.cn/coremail/index.jsp*
// @match        https://passport.ustc.edu.cn/*
// @match        https://rec.ustc.edu.cn/*
// @match        https://recapi.ustc.edu.cn/identity/other_login?*
// @match        https://www.bb.ustc.edu.cn/*
// @match        https://jw.ustc.edu.cn/login
// @icon         https://passport.ustc.edu.cn/images/favicon.ico
// @grant        none
// ==/UserScript==

(function () {
    'use strict';
    var uhp_config = {
        passport: {
            enabled: true, // If false, all features will be disabled for passport.ustc.edu.cn
            bypass_code: true, // Whether to bypass verification code or not
            focus: true // Whether to focus on "Login" button
        },
        mail: {
            enabled: true, // If false, all features will be disabled for mail.ustc.edu.cn
            focus: true, // Whether to focus on "Login" button
            domain: 'mail.ustc.edu.cn' // Automatically switch to given mail domain
            // Expected values:
            // 'mail.ustc.edu.cn'
            // 'ustc.edu.cn'
            // 'ah.edu.cn'
            // '' (Do nothing)
        },
        rec: {
            enabled: true, // If false, all features will be disabled for rec.ustc.edu.cn & recapi.ustc.edu.cn
            autologin: true, // Whether automatically clicks login (USTC cas login)
            opencurrent: true // Whether open links in current tab (Significantly improves performance)
        },
        bb: {
            enabled: true, // If false, all features will be disabled for www.bb.ustc.edu.cn
            autoauth: true, // Whether automatically authenticate when accessing outside school net
            autologin: true // Whether automatically clicks login
        },
        jw: {
            enabled: true, // ...
            login: 'focus' // What to do to the login button: 'none', 'focus', 'click'
        }
    };
    switch (window.location.host) {
        case 'mail.ustc.edu.cn': {
            if (!uhp_config.mail.enabled) {
                console.info("[USTC Helper] 'mail' feature disabled.");
                break;
            }
            if (uhp_config.mail.domain) {
                changeDomain(uhp_config.mail.domain);
                console.info(`[USTC Helper] Domain changed to ${uhp_config.mail.domain}.`);
            }
            if (uhp_config.mail.focus) {
                document.getElementById("login_button").focus();
                console.info("[USTC Helper] Login button focused.");
            }
            break;
        }
        case 'passport.ustc.edu.cn': {
            if (!uhp_config.passport.enabled) {
                console.info("[USTC Helper] 'passport' feature disabled.");
                break;
            }
            let form = document.getElementsByClassName('loginForm')[0];
            let options = {
                childList: true,
                attributes: false,
                subtree: true
            }
            function bypass() {
                let showCode = document.getElementsByName('showCode')[0];
                showCode.value = "";
                let code = document.querySelector('#valiCode');
                if (code) {
                    code.remove();
                    console.info("[USTC Helper] Verification code bypassed.");
                } else {
                    console.info("[USTC Helper] Verification code not found.");
                }
            }
            function focus() {
                document.getElementById('login').focus();
                console.info("[USTC Helper] Login button focused.");
            }
            function main() {
                if (uhp_config.passport.bypass_code) bypass();
                if (uhp_config.passport.focus) focus();
                observer.disconnect();
            }
            let observer = new MutationObserver(main);
            observer.observe(form, options);
            break;
        }
        case 'rec.ustc.edu.cn': {
            if (!uhp_config.rec.enabled) {
                console.info("[USTC Helper] 'rec' feature disabled.");
                break;
            }
            if (uhp_config.rec.opencurrent) {
                window.webpackJsonp.push_ = window.webpackJsonp.push;
                window.webpackJsonp.push = (val) => {
                    if (val[0][0] !== "chunk-5ae262a1")
                        return window.webpackJsonp.push_(val);
                    else { // Following script is adapted from https://rec.ustc.edu.cn/js/chunk-5ae262a1.b84e1461.js
                        val[1]["2c03"] = function (t, e, s) {
                            "use strict";
                            (function (t) {
                                s("55dd");
                                var r = s("a67e");
                                e["a"] = {
                                    name: "GroupLister",
                                    components: {
                                        GroupCreate: function () {
                                            return Promise.all([s.e("chunk-390136ce"), s.e("chunk-662e27b9")]).then(s.bind(null, "18fa"))
                                        },
                                        GroupAdd: function () {
                                            return s.e("chunk-5b916374").then(s.bind(null, "c1c7"))
                                        },
                                        GroupEdit: function () {
                                            return Promise.all([s.e("chunk-390136ce"), s.e("chunk-0daeb591")]).then(s.bind(null, "1fa6"))
                                        }
                                    },
                                    data: function () {
                                        return {
                                            status: {
                                                GroupCreateStatus: !1,
                                                GroupAddStatus: !1,
                                                GroupEditStatus: !1
                                            },
                                            loading: !1,
                                            nothing: !1,
                                            group: {},
                                            sortBy: {},
                                            headers: [{
                                                id: 1,
                                                title: "群名称",
                                                class: "groupname",
                                                sort: "asc",
                                                showSort: !0,
                                                field: "group_name"
                                            }, {
                                                id: 2,
                                                title: "群号",
                                                class: "groupid",
                                                sort: "des",
                                                showSort: !1,
                                                field: "group_number"
                                            }, {
                                                id: 3,
                                                title: "成员",
                                                class: "groupuser",
                                                sort: "des",
                                                showSort: !1,
                                                field: "group_memeber_count"
                                            }, {
                                                id: 5,
                                                title: "分享",
                                                class: "groupshare",
                                                sort: "des",
                                                showSort: !1,
                                                field: "group_share_file_count"
                                            }, {
                                                id: 6,
                                                title: "操作",
                                                class: "groupmenu",
                                                sort: "",
                                                showSort: !1
                                            }]
                                        }
                                    },
                                    created: function () {
                                        this.sortBy = this.headers[0],
                                            this.getGroups()
                                    },
                                    computed: {
                                        userInfo: function () {
                                            return this.$store.state.user.userInfo
                                        }
                                    },
                                    watch: {
                                        $route: function () {
                                            this.getGroups()
                                        }
                                    },
                                    filters: {
                                        identityNameFilter: function (t) {
                                            var e;
                                            switch (t) {
                                                case "owner":
                                                    e = "群主";
                                                    break;
                                                case "admin":
                                                    e = "管理员";
                                                    break;
                                                case "user":
                                                    e = "成员";
                                                    break;
                                                default:
                                                    break
                                            }
                                            return e
                                        }
                                    },
                                    methods: {
                                        createGroup: function () {
                                            t("#newgroup").modal("show")
                                        },
                                        addGroup: function () {
                                            t("#addgroup").modal("show")
                                        },
                                        invite: function (t) {
                                            var e = this.$router.resolve({
                                                name: "group",
                                                params: {
                                                    groupNumber: t.group_number
                                                }
                                            });
                                            this.$confirm({
                                                showYesBtn: !1,
                                                showCopyBtn: !0,
                                                copyBtnText: "复制文字",
                                                title: "邀请入群",
                                                type: "confirm",
                                                content: "打开链接进入群组主页即可申请加入群组:".concat(t.group_name, ",群组主页链接:").concat(window.location.origin).concat(e.href)
                                            }).then((function () { }
                                            )).catch((function () { }
                                            ))
                                        },
                                        goToGroupCloud: function (t, e) {
                                            if (["owner", "admin", "user"].indexOf(t.group_member_identity) < 0)
                                                return this.$message({
                                                    type: "warning",
                                                    message: "您不是组群成员,无法进入群盘"
                                                }),
                                                    !1;
                                            this.$store.commit("setSetting", {
                                                from: !0,
                                                drive: "groupdisk",
                                                tab: e,
                                                group: t
                                            }),
                                                this.$router.push({
                                                    name: "groupDisk",
                                                    params: {
                                                        groupNumber: t.group_number
                                                    }
                                                })
                                        },
                                        isShowMenu: function (t) {
                                            return ["owner", "admin", "user"].indexOf(t.group_member_identity) > -1
                                        },
                                        isEditGroup: function (t) {
                                            return ["owner", "admin"].indexOf(t.group_member_identity) > -1
                                        },
                                        goToGroup: function (t) {
                                            var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "group";
                                            if ("wait" === t.group_is_review)
                                                return this.$message({
                                                    type: "warning",
                                                    message: "群组待审核,不允许操作!"
                                                }),
                                                    !1;
                                            if ("refuse" === t.group_is_review)
                                                return this.$message({
                                                    type: "warning",
                                                    message: "群组审核未通过,不允许操作!"
                                                }),
                                                    !1;
                                            // Instead of opening in new tab, we prefer to use vue's solution
                                            // Modifiy start
                                            this.$router.replace({
                                                name: e,
                                                params: {
                                                    groupNumber: t.group_number
                                                }
                                            });
                                            // Modify end
                                        },
                                        goToGroupHome: function (t) {
                                            this.$store.commit("SET_GROUP_SHOWDESC", !1),
                                                this.$router.push({
                                                    name: "group",
                                                    params: {
                                                        groupNumber: t
                                                    }
                                                })
                                        },
                                        handleEditGroup: function (e) {
                                            var s = this;
                                            Object(r["g"])(e.group_number).then((function (t) {
                                                s.group = t.entity
                                            }
                                            )).catch((function (t) {
                                                s.$message({
                                                    type: "error",
                                                    message: t
                                                })
                                            }
                                            )),
                                                t("#editgroup").modal("show")
                                        },
                                        groupRefresh: function () {
                                            this.getGroups()
                                        },
                                        sortGroup: function (t) {
                                            if (6 === t)
                                                return !1;
                                            var e = this;
                                            this.headers.map((function (s) {
                                                return s.id === t ? (s.showSort = !0,
                                                    s.sort = "des" === s.sort ? "asc" : "des",
                                                    e.sortBy = s,
                                                    s) : (s.showSort = !1,
                                                        s.sort = "des",
                                                        s)
                                            }
                                            )),
                                                this.sortGroupBy()
                                        },
                                        getGroups: function () {
                                            var t = this;
                                            this.groups = [],
                                                this.loading = !0,
                                                this.nothing = !1,
                                                Object(r["r"])({}).then((function (e) {
                                                    if (200 === e.status_code)
                                                        if (t.loading = !1,
                                                            t.groups = e.entity.datas,
                                                            e.entity.total > 0) {
                                                            var s = 0;
                                                            e.entity.datas.map((function (t) {
                                                                "user" != t.group_member_identity && t.group_pending_member_count > 0 && (s += t.group_pending_member_count)
                                                            }
                                                            )),
                                                                t.$store.commit("setRequestNums", s),
                                                                t.sortGroupBy(!0)
                                                        } else
                                                            t.nothing = !0;
                                                    else
                                                        t.$message({
                                                            type: "error",
                                                            message: e.message
                                                        })
                                                }
                                                )).catch((function (e) {
                                                    t.$message({
                                                        type: "error",
                                                        message: e
                                                    })
                                                }
                                                ))
                                        },
                                        sortGroupBy: function () {
                                            var t = this
                                                , e = arguments.length > 0 && void 0 !== arguments[0] && arguments[0];
                                            this.groups.sort((function (s, r) {
                                                var o;
                                                return o = e ? r.group_is_review.localeCompare(s.group_is_review) : "group_name" === t.sortBy.field ? s[t.sortBy.field].localeCompare(r[t.sortBy.field]) : s[t.sortBy.field] - r[t.sortBy.field],
                                                    o = "asc" === t.sortBy.sort ? o : -o,
                                                    o
                                            }
                                            ))
                                        },
                                        groupCancel: function (t) {
                                            var e = this
                                                , s = "adopt" === t.group_is_review ? "解散" : "删除";
                                            this.$confirm({
                                                type: "confirm",
                                                content: "".concat(s, "群后,所有关于本群组的信息都将被删除且无法恢复,确定").concat(s, "【").concat(t.group_name, "】吗?"),
                                                showCancleBtn: !0,
                                                showYesBtn: !0,
                                                custom: []
                                            }).then((function () {
                                                Object(r["u"])({
                                                    groups_list: [t.group_number]
                                                }).then((function (t) {
                                                    200 === t.status_code ? (e.$message({
                                                        type: "success",
                                                        message: t.message
                                                    }),
                                                        e.getGroups()) : e.$message({
                                                            type: "error",
                                                            message: t.message
                                                        })
                                                }
                                                )).catch((function (t) {
                                                    e.$message({
                                                        type: "error",
                                                        message: t
                                                    })
                                                }
                                                ))
                                            }
                                            )).catch((function () { }
                                            ))
                                        },
                                        groupQuit: function (t) {
                                            var e = this;
                                            this.$confirm({
                                                type: "confirm",
                                                content: "确定退出该群组吗?",
                                                showCancleBtn: !0,
                                                showYesBtn: !0,
                                                custom: []
                                            }).then((function () {
                                                Object(r["v"])({
                                                    group_number: t,
                                                    action: "quit",
                                                    members_list: [e.userInfo.user_number]
                                                }).then((function (t) {
                                                    200 === t.status_code ? (e.$message({
                                                        type: "success",
                                                        message: t.message
                                                    }),
                                                        e.getGroups()) : e.$message({
                                                            type: "error",
                                                            message: t.message
                                                        })
                                                }
                                                )).catch((function (t) {
                                                    e.$message({
                                                        type: "error",
                                                        message: t
                                                    })
                                                }
                                                ))
                                            }
                                            )).catch((function () { }
                                            ))
                                        }
                                    },
                                    mounted: function () {
                                        var t = this;
                                        setTimeout((function () {
                                            for (var e in t.status)
                                                t.status[e] = !0
                                        }
                                        ), 500)
                                    }
                                }
                            }
                            ).call(this, s("1157"))
                        };
                        // console.log(val);
                        return window.webpackJsonp.push_(val);
                    }
                };
            }
            if (uhp_config.rec.autologin && document.location.pathname == '/') {
                let app = document.getElementById("app");
                let options = {
                    childList: true,
                    attributes: false,
                    subtree: true
                }
                let observer = new MutationObserver(() => {
                    let btn = document.getElementsByClassName('navbar-login-btn')[0];
                    if (btn) {
                        btn.click();
                        observer.disconnect();
                    }
                });
                observer.observe(app, options);
            } else if (uhp_config.rec.opencurrent) {
                let app = document.getElementById("app");
                let options = {
                    childList: true,
                    attributes: false,
                    subtree: true
                }
                let observer = new MutationObserver(() => {
                    let l = document.getElementsByClassName("app-list").length;
                    if (l) {
                        let links = app.getElementsByTagName("a");
                        for (let link of links) {
                            if (link.target == '_blank') link.removeAttribute("target");
                        }
                    }
                });
                observer.observe(app, options);
            }
            break;
        }
        case 'recapi.ustc.edu.cn': {
            if (!uhp_config.rec.enabled) {
                console.info("[USTC Helper] 'rec' feature disabled.");
                break;
            }
            if (uhp_config.rec.autologin) {
                let btn = document.querySelector("#ltwo > div > button");
                if (!btn) {
                    console.error("[USTC Helper] Login button not found!");
                } else {
                    btn.click();
                }
            }
            break;
        }
        case 'www.bb.ustc.edu.cn': {
            if (!uhp_config.bb.enabled) {
                console.info("[USTC Helper] 'bb' feature disabled.");
                break;
            }
            if (window.location.pathname == '/nginx_auth/' && uhp_config.bb.autoauth) {
                document.getElementsByTagName('a')[0].click();
            } else if ((window.location.pathname == '/' || window.location.pathname == '/webapps/login/') && uhp_config.bb.autologin) {
                document.querySelector('#login > table > tbody > tr > td:nth-child(2) > span > a').click();
            }
            break;
        }
        case 'jw.ustc.edu.cn': {
            if (!uhp_config.jw.enabled) {
                console.info("[USTC Helper] 'jw' feature disabled.");
                break;
            }
            if (uhp_config.jw.login) {
                let btn = document.getElementById('login-unified-wrapper');
                if (uhp_config.jw.login == 'focus') {
                    btn.focus();
                } else if (uhp_config.jw.login == 'click') {
                    btn.click();
                } else {
                    console.error(`[USTC Helper] Unknown option for jw.login: ${uhp_config.jw.login}`);
                }
            }
            break;
        }
        default:
            console.error("[USTC Helper] Unexpected host: " + window.location.host);
            break;
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址