USTC Helper

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

25.11.2022 itibariyledir. En son verisyonu görün.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         USTC Helper
// @name:zh-CN   USTC 助手
// @license      unlicense
// @namespace    http://tampermonkey.net/
// @version      0.5.0
// @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        GM_setValue
// @grant        GM_getValue
// @grant        GM_listValues
// ==/UserScript==

(function () {
    'use strict';
    GM_setValue('foo', 'bar');
    var default_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'
        }
    };
    var uhp_config = {};
    Object.keys(default_config).forEach((key)=>{
        Object.defineProperty(uhp_config, key, {
            get() {
                let user_value = GM_getValue(key);
                if (user_value) {
                    return user_value;
                } else {
                    return default_config[key];
                }
            }
        });
    });
    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;
    }
})();