Repository navigation
Authenticate to the backend with our own session token - #1064
Conversation
Swap the PHPSESSID for a backend-issued token once, kept in GM storage, and send only the token after that. The PHPSESSID is sent again only when the backend asks for it (SessionRequired), on re-exchange, or when the notification socket connects before we have a token, in which case the socket fetches one for everyone. Concurrent requests share one exchange; an invalid token is replaced transparently; logging out revokes it. Needs XMOJ-Script-dev/XMOJ-bbs#75 deployed first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Reviewer's GuideReworks client authentication around a backend-issued, GM-storage-backed session token, centralizes token-aware HTTP handling, adapts notification sockets to token authentication, and revokes the token during logout while retaining narrowly scoped PHPSESSID fallback behavior. Sequence diagram for backend token request and retry flowsequenceDiagram
participant Client
participant RequestAPI
participant GMStorage
participant Backend
participant XMOJ
Client->>RequestAPI: RequestAPI(Action, Data, CallBack, ErrorCallBack)
RequestAPI->>GMStorage: GetStoredBackendToken()
alt token missing or account changed
RequestAPI->>XMOJ: GetPHPSESSID()
RequestAPI->>Backend: PostAPI(Login, SessionID, Username)
Backend-->>RequestAPI: Token
RequestAPI->>GMStorage: StoreBackendToken(Token)
end
RequestAPI->>Backend: PostAPI(Action, Token, Data)
alt TokenInvalid
RequestAPI->>GMStorage: StoreBackendToken("")
RequestAPI->>Backend: PostAPI(Login, SessionID, Username)
Backend-->>RequestAPI: Replacement Token
RequestAPI->>Backend: PostAPI(Action, Token, Data)
else SessionRequired
RequestAPI->>XMOJ: GetPHPSESSIDOrReset()
RequestAPI->>Backend: PostAPI(Action, Token, SessionID, Data)
end
Backend-->>Client: Result
Sequence diagram for notification socket token authenticationsequenceDiagram
participant Client
participant Socket as NotificationSocket
participant Backend
participant GMStorage
Client->>GMStorage: GetStoredBackendToken()
alt token available
Client->>Socket: ConnectNotificationSocket()
Socket->>Backend: WebSocket /ws/notifications?Token=Token
else token missing
Client->>Socket: ConnectNotificationSocket()
Socket->>Backend: WebSocket /ws/notifications?SessionID=PHPSESSID&IssueToken=1
Backend-->>Socket: connected token
Socket-->>Client: connected message
Client->>GMStorage: StoreBackendToken(Token)
end
Backend-->>Socket: Notification messages
Sequence diagram for token revocation during logoutsequenceDiagram
actor User
participant Client
participant GMStorage
participant Backend
participant XMOJ
User->>Client: 注销
Client->>GMStorage: GetStoredBackendToken()
Client->>GMStorage: StoreBackendToken("")
alt token exists
Client->>Backend: PostAPI(Logout, Token)
Backend-->>Client: Logout result or timeout
end
Client->>XMOJ: Navigate to logout.php
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Deploying xmoj-script-dev-channel with
|
| Latest commit: |
8e6b60d
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://2e96db67.xmoj-script-dev-channel.pages.dev |
| Branch Preview URL: | https://session-token.xmoj-script-dev-channel.pages.dev |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 365f11990d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The account and profile tests run the source between `let RequestAPI` and `let SyncSettingsToCloud`, so RequestAPI now opens the auth block and the token helpers follow it. With a stored token it sends synchronously, and a throwing transport is caught on the async paths too. The test fixtures give the user a stored token, as a logged-in user has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
A body such as `null` parses fine but has no fields, and reading result.Success on it threw, turning "服务器响应异常" into a generic "请求失败". Only look for TokenInvalid/SessionRequired in real results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
0 issues found across 5 files (changes from recent commits).
Requires human review: Replaces per-request PHPSESSID auth with backend-issued session tokens (exchange, retry/revocation, socket handshake). This changes authentication and data-handling policy and depends on deploying the backend first, so it needs human sign-off.
Turn on auto-fix | Re-trigger cubic
There was a problem hiding this comment.
Review completed against the latest diff
Reply with feedback, questions, or to request a fix.
Turn on auto-fix | Re-trigger cubic
An empty document.cookie PHPSESSID means the cookie is httpOnly, which GetPHPSESSIDOrReset is already fixing with a reload; the user is logged in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Auto-approval blocked by 3 unresolved issues from previous reviews.
Turn on auto-fix | Re-trigger cubic
…r Login
A script that updates before the backend deploys (or after a backend
rollback) got "访问的页面不存在" from Login and failed every request. If
Login doesn't exist, use {SessionID, Username} for the rest of the page
load, as that backend expects.
A failed exchange is now remembered for 30 seconds, so a page full of
requests doesn't send the PHPSESSID once per request while xmoj is down.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Turn on auto-fix | Re-trigger cubic
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 705bc4d355
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A second logout entry, behind a confirmation, calls LogoutAll and then logs this device out as 注销 does. Other devices' sockets are closed with 4001; they drop their token and, if still logged in to xmoj, quietly get a new one. A token on its own is locked out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Auto-approval blocked by 4 unresolved issues from previous reviews.
Turn on auto-fix | Re-trigger cubic
- Logout waits briefly for a token exchange under way and revokes what it produced; after that no exchange starts, and a token still arriving (slow Login, or the socket) is revoked instead of stored. - A backend rolled back to before tokens answers "参数Token未知"; fall back to the old auth for the page load and keep the token for later. - Failed socket handshakes no longer delete a token: after three, ask the backend over HTTP, and only a TokenInvalid answer drops it. - The site's own logout (the classic logout.php link, the /web app's POST /api/logout) now revokes our token too, for users with ResetType off. - DebugMode logs redact tokens and PHPSESSIDs. - Only accept a Login reply that actually carries a token. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Replaces per-request PHPSESSID authentication with backend-issued session tokens, including exchange, retry, socket handshake, and revocation. This is a deliberate authentication and data-handling policy change that needs human sign-off despite the old-backend fallback.
Turn on auto-fix | Re-trigger cubic
The button ends plugin sessions, not XMOJ ones, so someone who has the password can simply log back in. The confirmation now leads with changing the XMOJ password, then lists what the button does and does not do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Replaces per-request PHPSESSID authentication with backend-issued session tokens, including exchange, retry, socket handshake, and revocation. This remains a deliberate authentication and data-handling policy change needing human sign-off despite the added warning dialog and tests.
View guided diff | Turn on auto-fix | Re-trigger cubic
New setting next to 调试模式, 调试日志中隐藏登录凭证, on by default so pasted logs stay safe. Turning it off logs tokens and PHPSESSIDs as they are. It is a sibling of DebugMode rather than a child: an entry with children renders as a heading without its own checkbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A
57cc40c to
8e6b60d
Compare
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Changes backend authentication to backend-issued session tokens and adds a “log out all devices” action. Human sign-off is needed for the authentication and data-handling policy change.
View guided diff | Turn on auto-fix | Re-trigger cubic
What does this PR aim to accomplish?:
This is the client side of XMOJ-Script-dev/XMOJ-bbs#75. It is safe to ship in either order. Against a backend without
Login(before #75 deploys, or after a rollback), the script falls back to the old{SessionID, Username}auth for that page load.Today every backend request sends the user's raw PHPSESSID, and the backend checks it against xmoj, which is slow. With this PR the script trades the PHPSESSID once for a token issued by our backend, then sends only the token. That makes requests faster and means the backend sees users' cookies as rarely as possible.
How does this PR accomplish the above?:
GetBackendToken()returns the stored token, or exchanges the PHPSESSID for one throughLogin. Concurrent callers share a single exchange.CurrentUsername, so switching accounts gets a new one.RequestAPIsends{Token}. It handles two replies:TokenInvalid: drop the token, re-exchange, and retry once.SessionRequired: retry once with{Token, SessionID}. OnlyUploadStd, andGetStdbefore a score is cached, ever do this.GetNoticeandGetAddOnScriptare sent without auth, so they still work when logged out.PostAPIwithout behaviour changes. The httpOnly cookie reset now runs only when a PHPSESSID is actually needed, instead of on every request.?Token=.IssueToken=1and stores the token from theconnectedmessage. Requests made meanwhile wait for it and fall back toLoginif it doesn't arrive.Login: ifLoginanswers "访问的页面不存在", the script uses the old auth for the rest of the page load.LogoutAll(Add LogoutAll: sign a user out of the backend on every device XMOJ-bbs#76), then logs this device out like 注销. Sockets the backend closes with4001drop their token, so their next connection re-verifies the xmoj session for a new token.Logout, 2 s timeout) before going tologout.php. It never exchanges a PHPSESSID just to revoke.Testing
wrangler devof XMOJ-bbs#75, with stubbed GM APIs and a fake PHPSESSID seeded into the local session cache. All 11 checks passed:Login, then token-only requestsGetStdsending the PHPSESSID only on the requested retryGetNoticeworking logged outLoginwhen the socket can't mint a tokenwrangler devof XMOJ-bbs#75, logged in to real xmoj as zhuchenrui2. On a fresh install:LoginGetStdsent the cookie only on the requested retry, and the second call was served from the score cache without itwrangler dev. Another device's socket closed with4001, its token was dropped, a copied token was refused, and the device, still logged in to xmoj, quietly got a new token and reconnected.masterlocally. Three concurrent requests made oneLoginprobe, then used the old auth, and no later request probed again.Login.account-settingsandprofile-pagerun the source betweenlet RequestAPIandlet SyncSettingsToCloud.RequestAPItherefore opens the auth block, and their fixtures now give the user a stored token, as a logged-in user has.nullis still passed to the caller.npm test: 99/99 locally.tests/userscript-harness.cjs, logged in, run in all four combinations:MonochromeUIon and off/webpages and its old pages (20 pages per run)/webredirects land correctlydev, there are no new console errors apart from the blocked backend callsCannot read properties of undefined (reading 'EmailHash')also appears ondev. It comes fromGetUserInforeturningundefinedwhen xmoj's ownuserinfo.phpfetch fails, so it predates this PR.Does this PR need a documentation update?:
No
By submitting this pull request, I confirm the following:
devfor XMOJ-Script,masterfor everything else).git rebase)MonochromeUIon/off × XMOJ/weband old pages. The harness blocks the backend, so a human should still click 注销 and open the BBS/mail pages once against the deployed backend.)🤖 Generated with Claude Code
https://claude.ai/code/session_017dqWu3YgeVRGwBt5pXDq4A