Exploitation toolbox for some undisclosed endpoints of SYSU.
A pnpm monorepo: environment-free logic lives in core, with a UserScript front end and a CLI on top of it. A browser
extension & APP version may follow.
- Video auto-complete — reports playback progress to the LMS until the video counts as watched.
- Quiz extraction — copies every question and its options to the clipboard.
- AI auto-answer — asks an OpenAI-compatible model for the answers, fills them in, submits. Endpoint, key and model are set behind the ⚙️ button.
- Autopilot — once started, chains through videos, chapter quizzes and review pages until the section runs out.
- CAS login — the CLI signs in through SYSU's SSO and keeps the session, never the password, on disk.
- Calendar export — the term's classes and exams from the 教务系统, the deadlines from the LMS, out as one
.ics. - Profile page — the student record the 学工系统 holds, laid out in the terminal the way Sysuer lays it out on a phone.
- Install Tampermonkey or a compatible userscript manager
- Build the project and install the generated
packages/userscript/dist/sysu-toolbox.user.js
pnpm install --fix-lockfile # Install dependencies
pnpm run typecheck # use tsgo to check TypeScript errors
pnpm run format # format with oxfmt
pnpm run lint:fix # fix lint errors with oxlint
pnpm run knip # check for unused things
pnpm run test # run every package's tests, with merged coverage
pnpm dev # start the userscript dev server with hot reload
pnpm build # build every package| Package | Role |
|---|---|
@mzwing/sysu-toolbox-core |
environment-free logic; ships TypeScript source, no build step |
@mzwing/sysu-toolbox-userscript |
Vite + vite-plugin-monkey front end, wires the GM/DOM adapters in |
@mzwing/sysu-toolbox-cli |
Clerc CLI; CAS login, profile page, .ics export |
core takes its environment as parameters instead of reaching for globals. userscript/host.ts binds the browser to
GM_xmlhttpRequest and localStorage; cli/host.ts binds Node to fetch, node:crypto and a session file.
Everything behind CAS goes through CasTransport, which carries response headers, manual redirects and a binary body
for the captcha. GM_xmlhttpRequest offers none of those, so the userscript keeps the plainer HttpTransport.
sysu-toolbox login <netid> # CAS session only; prompts for the password, never stores it
sysu-toolbox login <netid> --service <url> # also trades the session for a ticket to that service
sysu-toolbox profile # the 学工系统 student record, as a page
sysu-toolbox routes # the LMS pages the userscript handles
sysu-toolbox calendar # course schedule, exams and LMS deadlines → sysu-calendar.ics
sysu-toolbox calendar --source jwxt out.ics # just the 教务系统 side, to a named file
sysu-toolbox calendar --weeks 1-4 - # weeks one to four, to stdoutcalendar mints its own tickets, so a plain login is enough to run it, and the cookies it collects are written
back. --source takes all (the default), jwxt, lms or a comma-separated pair; --term (2025-1) and
--weeks (1-18 or 3,5,7) default to the current term and all of its weeks. Every class becomes its own event
rather than a recurrence rule, so 单双周 and cancelled sessions come out right; times carry TZID=Asia/Shanghai.
profile mints its own ticket too, but the 学工系统 needs one hop more than the others: its front end validates the
CAS ticket itself, in JavaScript, so landing on the redirect target authenticates nothing. authorizeXgxt makes that
exchange — POST /sso/login?realm=sysuRealm&ticket=… — which is what actually mints the access_token cookie. Every
字段分类 then becomes a section, labelled by the column dictionary that comes down with it; a repeating one — 家庭成员
及社会关系, say — becomes one numbered section per record, and empty columns and categories are left out.
jwxt.sysu.edu.cn and xgxt.sysu.edu.cn only answer from inside the campus network; off it the command reports
which host it could not reach and why. Their -443.webvpn.sysu.edu.cn twins are not spoken yet. The LMS half needs
neither.
The session lands in $XDG_CONFIG_HOME/sysu-toolbox/session.json, owner-readable only — treat it as a live
credential. Pipe the password in (echo pw | sysu-toolbox login <netid>) for scripted use; a captcha, when CAS
demands one, is written to a temp file whose path the prompt prints.
| File | Role |
|---|---|
core/routes.ts |
LMS route table, also the source of the @match list |
core/video.ts |
progress reporting and the auto-complete loop |
core/ai.ts |
the prompt and the model call |
core/settings.ts |
settings parsing over a storage port |
core/cas.ts |
the CAS login flow, redirect driver and session record |
core/cookies.ts |
host-keyed cookie jar; doubles as the persisted session shape |
core/ics.ts |
iCalendar writer: octet folding, escaping, the Shanghai zone |
core/jwxt.ts |
教务系统 client: the term's classes and exams as events |
core/lms.ts |
LMS calendar client: assignment and quiz deadlines |
core/xgxt.ts |
学工系统 client: the SPA's ticket exchange, then the student record |
core/json.ts |
forgiving accessors for the hand-parsed API payloads |
cli/host.ts |
the one place core meets Node: transport, RSA, captcha, session file |
cli/prompt.ts |
reading a password without echoing it |
cli/login.ts, calendar.ts |
the commands themselves |
cli/profile.ts |
the profile command, and the column alignment it prints with |
userscript/gm.ts, unsafe.ts |
GM_xmlhttpRequest and page globals behind ordinary APIs |
userscript/host.ts |
the one place core meets the browser: storage key, transports |
userscript/quiz.ts |
quiz DOM scraping and form filling |
userscript/quizRunner.ts |
the AI answering lifecycle the quiz panel renders |
userscript/autopilot.ts |
cross-page automation flags and where to go next |
userscript/*Panel.tsx |
one floating panel per page |
MIT
- @lbyxiaolizi - video auto-completion's concurrent thoughts and suggestions
- @candlest - original script